pytest-parallel
pytest-parallel copied to clipboard
Pytest-parallel and pytest-timeout hang when used together
This isn't a bug of pytest-parallel, but I wanted to raise it as a noteworthy issue and leave up to you to decide if it's worth working around pytest-timeout somehow.
Background: https://pypi.org/project/pytest-timeout/ (Potentially) Relevant issue for python-xdist: https://bitbucket.org/pytest-dev/pytest-timeout/issues/8/pytest-xdist-interop-signal-only-works-in
If you have any questions I'll be happy to answer.
Summary: Setup:
pip install pytest-parallel==0.0.8
pip install pytest-timeout==1.3.2
Config (filename: pytest.ini):
[pytest]
filterwarnings =
ignore:::tensorflow
timeout = 1
addopts = --workers auto
Test File(filename: fail.py):
def test_fail():
assert False
def test_fail_2():
assert False
Command:
Eliass-MacBook-Pro:diseaseTools etragas$ py_test fail.py
Output:
================================================================================== test session starts ==================================================================================
platform linux -- Python 3.6.7, pytest-3.8.0, py-1.7.0, pluggy-0.8.0
rootdir: /usr/src/app, inifile: pytest.ini
plugins: snapshottest-0.5.0, timeout-1.3.2, parallel-0.0.8, mock-1.5.0, cov-2.5.1, celery-4.2.1
timeout: 1.0s
timeout method: signal
timeout func_only: False
collected 2 items
pytest-parallel: 6 workers (processes), 1 test per worker (thread)
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.6/site-packages/pytest_parallel/__init__.py", line 80, in run
run_test(self.session, item, None)
File "/usr/local/lib/python3.6/site-packages/pytest_parallel/__init__.py", line 50, in run_test
item.ihook.pytest_runtest_protocol(item=item, nextitem=nextitem)
File "/usr/local/lib/python3.6/site-packages/pluggy/hooks.py", line 284, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 67, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 61, in <lambda>
firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 208, in _multicall
return outcome.get_result()
File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 182, in _multicall
next(gen) # first yield
File "/usr/local/lib/python3.6/site-packages/pytest_timeout.py", line 91, in pytest_runtest_protocol
timeout_setup(item)
File "/usr/local/lib/python3.6/site-packages/pytest_timeout.py", line 144, in timeout_setup
signal.signal(signal.SIGALRM, handler)
File "/usr/local/lib/python3.6/signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.6/site-packages/pytest_parallel/__init__.py", line 80, in run
run_test(self.session, item, None)
File "/usr/local/lib/python3.6/site-packages/pytest_parallel/__init__.py", line 50, in run_test
item.ihook.pytest_runtest_protocol(item=item, nextitem=nextitem)
File "/usr/local/lib/python3.6/site-packages/pluggy/hooks.py", line 284, in __call__
return self._hookexec(self, self.get_hookimpls(), kwargs)
File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 67, in _hookexec
return self._inner_hookexec(hook, methods, kwargs)
File "/usr/local/lib/python3.6/site-packages/pluggy/manager.py", line 61, in <lambda>
firstresult=hook.spec.opts.get("firstresult") if hook.spec else False,
File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 208, in _multicall
return outcome.get_result()
File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 80, in get_result
raise ex[1].with_traceback(ex[2])
File "/usr/local/lib/python3.6/site-packages/pluggy/callers.py", line 182, in _multicall
next(gen) # first yield
File "/usr/local/lib/python3.6/site-packages/pytest_timeout.py", line 91, in pytest_runtest_protocol
timeout_setup(item)
File "/usr/local/lib/python3.6/site-packages/pytest_timeout.py", line 144, in timeout_setup
signal.signal(signal.SIGALRM, handler)
File "/usr/local/lib/python3.6/signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread
Thanks for filing. The fix probably requires monkeypatching os._exit
Is there a plan to fix this issue?
Not sure if this has already been addressed or not. But I was able to fix the problem with this decorator: @pytest.mark.timeout(timeout=60, method='thread')