Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9a14214

Browse files
committed
Issue #25220: Fix "-m test --forever"
* Fix "-m test --forever": replace _test_forever() with self._test_forever() * Add unit test for --forever * Add unit test for a failing test * Fix also some pyflakes warnings in libregrtest
1 parent 3803114 commit 9a14214

4 files changed

Lines changed: 100 additions & 44 deletions

File tree

Lib/test/libregrtest/main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ def _test_forever(self, tests):
319319

320320
def run_tests(self):
321321
if self.ns.forever:
322-
self.tests = _test_forever(list(self.selected))
322+
self.tests = self._test_forever(list(self.selected))
323323
self.test_count = ''
324324
self.test_count_width = 3
325325
else:

Lib/test/libregrtest/refleak.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ def dash_R(the_module, test, indirect_test, huntrleaks):
4646
print("beginning", repcount, "repetitions", file=sys.stderr)
4747
print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr,
4848
flush=True)
49+
# initialize variables to make pyflakes quiet
50+
rc_before = alloc_before = 0
4951
for i in range(repcount):
5052
indirect_test()
5153
alloc_after, rc_after = dash_R_cleanup(fs, ps, pic, zdc, abcs)
@@ -158,6 +160,6 @@ def warm_caches():
158160
for i in range(256):
159161
s[i:i+1]
160162
# unicode cache
161-
x = [chr(i) for i in range(256)]
163+
[chr(i) for i in range(256)]
162164
# int cache
163-
x = list(range(-5, 257))
165+
list(range(-5, 257))

Lib/test/libregrtest/runtest_mp.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import time
66
import traceback
77
import types
8-
import unittest
98
from test import support
109
try:
1110
import threading
@@ -173,7 +172,7 @@ def get_running(workers):
173172
try:
174173
while finished < regrtest.ns.use_mp:
175174
try:
176-
item = output.get(timeout=PROGRESS_UPDATE)
175+
item = output.get(timeout=timeout)
177176
except queue.Empty:
178177
running = get_running(workers)
179178
if running:

Lib/test/test_regrtest.py

Lines changed: 94 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -330,58 +330,81 @@ def check_line(self, output, regex):
330330
self.assertRegex(output, regex)
331331

332332
def parse_executed_tests(self, output):
333-
parser = re.finditer(r'^\[[0-9]+/[0-9]+\] (%s)$' % self.TESTNAME_REGEX,
334-
output,
335-
re.MULTILINE)
336-
return set(match.group(1) for match in parser)
333+
regex = r'^\[ *[0-9]+(?:/ *[0-9]+)?\] (%s)$' % self.TESTNAME_REGEX
334+
parser = re.finditer(regex, output, re.MULTILINE)
335+
return list(match.group(1) for match in parser)
337336

338-
def check_executed_tests(self, output, tests, skipped=None):
337+
def check_executed_tests(self, output, tests, skipped=(), failed=(),
338+
randomize=False):
339339
if isinstance(tests, str):
340340
tests = [tests]
341-
executed = self.parse_executed_tests(output)
342-
self.assertEqual(executed, set(tests), output)
341+
if isinstance(skipped, str):
342+
skipped = [skipped]
343+
if isinstance(failed, str):
344+
failed = [failed]
343345
ntest = len(tests)
344-
if skipped:
345-
if isinstance(skipped, str):
346-
skipped = [skipped]
347-
nskipped = len(skipped)
348-
349-
plural = 's' if nskipped != 1 else ''
350-
names = ' '.join(sorted(skipped))
351-
expected = (r'%s test%s skipped:\n %s$'
352-
% (nskipped, plural, names))
353-
self.check_line(output, expected)
354-
355-
ok = ntest - nskipped
356-
if ok:
357-
self.check_line(output, r'%s test OK\.$' % ok)
346+
nskipped = len(skipped)
347+
nfailed = len(failed)
348+
349+
executed = self.parse_executed_tests(output)
350+
if randomize:
351+
self.assertEqual(set(executed), set(tests), output)
358352
else:
359-
self.check_line(output, r'All %s tests OK\.$' % ntest)
353+
self.assertEqual(executed, tests, output)
354+
355+
def plural(count):
356+
return 's' if count != 1 else ''
357+
358+
def list_regex(line_format, tests):
359+
count = len(tests)
360+
names = ' '.join(sorted(tests))
361+
regex = line_format % (count, plural(count))
362+
regex = r'%s:\n %s$' % (regex, names)
363+
return regex
364+
365+
if skipped:
366+
regex = list_regex('%s test%s skipped', skipped)
367+
self.check_line(output, regex)
368+
369+
if failed:
370+
regex = list_regex('%s test%s failed', failed)
371+
self.check_line(output, regex)
372+
373+
good = ntest - nskipped - nfailed
374+
if good:
375+
regex = r'%s test%s OK\.$' % (good, plural(good))
376+
if not skipped and not failed and good > 1:
377+
regex = 'All %s' % regex
378+
self.check_line(output, regex)
360379

361380
def parse_random_seed(self, output):
362381
match = self.regex_search(r'Using random seed ([0-9]+)', output)
363382
randseed = int(match.group(1))
364383
self.assertTrue(0 <= randseed <= 10000000, randseed)
365384
return randseed
366385

367-
def run_command(self, args, input=None):
386+
def run_command(self, args, input=None, exitcode=0):
368387
if not input:
369388
input = ''
370-
try:
371-
return subprocess.run(args,
372-
check=True, universal_newlines=True,
373-
input=input,
374-
stdout=subprocess.PIPE,
375-
stderr=subprocess.PIPE)
376-
except subprocess.CalledProcessError as exc:
377-
self.fail("%s\n"
389+
proc = subprocess.run(args,
390+
universal_newlines=True,
391+
input=input,
392+
stdout=subprocess.PIPE,
393+
stderr=subprocess.PIPE)
394+
if proc.returncode != exitcode:
395+
self.fail("Command %s failed with exit code %s\n"
378396
"\n"
379397
"stdout:\n"
398+
"---\n"
380399
"%s\n"
400+
"---\n"
381401
"\n"
382402
"stderr:\n"
403+
"---\n"
383404
"%s"
384-
% (str(exc), exc.stdout, exc.stderr))
405+
"---\n"
406+
% (str(args), proc.returncode, proc.stdout, proc.stderr))
407+
return proc
385408

386409

387410
def run_python(self, args, **kw):
@@ -411,11 +434,11 @@ def setUp(self):
411434

412435
def check_output(self, output):
413436
self.parse_random_seed(output)
414-
self.check_executed_tests(output, self.tests)
437+
self.check_executed_tests(output, self.tests, randomize=True)
415438

416439
def run_tests(self, args):
417-
stdout = self.run_python(args)
418-
self.check_output(stdout)
440+
output = self.run_python(args)
441+
self.check_output(output)
419442

420443
def test_script_regrtest(self):
421444
# Lib/test/regrtest.py
@@ -492,8 +515,24 @@ class ArgsTestCase(BaseTestCase):
492515
Test arguments of the Python test suite.
493516
"""
494517

495-
def run_tests(self, *args, input=None):
496-
return self.run_python(['-m', 'test', *args], input=input)
518+
def run_tests(self, *args, **kw):
519+
return self.run_python(['-m', 'test', *args], **kw)
520+
521+
def test_failing_test(self):
522+
# test a failing test
523+
code = textwrap.dedent("""
524+
import unittest
525+
526+
class FailingTest(unittest.TestCase):
527+
def test_failing(self):
528+
self.fail("bug")
529+
""")
530+
test_ok = self.create_test()
531+
test_failing = self.create_test(code=code)
532+
tests = [test_ok, test_failing]
533+
534+
output = self.run_tests(*tests, exitcode=1)
535+
self.check_executed_tests(output, tests, failed=test_failing)
497536

498537
def test_resources(self):
499538
# test -u command line option
@@ -572,8 +611,7 @@ def test_coverage(self):
572611
# test --coverage
573612
test = self.create_test()
574613
output = self.run_tests("--coverage", test)
575-
executed = self.parse_executed_tests(output)
576-
self.assertEqual(executed, {test}, output)
614+
self.check_executed_tests(output, [test])
577615
regex = ('lines +cov% +module +\(path\)\n'
578616
'(?: *[0-9]+ *[0-9]{1,2}% *[^ ]+ +\([^)]+\)+)+')
579617
self.check_line(output, regex)
@@ -584,6 +622,23 @@ def test_wait(self):
584622
output = self.run_tests("--wait", test, input='key')
585623
self.check_line(output, 'Press any key to continue')
586624

625+
def test_forever(self):
626+
# test --forever
627+
code = textwrap.dedent("""
628+
import unittest
629+
630+
class ForeverTester(unittest.TestCase):
631+
RUN = 1
632+
633+
def test_run(self):
634+
ForeverTester.RUN += 1
635+
if ForeverTester.RUN > 3:
636+
self.fail("fail at the 3rd runs")
637+
""")
638+
test = self.create_test(code=code)
639+
output = self.run_tests('--forever', test, exitcode=1)
640+
self.check_executed_tests(output, [test]*3, failed=test)
641+
587642

588643
if __name__ == '__main__':
589644
unittest.main()

0 commit comments

Comments
 (0)