Skip to content

Commit 74f0db8

Browse files
[2.7] bpo-30236: Backported regrtest options -m and -G. (#1394)
1 parent 8cf7ea2 commit 74f0db8

File tree

3 files changed

+49
-6
lines changed

3 files changed

+49
-6
lines changed

Lib/test/regrtest.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
-f/--fromfile -- read names of tests to run from a file (see below)
3838
-x/--exclude -- arguments are tests to *exclude*
3939
-s/--single -- single step through a set of tests (see below)
40+
-m/--match PAT -- match test cases and methods with glob pattern PAT
41+
-G/--failfast -- fail as soon as a test fails (only with -v or -W)
4042
-u/--use RES1,RES2,...
4143
-- specify which special resource intensive tests to run
4244
-M/--memlimit LIMIT
@@ -242,7 +244,7 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
242244
findleaks=False, use_resources=None, trace=False, coverdir='coverage',
243245
runleaks=False, huntrleaks=False, verbose2=False, print_slow=False,
244246
random_seed=None, use_mp=None, verbose3=False, forever=False,
245-
header=False, pgo=False):
247+
header=False, pgo=False, failfast=False, match_tests=None):
246248
"""Execute a test suite.
247249
248250
This also parses command-line options and modifies its behavior
@@ -268,12 +270,13 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
268270

269271
test_support.record_original_stdout(sys.stdout)
270272
try:
271-
opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:P',
273+
opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:PGm:',
272274
['help', 'verbose', 'verbose2', 'verbose3', 'quiet',
273275
'exclude', 'single', 'slow', 'randomize', 'fromfile=', 'findleaks',
274276
'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir',
275277
'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=',
276-
'multiprocess=', 'slaveargs=', 'forever', 'header', 'pgo'])
278+
'multiprocess=', 'slaveargs=', 'forever', 'header', 'pgo',
279+
'failfast', 'match='])
277280
except getopt.error, msg:
278281
usage(2, msg)
279282

@@ -291,6 +294,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
291294
verbose2 = True
292295
elif o in ('-W', '--verbose3'):
293296
verbose3 = True
297+
elif o in ('-G', '--failfast'):
298+
failfast = True
294299
elif o in ('-q', '--quiet'):
295300
quiet = True;
296301
verbose = 0
@@ -306,6 +311,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
306311
random_seed = int(a)
307312
elif o in ('-f', '--fromfile'):
308313
fromfile = a
314+
elif o in ('-m', '--match'):
315+
match_tests = a
309316
elif o in ('-l', '--findleaks'):
310317
findleaks = True
311318
elif o in ('-L', '--runleaks'):
@@ -380,6 +387,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,
380387
usage(2, "-T and -j don't go together!")
381388
if use_mp and findleaks:
382389
usage(2, "-l and -j don't go together!")
390+
if failfast and not (verbose or verbose3):
391+
usage("-G/--failfast needs either -v or -W")
383392

384393
good = []
385394
bad = []
@@ -514,6 +523,8 @@ def tests_and_args():
514523
args_tuple = (
515524
(test, verbose, quiet),
516525
dict(huntrleaks=huntrleaks, use_resources=use_resources,
526+
failfast=failfast,
527+
match_tests=match_tests,
517528
pgo=pgo)
518529
)
519530
yield (test, args_tuple)
@@ -609,7 +620,9 @@ def work():
609620
globals=globals(), locals=vars())
610621
else:
611622
try:
612-
result = runtest(test, verbose, quiet, huntrleaks, None, pgo)
623+
result = runtest(test, verbose, quiet, huntrleaks, None, pgo,
624+
failfast=failfast,
625+
match_tests=match_tests)
613626
accumulate_result(test, result)
614627
if verbose3 and result[0] == FAILED:
615628
if not pgo:
@@ -743,7 +756,8 @@ def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
743756
return stdtests + sorted(tests)
744757

745758
def runtest(test, verbose, quiet,
746-
huntrleaks=False, use_resources=None, pgo=False):
759+
huntrleaks=False, use_resources=None, pgo=False,
760+
failfast=False, match_tests=None):
747761
"""Run a single test.
748762
749763
test -- the name of the test
@@ -769,6 +783,9 @@ def runtest(test, verbose, quiet,
769783
if use_resources is not None:
770784
test_support.use_resources = use_resources
771785
try:
786+
test_support.match_tests = match_tests
787+
if failfast:
788+
test_support.failfast = True
772789
return runtest_inner(test, verbose, quiet, huntrleaks, pgo)
773790
finally:
774791
cleanup_test_droppings(test, verbose)

Lib/test/support/__init__.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import contextlib
77
import errno
8+
import fnmatch
89
import functools
910
import gc
1011
import socket
@@ -165,6 +166,8 @@ def get_attribute(obj, name):
165166
max_memuse = 0 # Disable bigmem tests (they will still be run with
166167
# small sizes, to make sure they work.)
167168
real_max_memuse = 0
169+
failfast = False
170+
match_tests = None
168171

169172
# _original_stdout is meant to hold stdout at the time regrtest began.
170173
# This may be "the real" stdout, or IDLE's emulation of stdout, or whatever.
@@ -1462,11 +1465,23 @@ def check_impl_detail(**guards):
14621465
return guards.get(platform.python_implementation().lower(), default)
14631466

14641467

1468+
def _filter_suite(suite, pred):
1469+
"""Recursively filter test cases in a suite based on a predicate."""
1470+
newtests = []
1471+
for test in suite._tests:
1472+
if isinstance(test, unittest.TestSuite):
1473+
_filter_suite(test, pred)
1474+
newtests.append(test)
1475+
else:
1476+
if pred(test):
1477+
newtests.append(test)
1478+
suite._tests = newtests
14651479

14661480
def _run_suite(suite):
14671481
"""Run tests from a unittest.TestSuite-derived class."""
14681482
if verbose:
1469-
runner = unittest.TextTestRunner(sys.stdout, verbosity=2)
1483+
runner = unittest.TextTestRunner(sys.stdout, verbosity=2,
1484+
failfast=failfast)
14701485
else:
14711486
runner = BasicTestRunner()
14721487

@@ -1497,6 +1512,14 @@ def run_unittest(*classes):
14971512
suite.addTest(cls)
14981513
else:
14991514
suite.addTest(unittest.makeSuite(cls))
1515+
def case_pred(test):
1516+
if match_tests is None:
1517+
return True
1518+
for name in test.id().split("."):
1519+
if fnmatch.fnmatchcase(name, match_tests):
1520+
return True
1521+
return False
1522+
_filter_suite(suite, case_pred)
15001523
_run_suite(suite)
15011524

15021525
#=======================================================================

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ Build
148148
Tests
149149
-----
150150

151+
- bpo-30236: Backported test.regrtest options -m/--match and -G/--failfast
152+
from Python 3.
153+
151154
- bpo-30223: To unify running tests in Python 2.7 and Python 3, the test
152155
package can be run as a script. This is equivalent to running the
153156
test.regrtest module as a script.

0 commit comments

Comments
 (0)