Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.5.0: pytest fails in testing/acceptance_test.py::TestLoadScope::test_workqueue_ordered_by_size unit #1068

Open
kloczek opened this issue Apr 16, 2024 · 1 comment

Comments

@kloczek
Copy link

kloczek commented Apr 16, 2024

I'm using python 3.10.14 and pytest 8.1.1.
Looks like something is wrong and pytest fails in one unit.

Here is pytest output:
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-pytest-xdist-3.5.0-4.fc37.x86_64/usr/lib64/python3.10/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-pytest-xdist-3.5.0-4.fc37.x86_64/usr/lib/python3.10/site-packages
+ /usr/bin/pytest -ra -m 'not network' -p no:randomly -p no:benchmark -p no:django -p no:twisted
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0
configfile: tox.ini
testpaths: testing
plugins: xdist-3.5.0, forked-1.6.0
collected 204 items

testing/acceptance_test.py ..............s..x.......xx..............s... [ 22%]
......x....................F.......................                      [ 47%]
testing/test_dsession.py .................x...x............              [ 63%]
testing/test_looponfail.py ...........x.ss                               [ 71%]
testing/test_newhooks.py ....                                            [ 73%]
testing/test_plugin.py ...................                               [ 82%]
testing/test_remote.py x....x........                                    [ 89%]
testing/test_workermanage.py ........x.......s...x.                      [100%]

=================================== FAILURES ===================================
_________________ TestLoadScope.test_workqueue_ordered_by_size _________________

self = <acceptance_test.TestLoadScope object at 0x7fa8c8313fa0>
pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_workqueue_ordered_by_size0')>

    def test_workqueue_ordered_by_size(self, pytester: pytest.Pytester) -> None:
        test_file = """
            import pytest
            @pytest.mark.parametrize('i', range({}))
            def test(i):
                pass
        """
        pytester.makepyfile(test_a=test_file.format(10), test_b=test_file.format(20))
        result = pytester.runpytest("-n2", "--dist=loadscope", "-v")
>       assert get_workers_and_test_count_by_prefix(
            "test_a.py::test", result.outlines
        ) == {"gw1": 10}
E       AssertionError: assert {'gw0': 10} == {'gw1': 10}
E
E         Left contains 1 more item:
E         {'gw0': 10}
E         Right contains 1 more item:
E         {'gw1': 10}
E         Use -v to get more diff

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/acceptance_test.py:1244: AssertionError
----------------------------- Captured stdout call -----------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_workqueue_ordered_by_size0
plugins: xdist-3.5.0, forked-1.6.0
created: 2/2 workers
2 workers [30 items]

scheduling tests via LoadScopeScheduling

test_a.py::test[0]
test_b.py::test[0]
[gw1] [  3%] PASSED test_b.py::test[0]
test_b.py::test[1]
[gw1] [  6%] PASSED test_b.py::test[1]
test_b.py::test[2]
[gw1] [ 10%] PASSED test_b.py::test[2]
test_b.py::test[3]
[gw1] [ 13%] PASSED test_b.py::test[3]
test_b.py::test[4]
[gw1] [ 16%] PASSED test_b.py::test[4]
test_b.py::test[5]
[gw1] [ 20%] PASSED test_b.py::test[5]
test_b.py::test[6]
[gw1] [ 23%] PASSED test_b.py::test[6]
test_b.py::test[7]
[gw1] [ 26%] PASSED test_b.py::test[7]
test_b.py::test[8]
[gw1] [ 30%] PASSED test_b.py::test[8]
test_b.py::test[9]
[gw1] [ 33%] PASSED test_b.py::test[9]
test_b.py::test[10]
[gw1] [ 36%] PASSED test_b.py::test[10]
test_b.py::test[11]
[gw1] [ 40%] PASSED test_b.py::test[11]
test_b.py::test[12]
[gw1] [ 43%] PASSED test_b.py::test[12]
test_b.py::test[13]
[gw1] [ 46%] PASSED test_b.py::test[13]
test_b.py::test[14]
[gw1] [ 50%] PASSED test_b.py::test[14]
test_b.py::test[15]
[gw1] [ 53%] PASSED test_b.py::test[15]
test_b.py::test[16]
[gw1] [ 56%] PASSED test_b.py::test[16]
test_b.py::test[17]
[gw1] [ 60%] PASSED test_b.py::test[17]
test_b.py::test[18]
[gw1] [ 63%] PASSED test_b.py::test[18]
test_b.py::test[19]
[gw1] [ 66%] PASSED test_b.py::test[19]
[gw0] [ 70%] PASSED test_a.py::test[0]
test_a.py::test[1]
[gw0] [ 73%] PASSED test_a.py::test[1]
test_a.py::test[2]
[gw0] [ 76%] PASSED test_a.py::test[2]
test_a.py::test[3]
[gw0] [ 80%] PASSED test_a.py::test[3]
test_a.py::test[4]
[gw0] [ 83%] PASSED test_a.py::test[4]
test_a.py::test[5]
[gw0] [ 86%] PASSED test_a.py::test[5]
test_a.py::test[6]
[gw0] [ 90%] PASSED test_a.py::test[6]
test_a.py::test[7]
[gw0] [ 93%] PASSED test_a.py::test[7]
test_a.py::test[8]
[gw0] [ 96%] PASSED test_a.py::test[8]
test_a.py::test[9]
[gw0] [100%] PASSED test_a.py::test[9]

============================== 30 passed in 0.47s ==============================
================================== XFAILURES ===================================
_____________________ TestDistEach.test_simple_diffoutput ______________________

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x7fa8c839cdc0>
when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: Optional[
            Union[Type[BaseException], Tuple[Type[BaseException], ...]]
        ] = None,
    ) -> "CallInfo[TResult]":
        """Call func, wrapping the result in a CallInfo.

        :param func:
            The function to call. Called without arguments.
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: Optional[TResult] = func()

/usr/lib/python3.10/site-packages/_pytest/runner.py:340:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/site-packages/_pytest/runner.py:240: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3.10/site-packages/pluggy/_hooks.py:501: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/lib/python3.10/site-packages/pluggy/_manager.py:119: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:85: in pytest_runtest_setup
    yield from unraisable_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:65: in unraisable_exception_runtest_hook
    yield
/usr/lib/python3.10/site-packages/_pytest/logging.py:843: in pytest_runtest_setup
    yield from self._runtest_for(item, "setup")
/usr/lib/python3.10/site-packages/_pytest/logging.py:832: in _runtest_for
    yield
/usr/lib/python3.10/site-packages/_pytest/capture.py:878: in pytest_runtest_setup
    return (yield)
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:82: in pytest_runtest_setup
    yield from thread_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:63: in thread_exception_runtest_hook
    yield
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_simple_diffoutput>

    @hookimpl(tryfirst=True)
    def pytest_runtest_setup(item: Item) -> None:
        skipped = evaluate_skip_marks(item)
        if skipped:
            raise skip.Exception(skipped.reason, _use_item_location=True)

        item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item)
        if xfailed and not item.config.option.runxfail and not xfailed.run:
>           xfail("[NOTRUN] " + xfailed.reason)
E           _pytest.outcomes.XFailed: [NOTRUN] other python versions might not have pytest installed

/usr/lib/python3.10/site-packages/_pytest/skipping.py:243: XFailed
________________________ test_terminate_on_hangingnode _________________________

pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_terminate_on_hangingnode0')>

    @pytest.mark.xfail
    def test_terminate_on_hangingnode(pytester: pytest.Pytester) -> None:
        p = pytester.makeconftest(
            """
            def pytest_sessionfinish(session):
                if session.nodeid == "my": # running on worker
                    import time
                    time.sleep(3)
        """
        )
        result = pytester.runpytest(p, "--dist=each", "--tx=popen//id=my")
        assert result.duration < 2.0
>       result.stdout.fnmatch_lines(["*killed*my*"])
E       Failed: nomatch: '*killed*my*'
E           and: '============================= test session starts =============================='
E           and: 'platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0'
E           and: 'rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_terminate_on_hangingnode0'
E           and: 'plugins: xdist-3.5.0, forked-1.6.0'
E           and: 'created: 1/1 worker'
E           and: '1 worker [0 items]'
E           and: ''
E           and: ''
E           and: '============================ no tests ran in 0.29s ============================='
E       remains unmatched: '*killed*my*'

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/acceptance_test.py:529: Failed
----------------------------- Captured stdout call -----------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_terminate_on_hangingnode0
plugins: xdist-3.5.0, forked-1.6.0
created: 1/1 worker
1 worker [0 items]


============================ no tests ran in 0.29s =============================
______________________________ test_session_hooks ______________________________

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x7fa8c83a37f0>
when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: Optional[
            Union[Type[BaseException], Tuple[Type[BaseException], ...]]
        ] = None,
    ) -> "CallInfo[TResult]":
        """Call func, wrapping the result in a CallInfo.

        :param func:
            The function to call. Called without arguments.
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: Optional[TResult] = func()

/usr/lib/python3.10/site-packages/_pytest/runner.py:340:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/site-packages/_pytest/runner.py:240: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3.10/site-packages/pluggy/_hooks.py:501: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/lib/python3.10/site-packages/pluggy/_manager.py:119: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:85: in pytest_runtest_setup
    yield from unraisable_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:65: in unraisable_exception_runtest_hook
    yield
/usr/lib/python3.10/site-packages/_pytest/logging.py:843: in pytest_runtest_setup
    yield from self._runtest_for(item, "setup")
/usr/lib/python3.10/site-packages/_pytest/logging.py:832: in _runtest_for
    yield
/usr/lib/python3.10/site-packages/_pytest/capture.py:878: in pytest_runtest_setup
    return (yield)
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:82: in pytest_runtest_setup
    yield from thread_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:63: in thread_exception_runtest_hook
    yield
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_session_hooks>

    @hookimpl(tryfirst=True)
    def pytest_runtest_setup(item: Item) -> None:
        skipped = evaluate_skip_marks(item)
        if skipped:
            raise skip.Exception(skipped.reason, _use_item_location=True)

        item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item)
        if xfailed and not item.config.option.runxfail and not xfailed.run:
>           xfail("[NOTRUN] " + xfailed.reason)
E           _pytest.outcomes.XFailed: [NOTRUN] works if run outside test suite

/usr/lib/python3.10/site-packages/_pytest/skipping.py:243: XFailed
______________________ TestNodeFailure.test_each_multiple ______________________

self = <acceptance_test.TestNodeFailure object at 0x7fa8c8421120>
pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_each_multiple0')>

    @pytest.mark.xfail(reason="#20: xdist race condition on node restart")
    def test_each_multiple(self, pytester: pytest.Pytester) -> None:
        f = pytester.makepyfile(
            """
            import os
            def test_a(): os._exit(1)
            def test_b(): pass
        """
        )
        res = pytester.runpytest(f, "--dist=each", "--tx=2*popen")
>       res.stdout.fnmatch_lines(
            [
                "*Replacing crashed worker*",
                "*Worker*crashed while running*",
                "*2 failed*2 passed*",
            ]
        )
E       Failed: nomatch: '*Replacing crashed worker*'
E           and: '============================= test session starts =============================='
E           and: 'platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0'
E           and: 'rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_each_multiple0'
E           and: 'plugins: xdist-3.5.0, forked-1.6.0'
E           and: 'created: 2/2 workers'
E           and: '2 workers [2 items]'
E           and: ''
E           and: '[gw1] node down: Not properly terminated'
E           and: 'F'
E           and: 'replacing crashed worker gw1'
E           and: '[gw0] node down: Not properly terminated'
E           and: 'F'
E           and: 'replacing crashed worker gw0'
E           and: '..'
E           and: '=================================== FAILURES ==================================='
E           and: '____________________________ test_each_multiple.py _____________________________'
E           and: '[gw1] linux -- Python 3.10.14 /usr/bin/python3'
E           and: "worker 'gw1' crashed while running 'test_each_multiple.py::test_a'"
E           and: '____________________________ test_each_multiple.py _____________________________'
E           and: '[gw0] linux -- Python 3.10.14 /usr/bin/python3'
E           and: "worker 'gw0' crashed while running 'test_each_multiple.py::test_a'"
E           and: '=========================== short test summary info ============================'
E           and: 'FAILED test_each_multiple.py::test_a'
E           and: 'FAILED test_each_multiple.py::test_a'
E           and: '========================= 2 failed, 2 passed in 0.70s =========================='
E       remains unmatched: '*Replacing crashed worker*'

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/acceptance_test.py:971: Failed
----------------------------- Captured stdout call -----------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_each_multiple0
plugins: xdist-3.5.0, forked-1.6.0
created: 2/2 workers
2 workers [2 items]

[gw1] node down: Not properly terminated
F
replacing crashed worker gw1
[gw0] node down: Not properly terminated
F
replacing crashed worker gw0
..
=================================== FAILURES ===================================
____________________________ test_each_multiple.py _____________________________
[gw1] linux -- Python 3.10.14 /usr/bin/python3
worker 'gw1' crashed while running 'test_each_multiple.py::test_a'
____________________________ test_each_multiple.py _____________________________
[gw0] linux -- Python 3.10.14 /usr/bin/python3
worker 'gw0' crashed while running 'test_each_multiple.py::test_a'
=========================== short test summary info ============================
FAILED test_each_multiple.py::test_a
FAILED test_each_multiple.py::test_a
========================= 2 failed, 2 passed in 0.70s ==========================
_____________________ TestDistReporter.test_rsync_printing _____________________

self = <test_dsession.TestDistReporter object at 0x7fa8c83095d0>
pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_rsync_printing0')>
linecomp = <_pytest.pytester.LineComp object at 0x7fa8c6fded10>

    @pytest.mark.xfail
    def test_rsync_printing(self, pytester: pytest.Pytester, linecomp) -> None:
        config = pytester.parseconfig()
>       from _pytest.pytest_terminal import TerminalReporter
E       ModuleNotFoundError: No module named '_pytest.pytest_terminal'

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_dsession.py:445: ModuleNotFoundError
_____________________________ test_pytest_issue419 _____________________________

pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_pytest_issue4190')>

    @pytest.mark.xfail(reason="duplicate test ids not supported yet")
    def test_pytest_issue419(pytester: pytest.Pytester) -> None:
        pytester.makepyfile(
            """
            import pytest

            @pytest.mark.parametrize('birth_year', [1988, 1988, ])
            def test_2011_table(birth_year):
                pass
        """
        )
        reprec = pytester.inline_run("-n1")
        reprec.assertoutcome(passed=2)
>       assert 0
E       assert 0

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_dsession.py:535: AssertionError
----------------------------- Captured stdout call -----------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_pytest_issue4190
plugins: xdist-3.5.0, forked-1.6.0
created: 1/1 worker
1 worker [2 items]

..                                                                       [100%]
============================== 2 passed in 0.29s ===============================
________________ TestLooponFailing.test_looponfail_removed_test ________________

self = <test_looponfail.TestLooponFailing object at 0x7fa8c85a0190>
pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_looponfail_removed_test0')>

    @pytest.mark.xfail(reason="broken by pytest 3.1+", strict=True)
    def test_looponfail_removed_test(self, pytester: pytest.Pytester) -> None:
        modcol = pytester.getmodulecol(
            textwrap.dedent(
                """
                def test_one():
                    assert 0
                def test_two():
                    assert 0
                """
            )
        )
        remotecontrol = RemoteControl(modcol.config)
        remotecontrol.loop_once()
        assert len(remotecontrol.failures) == 2

        modcol.path.write_text(
            textwrap.dedent(
                """
                def test_xxx(): # renamed test
                    assert 0
                def test_two():
                    assert 1 # pass now
                """
            )
        )
        removepyc(modcol.path)
        remotecontrol.loop_once()
>       assert len(remotecontrol.failures) == 0
E       AssertionError: assert 1 == 0
E        +  where 1 = len(['test_looponfail_removed_test.py::test_xxx'])
E        +    where ['test_looponfail_removed_test.py::test_xxx'] = <xdist.looponfail.RemoteControl object at 0x7fa8c758ae90>.failures

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_looponfail.py:288: AssertionError
----------------------------- Captured stdout call -----------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_looponfail_removed_test0
plugins: xdist-3.5.0, forked-1.6.0
collected 0 items

============================ no tests ran in 0.00s =============================
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_looponfail_removed_test0
plugins: xdist-3.5.0, forked-1.6.0
collected 2 items
collected 2 items

test_looponfail_removed_test.py FF                                       [100%]

=================================== FAILURES ===================================
___________________________________ test_one ___________________________________

    def test_one():
>       assert 0
E       assert 0

test_looponfail_removed_test.py:2: AssertionError
___________________________________ test_two ___________________________________

    def test_two():
>       assert 0
E       assert 0

test_looponfail_removed_test.py:4: AssertionError
=========================== short test summary info ============================
FAILED test_looponfail_removed_test.py::test_one - assert 0
FAILED test_looponfail_removed_test.py::test_two - assert 0
============================== 2 failed in 0.02s ===============================
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-273/test_looponfail_removed_test0
plugins: xdist-3.5.0, forked-1.6.0
collected 1 item
collected 3 items
collected 3 items

test_looponfail_removed_test.py F.                                       [100%]

=================================== FAILURES ===================================
___________________________________ test_xxx ___________________________________

    def test_xxx(): # renamed test
>       assert 0
E       assert 0

test_looponfail_removed_test.py:3: AssertionError
=========================== short test summary info ============================
FAILED test_looponfail_removed_test.py::test_xxx - assert 0
========================= 1 failed, 1 passed in 0.02s ==========================
____________________________ test_remoteinitconfig _____________________________

pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_remoteinitconfig0')>

    @pytest.mark.xfail(reason="#59")
    def test_remoteinitconfig(pytester: pytest.Pytester) -> None:
        from xdist.remote import remote_initconfig

        config1 = pytester.parseconfig()
        config2 = remote_initconfig(config1.option.__dict__, config1.args)
>       assert config2.option.__dict__ == config1.option.__dict__
E       AssertionError: assert {'assertmode'...w': None, ...} == {'assertmode'...w': None, ...}
E
E         Omitting 94 identical items, use -vv to show
E         Differing items:
E         {'file_or_dir': ['/tmp/pytest-of-tkloczko/pytest-273/test_remoteinitconfig0']} != {'file_or_dir': []}
E         Use -v to get more diff

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_remote.py:79: AssertionError
_____________ TestWorkerInteractor.test_happy_run_events_converted _____________

self = <test_remote.TestWorkerInteractor object at 0x7fa8c838a080>
pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-273/test_happy_run_events_converted0')>
worker = <test_remote.WorkerSetup object at 0x7fa8c7d0d900>

    def test_happy_run_events_converted(
        self, pytester: pytest.Pytester, worker: WorkerSetup
    ) -> None:
>       pytest.xfail("implement a simple test for event production")
E       _pytest.outcomes.XFailed: implement a simple test for event production

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_remote.py:187: XFailed
__________________ TestNodeManager.test_rsync_roots_no_roots ___________________

cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x7fa8c79131c0>
when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: Optional[
            Union[Type[BaseException], Tuple[Type[BaseException], ...]]
        ] = None,
    ) -> "CallInfo[TResult]":
        """Call func, wrapping the result in a CallInfo.

        :param func:
            The function to call. Called without arguments.
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: Optional[TResult] = func()

/usr/lib/python3.10/site-packages/_pytest/runner.py:340:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/site-packages/_pytest/runner.py:240: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3.10/site-packages/pluggy/_hooks.py:501: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/lib/python3.10/site-packages/pluggy/_manager.py:119: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:85: in pytest_runtest_setup
    yield from unraisable_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:65: in unraisable_exception_runtest_hook
    yield
/usr/lib/python3.10/site-packages/_pytest/logging.py:843: in pytest_runtest_setup
    yield from self._runtest_for(item, "setup")
/usr/lib/python3.10/site-packages/_pytest/logging.py:832: in _runtest_for
    yield
/usr/lib/python3.10/site-packages/_pytest/capture.py:878: in pytest_runtest_setup
    return (yield)
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:82: in pytest_runtest_setup
    yield from thread_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:63: in thread_exception_runtest_hook
    yield
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_rsync_roots_no_roots>

    @hookimpl(tryfirst=True)
    def pytest_runtest_setup(item: Item) -> None:
        skipped = evaluate_skip_marks(item)
        if skipped:
            raise skip.Exception(skipped.reason, _use_item_location=True)

        item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item)
        if xfailed and not item.config.option.runxfail and not xfailed.run:
>           xfail("[NOTRUN] " + xfailed.reason)
E           _pytest.outcomes.XFailed: [NOTRUN]

/usr/lib/python3.10/site-packages/_pytest/skipping.py:243: XFailed
_____________________ test_unserialize_warning_msg[Nested] _____________________

w_cls = 'Nested'

    @pytest.mark.parametrize(
        "w_cls",
        [
            UserWarning,
            MyWarning,
            "Imported",
            pytest.param(
                "Nested",
                marks=pytest.mark.xfail(reason="Nested warning classes are not supported."),
            ),
        ],
    )
    def test_unserialize_warning_msg(w_cls):
        """Test that warning serialization process works well"""

        # Create a test warning message
        with pytest.warns(UserWarning) as w:
            if not isinstance(w_cls, str):
                warnings.warn("hello", w_cls)
            elif w_cls == "Imported":
                generate_warning()
            elif w_cls == "Nested":
                # dynamic creation
                class MyWarning2(UserWarning):
                    pass

                warnings.warn("hello", MyWarning2)

        # Unpack
        assert len(w) == 1
        w_msg = w[0]

        # Serialize and deserialize
        data = serialize_warning_message(w_msg)
>       w_msg2 = unserialize_warning_message(data)

testing/test_workermanage.py:369:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

data = {'category_class_name': 'MyWarning2', 'category_module': 'test_workermanage', 'file': None, 'filename': '/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_workermanage.py', ...}

    def unserialize_warning_message(data):
        import warnings
        import importlib

        if data["message_module"]:
            mod = importlib.import_module(data["message_module"])
>           cls = getattr(mod, data["message_class_name"])
E           AttributeError: module 'test_workermanage' has no attribute 'MyWarning2'. Did you mean: 'MyWarning'?

../../BUILDROOT/python-pytest-xdist-3.5.0-4.fc37.x86_64/usr/lib/python3.10/site-packages/xdist/workermanage.py:417: AttributeError
=============================== warnings summary ===============================
testing/acceptance_test.py::TestDistribution::test_n1_pass
  /usr/lib/python3.10/site-packages/_pytest/pathlib.py:97: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-ed36e0e7-4ba6-4a0a-bbc5-e7d421682cb2/test_safe_get_no_perms0
  <class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_get_no_perms0'
    warnings.warn(

testing/acceptance_test.py::TestDistribution::test_n1_pass
  /usr/lib/python3.10/site-packages/_pytest/pathlib.py:97: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-ed36e0e7-4ba6-4a0a-bbc5-e7d421682cb2/test_safe_set_no_perms0
  <class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_set_no_perms0'
    warnings.warn(

testing/acceptance_test.py::TestDistribution::test_n1_pass
  /usr/lib/python3.10/site-packages/_pytest/pathlib.py:97: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-ed36e0e7-4ba6-4a0a-bbc5-e7d421682cb2/test_safe_delete_no_perms0
  <class 'OSError'>: [Errno 39] Directory not empty: 'test_safe_delete_no_perms0'
    warnings.warn(

testing/acceptance_test.py::TestDistribution::test_n1_pass
  /usr/lib/python3.10/site-packages/_pytest/pathlib.py:97: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-ed36e0e7-4ba6-4a0a-bbc5-e7d421682cb2/test_rmtree_errorhandler_rerai0
  <class 'OSError'>: [Errno 39] Directory not empty: 'test_rmtree_errorhandler_rerai0'
    warnings.warn(

testing/acceptance_test.py::TestDistribution::test_n1_pass
  /usr/lib/python3.10/site-packages/_pytest/pathlib.py:97: PytestWarning: (rm_rf) error removing /tmp/pytest-of-tkloczko/garbage-ed36e0e7-4ba6-4a0a-bbc5-e7d421682cb2
  <class 'OSError'>: [Errno 39] Directory not empty: '/tmp/pytest-of-tkloczko/garbage-ed36e0e7-4ba6-4a0a-bbc5-e7d421682cb2'
    warnings.warn(

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
SKIPPED [3] ../../../../../usr/lib/python3.10/site-packages/_pytest/pytester.py:1522: could not import 'pexpect': No module named 'pexpect'
SKIPPED [1] testing/acceptance_test.py:809: pytest 8.1.1 does not have the pytest_warning_captured hook.
SKIPPED [1] testing/test_workermanage.py:316: no 'gspecs' option found
XFAIL testing/acceptance_test.py::TestDistEach::test_simple_diffoutput - reason: [NOTRUN] other python versions might not have pytest installed
XFAIL testing/acceptance_test.py::test_terminate_on_hangingnode
XFAIL testing/acceptance_test.py::test_session_hooks - reason: [NOTRUN] works if run outside test suite
XFAIL testing/acceptance_test.py::TestNodeFailure::test_each_multiple - #20: xdist race condition on node restart
XFAIL testing/test_dsession.py::TestDistReporter::test_rsync_printing
XFAIL testing/test_dsession.py::test_pytest_issue419 - duplicate test ids not supported yet
XFAIL testing/test_looponfail.py::TestLooponFailing::test_looponfail_removed_test - broken by pytest 3.1+
XFAIL testing/test_remote.py::test_remoteinitconfig - #59
XFAIL testing/test_remote.py::TestWorkerInteractor::test_happy_run_events_converted - reason: implement a simple test for event production
XFAIL testing/test_workermanage.py::TestNodeManager::test_rsync_roots_no_roots - reason: [NOTRUN]
XFAIL testing/test_workermanage.py::test_unserialize_warning_msg[Nested] - Nested warning classes are not supported.
FAILED testing/acceptance_test.py::TestLoadScope::test_workqueue_ordered_by_size
= 1 failed, 187 passed, 5 skipped, 11 xfailed, 5 warnings in 65.93s (0:01:05) ==
@kloczek
Copy link
Author

kloczek commented Apr 16, 2024

Just tested 3.5.0 + all patches generated from master and looks like issue already has been resolved.

Here is pytest output:
+ PYTHONPATH=/home/tkloczko/rpmbuild/BUILDROOT/python-pytest-xdist-3.5.0-4.fc37.x86_64/usr/lib64/python3.10/site-packages:/home/tkloczko/rpmbuild/BUILDROOT/python-pytest-xdist-3.5.0-4.fc37.x86_64/usr/lib/python3.10/site-packages
+ /usr/bin/pytest -ra -m 'not network' -p no:randomly -p no:benchmark -p no:django -p no:twisted
==================================================================================== test session starts ====================================================================================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0
configfile: tox.ini
testpaths: testing
plugins: xdist-3.5.0, forked-1.6.0
collected 207 items

testing/acceptance_test.py ..............s..x.......xx..............s.........x...............................................                                                        [ 47%]
testing/test_dsession.py .................x...x............                                                                                                                           [ 64%]
testing/test_looponfail.py ............x.ss                                                                                                                                           [ 71%]
testing/test_newhooks.py ....                                                                                                                                                         [ 73%]
testing/test_plugin.py ...................                                                                                                                                            [ 83%]
testing/test_remote.py ....x........                                                                                                                                                  [ 89%]
testing/test_workermanage.py ........x.......s...x.                                                                                                                                   [100%]

========================================================================================= XFAILURES =========================================================================================
____________________________________________________________________________ TestDistEach.test_simple_diffoutput ____________________________________________________________________________

cls = <class '_pytest.runner.CallInfo'>, func = <function call_and_report.<locals>.<lambda> at 0x7f317a98c550>, when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: Optional[
            Union[Type[BaseException], Tuple[Type[BaseException], ...]]
        ] = None,
    ) -> "CallInfo[TResult]":
        """Call func, wrapping the result in a CallInfo.

        :param func:
            The function to call. Called without arguments.
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: Optional[TResult] = func()

/usr/lib/python3.10/site-packages/_pytest/runner.py:340:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/site-packages/_pytest/runner.py:240: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3.10/site-packages/pluggy/_hooks.py:501: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/lib/python3.10/site-packages/pluggy/_manager.py:119: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:85: in pytest_runtest_setup
    yield from unraisable_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:65: in unraisable_exception_runtest_hook
    yield
/usr/lib/python3.10/site-packages/_pytest/logging.py:843: in pytest_runtest_setup
    yield from self._runtest_for(item, "setup")
/usr/lib/python3.10/site-packages/_pytest/logging.py:832: in _runtest_for
    yield
/usr/lib/python3.10/site-packages/_pytest/capture.py:878: in pytest_runtest_setup
    return (yield)
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:82: in pytest_runtest_setup
    yield from thread_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:63: in thread_exception_runtest_hook
    yield
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_simple_diffoutput>

    @hookimpl(tryfirst=True)
    def pytest_runtest_setup(item: Item) -> None:
        skipped = evaluate_skip_marks(item)
        if skipped:
            raise skip.Exception(skipped.reason, _use_item_location=True)

        item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item)
        if xfailed and not item.config.option.runxfail and not xfailed.run:
>           xfail("[NOTRUN] " + xfailed.reason)
E           _pytest.outcomes.XFailed: [NOTRUN] other python versions might not have pytest installed

/usr/lib/python3.10/site-packages/_pytest/skipping.py:243: XFailed
_______________________________________________________________________________ test_terminate_on_hangingnode _______________________________________________________________________________

pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-56/test_terminate_on_hangingnode0')>

    @pytest.mark.xfail
    def test_terminate_on_hangingnode(pytester: pytest.Pytester) -> None:
        p = pytester.makeconftest(
            """
            def pytest_sessionfinish(session):
                if session.nodeid == "my": # running on worker
                    import time
                    time.sleep(3)
        """
        )
        result = pytester.runpytest(p, "--dist=each", "--tx=popen//id=my")
        assert result.duration < 2.0
>       result.stdout.fnmatch_lines(["*killed*my*"])
E       Failed: nomatch: '*killed*my*'
E           and: '============================= test session starts =============================='
E           and: 'platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0'
E           and: 'rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_terminate_on_hangingnode0'
E           and: 'plugins: xdist-3.5.0, forked-1.6.0'
E           and: 'created: 1/1 worker'
E           and: '1 worker [0 items]'
E           and: ''
E           and: ''
E           and: '============================ no tests ran in 0.29s ============================='
E       remains unmatched: '*killed*my*'

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/acceptance_test.py:528: Failed
----------------------------------------------------------------------------------- Captured stdout call ------------------------------------------------------------------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_terminate_on_hangingnode0
plugins: xdist-3.5.0, forked-1.6.0
created: 1/1 worker
1 worker [0 items]


============================ no tests ran in 0.29s =============================
____________________________________________________________________________________ test_session_hooks _____________________________________________________________________________________

cls = <class '_pytest.runner.CallInfo'>, func = <function call_and_report.<locals>.<lambda> at 0x7f317b10f9a0>, when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: Optional[
            Union[Type[BaseException], Tuple[Type[BaseException], ...]]
        ] = None,
    ) -> "CallInfo[TResult]":
        """Call func, wrapping the result in a CallInfo.

        :param func:
            The function to call. Called without arguments.
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: Optional[TResult] = func()

/usr/lib/python3.10/site-packages/_pytest/runner.py:340:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/site-packages/_pytest/runner.py:240: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3.10/site-packages/pluggy/_hooks.py:501: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/lib/python3.10/site-packages/pluggy/_manager.py:119: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:85: in pytest_runtest_setup
    yield from unraisable_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:65: in unraisable_exception_runtest_hook
    yield
/usr/lib/python3.10/site-packages/_pytest/logging.py:843: in pytest_runtest_setup
    yield from self._runtest_for(item, "setup")
/usr/lib/python3.10/site-packages/_pytest/logging.py:832: in _runtest_for
    yield
/usr/lib/python3.10/site-packages/_pytest/capture.py:878: in pytest_runtest_setup
    return (yield)
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:82: in pytest_runtest_setup
    yield from thread_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:63: in thread_exception_runtest_hook
    yield
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_session_hooks>

    @hookimpl(tryfirst=True)
    def pytest_runtest_setup(item: Item) -> None:
        skipped = evaluate_skip_marks(item)
        if skipped:
            raise skip.Exception(skipped.reason, _use_item_location=True)

        item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item)
        if xfailed and not item.config.option.runxfail and not xfailed.run:
>           xfail("[NOTRUN] " + xfailed.reason)
E           _pytest.outcomes.XFailed: [NOTRUN] works if run outside test suite

/usr/lib/python3.10/site-packages/_pytest/skipping.py:243: XFailed
____________________________________________________________________________ TestNodeFailure.test_each_multiple _____________________________________________________________________________

self = <acceptance_test.TestNodeFailure object at 0x7f317a943880>, pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-56/test_each_multiple0')>

    @pytest.mark.xfail(reason="#20: xdist race condition on node restart")
    def test_each_multiple(self, pytester: pytest.Pytester) -> None:
        f = pytester.makepyfile(
            """
            import os
            def test_a(): os._exit(1)
            def test_b(): pass
        """
        )
        res = pytester.runpytest(f, "--dist=each", "--tx=2*popen")
>       res.stdout.fnmatch_lines(
            [
                "*Replacing crashed worker*",
                "*Worker*crashed while running*",
                "*2 failed*2 passed*",
            ]
        )
E       Failed: nomatch: '*Replacing crashed worker*'
E           and: '============================= test session starts =============================='
E           and: 'platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0'
E           and: 'rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_each_multiple0'
E           and: 'plugins: xdist-3.5.0, forked-1.6.0'
E           and: 'created: 2/2 workers'
E           and: '2 workers [2 items]'
E           and: ''
E           and: '[gw0] node down: Not properly terminated'
E           and: 'F'
E           and: 'replacing crashed worker gw0'
E           and: '[gw1] node down: Not properly terminated'
E           and: 'F'
E           and: 'replacing crashed worker gw1'
E           and: '..'
E           and: '=================================== FAILURES ==================================='
E           and: '____________________________ test_each_multiple.py _____________________________'
E           and: '[gw0] linux -- Python 3.10.14 /usr/bin/python3'
E           and: "worker 'gw0' crashed while running 'test_each_multiple.py::test_a'"
E           and: '____________________________ test_each_multiple.py _____________________________'
E           and: '[gw1] linux -- Python 3.10.14 /usr/bin/python3'
E           and: "worker 'gw1' crashed while running 'test_each_multiple.py::test_a'"
E           and: '=========================== short test summary info ============================'
E           and: 'FAILED test_each_multiple.py::test_a'
E           and: 'FAILED test_each_multiple.py::test_a'
E           and: '========================= 2 failed, 2 passed in 0.69s =========================='
E       remains unmatched: '*Replacing crashed worker*'

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/acceptance_test.py:966: Failed
----------------------------------------------------------------------------------- Captured stdout call ------------------------------------------------------------------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_each_multiple0
plugins: xdist-3.5.0, forked-1.6.0
created: 2/2 workers
2 workers [2 items]

[gw0] node down: Not properly terminated
F
replacing crashed worker gw0
[gw1] node down: Not properly terminated
F
replacing crashed worker gw1
..
=================================== FAILURES ===================================
____________________________ test_each_multiple.py _____________________________
[gw0] linux -- Python 3.10.14 /usr/bin/python3
worker 'gw0' crashed while running 'test_each_multiple.py::test_a'
____________________________ test_each_multiple.py _____________________________
[gw1] linux -- Python 3.10.14 /usr/bin/python3
worker 'gw1' crashed while running 'test_each_multiple.py::test_a'
=========================== short test summary info ============================
FAILED test_each_multiple.py::test_a
FAILED test_each_multiple.py::test_a
========================= 2 failed, 2 passed in 0.69s ==========================
___________________________________________________________________________ TestDistReporter.test_rsync_printing ____________________________________________________________________________

self = <test_dsession.TestDistReporter object at 0x7f317afbcd30>, pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-56/test_rsync_printing0')>
linecomp = <_pytest.pytester.LineComp object at 0x7f317a4ecf70>

    @pytest.mark.xfail
    def test_rsync_printing(self, pytester: pytest.Pytester, linecomp) -> None:
        config = pytester.parseconfig()
        from _pytest.terminal import TerminalReporter

        rep = TerminalReporter(config, file=linecomp.stringio)
        config.pluginmanager.register(rep, "terminalreporter")
        dsession = DSession(config)

        class gw1:
            id = "X1"
            spec = execnet.XSpec("popen")

        class gw2:
            id = "X2"
            spec = execnet.XSpec("popen")

        # class rinfo:
        #    version_info = (2, 5, 1, 'final', 0)
        #    executable = "hello"
        #    platform = "xyz"
        #    cwd = "qwe"

        # dsession.pytest_xdist_newgateway(gw1, rinfo)
        # linecomp.assert_contains_lines([
        #     "*X1*popen*xyz*2.5*"
        # ])
>       dsession.pytest_xdist_rsyncstart(source="hello", gateways=[gw1, gw2])  # type: ignore[attr-defined]
E       AttributeError: 'DSession' object has no attribute 'pytest_xdist_rsyncstart'

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_dsession.py:469: AttributeError
___________________________________________________________________________________ test_pytest_issue419 ____________________________________________________________________________________

pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-56/test_pytest_issue4190')>

    @pytest.mark.xfail(reason="duplicate test ids not supported yet")
    def test_pytest_issue419(pytester: pytest.Pytester) -> None:
        pytester.makepyfile(
            """
            import pytest

            @pytest.mark.parametrize('birth_year', [1988, 1988, ])
            def test_2011_table(birth_year):
                pass
        """
        )
        reprec = pytester.inline_run("-n1")
        reprec.assertoutcome(passed=2)
>       assert 0
E       assert 0

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_dsession.py:535: AssertionError
----------------------------------------------------------------------------------- Captured stdout call ------------------------------------------------------------------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_pytest_issue4190
plugins: xdist-3.5.0, forked-1.6.0
created: 1/1 worker
1 worker [2 items]

..                                                                       [100%]
============================== 2 passed in 0.30s ===============================
______________________________________________________________________ TestLooponFailing.test_looponfail_removed_test _______________________________________________________________________

self = <test_looponfail.TestLooponFailing object at 0x7f317afbeb30>, pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-56/test_looponfail_removed_test0')>

    @pytest.mark.xfail(reason="broken by pytest 3.1+", strict=True)
    def test_looponfail_removed_test(self, pytester: pytest.Pytester) -> None:
        modcol = pytester.getmodulecol(
            textwrap.dedent(
                """
                def test_one():
                    assert 0
                def test_two():
                    assert 0
                """
            )
        )
        remotecontrol = RemoteControl(modcol.config)
        remotecontrol.loop_once()
        assert len(remotecontrol.failures) == 2

        modcol.path.write_text(
            textwrap.dedent(
                """
                def test_xxx(): # renamed test
                    assert 0
                def test_two():
                    assert 1 # pass now
                """
            )
        )
        removepyc(modcol.path)
        remotecontrol.loop_once()
>       assert len(remotecontrol.failures) == 0
E       AssertionError: assert 1 == 0
E        +  where 1 = len(['test_looponfail_removed_test.py::test_xxx'])
E        +    where ['test_looponfail_removed_test.py::test_xxx'] = <xdist.looponfail.RemoteControl object at 0x7f317a27b340>.failures

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_looponfail.py:316: AssertionError
----------------------------------------------------------------------------------- Captured stdout call ------------------------------------------------------------------------------------
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_looponfail_removed_test0
plugins: xdist-3.5.0, forked-1.6.0
collected 0 items

============================ no tests ran in 0.01s =============================
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_looponfail_removed_test0
plugins: xdist-3.5.0, forked-1.6.0
collected 2 items
collected 2 items

test_looponfail_removed_test.py FF                                       [100%]

=================================== FAILURES ===================================
___________________________________ test_one ___________________________________

    def test_one():
>       assert 0
E       assert 0

test_looponfail_removed_test.py:2: AssertionError
___________________________________ test_two ___________________________________

    def test_two():
>       assert 0
E       assert 0

test_looponfail_removed_test.py:4: AssertionError
=========================== short test summary info ============================
FAILED test_looponfail_removed_test.py::test_one - assert 0
FAILED test_looponfail_removed_test.py::test_two - assert 0
============================== 2 failed in 0.03s ===============================
============================= test session starts ==============================
platform linux -- Python 3.10.14, pytest-8.1.1, pluggy-1.4.0
rootdir: /tmp/pytest-of-tkloczko/pytest-56/test_looponfail_removed_test0
plugins: xdist-3.5.0, forked-1.6.0
collected 1 item
collected 3 items
collected 3 items

test_looponfail_removed_test.py F.                                       [100%]

=================================== FAILURES ===================================
___________________________________ test_xxx ___________________________________

    def test_xxx(): # renamed test
>       assert 0
E       assert 0

test_looponfail_removed_test.py:3: AssertionError
=========================== short test summary info ============================
FAILED test_looponfail_removed_test.py::test_xxx - assert 0
========================= 1 failed, 1 passed in 0.03s ==========================
___________________________________________________________________ TestWorkerInteractor.test_happy_run_events_converted ____________________________________________________________________

self = <test_remote.TestWorkerInteractor object at 0x7f317a99e8c0>, pytester = <Pytester PosixPath('/tmp/pytest-of-tkloczko/pytest-56/test_happy_run_events_converted0')>
worker = <test_remote.WorkerSetup object at 0x7f317a97ce20>

    def test_happy_run_events_converted(
        self, pytester: pytest.Pytester, worker: WorkerSetup
    ) -> None:
>       pytest.xfail("implement a simple test for event production")
E       _pytest.outcomes.XFailed: implement a simple test for event production

/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_remote.py:178: XFailed
_________________________________________________________________________ TestNodeManager.test_rsync_roots_no_roots _________________________________________________________________________

cls = <class '_pytest.runner.CallInfo'>, func = <function call_and_report.<locals>.<lambda> at 0x7f317a983f40>, when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)

    @classmethod
    def from_call(
        cls,
        func: Callable[[], TResult],
        when: Literal["collect", "setup", "call", "teardown"],
        reraise: Optional[
            Union[Type[BaseException], Tuple[Type[BaseException], ...]]
        ] = None,
    ) -> "CallInfo[TResult]":
        """Call func, wrapping the result in a CallInfo.

        :param func:
            The function to call. Called without arguments.
        :param when:
            The phase in which the function is called.
        :param reraise:
            Exception or exceptions that shall propagate if raised by the
            function, instead of being wrapped in the CallInfo.
        """
        excinfo = None
        start = timing.time()
        precise_start = timing.perf_counter()
        try:
>           result: Optional[TResult] = func()

/usr/lib/python3.10/site-packages/_pytest/runner.py:340:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/site-packages/_pytest/runner.py:240: in <lambda>
    lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/usr/lib/python3.10/site-packages/pluggy/_hooks.py:501: in __call__
    return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/usr/lib/python3.10/site-packages/pluggy/_manager.py:119: in _hookexec
    return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:85: in pytest_runtest_setup
    yield from unraisable_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/unraisableexception.py:65: in unraisable_exception_runtest_hook
    yield
/usr/lib/python3.10/site-packages/_pytest/logging.py:843: in pytest_runtest_setup
    yield from self._runtest_for(item, "setup")
/usr/lib/python3.10/site-packages/_pytest/logging.py:832: in _runtest_for
    yield
/usr/lib/python3.10/site-packages/_pytest/capture.py:878: in pytest_runtest_setup
    return (yield)
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:82: in pytest_runtest_setup
    yield from thread_exception_runtest_hook()
/usr/lib/python3.10/site-packages/_pytest/threadexception.py:63: in thread_exception_runtest_hook
    yield
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

item = <Function test_rsync_roots_no_roots>

    @hookimpl(tryfirst=True)
    def pytest_runtest_setup(item: Item) -> None:
        skipped = evaluate_skip_marks(item)
        if skipped:
            raise skip.Exception(skipped.reason, _use_item_location=True)

        item.stash[xfailed_key] = xfailed = evaluate_xfail_marks(item)
        if xfailed and not item.config.option.runxfail and not xfailed.run:
>           xfail("[NOTRUN] " + xfailed.reason)
E           _pytest.outcomes.XFailed: [NOTRUN]

/usr/lib/python3.10/site-packages/_pytest/skipping.py:243: XFailed
___________________________________________________________________________ test_unserialize_warning_msg[Nested] ____________________________________________________________________________

w_cls = 'Nested'

    @pytest.mark.parametrize(
        "w_cls",
        [
            UserWarning,
            MyWarning,
            "Imported",
            pytest.param(
                "Nested",
                marks=pytest.mark.xfail(reason="Nested warning classes are not supported."),
            ),
        ],
    )
    def test_unserialize_warning_msg(w_cls):
        """Test that warning serialization process works well."""
        # Create a test warning message
        with pytest.warns(UserWarning) as w:
            if not isinstance(w_cls, str):
                warnings.warn("hello", w_cls)
            elif w_cls == "Imported":
                generate_warning()
            elif w_cls == "Nested":
                # dynamic creation
                class MyWarning2(UserWarning):
                    pass

                warnings.warn("hello", MyWarning2)

        # Unpack
        assert len(w) == 1
        w_msg = w[0]

        # Serialize and deserialize
        data = serialize_warning_message(w_msg)
>       w_msg2 = unserialize_warning_message(data)

testing/test_workermanage.py:373:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

data = {'category_class_name': 'MyWarning2', 'category_module': 'test_workermanage', 'file': None, 'filename': '/home/tkloczko/rpmbuild/BUILD/pytest-xdist-3.5.0/testing/test_workermanage.py', ...}

    def unserialize_warning_message(data):
        import importlib
        import warnings

        if data["message_module"]:
            mod = importlib.import_module(data["message_module"])
>           cls = getattr(mod, data["message_class_name"])
E           AttributeError: module 'test_workermanage' has no attribute 'MyWarning2'. Did you mean: 'MyWarning'?

../../BUILDROOT/python-pytest-xdist-3.5.0-4.fc37.x86_64/usr/lib/python3.10/site-packages/xdist/workermanage.py:408: AttributeError
================================================================================== short test summary info ==================================================================================
SKIPPED [3] ../../../../../usr/lib/python3.10/site-packages/_pytest/pytester.py:1522: could not import 'pexpect': No module named 'pexpect'
SKIPPED [1] testing/acceptance_test.py:804: pytest 8.1.1 does not have the pytest_warning_captured hook.
SKIPPED [1] testing/test_workermanage.py:321: no 'gspecs' option found
XFAIL testing/acceptance_test.py::TestDistEach::test_simple_diffoutput - reason: [NOTRUN] other python versions might not have pytest installed
XFAIL testing/acceptance_test.py::test_terminate_on_hangingnode
XFAIL testing/acceptance_test.py::test_session_hooks - reason: [NOTRUN] works if run outside test suite
XFAIL testing/acceptance_test.py::TestNodeFailure::test_each_multiple - #20: xdist race condition on node restart
XFAIL testing/test_dsession.py::TestDistReporter::test_rsync_printing
XFAIL testing/test_dsession.py::test_pytest_issue419 - duplicate test ids not supported yet
XFAIL testing/test_looponfail.py::TestLooponFailing::test_looponfail_removed_test - broken by pytest 3.1+
XFAIL testing/test_remote.py::TestWorkerInteractor::test_happy_run_events_converted - reason: implement a simple test for event production
XFAIL testing/test_workermanage.py::TestNodeManager::test_rsync_roots_no_roots - reason: [NOTRUN]
XFAIL testing/test_workermanage.py::test_unserialize_warning_msg[Nested] - Nested warning classes are not supported.
=================================================================== 192 passed, 5 skipped, 10 xfailed in 69.91s (0:01:09) ===================================================================

Maybe it would be good to flush all already committed changes and release new version? 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant