From 3268f8a0017a8ff16fdf2ad2d4a31f8e0363b191 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Mon, 15 Jan 2024 11:13:24 +0100 Subject: [PATCH 1/3] refleak tests: Show number of leaks in progress reports Instead of showing a dot for each iteration, show: - '.' for warmup or no leaks - number of leaks for 1-9 - 'X' if there are more leaks This allows more rapid iteration: I don't need to wait for the final report to see if the test still leaks. --- Lib/test/libregrtest/refleak.py | 27 ++++++++++++++----- Lib/test/test_regrtest.py | 4 +-- ...-02-20-15-47-41.gh-issue-115720.w8i8UG.rst | 2 ++ 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/Tests/2024-02-20-15-47-41.gh-issue-115720.w8i8UG.rst diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 71a70af6882d16..d01f5fba5f876c 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -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 zero, 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) @@ -116,13 +119,25 @@ 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 = str(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 diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index b80e0524593fc7..7e1eaa7d6a515e 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -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) diff --git a/Misc/NEWS.d/next/Tests/2024-02-20-15-47-41.gh-issue-115720.w8i8UG.rst b/Misc/NEWS.d/next/Tests/2024-02-20-15-47-41.gh-issue-115720.w8i8UG.rst new file mode 100644 index 00000000000000..a03ee11d974251 --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2024-02-20-15-47-41.gh-issue-115720.w8i8UG.rst @@ -0,0 +1,2 @@ +Leak tests (``-R``, ``--huntrleaks``) now show a summary of the number of +leaks found in each iteration. From 0dd589eafd34fe7e7179dd90b18b60102216280d Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 20 Feb 2024 16:37:58 +0100 Subject: [PATCH 2/3] Replace str() by tuple lookup --- Lib/test/libregrtest/refleak.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index d01f5fba5f876c..683cfcfb535a2f 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -129,7 +129,9 @@ def get_pooled_int(value): if total_leaks <= 0: symbol = '.' elif total_leaks < 10: - symbol = str(total_leaks) + symbol = ( + '.', '1', '2', '3', '4', '5', '6', '7', '8', '9', + )[total_leaks] else: symbol = 'X' if i == warmups: From f2a10a161301502e4718410afbcb7b9f077d5e61 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 21 Feb 2024 10:04:12 +0100 Subject: [PATCH 3/3] Show full result if it's not all zeros --- Lib/test/libregrtest/refleak.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Lib/test/libregrtest/refleak.py b/Lib/test/libregrtest/refleak.py index 683cfcfb535a2f..f582c0d3e7ff13 100644 --- a/Lib/test/libregrtest/refleak.py +++ b/Lib/test/libregrtest/refleak.py @@ -89,7 +89,7 @@ def get_pooled_int(value): if not quiet: print("beginning", repcount, "repetitions. Showing number of leaks " - "(. for zero, X for 10 or more)", + "(. for 0 or less, X for 10 or more)", file=sys.stderr) numbers = ("1234567890"*(repcount//10 + 1))[:repcount] numbers = numbers[:warmups] + ':' + numbers[warmups:] @@ -175,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)