blob: 6e06049fbdd693f61117b82412b84feb6636598f [file] [log] [blame]
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001"""This test checks for correct wait3() behavior.
2"""
3
4import os
Zackery Spytz682107c2019-09-09 09:48:32 -06005import subprocess
6import sys
Thomas Wouters0e3f5912006-08-11 14:57:12 +00007import time
Benjamin Petersone549ead2009-03-28 21:42:05 +00008import unittest
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00009from test.fork_wait import ForkWait
Victor Stinner0d63bac2019-12-11 11:30:03 +010010from test import support
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000011
Brett Cannoncc134312012-11-14 15:49:55 -050012if not hasattr(os, 'fork'):
Brett Cannoncd8efa32012-11-14 15:16:53 -050013 raise unittest.SkipTest("os.fork not defined")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000014
Brett Cannoncd8efa32012-11-14 15:16:53 -050015if not hasattr(os, 'wait3'):
16 raise unittest.SkipTest("os.wait3 not defined")
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000017
18class Wait3Test(ForkWait):
Victor Stinner27c62312020-03-31 21:46:40 +020019 def wait_impl(self, cpid, *, exitcode):
Antoine Pitrou606c3f52011-05-09 21:17:02 +020020 # This many iterations can be required, since some previously run
21 # tests (e.g. test_ctypes) could have spawned a lot of children
22 # very quickly.
Victor Stinner0d63bac2019-12-11 11:30:03 +010023 deadline = time.monotonic() + support.SHORT_TIMEOUT
Victor Stinner1e48eb32014-03-18 00:39:04 +010024 while time.monotonic() <= deadline:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000025 # wait3() shouldn't hang, but some of the buildbots seem to hang
26 # in the forking tests. This is an attempt to fix the problem.
27 spid, status, rusage = os.wait3(os.WNOHANG)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000028 if spid == cpid:
29 break
Antoine Pitrou606c3f52011-05-09 21:17:02 +020030 time.sleep(0.1)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000031
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000032 self.assertEqual(spid, cpid)
Victor Stinner27c62312020-03-31 21:46:40 +020033 self.assertEqual(status, exitcode << 8,
34 "cause = %d, exit = %d" % (status&0xff, status>>8))
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035 self.assertTrue(rusage)
36
Zackery Spytz682107c2019-09-09 09:48:32 -060037 def test_wait3_rusage_initialized(self):
38 # Ensure a successful wait3() call where no child was ready to report
39 # its exit status does not return uninitialized memory in the rusage
40 # structure. See bpo-36279.
41 args = [sys.executable, '-c', 'import sys; sys.stdin.read()']
42 proc = subprocess.Popen(args, stdin=subprocess.PIPE)
43 try:
44 pid, status, rusage = os.wait3(os.WNOHANG)
45 self.assertEqual(0, pid)
46 self.assertEqual(0, status)
47 self.assertEqual(0, sum(rusage))
48 finally:
49 proc.stdin.close()
50 proc.wait()
51
52
Zachary Ware38c707e2015-04-13 15:00:43 -050053def tearDownModule():
Victor Stinner0d63bac2019-12-11 11:30:03 +010054 support.reap_children()
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000055
56if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -050057 unittest.main()