-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Switch to ThreadedChildWatcher and test #5877
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
Changes from all commits
dc361c4
95b0e5d
6b2d5af
3072ae0
8af64ab
3b51df0
0d624ca
b56b139
b99f35c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Uses :py:class:`~asyncio.ThreadedChildWatcher` under POSIX to allow setting up test loop in non-main thread. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,14 +6,15 @@ | |
import pytest | ||
|
||
from aiohttp import web | ||
from aiohttp.test_utils import AioHTTPTestCase | ||
from aiohttp.helpers import PY_38 | ||
from aiohttp.test_utils import AioHTTPTestCase, loop_context | ||
|
||
|
||
@pytest.mark.skipif( | ||
platform.system() == "Windows", reason="the test is not valid for Windows" | ||
) | ||
async def test_subprocess_co(loop: Any) -> None: | ||
assert threading.current_thread() is threading.main_thread() | ||
sweatybridge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert PY_38 or threading.current_thread() is threading.main_thread() | ||
proc = await asyncio.create_subprocess_shell( | ||
"exit 0", | ||
stdin=asyncio.subprocess.DEVNULL, | ||
|
@@ -43,3 +44,24 @@ def test_default_loop(self) -> None: | |
|
||
def test_default_loop(loop: Any) -> None: | ||
assert asyncio.get_event_loop() is loop | ||
|
||
|
||
@pytest.mark.xfail(not PY_38, reason="ThreadedChildWatcher is only available in 3.8+") | ||
def test_setup_loop_non_main_thread() -> None: | ||
child_exc = None | ||
|
||
def target() -> None: | ||
try: | ||
with loop_context() as loop: | ||
assert asyncio.get_event_loop() is loop | ||
loop.run_until_complete(test_subprocess_co(loop)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see this calls subprocesses but what about registering signal handlers? This is what actually fails on old watchers. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Registering signal handlers will always fail in non-main thread, regardless of whether we are using old or new watcher. The new watcher avoids this issue by not registering signal handlers at all (using waitpid as alternative). What we want to ensure in this test is that child processes can be watched, not whether signals can be successfully registered. In other words, since the library no longer registers signal handler on python 3.8, it's not relevant to cover signal registering in tests. Am I misunderstanding something? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. The original problem with xdist was exactly the fact that there's a problem with the signal handlers that happens in an inconsistent manner. This is what blocks #5431 and all the previous attempts. I was sure that the new watchers were supposed to fix this based on what @asvetlov mentioned to me privately. Are you sure it's still problematic? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I'm saying is signal handling is an independent problem from watching child process. The old watcher uses signal handling and will crash when mixed with xdist. The new watcher doesn't use signal handling and therefore is not problematic. Our test only need to verify that child process is watched, it doesn't matter whether it's implemented signals or not. For reference, here's cpython's implementation for Compare that with |
||
except Exception as exc: | ||
nonlocal child_exc | ||
child_exc = exc | ||
|
||
# Ensures setup_test_loop can be called by pytest-xdist in non-main thread. | ||
t = threading.Thread(target=target) | ||
t.start() | ||
t.join() | ||
|
||
assert child_exc is None |
Uh oh!
There was an error while loading. Please reload this page.