Skip to content

Commit

Permalink
pythongh-115720: Show number of leaks in huntrleaks progress reports (p…
Browse files Browse the repository at this point in the history
…ythonGH-115726)

Instead of showing a dot for each iteration, show:
- '.' for zero (on negative) leaks
- number of leaks for 1-9
- 'X' if there are more leaks

This allows more rapid iteration: when bisecting, I don't need
to wait for the final report to see if the test still leaks.

Also, show the full result if there are any non-zero entries.
This shows negative entries, for the unfortunate cases where
a reference is created and cleaned up in different runs.

Test *failure* is still determined by the existing heuristic.
  • Loading branch information
encukou committed Feb 27, 2024
1 parent 6087315 commit af5f9d6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 14 deletions.
47 changes: 35 additions & 12 deletions Lib/test/libregrtest/refleak.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,12 @@ def get_pooled_int(value):
rc_before = alloc_before = fd_before = interned_before = 0

if not quiet:
print("beginning", repcount, "repetitions", file=sys.stderr)
print(("1234567890"*(repcount//10 + 1))[:repcount], file=sys.stderr,
flush=True)
print("beginning", repcount, "repetitions. Showing number of leaks "
"(. for 0 or less, X for 10 or more)",
file=sys.stderr)
numbers = ("1234567890"*(repcount//10 + 1))[:repcount]
numbers = numbers[:warmups] + ':' + numbers[warmups:]
print(numbers, file=sys.stderr, flush=True)

results = None
dash_R_cleanup(fs, ps, pic, zdc, abcs)
Expand All @@ -116,13 +119,27 @@ def get_pooled_int(value):
rc_after = gettotalrefcount() - interned_after * 2
fd_after = fd_count()

if not quiet:
print('.', end='', file=sys.stderr, flush=True)

rc_deltas[i] = get_pooled_int(rc_after - rc_before)
alloc_deltas[i] = get_pooled_int(alloc_after - alloc_before)
fd_deltas[i] = get_pooled_int(fd_after - fd_before)

if not quiet:
# use max, not sum, so total_leaks is one of the pooled ints
total_leaks = max(rc_deltas[i], alloc_deltas[i], fd_deltas[i])
if total_leaks <= 0:
symbol = '.'
elif total_leaks < 10:
symbol = (
'.', '1', '2', '3', '4', '5', '6', '7', '8', '9',
)[total_leaks]
else:
symbol = 'X'
if i == warmups:
print(' ', end='', file=sys.stderr, flush=True)
print(symbol, end='', file=sys.stderr, flush=True)
del total_leaks
del symbol

alloc_before = alloc_after
rc_before = rc_after
fd_before = fd_after
Expand Down Expand Up @@ -158,14 +175,20 @@ def check_fd_deltas(deltas):
]:
# ignore warmup runs
deltas = deltas[warmups:]
if checker(deltas):
failing = checker(deltas)
suspicious = any(deltas)
if failing or suspicious:
msg = '%s leaked %s %s, sum=%s' % (
test_name, deltas, item_name, sum(deltas))
print(msg, file=sys.stderr, flush=True)
with open(filename, "a", encoding="utf-8") as refrep:
print(msg, file=refrep)
refrep.flush()
failed = True
print(msg, end='', file=sys.stderr)
if failing:
print(file=sys.stderr, flush=True)
with open(filename, "a", encoding="utf-8") as refrep:
print(msg, file=refrep)
refrep.flush()
failed = True
else:
print(' (this is fine)', file=sys.stderr, flush=True)
return (failed, results)


Expand Down
4 changes: 2 additions & 2 deletions Lib/test/test_regrtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1171,8 +1171,8 @@ def check_leak(self, code, what, *, run_workers=False):
stderr=subprocess.STDOUT)
self.check_executed_tests(output, [test], failed=test, stats=1)

line = 'beginning 6 repetitions\n123456\n......\n'
self.check_line(output, re.escape(line))
line = r'beginning 6 repetitions. .*\n123:456\n[.0-9X]{3} 111\n'
self.check_line(output, line)

line2 = '%s leaked [1, 1, 1] %s, sum=3\n' % (test, what)
self.assertIn(line2, output)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Leak tests (``-R``, ``--huntrleaks``) now show a summary of the number of
leaks found in each iteration.

0 comments on commit af5f9d6

Please sign in to comment.