From: Serhiy Storchaka Date: Wed, 3 May 2017 21:23:50 +0000 (+0300) Subject: [2.7] bpo-30236: Backported regrtest options -m and -G. (#1394) X-Git-Tag: v2.7.14rc1~178 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=74f0db885fa84e3a1c73b3ae1edc723d48f7bad2;p=python [2.7] bpo-30236: Backported regrtest options -m and -G. (#1394) --- diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index e49bcb962f..413d7f9064 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -37,6 +37,8 @@ Selecting tests -f/--fromfile -- read names of tests to run from a file (see below) -x/--exclude -- arguments are tests to *exclude* -s/--single -- single step through a set of tests (see below) +-m/--match PAT -- match test cases and methods with glob pattern PAT +-G/--failfast -- fail as soon as a test fails (only with -v or -W) -u/--use RES1,RES2,... -- specify which special resource intensive tests to run -M/--memlimit LIMIT @@ -242,7 +244,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, 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, forever=False, - header=False, pgo=False): + header=False, pgo=False, failfast=False, match_tests=None): """Execute a test suite. This also parses command-line options and modifies its behavior @@ -268,12 +270,13 @@ 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:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:P', + opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:PGm:', ['help', 'verbose', 'verbose2', 'verbose3', 'quiet', 'exclude', 'single', 'slow', 'randomize', 'fromfile=', 'findleaks', 'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir', 'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=', - 'multiprocess=', 'slaveargs=', 'forever', 'header', 'pgo']) + 'multiprocess=', 'slaveargs=', 'forever', 'header', 'pgo', + 'failfast', 'match=']) except getopt.error, msg: usage(2, msg) @@ -291,6 +294,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, verbose2 = True elif o in ('-W', '--verbose3'): verbose3 = True + elif o in ('-G', '--failfast'): + failfast = True elif o in ('-q', '--quiet'): quiet = True; verbose = 0 @@ -306,6 +311,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, random_seed = int(a) elif o in ('-f', '--fromfile'): fromfile = a + elif o in ('-m', '--match'): + match_tests = a elif o in ('-l', '--findleaks'): findleaks = True elif o in ('-L', '--runleaks'): @@ -380,6 +387,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, usage(2, "-T and -j don't go together!") if use_mp and findleaks: usage(2, "-l and -j don't go together!") + if failfast and not (verbose or verbose3): + usage("-G/--failfast needs either -v or -W") good = [] bad = [] @@ -514,6 +523,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, args_tuple = ( (test, verbose, quiet), dict(huntrleaks=huntrleaks, use_resources=use_resources, + failfast=failfast, + match_tests=match_tests, pgo=pgo) ) yield (test, args_tuple) @@ -609,7 +620,9 @@ def main(tests=None, testdir=None, verbose=0, quiet=False, globals=globals(), locals=vars()) else: try: - result = runtest(test, verbose, quiet, huntrleaks, None, pgo) + result = runtest(test, verbose, quiet, huntrleaks, None, pgo, + failfast=failfast, + match_tests=match_tests) accumulate_result(test, result) if verbose3 and result[0] == FAILED: if not pgo: @@ -743,7 +756,8 @@ def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): return stdtests + sorted(tests) def runtest(test, verbose, quiet, - huntrleaks=False, use_resources=None, pgo=False): + huntrleaks=False, use_resources=None, pgo=False, + failfast=False, match_tests=None): """Run a single test. test -- the name of the test @@ -769,6 +783,9 @@ def runtest(test, verbose, quiet, if use_resources is not None: test_support.use_resources = use_resources try: + test_support.match_tests = match_tests + if failfast: + test_support.failfast = True return runtest_inner(test, verbose, quiet, huntrleaks, pgo) finally: cleanup_test_droppings(test, verbose) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index fa75ff881d..ef0ced6fae 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -5,6 +5,7 @@ if __name__ != 'test.support': import contextlib import errno +import fnmatch import functools import gc import socket @@ -165,6 +166,8 @@ use_resources = None # Flag set to [] by regrtest.py max_memuse = 0 # Disable bigmem tests (they will still be run with # small sizes, to make sure they work.) real_max_memuse = 0 +failfast = False +match_tests = None # _original_stdout is meant to hold stdout at the time regrtest began. # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever. @@ -1462,11 +1465,23 @@ def check_impl_detail(**guards): return guards.get(platform.python_implementation().lower(), default) +def _filter_suite(suite, pred): + """Recursively filter test cases in a suite based on a predicate.""" + newtests = [] + for test in suite._tests: + if isinstance(test, unittest.TestSuite): + _filter_suite(test, pred) + newtests.append(test) + else: + if pred(test): + newtests.append(test) + suite._tests = newtests def _run_suite(suite): """Run tests from a unittest.TestSuite-derived class.""" if verbose: - runner = unittest.TextTestRunner(sys.stdout, verbosity=2) + runner = unittest.TextTestRunner(sys.stdout, verbosity=2, + failfast=failfast) else: runner = BasicTestRunner() @@ -1497,6 +1512,14 @@ def run_unittest(*classes): suite.addTest(cls) else: suite.addTest(unittest.makeSuite(cls)) + def case_pred(test): + if match_tests is None: + return True + for name in test.id().split("."): + if fnmatch.fnmatchcase(name, match_tests): + return True + return False + _filter_suite(suite, case_pred) _run_suite(suite) #======================================================================= diff --git a/Misc/NEWS b/Misc/NEWS index 50a2c78ac9..47a00a6042 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -148,6 +148,9 @@ Build Tests ----- +- bpo-30236: Backported test.regrtest options -m/--match and -G/--failfast + from Python 3. + - bpo-30223: To unify running tests in Python 2.7 and Python 3, the test package can be run as a script. This is equivalent to running the test.regrtest module as a script.