mirror of
https://github.com/python/cpython.git
synced 2025-12-04 08:34:25 +00:00
Issue #15320: Make iterating the list of tests thread-safe when running tests in multiprocess mode.
Patch by Chris Jerdonek.
This commit is contained in:
parent
707bd4e385
commit
09f2e6f902
2 changed files with 31 additions and 12 deletions
|
|
@ -550,16 +550,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
from subprocess import Popen, PIPE
|
from subprocess import Popen, PIPE
|
||||||
debug_output_pat = re.compile(r"\[\d+ refs\]$")
|
debug_output_pat = re.compile(r"\[\d+ refs\]$")
|
||||||
output = Queue()
|
output = Queue()
|
||||||
def tests_and_args():
|
pending = MultiprocessTests(tests)
|
||||||
for test in tests:
|
|
||||||
args_tuple = (
|
|
||||||
(test, verbose, quiet),
|
|
||||||
dict(huntrleaks=huntrleaks, use_resources=use_resources,
|
|
||||||
debug=debug, output_on_failure=verbose3,
|
|
||||||
failfast=failfast, match_tests=match_tests)
|
|
||||||
)
|
|
||||||
yield (test, args_tuple)
|
|
||||||
pending = tests_and_args()
|
|
||||||
opt_args = support.args_from_interpreter_flags()
|
opt_args = support.args_from_interpreter_flags()
|
||||||
base_cmd = [sys.executable] + opt_args + ['-m', 'test.regrtest']
|
base_cmd = [sys.executable] + opt_args + ['-m', 'test.regrtest']
|
||||||
def work():
|
def work():
|
||||||
|
|
@ -567,10 +558,16 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
test, args_tuple = next(pending)
|
test = next(pending)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
output.put((None, None, None, None))
|
output.put((None, None, None, None))
|
||||||
return
|
return
|
||||||
|
args_tuple = (
|
||||||
|
(test, verbose, quiet),
|
||||||
|
dict(huntrleaks=huntrleaks, use_resources=use_resources,
|
||||||
|
debug=debug, output_on_failure=verbose3,
|
||||||
|
failfast=failfast, match_tests=match_tests)
|
||||||
|
)
|
||||||
# -E is needed by some tests, e.g. test_import
|
# -E is needed by some tests, e.g. test_import
|
||||||
# Running the child from the same working directory ensures
|
# Running the child from the same working directory ensures
|
||||||
# that TEMPDIR for the child is the same when
|
# that TEMPDIR for the child is the same when
|
||||||
|
|
@ -622,7 +619,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
test_index += 1
|
test_index += 1
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
interrupted = True
|
interrupted = True
|
||||||
pending.close()
|
pending.interrupted = True
|
||||||
for worker in workers:
|
for worker in workers:
|
||||||
worker.join()
|
worker.join()
|
||||||
else:
|
else:
|
||||||
|
|
@ -766,6 +763,25 @@ def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
|
||||||
tests.append(modname)
|
tests.append(modname)
|
||||||
return stdtests + sorted(tests)
|
return stdtests + sorted(tests)
|
||||||
|
|
||||||
|
# We do not use a generator so multiple threads can call next().
|
||||||
|
class MultiprocessTests(object):
|
||||||
|
|
||||||
|
"""A thread-safe iterator over tests for multiprocess mode."""
|
||||||
|
|
||||||
|
def __init__(self, tests):
|
||||||
|
self.interrupted = False
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
self.tests = tests
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
with self.lock:
|
||||||
|
if self.interrupted:
|
||||||
|
raise StopIteration('tests interrupted')
|
||||||
|
return next(self.tests)
|
||||||
|
|
||||||
def replace_stdout():
|
def replace_stdout():
|
||||||
"""Set stdout encoder error handler to backslashreplace (as stderr error
|
"""Set stdout encoder error handler to backslashreplace (as stderr error
|
||||||
handler) to avoid UnicodeEncodeError when printing a traceback"""
|
handler) to avoid UnicodeEncodeError when printing a traceback"""
|
||||||
|
|
|
||||||
|
|
@ -378,6 +378,9 @@ Extension Modules
|
||||||
Tests
|
Tests
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- Issue #15320: Make iterating the list of tests thread-safe when running
|
||||||
|
tests in multiprocess mode. Patch by Chris Jerdonek.
|
||||||
|
|
||||||
- Issue #15230: Adopted a more systematic approach in the runpy tests
|
- Issue #15230: Adopted a more systematic approach in the runpy tests
|
||||||
|
|
||||||
- Issue #15300: Ensure the temporary test working directories are in the same
|
- Issue #15300: Ensure the temporary test working directories are in the same
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue