gh-115122: Add --bisect option to regrtest (#115123)

* test.bisect_cmd now exit with code 0 on success, and code 1 on
  failure. Before, it was the opposite.
* test.bisect_cmd now runs the test worker process with
  -X faulthandler.
* regrtest RunTests: Add create_python_cmd() and bisect_cmd()
  methods.
This commit is contained in:
Victor Stinner 2024-02-18 21:06:39 +01:00 committed by GitHub
parent 0c80da4c14
commit 1e5719a663
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 178 additions and 30 deletions

View file

@ -399,7 +399,7 @@ class ParseArgsTestCase(unittest.TestCase):
self.checkError(['--unknown-option'],
'unrecognized arguments: --unknown-option')
def check_ci_mode(self, args, use_resources, rerun=True):
def create_regrtest(self, args):
ns = cmdline._parse_args(args)
# Check Regrtest attributes which are more reliable than Namespace
@ -411,6 +411,10 @@ class ParseArgsTestCase(unittest.TestCase):
regrtest = main.Regrtest(ns)
return regrtest
def check_ci_mode(self, args, use_resources, rerun=True):
regrtest = self.create_regrtest(args)
self.assertEqual(regrtest.num_workers, -1)
self.assertEqual(regrtest.want_rerun, rerun)
self.assertTrue(regrtest.randomize)
@ -455,6 +459,11 @@ class ParseArgsTestCase(unittest.TestCase):
ns = cmdline._parse_args(args)
self.assertFalse(ns._add_python_opts)
def test_bisect(self):
args = ['--bisect']
regrtest = self.create_regrtest(args)
self.assertTrue(regrtest.want_bisect)
@dataclasses.dataclass(slots=True)
class Rerun:
@ -1192,6 +1201,47 @@ class ArgsTestCase(BaseTestCase):
def test_huntrleaks_mp(self):
self.check_huntrleaks(run_workers=True)
@unittest.skipUnless(support.Py_DEBUG, 'need a debug build')
def test_huntrleaks_bisect(self):
# test --huntrleaks --bisect
code = textwrap.dedent("""
import unittest
GLOBAL_LIST = []
class RefLeakTest(unittest.TestCase):
def test1(self):
pass
def test2(self):
pass
def test3(self):
GLOBAL_LIST.append(object())
def test4(self):
pass
""")
test = self.create_test('huntrleaks', code=code)
filename = 'reflog.txt'
self.addCleanup(os_helper.unlink, filename)
cmd = ['--huntrleaks', '3:3:', '--bisect', test]
output = self.run_tests(*cmd,
exitcode=EXITCODE_BAD_TEST,
stderr=subprocess.STDOUT)
self.assertIn(f"Bisect {test}", output)
self.assertIn(f"Bisect {test}: exit code 0", output)
# test3 is the one which leaks
self.assertIn("Bisection completed in", output)
self.assertIn(
"Tests (1):\n"
f"* {test}.RefLeakTest.test3\n",
output)
@unittest.skipUnless(support.Py_DEBUG, 'need a debug build')
def test_huntrleaks_fd_leak(self):
# test --huntrleaks for file descriptor leak