]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-110367: Enhance regrtest -jN --verbose3 (#110368)
authorVictor Stinner <vstinner@python.org>
Thu, 5 Oct 2023 06:24:43 +0000 (08:24 +0200)
committerGitHub <noreply@github.com>
Thu, 5 Oct 2023 06:24:43 +0000 (08:24 +0200)
When using worker processes (-jN) with --verbose3 option, regrtest
can now display the worker output even if a worker process does
crash.  Previously, sys.stdout and sys.stderr were replaced and so
the worker output was lost on a crash.

Lib/test/libregrtest/run_workers.py
Lib/test/test_faulthandler.py
Lib/test/test_regrtest.py
Misc/NEWS.d/next/Tests/2023-10-04-18-27-47.gh-issue-110367.Nnq1I7.rst [new file with mode: 0644]

index 6eb32e59635865a7cd13b70ba3b0e55a6da2bae2..106f9730832e5437cf84cbdd89460fdabff8248a 100644 (file)
@@ -262,6 +262,9 @@ class WorkerThread(threading.Thread):
         kwargs = {}
         if match_tests:
             kwargs['match_tests'] = match_tests
+        if self.runtests.output_on_failure:
+            kwargs['verbose'] = True
+            kwargs['output_on_failure'] = False
         return self.runtests.copy(
             tests=tests,
             json_file=json_file,
@@ -562,8 +565,16 @@ class RunWorkers:
         self.results.accumulate_result(result, self.runtests)
         self.display_result(mp_result)
 
-        if mp_result.worker_stdout:
-            print(mp_result.worker_stdout, flush=True)
+        # Display worker stdout
+        if not self.runtests.output_on_failure:
+            show_stdout = True
+        else:
+            # --verbose3 ignores stdout on success
+            show_stdout = (result.state != State.PASSED)
+        if show_stdout:
+            stdout = mp_result.worker_stdout
+            if stdout:
+                print(stdout, flush=True)
 
         return result
 
index 3c1e8c150ae71166582d83f19354db7cde548eb8..4dce7a7dd8c8df1ea8235e8b5933fb7d75a18cf4 100644 (file)
@@ -35,7 +35,7 @@ def expected_traceback(lineno1, lineno2, header, min_count=1):
         return '^' + regex + '$'
 
 def skip_segfault_on_android(test):
-    # Issue #32138: Raising SIGSEGV on Android may not cause a crash.
+    # gh-76319: Raising SIGSEGV on Android may not cause a crash.
     return unittest.skipIf(is_android,
                            'raising SIGSEGV on Android is unreliable')(test)
 
index f24d23e5c2f7314ce91b9fbf1b0b6ab814b810df..66463fd2bbea226dec735cc20e92be84c19b673f 100644 (file)
@@ -42,6 +42,8 @@ EXITCODE_NO_TESTS_RAN = 4
 EXITCODE_RERUN_FAIL = 5
 EXITCODE_INTERRUPTED = 130
 
+MS_WINDOWS = (sys.platform == 'win32')
+
 TEST_INTERRUPTED = textwrap.dedent("""
     from signal import SIGINT, raise_signal
     try:
@@ -2036,6 +2038,38 @@ class ArgsTestCase(BaseTestCase):
             with self.subTest(opt=opt):
                 self.check_add_python_opts(opt)
 
+    # gh-76319: Raising SIGSEGV on Android may not cause a crash.
+    @unittest.skipIf(support.is_android,
+                     'raising SIGSEGV on Android is unreliable')
+    def test_worker_output_on_failure(self):
+        try:
+            from faulthandler import _sigsegv
+        except ImportError:
+            self.skipTest("need faulthandler._sigsegv")
+
+        code = textwrap.dedent(r"""
+            import faulthandler
+            import unittest
+            from test import support
+
+            class CrashTests(unittest.TestCase):
+                def test_crash(self):
+                    print("just before crash!", flush=True)
+
+                    with support.SuppressCrashReport():
+                        faulthandler._sigsegv(True)
+        """)
+        testname = self.create_test(code=code)
+
+        output = self.run_tests("-j1", testname, exitcode=EXITCODE_BAD_TEST)
+        self.check_executed_tests(output, testname,
+                                  failed=[testname],
+                                  stats=0, parallel=True)
+        if not MS_WINDOWS:
+            exitcode = -int(signal.SIGSEGV)
+            self.assertIn(f"Exit code {exitcode} (SIGSEGV)", output)
+        self.check_line(output, "just before crash!", full=True, regex=False)
+
 
 class TestUtils(unittest.TestCase):
     def test_format_duration(self):
diff --git a/Misc/NEWS.d/next/Tests/2023-10-04-18-27-47.gh-issue-110367.Nnq1I7.rst b/Misc/NEWS.d/next/Tests/2023-10-04-18-27-47.gh-issue-110367.Nnq1I7.rst
new file mode 100644 (file)
index 0000000..a1a6a09
--- /dev/null
@@ -0,0 +1,4 @@
+regrtest: When using worker processes (-jN) with --verbose3 option, regrtest
+can now display the worker output even if a worker process does crash.
+Previously, sys.stdout and sys.stderr were replaced and so the worker output
+was lost on a crash. Patch by Victor Stinner.