◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
3 changes: 3 additions & 0 deletions Lib/test/libregrtest/cmdline.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,9 @@ def _create_parser():
' , don\'t execute them')
group.add_argument('-P', '--pgo', dest='pgo', action='store_true',
help='enable Profile Guided Optimization training')

return parser

Expand Down
16 changes: 14 additions & 2 deletions Lib/test/libregrtest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,13 @@ def _list_cases(self, suite):
if isinstance(test, unittest.TestSuite):
self._list_cases(test)
elif isinstance(test, unittest.TestCase):
print(test.id())

def list_cases(self):
for test in self.selected:
abstest = get_abs_module(self.ns, test)
try:
Expand Down Expand Up @@ -474,6 +478,8 @@ def finalize(self):
result = "FAILURE"
elif self.interrupted:
result = "INTERRUPTED"
else:
result = "SUCCESS"
print("Tests result: %s" % result)
Expand Down Expand Up @@ -534,7 +540,13 @@ def _main(self, tests, kwargs):
self.rerun_failed_tests()

self.finalize()
sys.exit(len(self.bad) > 0 or self.interrupted)


def removepy(names):
Expand Down
25 changes: 22 additions & 3 deletions Lib/test/libregrtest/refleak.py
Original file line number Diff line number Diff line change
@@ -93,9 +93,21 @@ def dash_R(the_module, test, indirect_test, huntrleaks):
rc_before = rc_after
fd_before = fd_after
print(file=sys.stderr)
# These checkers return False on success, True on failure
def check_rc_deltas(deltas):
return any(deltas)
def check_alloc_deltas(deltas):
# At least 1/3rd of 0s
if 3 * deltas.count(0) < len(deltas):
Expand All @@ -104,14 +116,21 @@ def check_alloc_deltas(deltas):
if not set(deltas) <= {1,0,-1}:
return True
return False
failed = False
for deltas, item_name, checker in [
(rc_deltas, 'references', check_rc_deltas),
(alloc_deltas, 'memory blocks', check_alloc_deltas),
(fd_deltas, 'file descriptors', check_rc_deltas)]:
if checker(deltas):
msg = '%s leaked %s %s, sum=%s' % (
test, deltas[nwarmup:], item_name, sum(deltas))
print(msg, file=sys.stderr, flush=True)
with open(fname, "a") as refrep:
print(msg, file=refrep)
Expand Down
32 changes: 18 additions & 14 deletions Lib/test/support/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1898,6 +1898,23 @@ def _run_suite(suite):
raise TestFailed(err)


def run_unittest(*classes):
"""Run tests from unittest.TestCase-derived classes."""
valid_types = (unittest.TestSuite, unittest.TestCase)
Expand All @@ -1912,20 +1929,7 @@ def run_unittest(*classes):
suite.addTest(cls)
else:
suite.addTest(unittest.makeSuite(cls))
def case_pred(test):
if match_tests is None:
return True
test_id = test.id()

for match_test in match_tests:
if fnmatch.fnmatchcase(test_id, match_test):
return True

for name in test_id.split("."):
if fnmatch.fnmatchcase(name, match_test):
return True
return False
_filter_suite(suite, case_pred)
_run_suite(suite)

#=======================================================================
Expand Down
113 changes: 83 additions & 30 deletions Lib/test/test_regrtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,19 +377,19 @@ def parse_executed_tests(self, output):
return list(match.group(1) for match in parser)

def check_executed_tests(self, output, tests, skipped=(), failed=(),
omitted=(), randomize=False, interrupted=False):
if isinstance(tests, str):
tests = [tests]
if isinstance(skipped, str):
skipped = [skipped]
if isinstance(failed, str):
failed = [failed]
if isinstance(omitted, str):
omitted = [omitted]
ntest = len(tests)
nskipped = len(skipped)
nfailed = len(failed)
nomitted = len(omitted)

executed = self.parse_executed_tests(output)
if randomize:
@@ -415,11 +415,17 @@ def list_regex(line_format, tests):
regex = list_regex('%s test%s failed', failed)
self.check_line(output, regex)

if omitted:
regex = list_regex('%s test%s omitted', omitted)
self.check_line(output, regex)

good = ntest - nskipped - nfailed - nomitted
if good:
regex = r'%s test%s OK\.$' % (good, plural(good))
if not skipped and not failed and good > 1:
@@ -429,10 +435,12 @@ def list_regex(line_format, tests):
if interrupted:
self.check_line(output, 'Test suite interrupted by signal SIGINT.')

if nfailed:
result = 'FAILURE'
elif interrupted:
result = 'INTERRUPTED'
else:
result = 'SUCCESS'
self.check_line(output, 'Tests result: %s' % result)
Expand Down Expand Up @@ -604,7 +612,7 @@ def test_failing(self):
test_failing = self.create_test('failing', code=code)
tests = [test_ok, test_failing]

output = self.run_tests(*tests, exitcode=1)
self.check_executed_tests(output, tests, failed=test_failing)

def test_resources(self):
Expand Up @@ -703,7 +711,7 @@ def test_fromfile(self):
def test_interrupted(self):
code = TEST_INTERRUPTED
test = self.create_test('sigint', code=code)
output = self.run_tests(test, exitcode=1)
self.check_executed_tests(output, test, omitted=test,
interrupted=True)

Expand Down Expand Up @@ -732,7 +740,7 @@ def test_slow_interrupted(self):
args = ("--slowest", "-j2", test)
else:
args = ("--slowest", test)
output = self.run_tests(*args, exitcode=1)
self.check_executed_tests(output, test,
omitted=test, interrupted=True)

Expand Down Expand Up @@ -772,9 +780,43 @@ def test_run(self):
builtins.__dict__['RUN'] = 1
""")
test = self.create_test('forever', code=code)
output = self.run_tests('--forever', test, exitcode=1)
self.check_executed_tests(output, [test]*3, failed=test)

@unittest.skipUnless(Py_DEBUG, 'need a debug build')
def test_huntrleaks_fd_leak(self):
# test --huntrleaks for file descriptor leak
Expand All @@ -799,24 +841,7 @@ def test_leak(self):
fd = os.open(__file__, os.O_RDONLY)
# bug: never cloes the file descriptor
""")
test = self.create_test('huntrleaks', code=code)

filename = 'reflog.txt'
self.addCleanup(support.unlink, filename)
output = self.run_tests('--huntrleaks', '3:3:', test,
exitcode=1,
stderr=subprocess.STDOUT)
self.check_executed_tests(output, [test], failed=test)

line = 'beginning 6 repetitions\n123456\n......\n'
self.check_line(output, re.escape(line))

line2 = '%s leaked [1, 1, 1] file descriptors, sum=3\n' % test
self.assertIn(line2, output)

with open(filename) as fp:
reflog = fp.read()
self.assertIn(line2, reflog)

def test_list_tests(self):
# test --list-tests
Expand All @@ -837,19 +862,28 @@ def test_method2(self):
pass
""")
testname = self.create_test(code=code)
all_methods = ['%s.Tests.test_method1' % testname,
'%s.Tests.test_method2' % testname]
output = self.run_tests('--list-cases', testname)
self.assertEqual(output.splitlines(), all_methods)

def test_crashed(self):
# Any code which causes a crash
code = 'import faulthandler; faulthandler._sigsegv()'
crash_test = self.create_test(name="crash", code=code)
ok_test = self.create_test(name="ok")

tests = [crash_test, ok_test]
output = self.run_tests("-j2", *tests, exitcode=1)
self.check_executed_tests(output, tests, failed=crash_test,
randomize=True)

Expand Down Expand Up @@ -898,6 +932,25 @@ def test_method4(self):
subset = ['test_method1', 'test_method3']
self.assertEqual(methods, subset)


if __name__ == '__main__':
unittest.main()
Toggle all file notes Toggle all file annotations