mirror of
https://github.com/python/cpython.git
synced 2025-12-10 11:00:14 +00:00
bpo-36719: Fix regrtest re-run (GH-12964)
Properly handle a test which fail but then pass. Add test_rerun_success() unit test.
This commit is contained in:
parent
75120d2205
commit
837acc1957
3 changed files with 35 additions and 14 deletions
|
|
@ -103,17 +103,18 @@ class Regrtest:
|
||||||
| set(self.resource_denieds) | set(self.environment_changed)
|
| set(self.resource_denieds) | set(self.environment_changed)
|
||||||
| set(self.run_no_tests))
|
| set(self.run_no_tests))
|
||||||
|
|
||||||
def accumulate_result(self, result):
|
def accumulate_result(self, result, rerun=False):
|
||||||
test_name = result.test_name
|
test_name = result.test_name
|
||||||
ok = result.result
|
ok = result.result
|
||||||
|
|
||||||
if ok not in (CHILD_ERROR, INTERRUPTED):
|
if ok not in (CHILD_ERROR, INTERRUPTED) and not rerun:
|
||||||
self.test_times.append((result.test_time, test_name))
|
self.test_times.append((result.test_time, test_name))
|
||||||
|
|
||||||
if ok == PASSED:
|
if ok == PASSED:
|
||||||
self.good.append(test_name)
|
self.good.append(test_name)
|
||||||
elif ok in (FAILED, CHILD_ERROR):
|
elif ok in (FAILED, CHILD_ERROR):
|
||||||
self.bad.append(test_name)
|
if not rerun:
|
||||||
|
self.bad.append(test_name)
|
||||||
elif ok == ENV_CHANGED:
|
elif ok == ENV_CHANGED:
|
||||||
self.environment_changed.append(test_name)
|
self.environment_changed.append(test_name)
|
||||||
elif ok == SKIPPED:
|
elif ok == SKIPPED:
|
||||||
|
|
@ -123,9 +124,14 @@ class Regrtest:
|
||||||
self.resource_denieds.append(test_name)
|
self.resource_denieds.append(test_name)
|
||||||
elif ok == TEST_DID_NOT_RUN:
|
elif ok == TEST_DID_NOT_RUN:
|
||||||
self.run_no_tests.append(test_name)
|
self.run_no_tests.append(test_name)
|
||||||
elif ok != INTERRUPTED:
|
elif ok == INTERRUPTED:
|
||||||
|
self.interrupted = True
|
||||||
|
else:
|
||||||
raise ValueError("invalid test result: %r" % ok)
|
raise ValueError("invalid test result: %r" % ok)
|
||||||
|
|
||||||
|
if rerun and ok not in {FAILED, CHILD_ERROR, INTERRUPTED}:
|
||||||
|
self.bad.remove(test_name)
|
||||||
|
|
||||||
xml_data = result.xml_data
|
xml_data = result.xml_data
|
||||||
if xml_data:
|
if xml_data:
|
||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
|
@ -287,13 +293,11 @@ class Regrtest:
|
||||||
for test_name in self.rerun:
|
for test_name in self.rerun:
|
||||||
print(f"Re-running {test_name} in verbose mode", flush=True)
|
print(f"Re-running {test_name} in verbose mode", flush=True)
|
||||||
self.ns.verbose = True
|
self.ns.verbose = True
|
||||||
ok = runtest(self.ns, test_name)
|
result = runtest(self.ns, test_name)
|
||||||
|
|
||||||
if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
|
self.accumulate_result(result, rerun=True)
|
||||||
self.bad.remove(test_name)
|
|
||||||
|
|
||||||
if ok.result == INTERRUPTED:
|
if result.result == INTERRUPTED:
|
||||||
self.interrupted = True
|
|
||||||
break
|
break
|
||||||
|
|
||||||
if self.bad:
|
if self.bad:
|
||||||
|
|
@ -392,7 +396,6 @@ class Regrtest:
|
||||||
self.accumulate_result(result)
|
self.accumulate_result(result)
|
||||||
|
|
||||||
if result.result == INTERRUPTED:
|
if result.result == INTERRUPTED:
|
||||||
self.interrupted = True
|
|
||||||
break
|
break
|
||||||
|
|
||||||
previous_test = format_test_result(result)
|
previous_test = format_test_result(result)
|
||||||
|
|
|
||||||
|
|
@ -255,9 +255,6 @@ class MultiprocessRunner:
|
||||||
if mp_result.stderr and not self.ns.pgo:
|
if mp_result.stderr and not self.ns.pgo:
|
||||||
print(mp_result.stderr, file=sys.stderr, flush=True)
|
print(mp_result.stderr, file=sys.stderr, flush=True)
|
||||||
|
|
||||||
if mp_result.result.result == INTERRUPTED:
|
|
||||||
self.regrtest.interrupted = True
|
|
||||||
|
|
||||||
if must_stop(mp_result.result):
|
if must_stop(mp_result.result):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -484,7 +484,7 @@ class BaseTestCase(unittest.TestCase):
|
||||||
result.append('SUCCESS')
|
result.append('SUCCESS')
|
||||||
result = ', '.join(result)
|
result = ', '.join(result)
|
||||||
if rerun:
|
if rerun:
|
||||||
self.check_line(output, 'Tests result: %s' % result)
|
self.check_line(output, 'Tests result: FAILURE')
|
||||||
result = 'FAILURE then %s' % result
|
result = 'FAILURE then %s' % result
|
||||||
|
|
||||||
self.check_line(output, 'Tests result: %s' % result)
|
self.check_line(output, 'Tests result: %s' % result)
|
||||||
|
|
@ -989,6 +989,7 @@ class ArgsTestCase(BaseTestCase):
|
||||||
fail_env_changed=True)
|
fail_env_changed=True)
|
||||||
|
|
||||||
def test_rerun_fail(self):
|
def test_rerun_fail(self):
|
||||||
|
# FAILURE then FAILURE
|
||||||
code = textwrap.dedent("""
|
code = textwrap.dedent("""
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
|
@ -1003,6 +1004,26 @@ class ArgsTestCase(BaseTestCase):
|
||||||
self.check_executed_tests(output, [testname],
|
self.check_executed_tests(output, [testname],
|
||||||
failed=testname, rerun=testname)
|
failed=testname, rerun=testname)
|
||||||
|
|
||||||
|
def test_rerun_success(self):
|
||||||
|
# FAILURE then SUCCESS
|
||||||
|
code = textwrap.dedent("""
|
||||||
|
import builtins
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class Tests(unittest.TestCase):
|
||||||
|
failed = False
|
||||||
|
|
||||||
|
def test_fail_once(self):
|
||||||
|
if not hasattr(builtins, '_test_failed'):
|
||||||
|
builtins._test_failed = True
|
||||||
|
self.fail("bug")
|
||||||
|
""")
|
||||||
|
testname = self.create_test(code=code)
|
||||||
|
|
||||||
|
output = self.run_tests("-w", testname, exitcode=0)
|
||||||
|
self.check_executed_tests(output, [testname],
|
||||||
|
rerun=testname)
|
||||||
|
|
||||||
def test_no_tests_ran(self):
|
def test_no_tests_ran(self):
|
||||||
code = textwrap.dedent("""
|
code = textwrap.dedent("""
|
||||||
import unittest
|
import unittest
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue