[Python-checkins] bpo-40094: Enhance threading tests (GH-19260)

Victor Stinner webhook-mailer at python.org
Tue Mar 31 15:49:50 EDT 2020


https://github.com/python/cpython/commit/a9f9687a7ce25e7c0c89f88f52db323104668ae0
commit: a9f9687a7ce25e7c0c89f88f52db323104668ae0
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-03-31T21:49:44+02:00
summary:

bpo-40094: Enhance threading tests (GH-19260)

* Rewrite test_thread.test_forkinthread() to use
  support.wait_process() and wait for the child process in the main
  thread, not in the spawned thread.
* test_threading now uses support.wait_process() and checks the child
  process exit code to detect crashes.

files:
M Lib/test/test_thread.py
M Lib/test/test_threading.py

diff --git a/Lib/test/test_thread.py b/Lib/test/test_thread.py
index 9f4801f47e3aa..77e46f2c2f15a 100644
--- a/Lib/test/test_thread.py
+++ b/Lib/test/test_thread.py
@@ -225,30 +225,31 @@ def setUp(self):
     @unittest.skipUnless(hasattr(os, 'fork'), 'need os.fork')
     @support.reap_threads
     def test_forkinthread(self):
-        status = "not set"
+        pid = None
 
-        def thread1():
-            nonlocal status
+        def fork_thread(read_fd, write_fd):
+            nonlocal pid
 
             # fork in a thread
             pid = os.fork()
-            if pid == 0:
-                # child
-                try:
-                    os.close(self.read_fd)
-                    os.write(self.write_fd, b"OK")
-                finally:
-                    os._exit(0)
-            else:
-                # parent
-                os.close(self.write_fd)
-                pid, status = os.waitpid(pid, 0)
+            if pid:
+                # parent process
+                return
+
+            # child process
+            try:
+                os.close(read_fd)
+                os.write(write_fd, b"OK")
+            finally:
+                os._exit(0)
 
         with support.wait_threads_exit():
-            thread.start_new_thread(thread1, ())
-            self.assertEqual(os.read(self.read_fd, 2), b"OK",
-                             "Unable to fork() in thread")
-        self.assertEqual(status, 0)
+            thread.start_new_thread(fork_thread, (self.read_fd, self.write_fd))
+            self.assertEqual(os.read(self.read_fd, 2), b"OK")
+            os.close(self.write_fd)
+
+        self.assertIsNotNone(pid)
+        support.wait_process(pid, exitcode=0)
 
     def tearDown(self):
         try:
diff --git a/Lib/test/test_threading.py b/Lib/test/test_threading.py
index da17e1281d986..8a4efd647096a 100644
--- a/Lib/test/test_threading.py
+++ b/Lib/test/test_threading.py
@@ -485,9 +485,7 @@ def test_is_alive_after_fork(self):
             else:
                 t.join()
 
-                pid, status = os.waitpid(pid, 0)
-                self.assertTrue(os.WIFEXITED(status))
-                self.assertEqual(10, os.WEXITSTATUS(status))
+                support.wait_process(pid, exitcode=10)
 
     def test_main_thread(self):
         main = threading.main_thread()
@@ -507,6 +505,7 @@ def f():
     def test_main_thread_after_fork(self):
         code = """if 1:
             import os, threading
+            from test import support
 
             pid = os.fork()
             if pid == 0:
@@ -515,7 +514,7 @@ def test_main_thread_after_fork(self):
                 print(main.ident == threading.current_thread().ident)
                 print(main.ident == threading.get_ident())
             else:
-                os.waitpid(pid, 0)
+                support.wait_process(pid, exitcode=0)
         """
         _, out, err = assert_python_ok("-c", code)
         data = out.decode().replace('\r', '')
@@ -528,6 +527,7 @@ def test_main_thread_after_fork(self):
     def test_main_thread_after_fork_from_nonmain_thread(self):
         code = """if 1:
             import os, threading, sys
+            from test import support
 
             def f():
                 pid = os.fork()
@@ -540,7 +540,7 @@ def f():
                     # we have to flush before exit.
                     sys.stdout.flush()
                 else:
-                    os.waitpid(pid, 0)
+                    support.wait_process(pid, exitcode=0)
 
             th = threading.Thread(target=f)
             th.start()
@@ -813,11 +813,15 @@ def test_1_join_on_shutdown(self):
     def test_2_join_in_forked_process(self):
         # Like the test above, but from a forked interpreter
         script = """if 1:
+            from test import support
+
             childpid = os.fork()
             if childpid != 0:
-                os.waitpid(childpid, 0)
+                # parent process
+                support.wait_process(childpid, exitcode=0)
                 sys.exit(0)
 
+            # child process
             t = threading.Thread(target=joiningfunc,
                                  args=(threading.current_thread(),))
             t.start()
@@ -832,13 +836,17 @@ def test_3_join_in_forked_from_thread(self):
         # In the forked process, the main Thread object must be marked as stopped.
 
         script = """if 1:
+            from test import support
+
             main_thread = threading.current_thread()
             def worker():
                 childpid = os.fork()
                 if childpid != 0:
-                    os.waitpid(childpid, 0)
+                    # parent process
+                    support.wait_process(childpid, exitcode=0)
                     sys.exit(0)
 
+                # child process
                 t = threading.Thread(target=joiningfunc,
                                      args=(main_thread,))
                 print('end of main')
@@ -901,9 +909,9 @@ def do_fork_and_wait():
             # just fork a child process and wait it
             pid = os.fork()
             if pid > 0:
-                os.waitpid(pid, 0)
+                support.wait_process(pid, exitcode=50)
             else:
-                os._exit(0)
+                os._exit(50)
 
         # start a bunch of threads that will fork() child processes
         threads = []
@@ -930,12 +938,11 @@ def test_clear_threads_states_after_fork(self):
         if pid == 0:
             # check that threads states have been cleared
             if len(sys._current_frames()) == 1:
-                os._exit(0)
+                os._exit(51)
             else:
-                os._exit(1)
+                os._exit(52)
         else:
-            _, status = os.waitpid(pid, 0)
-            self.assertEqual(0, status)
+            support.wait_process(pid, exitcode=51)
 
         for t in threads:
             t.join()



More information about the Python-checkins mailing list