From 438cb0da0513e8a04e7fb2a9def7a34b89805066 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 14 Jun 2018 14:58:13 +0200 Subject: [PATCH 1/3] bpo-33718: regrtest: use format_duration() to display failed tests (GH-7686) * Enhance also format_duration(): work on integers and rounds towards +infinity (math.ceil). * Write unit tests on format_duration() (cherry picked from commit 4ffe9c2b251f6e027b26250b7a2618e78d4edd22) --- Lib/test/libregrtest/runtest_mp.py | 2 +- Lib/test/libregrtest/utils.py | 27 ++++++++++++++++++--------- Lib/test/test_regrtest.py | 25 +++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index f7fa10cf551a4e..907451cf63116c 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -200,7 +200,7 @@ def get_running(workers): if (ok not in (CHILD_ERROR, INTERRUPTED) and test_time >= PROGRESS_MIN_TIME and not regrtest.ns.pgo): - text += ' (%.0f sec)' % test_time + text += ' (%s)' % format_duration(test_time) elif ok == CHILD_ERROR: text = '%s (%s)' % (text, test_time) running = get_running(workers) diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py index 85049cb06b3649..d36bf9196626db 100644 --- a/Lib/test/libregrtest/utils.py +++ b/Lib/test/libregrtest/utils.py @@ -1,19 +1,28 @@ import os.path +import math import textwrap def format_duration(seconds): - if seconds < 1.0: - return '%.0f ms' % (seconds * 1e3) - if seconds < 60.0: - return '%.0f sec' % seconds + ms = math.ceil(seconds * 1e3) + seconds, ms = divmod(ms, 1000) + minutes, seconds = divmod(seconds, 60) + hours, minutes = divmod(minutes, 60) - minutes, seconds = divmod(seconds, 60.0) - hours, minutes = divmod(minutes, 60.0) + parts = [] if hours: - return '%.0f hour %.0f min' % (hours, minutes) - else: - return '%.0f min %.0f sec' % (minutes, seconds) + parts.append('%s hour' % hours) + if minutes: + parts.append('%s min' % minutes) + if seconds: + parts.append('%s sec' % seconds) + if ms: + parts.append('%s ms' % ms) + if not parts: + return '0 ms' + + parts = parts[:2] + return ' '.join(parts) def removepy(names): diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py index 10411522dffb02..af332ad15d922a 100644 --- a/Lib/test/test_regrtest.py +++ b/Lib/test/test_regrtest.py @@ -19,6 +19,7 @@ import unittest from test import libregrtest from test import support +from test.libregrtest import utils Py_DEBUG = hasattr(sys, 'getobjects') @@ -980,5 +981,29 @@ def test_bug(self): failed=testname, rerun=testname) +class TestUtils(unittest.TestCase): + def test_format_duration(self): + self.assertEqual(utils.format_duration(0), + '0 ms') + self.assertEqual(utils.format_duration(1e-9), + '1 ms') + self.assertEqual(utils.format_duration(10e-3), + '10 ms') + self.assertEqual(utils.format_duration(1.5), + '1 sec 500 ms') + self.assertEqual(utils.format_duration(1), + '1 sec') + self.assertEqual(utils.format_duration(2 * 60), + '2 min') + self.assertEqual(utils.format_duration(2 * 60 + 1), + '2 min 1 sec') + self.assertEqual(utils.format_duration(3 * 3600), + '3 hour') + self.assertEqual(utils.format_duration(3 * 3600 + 2 * 60 + 1), + '3 hour 2 min') + self.assertEqual(utils.format_duration(3 * 3600 + 1), + '3 hour 1 sec') + + if __name__ == '__main__': unittest.main() From 9e54695b4ef776299bec45a1e6db9e48dee1a126 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Sat, 16 Jun 2018 01:20:56 +0100 Subject: [PATCH 2/3] bpo-33873: regrtest: Add warning on -R 1:3 (GH-7736) regrtest: Add warning when using less than 3 warmup runs like -R 1:3. (cherry picked from commit cac4fef8860e66a9da67d09762f5b614b9471a12) --- Lib/test/libregrtest/main.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 3429b3726abe90..569d034af1a338 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -462,6 +462,13 @@ def run_tests(self): or self.tests or self.ns.args)): self.display_header() + if self.ns.huntrleaks: + warmup, repetitions, _ = self.ns.huntrleaks + if warmup < 3: + msg = ("WARNING: Running tests with --huntrleaks/-R and less than " + "3 warmup repetitions can give false positives!") + print(msg, file=sys.stdout, flush=True) + if self.ns.randomize: print("Using random seed", self.ns.random_seed) From 62b588eb338744e0097663637dfdb829c3dd1789 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 26 Jun 2018 15:17:26 +0100 Subject: [PATCH 3/3] bpo-33873: Fix bug in `runtest.py` and add checks for invalid `-R` parameters (GH-7735) Fix bug in `Lib/test/libregrtest/runtest.py` that makes running tests an extra time than the specified number of runs. Add check for invalid --huntrleaks/-R parameters. (cherry picked from commit 58ed7307ea0b5c5aa052291ebc3030f314f938d8) --- Lib/test/libregrtest/main.py | 9 +++++++++ Lib/test/libregrtest/runtest.py | 3 ++- .../next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index 569d034af1a338..e262a7a172b931 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -533,6 +533,15 @@ def main(self, tests=None, **kwargs): def _main(self, tests, kwargs): self.ns = self.parse_args(kwargs) + if self.ns.huntrleaks: + warmup, repetitions, _ = self.ns.huntrleaks + if warmup < 1 or repetitions < 1: + msg = ("Invalid values for the --huntrleaks/-R parameters. The " + "number of warmups and repetitions must be at least 1 " + "each (1:1).") + print(msg, file=sys.stderr, flush=True) + sys.exit(2) + if self.ns.slaveargs is not None: from test.libregrtest.runtest_mp import run_tests_slave run_tests_slave(self.ns.slaveargs) diff --git a/Lib/test/libregrtest/runtest.py b/Lib/test/libregrtest/runtest.py index 12bf422c902dc1..3e1afd41997aad 100644 --- a/Lib/test/libregrtest/runtest.py +++ b/Lib/test/libregrtest/runtest.py @@ -173,9 +173,10 @@ def test_runner(): if loader.errors: raise Exception("errors while loading tests") support.run_unittest(tests) - test_runner() if ns.huntrleaks: refleak = dash_R(the_module, test, test_runner, ns.huntrleaks) + else: + test_runner() test_time = time.time() - start_time post_test_cleanup() except support.ResourceDenied as msg: diff --git a/Misc/NEWS.d/next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst b/Misc/NEWS.d/next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst new file mode 100644 index 00000000000000..f4f425570267db --- /dev/null +++ b/Misc/NEWS.d/next/Tests/2018-06-16-01-37-31.bpo-33873.d86vab.rst @@ -0,0 +1,4 @@ +Fix a bug in ``regrtest`` that caused an extra test to run if +--huntrleaks/-R was used. Exit with error in case that invalid +parameters are specified to --huntrleaks/-R (at least one warmup +run and one repetition must be used).