mirror of https://github.com/python/cpython
Merged revisions 76260 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r76260 | r.david.murray | 2009-11-14 10:18:22 -0500 (Sat, 14 Nov 2009) | 5 lines Issue #7312 (new feature): Add a -F flag to run the selected tests in a loop until a test fails. Can be combined with -j. Patch by Antoine Pitrou. ........
This commit is contained in:
parent
864b3f08d8
commit
7dc72cc1c4
|
@ -45,6 +45,7 @@ Special runs
|
||||||
-t/--threshold THRESHOLD
|
-t/--threshold THRESHOLD
|
||||||
-- call gc.set_threshold(THRESHOLD)
|
-- call gc.set_threshold(THRESHOLD)
|
||||||
-n/--nowindows -- suppress error message boxes on Windows
|
-n/--nowindows -- suppress error message boxes on Windows
|
||||||
|
-F/--forever -- run the selected tests in a loop, until an error happens
|
||||||
|
|
||||||
If non-option arguments are present, they are names for tests to run,
|
If non-option arguments are present, they are names for tests to run,
|
||||||
unless -x is given, in which case they are names for tests not to run.
|
unless -x is given, in which case they are names for tests not to run.
|
||||||
|
@ -147,6 +148,7 @@ option '-uall,-gui'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import getopt
|
import getopt
|
||||||
|
import itertools
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
@ -217,7 +219,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
exclude=False, single=False, randomize=False, fromfile=None,
|
exclude=False, single=False, randomize=False, fromfile=None,
|
||||||
findleaks=False, use_resources=None, trace=False, coverdir='coverage',
|
findleaks=False, use_resources=None, trace=False, coverdir='coverage',
|
||||||
runleaks=False, huntrleaks=False, verbose2=False, print_slow=False,
|
runleaks=False, huntrleaks=False, verbose2=False, print_slow=False,
|
||||||
random_seed=None, use_mp=None, verbose3=False):
|
random_seed=None, use_mp=None, verbose3=False, forever=False):
|
||||||
"""Execute a test suite.
|
"""Execute a test suite.
|
||||||
|
|
||||||
This also parses command-line options and modifies its behavior
|
This also parses command-line options and modifies its behavior
|
||||||
|
@ -243,12 +245,13 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
|
|
||||||
support.record_original_stdout(sys.stdout)
|
support.record_original_stdout(sys.stdout)
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:wWM:nj:',
|
opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:nj:',
|
||||||
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
|
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
|
||||||
'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks',
|
'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks',
|
||||||
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
|
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
|
||||||
'runleaks', 'huntrleaks=', 'memlimit=', 'debug', 'start=',
|
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
|
||||||
'nowindows', 'randseed=', 'multiprocess=', 'slaveargs='])
|
'multiprocess=', 'slaveargs=', 'forever', 'debug', 'start=',
|
||||||
|
'nowindows'])
|
||||||
except getopt.error as msg:
|
except getopt.error as msg:
|
||||||
usage(msg)
|
usage(msg)
|
||||||
|
|
||||||
|
@ -353,6 +356,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
|
for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
|
||||||
msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
|
msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
|
||||||
msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
|
msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
|
||||||
|
elif o in ('-F', '--forever'):
|
||||||
|
forever = True
|
||||||
elif o in ('-j', '--multiprocess'):
|
elif o in ('-j', '--multiprocess'):
|
||||||
use_mp = int(a)
|
use_mp = int(a)
|
||||||
elif o == '--slaveargs':
|
elif o == '--slaveargs':
|
||||||
|
@ -396,8 +401,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
filename = os.path.join(gettempdir(), 'pynexttest')
|
filename = os.path.join(gettempdir(), 'pynexttest')
|
||||||
try:
|
try:
|
||||||
fp = open(filename, 'r')
|
fp = open(filename, 'r')
|
||||||
next = fp.read().strip()
|
next_test = fp.read().strip()
|
||||||
tests = [next]
|
tests = [next_test]
|
||||||
fp.close()
|
fp.close()
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
@ -443,6 +448,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,
|
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix,
|
||||||
tempfile.gettempdir()],
|
tempfile.gettempdir()],
|
||||||
trace=False, count=True)
|
trace=False, count=True)
|
||||||
|
|
||||||
test_times = []
|
test_times = []
|
||||||
support.verbose = verbose # Tell tests to be moderately quiet
|
support.verbose = verbose # Tell tests to be moderately quiet
|
||||||
support.use_resources = use_resources
|
support.use_resources = use_resources
|
||||||
|
@ -464,6 +470,17 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
skipped.append(test)
|
skipped.append(test)
|
||||||
resource_denieds.append(test)
|
resource_denieds.append(test)
|
||||||
|
|
||||||
|
if forever:
|
||||||
|
def test_forever(tests=list(tests)):
|
||||||
|
while True:
|
||||||
|
for test in tests:
|
||||||
|
yield test
|
||||||
|
if bad:
|
||||||
|
return
|
||||||
|
tests = test_forever()
|
||||||
|
else:
|
||||||
|
tests = iter(tests)
|
||||||
|
|
||||||
if use_mp:
|
if use_mp:
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from queue import Queue, Empty
|
from queue import Queue, Empty
|
||||||
|
@ -472,20 +489,22 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
debug_output_pat = re.compile(r"\[\d+ refs\]$")
|
debug_output_pat = re.compile(r"\[\d+ refs\]$")
|
||||||
pending = deque()
|
pending = deque()
|
||||||
output = Queue()
|
output = Queue()
|
||||||
for test in tests:
|
def tests_and_args():
|
||||||
args_tuple = (
|
for test in tests:
|
||||||
(test, verbose, quiet, testdir),
|
args_tuple = (
|
||||||
dict(huntrleaks=huntrleaks, use_resources=use_resources,
|
(test, verbose, quiet, testdir),
|
||||||
debug=debug)
|
dict(huntrleaks=huntrleaks, use_resources=use_resources,
|
||||||
)
|
debug=debug)
|
||||||
pending.append((test, args_tuple))
|
)
|
||||||
|
yield (test, args_tuple)
|
||||||
|
pending = tests_and_args()
|
||||||
def work():
|
def work():
|
||||||
# A worker thread.
|
# A worker thread.
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
test, args_tuple = pending.popleft()
|
test, args_tuple = next(pending)
|
||||||
except IndexError:
|
except StopIteration:
|
||||||
output.put((None, None, None, None))
|
output.put((None, None, None, None))
|
||||||
return
|
return
|
||||||
# -E is needed by some tests, e.g. test_import
|
# -E is needed by some tests, e.g. test_import
|
||||||
|
@ -498,6 +517,9 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
# comes from the shutdown of the interpreter in the subcommand.
|
# comes from the shutdown of the interpreter in the subcommand.
|
||||||
stderr = debug_output_pat.sub("", stderr)
|
stderr = debug_output_pat.sub("", stderr)
|
||||||
stdout, _, result = stdout.strip().rpartition("\n")
|
stdout, _, result = stdout.strip().rpartition("\n")
|
||||||
|
if not result:
|
||||||
|
output.put((None, None, None, None))
|
||||||
|
return
|
||||||
result = json.loads(result)
|
result = json.loads(result)
|
||||||
if not quiet:
|
if not quiet:
|
||||||
stdout = test+'\n'+stdout
|
stdout = test+'\n'+stdout
|
||||||
|
@ -509,20 +531,22 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
||||||
for worker in workers:
|
for worker in workers:
|
||||||
worker.start()
|
worker.start()
|
||||||
finished = 0
|
finished = 0
|
||||||
while finished < use_mp:
|
try:
|
||||||
test, stdout, stderr, result = output.get()
|
while finished < use_mp:
|
||||||
if test is None:
|
test, stdout, stderr, result = output.get()
|
||||||
finished += 1
|
if test is None:
|
||||||
continue
|
finished += 1
|
||||||
if stdout:
|
continue
|
||||||
print(stdout)
|
if stdout:
|
||||||
if stderr:
|
print(stdout)
|
||||||
print(stderr, file=sys.stderr)
|
if stderr:
|
||||||
if result[0] == INTERRUPTED:
|
print(stderr, file=sys.stderr)
|
||||||
assert result[1] == 'KeyboardInterrupt'
|
if result[0] == INTERRUPTED:
|
||||||
pending.clear()
|
assert result[1] == 'KeyboardInterrupt'
|
||||||
raise KeyboardInterrupt # What else?
|
raise KeyboardInterrupt # What else?
|
||||||
accumulate_result(test, result)
|
accumulate_result(test, result)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pending.close()
|
||||||
for worker in workers:
|
for worker in workers:
|
||||||
worker.join()
|
worker.join()
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -378,6 +378,9 @@ Documentation
|
||||||
Tests
|
Tests
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
- Issue #7312: Add a -F flag to run the selected tests in a loop until
|
||||||
|
a test fails. Can be combined with -j.
|
||||||
|
|
||||||
- Issue #6551: test_zipimport could import and then destroy some modules of
|
- Issue #6551: test_zipimport could import and then destroy some modules of
|
||||||
the encodings package, which would make other tests fail further down
|
the encodings package, which would make other tests fail further down
|
||||||
the road because the internally cached encoders and decoders would point
|
the road because the internally cached encoders and decoders would point
|
||||||
|
|
Loading…
Reference in New Issue