diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2017-06-15 22:08:39 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-15 22:08:39 (GMT) |
commit | 33cf0c4cd6e8abe138c3469ca9ec1502410945f0 (patch) | |
tree | b9f104b4a6fafdc3c622844b2b5fb9b9fa6e79f7 /Lib/test | |
parent | 263dcc39daa74066c2b2fcb007a4bd4f7ec65073 (diff) | |
download | cpython-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-x | Lib/test/regrtest.py | 110 |
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 = [] |