mirror of https://github.com/python/cpython
[3.13] gh-119050: Add XML support to libregrtest refleak checker (GH-119148) (#119270)
gh-119050: Add XML support to libregrtest refleak checker (GH-119148)
regrtest test runner: Add XML support to the refleak checker
(-R option).
* run_unittest() now stores XML elements as string, rather than
objects, in support.junit_xml_list.
* runtest_refleak() now saves/restores XML strings before/after
checking for reference leaks. Save XML into a temporary file.
(cherry picked from commit 9257731f5d
)
Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
parent
071d996e13
commit
42a8d11752
|
@ -520,15 +520,6 @@ def _parse_args(args, **kwargs):
|
|||
"--huntrleaks without -jN option",
|
||||
file=sys.stderr)
|
||||
|
||||
if ns.huntrleaks and ns.xmlpath:
|
||||
# The XML data is written into a file outside runtest_refleak(), so
|
||||
# it looks like a leak but it's not. Simply disable XML output when
|
||||
# hunting for reference leaks (gh-83434).
|
||||
ns.xmlpath = None
|
||||
print("WARNING: Disable --junit-xml because it's incompatible "
|
||||
"with --huntrleaks",
|
||||
file=sys.stderr)
|
||||
|
||||
if ns.forever:
|
||||
# --forever implies --failfast
|
||||
ns.failfast = True
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import os
|
||||
import sys
|
||||
import warnings
|
||||
from inspect import isabstract
|
||||
|
@ -23,6 +24,30 @@ except ImportError:
|
|||
cls._abc_negative_cache, cls._abc_negative_cache_version)
|
||||
|
||||
|
||||
def save_support_xml(filename):
|
||||
if support.junit_xml_list is None:
|
||||
return
|
||||
|
||||
import pickle
|
||||
with open(filename, 'xb') as fp:
|
||||
pickle.dump(support.junit_xml_list, fp)
|
||||
support.junit_xml_list = None
|
||||
|
||||
|
||||
def restore_support_xml(filename):
|
||||
try:
|
||||
fp = open(filename, 'rb')
|
||||
except FileNotFoundError:
|
||||
return
|
||||
|
||||
import pickle
|
||||
with fp:
|
||||
xml_list = pickle.load(fp)
|
||||
os.unlink(filename)
|
||||
|
||||
support.junit_xml_list = xml_list
|
||||
|
||||
|
||||
def runtest_refleak(test_name, test_func,
|
||||
hunt_refleak: HuntRefleak,
|
||||
quiet: bool):
|
||||
|
@ -95,7 +120,8 @@ def runtest_refleak(test_name, test_func,
|
|||
numbers = numbers[:warmups] + ':' + numbers[warmups:]
|
||||
print(numbers, file=sys.stderr, flush=True)
|
||||
|
||||
results = None
|
||||
xml_filename = 'refleak-xml.tmp'
|
||||
result = None
|
||||
dash_R_cleanup(fs, ps, pic, zdc, abcs)
|
||||
support.gc_collect()
|
||||
|
||||
|
@ -103,10 +129,11 @@ def runtest_refleak(test_name, test_func,
|
|||
current = refleak_helper._hunting_for_refleaks
|
||||
refleak_helper._hunting_for_refleaks = True
|
||||
try:
|
||||
results = test_func()
|
||||
result = test_func()
|
||||
finally:
|
||||
refleak_helper._hunting_for_refleaks = current
|
||||
|
||||
save_support_xml(xml_filename)
|
||||
dash_R_cleanup(fs, ps, pic, zdc, abcs)
|
||||
support.gc_collect()
|
||||
|
||||
|
@ -145,6 +172,8 @@ def runtest_refleak(test_name, test_func,
|
|||
fd_before = fd_after
|
||||
interned_before = interned_after
|
||||
|
||||
restore_support_xml(xml_filename)
|
||||
|
||||
if not quiet:
|
||||
print(file=sys.stderr)
|
||||
|
||||
|
@ -189,7 +218,7 @@ def runtest_refleak(test_name, test_func,
|
|||
failed = True
|
||||
else:
|
||||
print(' (this is fine)', file=sys.stderr, flush=True)
|
||||
return (failed, results)
|
||||
return (failed, result)
|
||||
|
||||
|
||||
def dash_R_cleanup(fs, ps, pic, zdc, abcs):
|
||||
|
|
|
@ -57,7 +57,10 @@ def _run_suite(suite):
|
|||
result = runner.run(suite)
|
||||
|
||||
if support.junit_xml_list is not None:
|
||||
support.junit_xml_list.append(result.get_xml_element())
|
||||
import xml.etree.ElementTree as ET
|
||||
xml_elem = result.get_xml_element()
|
||||
xml_str = ET.tostring(xml_elem).decode('ascii')
|
||||
support.junit_xml_list.append(xml_str)
|
||||
|
||||
if not result.testsRun and not result.skipped and not result.errors:
|
||||
raise support.TestDidNotRun
|
||||
|
@ -280,9 +283,7 @@ def _runtest(result: TestResult, runtests: RunTests) -> None:
|
|||
|
||||
xml_list = support.junit_xml_list
|
||||
if xml_list:
|
||||
import xml.etree.ElementTree as ET
|
||||
result.xml_data = [ET.tostring(x).decode('us-ascii')
|
||||
for x in xml_list]
|
||||
result.xml_data = xml_list
|
||||
finally:
|
||||
if use_timeout:
|
||||
faulthandler.cancel_dump_traceback_later()
|
||||
|
|
|
@ -473,15 +473,6 @@ class ParseArgsTestCase(unittest.TestCase):
|
|||
self.assertEqual(regrtest.hunt_refleak.runs, 10)
|
||||
self.assertFalse(regrtest.output_on_failure)
|
||||
|
||||
def test_xml_huntrleaks(self):
|
||||
args = ['-R', '3:12', '--junit-xml', 'output.xml']
|
||||
with support.captured_stderr():
|
||||
regrtest = self.create_regrtest(args)
|
||||
self.assertIsNotNone(regrtest.hunt_refleak)
|
||||
self.assertEqual(regrtest.hunt_refleak.warmups, 3)
|
||||
self.assertEqual(regrtest.hunt_refleak.runs, 12)
|
||||
self.assertIsNone(regrtest.junit_filename)
|
||||
|
||||
|
||||
@dataclasses.dataclass(slots=True)
|
||||
class Rerun:
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
regrtest test runner: Add XML support to the refleak checker (-R option).
|
||||
Patch by Victor Stinner.
|
Loading…
Reference in New Issue