Index: Lib/test/regrtest.py =================================================================== --- Lib/test/regrtest.py (révision 76258) +++ Lib/test/regrtest.py (copie de travail) @@ -43,6 +43,7 @@ -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 @@ import cStringIO import getopt +import itertools import json import os import random @@ -219,7 +221,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ -475,20 +493,22 @@ 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: