17db96d56Sopenharmony_ci"""This test checks for correct wait3() behavior.
27db96d56Sopenharmony_ci"""
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ciimport os
57db96d56Sopenharmony_ciimport subprocess
67db96d56Sopenharmony_ciimport sys
77db96d56Sopenharmony_ciimport time
87db96d56Sopenharmony_ciimport unittest
97db96d56Sopenharmony_cifrom test.fork_wait import ForkWait
107db96d56Sopenharmony_cifrom test import support
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ciif not support.has_fork_support:
137db96d56Sopenharmony_ci    raise unittest.SkipTest("requires working os.fork()")
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ciif not hasattr(os, 'wait3'):
167db96d56Sopenharmony_ci    raise unittest.SkipTest("os.wait3 not defined")
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ciclass Wait3Test(ForkWait):
197db96d56Sopenharmony_ci    def wait_impl(self, cpid, *, exitcode):
207db96d56Sopenharmony_ci        # This many iterations can be required, since some previously run
217db96d56Sopenharmony_ci        # tests (e.g. test_ctypes) could have spawned a lot of children
227db96d56Sopenharmony_ci        # very quickly.
237db96d56Sopenharmony_ci        deadline = time.monotonic() + support.SHORT_TIMEOUT
247db96d56Sopenharmony_ci        while time.monotonic() <= deadline:
257db96d56Sopenharmony_ci            # wait3() shouldn't hang, but some of the buildbots seem to hang
267db96d56Sopenharmony_ci            # in the forking tests.  This is an attempt to fix the problem.
277db96d56Sopenharmony_ci            spid, status, rusage = os.wait3(os.WNOHANG)
287db96d56Sopenharmony_ci            if spid == cpid:
297db96d56Sopenharmony_ci                break
307db96d56Sopenharmony_ci            time.sleep(0.1)
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci        self.assertEqual(spid, cpid)
337db96d56Sopenharmony_ci        self.assertEqual(os.waitstatus_to_exitcode(status), exitcode)
347db96d56Sopenharmony_ci        self.assertTrue(rusage)
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ci    def test_wait3_rusage_initialized(self):
377db96d56Sopenharmony_ci        # Ensure a successful wait3() call where no child was ready to report
387db96d56Sopenharmony_ci        # its exit status does not return uninitialized memory in the rusage
397db96d56Sopenharmony_ci        # structure. See bpo-36279.
407db96d56Sopenharmony_ci        args = [sys.executable, '-c', 'import sys; sys.stdin.read()']
417db96d56Sopenharmony_ci        proc = subprocess.Popen(args, stdin=subprocess.PIPE)
427db96d56Sopenharmony_ci        try:
437db96d56Sopenharmony_ci            pid, status, rusage = os.wait3(os.WNOHANG)
447db96d56Sopenharmony_ci            self.assertEqual(0, pid)
457db96d56Sopenharmony_ci            self.assertEqual(0, status)
467db96d56Sopenharmony_ci            self.assertEqual(0, sum(rusage))
477db96d56Sopenharmony_ci        finally:
487db96d56Sopenharmony_ci            proc.stdin.close()
497db96d56Sopenharmony_ci            proc.wait()
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_cidef tearDownModule():
537db96d56Sopenharmony_ci    support.reap_children()
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ciif __name__ == "__main__":
567db96d56Sopenharmony_ci    unittest.main()
57