]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-101634: regrtest reports decoding error as failed test (#106169)
authorVictor Stinner <vstinner@python.org>
Wed, 28 Jun 2023 02:26:52 +0000 (04:26 +0200)
committerGitHub <noreply@github.com>
Wed, 28 Jun 2023 02:26:52 +0000 (04:26 +0200)
When running the Python test suite with -jN option, if a worker stdout
cannot be decoded from the locale encoding report a failed testn so the
exitcode is non-zero.

Lib/test/libregrtest/runtest_mp.py
Lib/test/test_regrtest.py
Misc/NEWS.d/next/Tests/2023-06-28-02-51-08.gh-issue-101634.Rayczr.rst [new file with mode: 0644]

index a12fcb46e0fd0be3de84a42141ab26bcd7752a1d..62e6c6df36518c261e0b13fb87480b46420da0c1 100644 (file)
@@ -277,6 +277,7 @@ class TestWorkerProcess(threading.Thread):
             encoding = locale.getencoding()
         else:
             encoding = sys.stdout.encoding
+
         # gh-94026: Write stdout+stderr to a tempfile as workaround for
         # non-blocking pipes on Emscripten with NodeJS.
         with tempfile.TemporaryFile('w+', encoding=encoding) as stdout_fh:
@@ -298,7 +299,14 @@ class TestWorkerProcess(threading.Thread):
                 retcode = self._run_process(test_name, None, stdout_fh)
                 tmp_files = ()
             stdout_fh.seek(0)
-            stdout = stdout_fh.read().strip()
+
+            try:
+                stdout = stdout_fh.read().strip()
+            except Exception as exc:
+                # gh-101634: Catch UnicodeDecodeError if stdout cannot be
+                # decoded from encoding
+                err_msg = f"Cannot read process stdout: {exc}"
+                return self.mp_result_error(ChildError(test_name), '', err_msg)
 
         if retcode is None:
             return self.mp_result_error(Timeout(test_name), stdout)
@@ -481,6 +489,8 @@ class MultiprocessTestRunner:
             # Thread got an exception
             format_exc = item[1]
             print_warning(f"regrtest worker thread failed: {format_exc}")
+            result = ChildError("<regrtest worker>")
+            self.regrtest.accumulate_result(result)
             return True
 
         self.test_index += 1
index ac49fbae847726f22abc9429b1f01428921cc6f2..806b932a164df81ab0a1aa4a8ab58539f497a59f 100644 (file)
@@ -7,6 +7,7 @@ Note: test_regrtest cannot be run twice in parallel.
 import contextlib
 import glob
 import io
+import locale
 import os.path
 import platform
 import re
@@ -1551,6 +1552,41 @@ class ArgsTestCase(BaseTestCase):
                           f"files (1): mytmpfile",
                           output)
 
+    def test_mp_decode_error(self):
+        # gh-101634: If a worker stdout cannot be decoded, report a failed test
+        # and a non-zero exit code.
+        if sys.platform == 'win32':
+            encoding = locale.getencoding()
+        else:
+            encoding = sys.stdout.encoding
+            if encoding is None:
+                encoding = sys.__stdout__.encoding
+                if encoding is None:
+                    self.skipTest(f"cannot get regrtest worker encoding")
+
+        nonascii = b"byte:\xa0\xa9\xff\n"
+        try:
+            nonascii.decode(encoding)
+        except UnicodeDecodeError:
+            pass
+        else:
+            self.skipTest(f"{encoding} can decode non-ASCII bytes {nonascii!a}")
+
+        code = textwrap.dedent(fr"""
+            import sys
+            # bytes which cannot be decoded from UTF-8
+            nonascii = {nonascii!a}
+            sys.stdout.buffer.write(nonascii)
+            sys.stdout.buffer.flush()
+        """)
+        testname = self.create_test(code=code)
+
+        output = self.run_tests("--fail-env-changed", "-v", "-j1", testname,
+                                exitcode=EXITCODE_BAD_TEST)
+        self.check_executed_tests(output, [testname],
+                                  failed=[testname],
+                                  randomize=True)
+
 
 class TestUtils(unittest.TestCase):
     def test_format_duration(self):
diff --git a/Misc/NEWS.d/next/Tests/2023-06-28-02-51-08.gh-issue-101634.Rayczr.rst b/Misc/NEWS.d/next/Tests/2023-06-28-02-51-08.gh-issue-101634.Rayczr.rst
new file mode 100644 (file)
index 0000000..6fbfc84
--- /dev/null
@@ -0,0 +1,3 @@
+When running the Python test suite with ``-jN`` option, if a worker stdout
+cannot be decoded from the locale encoding report a failed testn so the
+exitcode is non-zero. Patch by Victor Stinner.