Skip to content

Commit 27c6231

Browse files
authored
bpo-40094: Enhance fork and wait tests (GH-19259)
* test_fork1: remove duplicated wait_impl() method: reuse fork_wait.py implementation instead. * Use exit code different than 0 to ensure that we executed the expected code path.
1 parent 278c1e1 commit 27c6231

File tree

4 files changed

+15
-24
lines changed

4 files changed

+15
-24
lines changed

Lib/test/fork_wait.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ def f(self, id):
4343
except OSError:
4444
pass
4545

46-
def wait_impl(self, cpid):
47-
support.wait_process(cpid, exitcode=0)
46+
def wait_impl(self, cpid, *, exitcode):
47+
support.wait_process(cpid, exitcode=exitcode)
4848

4949
def test_wait(self):
5050
for i in range(NUM_THREADS):
@@ -79,4 +79,4 @@ def test_wait(self):
7979
os._exit(n)
8080
else:
8181
# Parent
82-
self.wait_impl(cpid)
82+
self.wait_impl(cpid, exitcode=0)

Lib/test/test_fork1.py

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,6 @@
1717
support.get_attribute(os, 'fork')
1818

1919
class ForkTest(ForkWait):
20-
def wait_impl(self, cpid):
21-
deadline = time.monotonic() + support.SHORT_TIMEOUT
22-
while time.monotonic() <= deadline:
23-
# waitpid() shouldn't hang, but some of the buildbots seem to hang
24-
# in the forking tests. This is an attempt to fix the problem.
25-
spid, status = os.waitpid(cpid, os.WNOHANG)
26-
if spid == cpid:
27-
break
28-
time.sleep(0.1)
29-
30-
self.assertEqual(spid, cpid)
31-
self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
32-
3320
def test_threaded_import_lock_fork(self):
3421
"""Check fork() in main thread works while a subthread is doing an import"""
3522
import_started = threading.Event()
@@ -46,6 +33,7 @@ def importer():
4633
t = threading.Thread(target=importer)
4734
t.start()
4835
import_started.wait()
36+
exitcode = 42
4937
pid = os.fork()
5038
try:
5139
# PyOS_BeforeFork should have waited for the import to complete
@@ -54,7 +42,7 @@ def importer():
5442
if not pid:
5543
m = __import__(fake_module_name)
5644
if m == complete_module:
57-
os._exit(0)
45+
os._exit(exitcode)
5846
else:
5947
if support.verbose > 1:
6048
print("Child encountered partial module")
@@ -64,7 +52,7 @@ def importer():
6452
# Exitcode 1 means the child got a partial module (bad.) No
6553
# exitcode (but a hang, which manifests as 'got pid 0')
6654
# means the child deadlocked (also bad.)
67-
self.wait_impl(pid)
55+
self.wait_impl(pid, exitcode=exitcode)
6856
finally:
6957
try:
7058
os.kill(pid, signal.SIGKILL)
@@ -74,6 +62,7 @@ def importer():
7462

7563
def test_nested_import_lock_fork(self):
7664
"""Check fork() in main thread works while the main thread is doing an import"""
65+
exitcode = 42
7766
# Issue 9573: this used to trigger RuntimeError in the child process
7867
def fork_with_import_lock(level):
7968
release = 0
@@ -95,8 +84,8 @@ def fork_with_import_lock(level):
9584
os._exit(1)
9685
raise
9786
if in_child:
98-
os._exit(0)
99-
self.wait_impl(pid)
87+
os._exit(exitcode)
88+
self.wait_impl(pid, exitcode=exitcode)
10089

10190
# Check this works with various levels of nested
10291
# import in the main thread

Lib/test/test_wait3.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
raise unittest.SkipTest("os.wait3 not defined")
1717

1818
class Wait3Test(ForkWait):
19-
def wait_impl(self, cpid):
19+
def wait_impl(self, cpid, *, exitcode):
2020
# This many iterations can be required, since some previously run
2121
# tests (e.g. test_ctypes) could have spawned a lot of children
2222
# very quickly.
@@ -30,7 +30,8 @@ def wait_impl(self, cpid):
3030
time.sleep(0.1)
3131

3232
self.assertEqual(spid, cpid)
33-
self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
33+
self.assertEqual(status, exitcode << 8,
34+
"cause = %d, exit = %d" % (status&0xff, status>>8))
3435
self.assertTrue(rusage)
3536

3637
def test_wait3_rusage_initialized(self):

Lib/test/test_wait4.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515

1616
class Wait4Test(ForkWait):
17-
def wait_impl(self, cpid):
17+
def wait_impl(self, cpid, *, exitcode):
1818
option = os.WNOHANG
1919
if sys.platform.startswith('aix'):
2020
# Issue #11185: wait4 is broken on AIX and will always return 0
@@ -29,7 +29,8 @@ def wait_impl(self, cpid):
2929
break
3030
time.sleep(0.1)
3131
self.assertEqual(spid, cpid)
32-
self.assertEqual(status, 0, "cause = %d, exit = %d" % (status&0xff, status>>8))
32+
self.assertEqual(status, exitcode << 8,
33+
"cause = %d, exit = %d" % (status&0xff, status>>8))
3334
self.assertTrue(rusage)
3435

3536
def tearDownModule():

0 commit comments

Comments
 (0)