The-Compiler / pytest-xvfb

A pytest plugin to run Xvfb (or Xephyr/Xvnc) for tests.
MIT License
70 stars 11 forks source link

When pytest-xvfb is active sometimes pytest hangs near the beginning of a test run #30

Closed exarkun closed 1 year ago

exarkun commented 2 years ago

Bug description

Using pytest-xvfb 2.0.0 when running GridSync's test suite, sometimes instead of running the test suite pytest hangs without producing any output. After about 10 minutes the pytest process fails with this output:

py39 run-test: commands[0] | /home/exarkun/Work/python/gridsync/.tox/py39/bin/python -m pytest -vvvvv -sv -k test_supervisor_restarts_process_when_killed
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/_pytest/main.py", line 264, in wrap_session
INTERNALERROR>     config._do_configure()
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/_pytest/config/__init__.py", line 995, in _do_configure
INTERNALERROR>     self.hook.pytest_configure.call_historic(kwargs=dict(config=self))
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pluggy/_hooks.py", line 277, in call_historic
INTERNALERROR>     res = self._hookexec(self.name, self.get_hookimpls(), kwargs, False)
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pytest_xvfb.py", line 93, in pytest_configure
INTERNALERROR>     config.xvfb.start()
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pytest_xvfb.py", line 54, in start
INTERNALERROR>     self._virtual_display.start()
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pyvirtualdisplay/display.py", line 72, in start
INTERNALERROR>     self._obj.start()
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pyvirtualdisplay/abstractdisplay.py", line 149, in start
INTERNALERROR>     self._start1_has_displayfd()
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pyvirtualdisplay/abstractdisplay.py", line 197, in _start1_has_displayfd
INTERNALERROR>     self.display = int(self._wait_for_pipe_text(rfd))
INTERNALERROR>   File "/home/exarkun/Work/python/gridsync/.tox/py39/lib/python3.9/site-packages/pyvirtualdisplay/abstractdisplay.py", line 309, in _wait_for_pipe_text
INTERNALERROR>     raise XStartTimeoutError(
INTERNALERROR> pyvirtualdisplay.abstractdisplay.XStartTimeoutError: No reply from program Xvfb. command:['Xvfb', '-br', '-nolisten', 'tcp', '-screen', '0', '800x600x16', '-displayfd', '10']
ERROR: InvocationError for command /home/exarkun/Work/python/gridsync/.tox/py39/bin/python -m pytest -vvvvv -sv -k test_supervisor_restarts_process_when_killed (exited with code 3)

An inspection of process states while it is hung shows that Xvfb is running and waiting on /nix/store/35xlkmb0l6c90jpmj3gj41zl6hg3ss3j-xkbcomp-1.4.5/bin/xkbcomp -w 1 -R/nix/store/v33s87n02p5lfnh5wj60wymxz7zd1zh4-xkeyboard-config-2.33/share/X11/xkb -xkm - -em1 The XKEYBOARD keymap compiler (xkbcomp) reports: -emp > -eml Errors from xkbcomp are not fatal to the X server /tmp/server-1.xkm

xkbcomp in turn is waiting on a write() to stderr of a warning Could not resolve keysym XF86MacroPreset2.

It seems like the way pytest-xvfb drives Xvfb leads to a deadlock between the python/pytest process and the xkbcomp process, with Python waiting for xkbcomp to finish and xkbcomp waiting for something to read its stderr.

The-Compiler commented 1 year ago

This seems to be https://github.com/ponty/PyVirtualDisplay/issues/62 - not sure why it happens, but it doesn't look like the plugin itself can do much about it.