Skip to content

Commit 1d55888

Browse files
authored
bpo-33873: Backport regrtest from master to 3.7 (GH-7935) (GH-7937)
* 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 4ffe9c2) * 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 cac4fef) * 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 58ed730) (cherry picked from commit d1f9481)
1 parent c604063 commit 1d55888

File tree

6 files changed

+66
-11
lines changed

6 files changed

+66
-11
lines changed

‎Lib/test/libregrtest/main.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,13 @@ def run_tests(self):
462462
or self.tests or self.ns.args)):
463463
self.display_header()
464464

465+
if self.ns.huntrleaks:
466+
warmup, repetitions, _ = self.ns.huntrleaks
467+
if warmup < 3:
468+
msg = ("WARNING: Running tests with --huntrleaks/-R and less than "
469+
"3 warmup repetitions can give false positives!")
470+
print(msg, file=sys.stdout, flush=True)
471+
465472
if self.ns.randomize:
466473
print("Using random seed", self.ns.random_seed)
467474

@@ -526,6 +533,15 @@ def main(self, tests=None, **kwargs):
526533
def _main(self, tests, kwargs):
527534
self.ns = self.parse_args(kwargs)
528535

536+
if self.ns.huntrleaks:
537+
warmup, repetitions, _ = self.ns.huntrleaks
538+
if warmup < 1 or repetitions < 1:
539+
msg = ("Invalid values for the --huntrleaks/-R parameters. The "
540+
"number of warmups and repetitions must be at least 1 "
541+
"each (1:1).")
542+
print(msg, file=sys.stderr, flush=True)
543+
sys.exit(2)
544+
529545
if self.ns.slaveargs is not None:
530546
from test.libregrtest.runtest_mp import run_tests_slave
531547
run_tests_slave(self.ns.slaveargs)

‎Lib/test/libregrtest/runtest.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,10 @@ def test_runner():
173173
if loader.errors:
174174
raise Exception("errors while loading tests")
175175
support.run_unittest(tests)
176-
test_runner()
177176
if ns.huntrleaks:
178177
refleak = dash_R(the_module, test, test_runner, ns.huntrleaks)
178+
else:
179+
test_runner()
179180
test_time = time.time() - start_time
180181
post_test_cleanup()
181182
except support.ResourceDenied as msg:

‎Lib/test/libregrtest/runtest_mp.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ def get_running(workers):
204204
if (ok not in (CHILD_ERROR, INTERRUPTED)
205205
and test_time >= PROGRESS_MIN_TIME
206206
and not regrtest.ns.pgo):
207-
text += ' (%.0f sec)' % test_time
207+
text += ' (%s)' % format_duration(test_time)
208208
elif ok == CHILD_ERROR:
209209
text = '%s (%s)' % (text, test_time)
210210
running = get_running(workers)

‎Lib/test/libregrtest/utils.py‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
import os.path
2+
import math
23
import textwrap
34

45

56
def format_duration(seconds):
6-
if seconds < 1.0:
7-
return '%.0f ms' % (seconds * 1e3)
8-
if seconds < 60.0:
9-
return '%.0f sec' % seconds
7+
ms = math.ceil(seconds * 1e3)
8+
seconds, ms = divmod(ms, 1000)
9+
minutes, seconds = divmod(seconds, 60)
10+
hours, minutes = divmod(minutes, 60)
1011

11-
minutes, seconds = divmod(seconds, 60.0)
12-
hours, minutes = divmod(minutes, 60.0)
12+
parts = []
1313
if hours:
14-
return '%.0f hour %.0f min' % (hours, minutes)
15-
else:
16-
return '%.0f min %.0f sec' % (minutes, seconds)
14+
parts.append('%s hour' % hours)
15+
if minutes:
16+
parts.append('%s min' % minutes)
17+
if seconds:
18+
parts.append('%s sec' % seconds)
19+
if ms:
20+
parts.append('%s ms' % ms)
21+
if not parts:
22+
return '0 ms'
23+
24+
parts = parts[:2]
25+
return ' '.join(parts)
1726

1827

1928
def removepy(names):

‎Lib/test/test_regrtest.py‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import unittest
1919
from test import libregrtest
2020
from test import support
21+
from test.libregrtest import utils
2122

2223

2324
Py_DEBUG = hasattr(sys, 'getobjects')
@@ -984,5 +985,29 @@ def test_bug(self):
984985
failed=testname, rerun=testname)
985986

986987

988+
class TestUtils(unittest.TestCase):
989+
def test_format_duration(self):
990+
self.assertEqual(utils.format_duration(0),
991+
'0 ms')
992+
self.assertEqual(utils.format_duration(1e-9),
993+
'1 ms')
994+
self.assertEqual(utils.format_duration(10e-3),
995+
'10 ms')
996+
self.assertEqual(utils.format_duration(1.5),
997+
'1 sec 500 ms')
998+
self.assertEqual(utils.format_duration(1),
999+
'1 sec')
1000+
self.assertEqual(utils.format_duration(2 * 60),
1001+
'2 min')
1002+
self.assertEqual(utils.format_duration(2 * 60 + 1),
1003+
'2 min 1 sec')
1004+
self.assertEqual(utils.format_duration(3 * 3600),
1005+
'3 hour')
1006+
self.assertEqual(utils.format_duration(3 * 3600 + 2 * 60 + 1),
1007+
'3 hour 2 min')
1008+
self.assertEqual(utils.format_duration(3 * 3600 + 1),
1009+
'3 hour 1 sec')
1010+
1011+
9871012
if __name__ == '__main__':
9881013
unittest.main()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix a bug in ``regrtest`` that caused an extra test to run if
2+
--huntrleaks/-R was used. Exit with error in case that invalid
3+
parameters are specified to --huntrleaks/-R (at least one warmup
4+
run and one repetition must be used).

0 commit comments

Comments
 (0)