summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-06-15 22:08:39 (GMT)
committerGitHub <noreply@github.com>2017-06-15 22:08:39 (GMT)
commit33cf0c4cd6e8abe138c3469ca9ec1502410945f0 (patch)
treeb9f104b4a6fafdc3c622844b2b5fb9b9fa6e79f7 /Lib/test
parent263dcc39daa74066c2b2fcb007a4bd4f7ec65073 (diff)
downloadcpython-33cf0c4cd6e8abe138c3469ca9ec1502410945f0.zip
cpython-33cf0c4cd6e8abe138c3469ca9ec1502410945f0.tar.gz
cpython-33cf0c4cd6e8abe138c3469ca9ec1502410945f0.tar.bz2
bpo-30675: Fix multiprocessing code in regrtest (#2220)
* Rewrite code to pass slaveargs from the master process to worker processes: reuse the same code of the Python master branch * Move code to initialize tests in a new setup_tests() function, similar change was done in the master branch * In a worker process, call setup_tests() with the namespace built from slaveargs to initialize correctly tests Before this change, warm_caches() was not called in worker processes because the setup was done before rebuilding the namespace from slaveargs. As a consequence, the huntrleaks feature was unstable. For example, test_zipfile reported randomly false positive on reference leaks.
Diffstat (limited to 'Lib/test')
-rwxr-xr-xLib/test/regrtest.py110
1 files changed, 63 insertions, 47 deletions
diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py
index 6cb9d5a..e5aa3e3 100755
--- a/Lib/test/regrtest.py
+++ b/Lib/test/regrtest.py
@@ -140,6 +140,7 @@ import sysconfig
import tempfile
import time
import traceback
+import types
import unittest
import warnings
from inspect import isabstract
@@ -448,17 +449,15 @@ def run_test_in_subprocess(testname, ns):
# required to spawn a new process with PGO flag on/off
if ns.pgo:
base_cmd = base_cmd + ['--pgo']
- slaveargs = (
- (testname, ns.verbose, ns.quiet),
- dict(huntrleaks=ns.huntrleaks,
- use_resources=ns.use_resources,
- output_on_failure=ns.verbose3,
- timeout=ns.timeout, failfast=ns.failfast,
- match_tests=ns.match_tests, pgo=ns.pgo))
+
+ ns_dict = vars(ns)
+ slaveargs = (ns_dict, testname)
+ slaveargs = json.dumps(slaveargs)
+
# Running the child from the same working directory as regrtest's original
# invocation ensures that TEMPDIR for the child is the same when
# sysconfig.is_python_build() is true. See issue 15300.
- popen = Popen(base_cmd + ['--slaveargs', json.dumps(slaveargs)],
+ popen = Popen(base_cmd + ['--slaveargs', slaveargs],
stdout=PIPE, stderr=PIPE,
universal_newlines=True,
close_fds=(os.name != 'nt'),
@@ -468,6 +467,43 @@ def run_test_in_subprocess(testname, ns):
return retcode, stdout, stderr
+def setup_tests(ns):
+ if ns.huntrleaks:
+ # Avoid false positives due to various caches
+ # filling slowly with random data:
+ warm_caches()
+ if ns.memlimit is not None:
+ support.set_memlimit(ns.memlimit)
+ if ns.threshold is not None:
+ import gc
+ gc.set_threshold(ns.threshold)
+ if ns.nowindows:
+ print('The --nowindows (-n) option is deprecated. '
+ 'Use -vv to display assertions in stderr.')
+ try:
+ import msvcrt
+ except ImportError:
+ pass
+ else:
+ msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS|
+ msvcrt.SEM_NOALIGNMENTFAULTEXCEPT|
+ msvcrt.SEM_NOGPFAULTERRORBOX|
+ msvcrt.SEM_NOOPENFILEERRORBOX)
+ try:
+ msvcrt.CrtSetReportMode
+ except AttributeError:
+ # release build
+ pass
+ else:
+ for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
+ if ns.verbose and ns.verbose >= 2:
+ msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
+ msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
+ else:
+ msvcrt.CrtSetReportMode(m, 0)
+
+
+
def main(tests=None, **kwargs):
"""Execute a test suite.
@@ -509,58 +545,38 @@ def main(tests=None, **kwargs):
ns = _parse_args(sys.argv[1:], **kwargs)
- if ns.huntrleaks:
- # Avoid false positives due to various caches
- # filling slowly with random data:
- warm_caches()
- if ns.memlimit is not None:
- support.set_memlimit(ns.memlimit)
- if ns.threshold is not None:
- import gc
- gc.set_threshold(ns.threshold)
- if ns.nowindows:
- print('The --nowindows (-n) option is deprecated. '
- 'Use -vv to display assertions in stderr.')
- try:
- import msvcrt
- except ImportError:
- pass
- else:
- msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS|
- msvcrt.SEM_NOALIGNMENTFAULTEXCEPT|
- msvcrt.SEM_NOGPFAULTERRORBOX|
- msvcrt.SEM_NOOPENFILEERRORBOX)
- try:
- msvcrt.CrtSetReportMode
- except AttributeError:
- # release build
- pass
- else:
- for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
- if ns.verbose and ns.verbose >= 2:
- msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
- msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
- else:
- msvcrt.CrtSetReportMode(m, 0)
- if ns.wait:
- input("Press any key to continue...")
-
if ns.slaveargs is not None:
- args, kwargs = json.loads(ns.slaveargs)
- if kwargs.get('huntrleaks'):
+ ns_dict, testname = json.loads(ns.slaveargs)
+ ns = types.SimpleNamespace(**ns_dict)
+
+ setup_tests(ns)
+
+ if ns.huntrleaks:
unittest.BaseTestSuite._cleanup = False
+
try:
- result = runtest(*args, **kwargs)
+ result = runtest(testname, ns.verbose, ns.quiet,
+ ns.huntrleaks,
+ output_on_failure=ns.verbose3,
+ timeout=ns.timeout, failfast=ns.failfast,
+ match_tests=ns.match_tests, pgo=ns.pgo,
+ use_resources=ns.use_resources)
except KeyboardInterrupt:
result = INTERRUPTED, ''
except BaseException as e:
traceback.print_exc()
result = CHILD_ERROR, str(e)
+
sys.stdout.flush()
print() # Force a newline (just in case)
print(json.dumps(result))
sys.exit(0)
+ setup_tests(ns)
+
+ if ns.wait:
+ input("Press any key to continue...")
+
good = []
bad = []
skipped = []