New issue 625: xdist: deadlock under pypy
https://bitbucket.org/hpk42/pytest/issue/625/xdist-deadlock-under-pypy

Buck Evan:

Below is a minimal reproduction. It seems that a few factors need to conspire 
to tickle this bug:

  1. test uses subprocess.Popen and tmpdir fixture
  2. test is not run first
  3. runner is passed -n greater than 2 (although exactly 2 makes it most 
likely)


Reproduction script:

```
#!python

# This is my commandline, on osx:
#       $ py.test -vvs -n 2 ./demo.py
#
# I haven't been able to test linux-pypy, but I can't repro under osx-cpython.
#
# I also notice that each deadlock leaks a worker process from xdist.
# I have to go clean them up with killall


def test_dummy(tmpdir):
    """deadlock doesn't occur if i remove this test, or if i put it second"""
    return


import pytest
@pytest.mark.timeout(10)  # this is necessary just to get some feedback from 
the test, the deadlock still happens without it.
def test_deadlocks_sometimes(tmpdir):  # I haven't seen a deadlock if i remove 
this fixture.
    """This deadlocks most often (around 50%) with -n2, but still deadlocks 
with -n >2.
    I haven't seen it deadlock with -n1.
    """

    from subprocess import Popen
    Popen(
        ('echo', 'hi', 'there!'),  # doesn't matter what the command is.
        close_fds=True,  # with True, we get a timeout and two stack traces
        # with False, I see a FAIL after ten seconds, but it continues to 
deadlock,
        # and I get a single, different traceback on ctrl+c
    )
```


Traceback with close_fds=True:

```
____________________________________________________________ 
test_uncolored_pipe ____________________________________________________________
[gw0] darwin -- Python 3.2.5 /Users/buck/venv/venv-update4/bin/pypy3
tmpdir = 
local('/private/var/folders/ss/ykf37pld1hl480qcdknf_zc577t9rc/T/pytest-239/popen-gw0/test_uncolored_pipe0')

    @pytest.mark.timeout(10)
    def test_uncolored_pipe(tmpdir):
        tmpdir.chdir()

        from subprocess import Popen
        return Popen(
            ('echo', 'hi', 'there!'),
>           close_fds=True,
        ).wait()

/Users/buck/trees/yelp/venv-update/color.py:13:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/Users/buck/prefices/brew/Cellar/pypy3/2.3.1_1/libexec/lib-python/3/subprocess.py:744:
 in __init__
    restore_signals, start_new_session)
/Users/buck/prefices/brew/Cellar/pypy3/2.3.1_1/libexec/lib-python/3/subprocess.py:1359:
 in _execute_child
    part = _eintr_retry_call(os.read, errpipe_read, 50000)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

func = <built-in function read>, args = (10, 50000)

    def _eintr_retry_call(func, *args):
        while True:
            try:
>               return func(*args)
E               Failed: Timeout >10s

/Users/buck/prefices/brew/Cellar/pypy3/2.3.1_1/libexec/lib-python/3/subprocess.py:455:
 Failed
----------------------------------------------------------- Captured stderr 
call ------------------------------------------------------------

~~~~~~~~~~~~~~~~~~~~~~~ Stack of <unknown> (4433383424) ~~~~~~~~~~~~~~~~~~~~~~~~
  File "/Users/buck/venv/venv-update4/site-packages/execnet/gateway_base.py", 
line 254, in _perform_spawn
    reply.run()
  File "/Users/buck/venv/venv-update4/site-packages/execnet/gateway_base.py", 
line 192, in run
    self._result = func(*args, **kwargs)
  File "/Users/buck/venv/venv-update4/site-packages/execnet/gateway_base.py", 
line 914, in _thread_receiver
    msg = Message.from_io(io)
  File "/Users/buck/venv/venv-update4/site-packages/execnet/gateway_base.py", 
line 390, in from_io
    header = io.read(9) # type 1, channel 4, payload 4
  File "/Users/buck/venv/venv-update4/site-packages/execnet/gateway_base.py", 
line 360, in read
    data = self._read(numbytes-len(buf))
========================================================== short test summary 
info ==========================================================
FAIL color.py::test_uncolored_pipe
==================================================== 1 failed, 1 passed in 
11.21 seconds ====================================================
```

Traceback with close_fds=False:

```
color.py::test_deadlocks_sometimes
[gw1] FAILED color.py::test_deadlocks_sometimes

^CTraceback (most recent call last):
  File "/Users/buck/venv/venv-update4/bin/py.test", line 9, in <module>
    load_entry_point('pytest==2.6.4', 'console_scripts', 'py.test')()
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/config.py", line 
41, in main
    return config.hook.pytest_cmdline_main(config=config)
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/core.py", line 413, 
in __call__
    return self._docall(methods, kwargs)
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/core.py", line 424, 
in _docall
    res = mc.execute()
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/core.py", line 315, 
in execute
    res = method(**kwargs)
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/main.py", line 116, 
in pytest_cmdline_main
    return wrap_session(config, _main)
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/main.py", line 109, 
in wrap_session
    exitstatus=session.exitstatus)
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/core.py", line 413, 
in __call__
    return self._docall(methods, kwargs)
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/core.py", line 424, 
in _docall
    res = mc.execute()
  File "/Users/buck/venv/venv-update4/site-packages/_pytest/core.py", line 315, 
in execute
    res = method(**kwargs)
  File "/Users/buck/venv/venv-update4/site-packages/xdist/dsession.py", line 
487, in pytest_sessionfinish
    nm.teardown_nodes()
  File "/Users/buck/venv/venv-update4/site-packages/xdist/slavemanage.py", line 
59, in teardown_nodes
    self.group.terminate(self.EXIT_TIMEOUT)
  File "/Users/buck/venv/venv-update4/site-packages/execnet/multi.py", line 
204, in terminate
    for gw in self._gateways_to_join])
  File "/Users/buck/venv/venv-update4/site-packages/execnet/multi.py", line 
293, in safe_terminate
    workerpool.waitall()
  File "/Users/buck/venv/venv-update4/site-packages/execnet/gateway_base.py", 
line 302, in waitall
    return my_waitall_event.wait(timeout=timeout)
  File 
"/Users/buck/prefices/brew/Cellar/pypy3/2.3.1_1/libexec/lib-python/3/threading.py",
 line 422, in wait
    signaled = self._cond.wait(timeout)
  File 
"/Users/buck/prefices/brew/Cellar/pypy3/2.3.1_1/libexec/lib-python/3/threading.py",
 line 235, in wait
    waiter.acquire()
KeyboardInterrupt
```


_______________________________________________
pytest-commit mailing list
pytest-commit@python.org
https://mail.python.org/mailman/listinfo/pytest-commit

Reply via email to