[Python-checkins] bpo-37531: sync regrtest with master branch (GH-16285) (GH-16289)

Victor Stinner webhook-mailer at python.org
Thu Sep 19 12:40:51 EDT 2019


https://github.com/python/cpython/commit/5e1400a6bcbb3350a6665176980a2b8343075c63
commit: 5e1400a6bcbb3350a6665176980a2b8343075c63
branch: 3.7
author: Victor Stinner <vstinner at redhat.com>
committer: GitHub <noreply at github.com>
date: 2019-09-19T18:40:46+02:00
summary:

bpo-37531: sync regrtest with master branch (GH-16285) (GH-16289)

(cherry picked from commit fb7746d5d10ec4a34198da672018ba15f5667079)

files:
M Lib/test/libregrtest/main.py
M Lib/test/libregrtest/runtest_mp.py

diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index 7d6a62863599..a59a03d4f251 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -21,6 +21,12 @@
 from test import support
 
 
+# bpo-38203: Maximum delay in seconds to exit Python (call Py_Finalize()).
+# Used to protect against threading._shutdown() hang.
+# Must be smaller than buildbot "1200 seconds without output" limit.
+EXIT_TIMEOUT = 120.0
+
+
 class Regrtest:
     """Execute a test suite.
 
@@ -157,11 +163,6 @@ def display_progress(self, test_index, text):
     def parse_args(self, kwargs):
         ns = _parse_args(sys.argv[1:], **kwargs)
 
-        if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
-            print("Warning: The timeout option requires "
-                  "faulthandler.dump_traceback_later", file=sys.stderr)
-            ns.timeout = None
-
         if ns.xmlpath:
             support.junit_xml_list = self.testsuite_xml = []
 
@@ -611,16 +612,24 @@ def main(self, tests=None, **kwargs):
 
         test_cwd = self.create_temp_dir()
 
-        # Run the tests in a context manager that temporarily changes the CWD
-        # to a temporary and writable directory. If it's not possible to
-        # create or change the CWD, the original CWD will be used.
-        # The original CWD is available from support.SAVEDCWD.
-        with support.temp_cwd(test_cwd, quiet=True):
-            # When using multiprocessing, worker processes will use test_cwd
-            # as their parent temporary directory. So when the main process
-            # exit, it removes also subdirectories of worker processes.
-            self.ns.tempdir = test_cwd
-            self._main(tests, kwargs)
+        try:
+            # Run the tests in a context manager that temporarily changes the CWD
+            # to a temporary and writable directory. If it's not possible to
+            # create or change the CWD, the original CWD will be used.
+            # The original CWD is available from support.SAVEDCWD.
+            with support.temp_cwd(test_cwd, quiet=True):
+                # When using multiprocessing, worker processes will use test_cwd
+                # as their parent temporary directory. So when the main process
+                # exit, it removes also subdirectories of worker processes.
+                self.ns.tempdir = test_cwd
+
+                self._main(tests, kwargs)
+        except SystemExit as exc:
+            # bpo-38203: Python can hang at exit in Py_Finalize(), especially
+            # on threading._shutdown() call: put a timeout
+            faulthandler.dump_traceback_later(EXIT_TIMEOUT, exit=True)
+
+            sys.exit(exc.code)
 
     def getloadavg(self):
         if self.win_load_tracker is not None:
diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py
index 482bb80726dc..9cb5be6bb8ae 100644
--- a/Lib/test/libregrtest/runtest_mp.py
+++ b/Lib/test/libregrtest/runtest_mp.py
@@ -185,14 +185,14 @@ def mp_result_error(self, test_name, error_type, stdout='', stderr='',
     def _timedout(self, test_name):
         self._kill()
 
-        stdout = sterr = ''
+        stdout = stderr = ''
         popen = self._popen
         try:
             stdout, stderr = popen.communicate(timeout=JOIN_TIMEOUT)
         except (subprocess.TimeoutExpired, OSError) as exc:
             print("WARNING: Failed to read worker process %s output "
                   "(timeout=%.1f sec): %r"
-                  % (popen.pid, exc, timeout),
+                  % (popen.pid, JOIN_TIMEOUT, exc),
                   file=sys.stderr, flush=True)
 
         self._close_wait()



More information about the Python-checkins mailing list