Emrun 和无头铬 - 如何让这两者协同工作?

Emrun and headless chrome - how to make those two work together?

本文关键字:协同工作 Emrun      更新时间:2023-10-16

我想在 docker 环境中使用无头 chrome 来运行编译为 Web 汇编的 c++ 测试。

我已经确保我的测试可执行文件与--emrun标志链接,以确保所有输出都发布到 emrun 服务器并打印到控制台(然后由 CTest 框架捕获(。

但是,当运行无头镀铬时

emrun --browser=chrome --browser_args="--no-sandbox --disable-gpu --use-gl=swiftshader --headless" ./MyTestExecutable.html --gtest_filter=MyTestFixture.myTest

没有任何东西被打印到输出中。但是,如果我将命令更改为

emrun --browser=chrome --browser_args="--no-sandbox --disable-gpu --use-gl=swiftshader --headless --remote-debugging-port=9222" ./MyTestExecutable.html --gtest_filter=MyTestFixture.myTest

测试输出愉快地打印到命令行,但如果输出超过 cca 9kB,则会被截断,这本身就是一个问题 - 见下文。但是,chrome 调试会话一直挂起并使用端口 9222。我目前的解决方法是确保 CTest 框架中的每个单元测试都有自己唯一的调试端口,并让 chrome 会话保持生成状态,直到容器停止 - docker 会清理它们。这个解决方案很脏,我不喜欢它。

我想知道是否有人知道如果不向 Chrome 提供--remote-debugging-port,为什么不会从 emrun 服务器打印任何内容?

我的预感是,chrome 在完成执行后停止向 emrun 服务器发送数据,并且启用调试会以某种方式减慢 chrome,从而腾出时间将至少一些输出发送到 emrun 服务器(这也解释了大输出大小的截断(。

我还去查看了Emscripten人员如何运行他们的CI测试,并看到他们在Xvfb下使用全铬而不是无头铬。但是,我也尝试过,这导致了其他一些问题,例如如果在容器内运行,则使用 SIGTRAP 进行 chrome 崩溃,但不作为 root 用户和 Jenkins 的 docker 插件在用户模式下运行所有容器(即你不是容器内的根 - 理论上我可以让 Jenkins 以 root 身份运行容器,但这会导致我不希望有的其他问题(。

除此之外,在 Xvfb 下的 chrome 的情况下仍然存在日志截断,所以这对我来说仍然是有问题的。

最后,我尝试使用 Firefox 进行测试,它有点工作,但行为很奇怪:

emrun --browser=firefox --browser_args="--headless" ./MyTestExecutable.html --gtest_filter=MyTestFixture.myTest

工作正常,输出不会被截断。但是,再次运行相同的命令会随着 emrun 服务器的启动而失败,因为它默认侦听的端口 (6931( 正在使用中。这很奇怪,因为 emrun 服务器没有列在ps输出中,但是有几个firefox-bin,这表明 Firefox 在 emrun 进程完成后一直挂起,更奇怪的是,杀死这些进程会使端口 6931 再次自由。因此,Firefox 似乎以某种方式"捕获"了 emrun 服务器正在侦听的端口的所有权。我真的不知道这怎么可能。

所以,我的问题是如何让 emrun 很好地使用无头 chrome,以及为什么在使用 chrome 时应用程序输出会被截断?我的测试框架需要应用程序的整个输出来确定测试是通过还是失败,目前对于具有大量输出的测试,chrome 无法做到这一点。

你有什么经验?如果您曾经使用 Emscripten 将 c++ 应用程序移植到 Web,那么您是如何设置 CI 环境的?

到目前为止,我能想到的最佳解决方案是:

emrun --browser=chrome --hostname=localhost --kill_exit --browser_args="--headless --remote-debugging-port=0 --disable-gpu --disable-software-rasterizer" web/index.html

指定端口 0 似乎可以修复控制台输出,同时分配一个随机端口号,因此您不必在测试框架中为此烦恼。