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
b6fb8dcbce
commit
7f7eea651f
|
@ -43,6 +43,7 @@ Special runs
|
|||
-N/--nocoverdir -- Put coverage files alongside modules
|
||||
-t/--threshold THRESHOLD
|
||||
-- call gc.set_threshold(THRESHOLD)
|
||||
-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,
|
||||
unless -x is given, in which case they are names for tests not to run.
|
||||
|
@ -150,6 +151,7 @@ option '-uall,-bsddb'.
|
|||
|
||||
import cStringIO
|
||||
import getopt
|
||||
import itertools
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
|
@ -219,7 +221,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
exclude=False, single=False, randomize=False, fromfile=None,
|
||||
findleaks=False, use_resources=None, trace=False, coverdir='coverage',
|
||||
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.
|
||||
|
||||
This also parses command-line options and modifies its behavior
|
||||
|
@ -244,12 +246,12 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
|
||||
test_support.record_original_stdout(sys.stdout)
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:wWM:j:',
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsSrf:lu:t:TD:NLR:FwWM:j:',
|
||||
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
|
||||
'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks',
|
||||
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
|
||||
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
|
||||
'multiprocess=', 'slaveargs='])
|
||||
'multiprocess=', 'slaveargs=', 'forever'])
|
||||
except getopt.error, msg:
|
||||
usage(2, msg)
|
||||
|
||||
|
@ -329,6 +331,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
use_resources.remove(r)
|
||||
elif r not in use_resources:
|
||||
use_resources.append(r)
|
||||
elif o in ('-F', '--forever'):
|
||||
forever = True
|
||||
elif o in ('-j', '--multiprocess'):
|
||||
use_mp = int(a)
|
||||
elif o == '--slaveargs':
|
||||
|
@ -371,8 +375,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
filename = os.path.join(gettempdir(), 'pynexttest')
|
||||
try:
|
||||
fp = open(filename, 'r')
|
||||
next = fp.read().strip()
|
||||
tests = [next]
|
||||
next_test = fp.read().strip()
|
||||
tests = [next_test]
|
||||
fp.close()
|
||||
except IOError:
|
||||
pass
|
||||
|
@ -411,6 +415,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
import trace
|
||||
tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
|
||||
trace=False, count=True)
|
||||
|
||||
test_times = []
|
||||
test_support.use_resources = use_resources
|
||||
save_modules = sys.modules.keys()
|
||||
|
@ -431,6 +436,17 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
skipped.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:
|
||||
from threading import Thread
|
||||
from Queue import Queue, Empty
|
||||
|
@ -439,19 +455,21 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
debug_output_pat = re.compile(r"\[\d+ refs\]$")
|
||||
pending = deque()
|
||||
output = Queue()
|
||||
for test in tests:
|
||||
args_tuple = (
|
||||
(test, verbose, quiet, testdir),
|
||||
dict(huntrleaks=huntrleaks, use_resources=use_resources)
|
||||
)
|
||||
pending.append((test, args_tuple))
|
||||
def tests_and_args():
|
||||
for test in tests:
|
||||
args_tuple = (
|
||||
(test, verbose, quiet, testdir),
|
||||
dict(huntrleaks=huntrleaks, use_resources=use_resources)
|
||||
)
|
||||
yield (test, args_tuple)
|
||||
pending = tests_and_args()
|
||||
def work():
|
||||
# A worker thread.
|
||||
try:
|
||||
while True:
|
||||
try:
|
||||
test, args_tuple = pending.popleft()
|
||||
except IndexError:
|
||||
test, args_tuple = next(pending)
|
||||
except StopIteration:
|
||||
output.put((None, None, None, None))
|
||||
return
|
||||
# -E is needed by some tests, e.g. test_import
|
||||
|
@ -464,6 +482,9 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
# comes from the shutdown of the interpreter in the subcommand.
|
||||
stderr = debug_output_pat.sub("", stderr)
|
||||
stdout, _, result = stdout.strip().rpartition("\n")
|
||||
if not result:
|
||||
output.put((None, None, None, None))
|
||||
return
|
||||
result = json.loads(result)
|
||||
if not quiet:
|
||||
stdout = test+'\n'+stdout
|
||||
|
@ -475,20 +496,22 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
|
|||
for worker in workers:
|
||||
worker.start()
|
||||
finished = 0
|
||||
while finished < use_mp:
|
||||
test, stdout, stderr, result = output.get()
|
||||
if test is None:
|
||||
finished += 1
|
||||
continue
|
||||
if stdout:
|
||||
print stdout
|
||||
if stderr:
|
||||
print >>sys.stderr, stderr
|
||||
if result[0] == INTERRUPTED:
|
||||
assert result[1] == 'KeyboardInterrupt'
|
||||
pending.clear()
|
||||
raise KeyboardInterrupt # What else?
|
||||
accumulate_result(test, result)
|
||||
try:
|
||||
while finished < use_mp:
|
||||
test, stdout, stderr, result = output.get()
|
||||
if test is None:
|
||||
finished += 1
|
||||
continue
|
||||
if stdout:
|
||||
print stdout
|
||||
if stderr:
|
||||
print >>sys.stderr, stderr
|
||||
if result[0] == INTERRUPTED:
|
||||
assert result[1] == 'KeyboardInterrupt'
|
||||
raise KeyboardInterrupt # What else?
|
||||
accumulate_result(test, result)
|
||||
except KeyboardInterrupt:
|
||||
pending.close()
|
||||
for worker in workers:
|
||||
worker.join()
|
||||
else:
|
||||
|
|
|
@ -1567,6 +1567,9 @@ Extension Modules
|
|||
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 #7295: Do not use a hardcoded file name in test_tarfile.
|
||||
|
||||
- Issue #7270: Add some dedicated unit tests for multi-thread synchronization
|
||||
|
|
Loading…
Reference in New Issue