Skip to content

gh-109582: test_fork_signal_handling should wait for event #109605

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

Merged
merged 1 commit into from
Sep 21, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions Lib/test/test_asyncio/test_unix_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
import stat
import sys
import threading
import time
import unittest
from unittest import mock
import warnings
from test import support
from test.support import os_helper
from test.support import socket_helper
from test.support import wait_process
Expand Down Expand Up @@ -1911,8 +1913,14 @@ def test_fork_signal_handling(self):
parent_handled = manager.Event()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't know that another test_asyncio test uses multiprocessing.

It might be interesting to call from multiprocessing.util._cleanup_tests() in this test file as well: see commit 09ea4b8 and gh-109295.

But this one is less important since it doesn't pull most heavy multiprocessing resources, it's "just" a fork manager :-)

def child_main():
signal.signal(signal.SIGTERM, lambda *args: child_handled.set())
def on_sigterm(*args):
child_handled.set()
sys.exit()

signal.signal(signal.SIGTERM, on_sigterm)
child_started.set()
while True:
time.sleep(1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It took me a while to understand that the child doesn't run the loop forever, but is interrupted by SIGTERM and so exits immediately.


async def main():
loop = asyncio.get_running_loop()
Expand All @@ -1922,7 +1930,7 @@ async def main():
process.start()
child_started.wait()
os.kill(process.pid, signal.SIGTERM)
process.join()
process.join(timeout=support.SHORT_TIMEOUT)

async def func():
await asyncio.sleep(0.1)
Expand All @@ -1933,6 +1941,7 @@ async def func():

asyncio.run(main())

child_handled.wait(timeout=support.SHORT_TIMEOUT)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that's a good way to synchronize the parent and the child.

self.assertFalse(parent_handled.is_set())
self.assertTrue(child_handled.is_set())

Expand Down