From 3dd802d8f287e8f11848cfb068cf73000a9d0d94 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 1 Jun 2018 12:29:39 +0200 Subject: [PATCH] bpo-33718: regrtest: update from master (GH-7305) --- Lib/test/libregrtest/main.py | 97 ++++++++++++------------------ Lib/test/libregrtest/runtest_mp.py | 4 +- Lib/test/libregrtest/utils.py | 47 +++++++++++++++ 3 files changed, 87 insertions(+), 61 deletions(-) create mode 100644 Lib/test/libregrtest/utils.py diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index ce01c8ce58..6a818cdd2c 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -8,7 +8,6 @@ import re import sys import sysconfig import tempfile -import textwrap import time import unittest from test.libregrtest.cmdline import _parse_args @@ -18,6 +17,7 @@ from test.libregrtest.runtest import ( INTERRUPTED, CHILD_ERROR, PROGRESS_MIN_TIME, format_test_result) from test.libregrtest.setup import setup_tests +from test.libregrtest.utils import removepy, count, format_duration, printlist from test import support try: import gc @@ -41,16 +41,6 @@ else: TEMPDIR = os.path.abspath(TEMPDIR) -def format_duration(seconds): - if seconds < 1.0: - return '%.0f ms' % (seconds * 1e3) - if seconds < 60.0: - return '%.0f sec' % seconds - - minutes, seconds = divmod(seconds, 60.0) - return '%.0f min %.0f sec' % (minutes, seconds) - - class Regrtest: """Execute a test suite. @@ -88,6 +78,7 @@ class Regrtest: self.skipped = [] self.resource_denieds = [] self.environment_changed = [] + self.rerun = [] self.interrupted = False # used by --slow @@ -281,10 +272,11 @@ class Regrtest: self.ns.verbose = True self.ns.failfast = False self.ns.verbose3 = False - self.ns.match_tests = None + print() print("Re-running failed tests in verbose mode") - for test in self.bad[:]: + self.rerun = self.bad[:] + for test in self.rerun: print("Re-running test %r in verbose mode" % test, flush=True) try: self.ns.verbose = True @@ -302,22 +294,27 @@ class Regrtest: print(count(len(self.bad), 'test'), "failed again:") printlist(self.bad) + self.display_result() + def display_result(self): + # If running the test suite for PGO then no one cares about results. + if self.ns.pgo: + return + + print() + print("== Tests result: %s ==" % self.get_tests_result()) + if self.interrupted: - # print a newline after ^C print() + # print a newline after ^C print("Test suite interrupted by signal SIGINT.") executed = set(self.good) | set(self.bad) | set(self.skipped) omitted = set(self.selected) - executed print(count(len(omitted), "test"), "omitted:") printlist(omitted) - # If running the test suite for PGO then no one cares about - # results. - if self.ns.pgo: - return - if self.good and not self.ns.quiet: + print() if (not self.bad and not self.skipped and not self.interrupted @@ -348,6 +345,11 @@ class Regrtest: print(count(len(self.skipped), "test"), "skipped:") printlist(self.skipped) + if self.rerun: + print() + print("%s:" % count(len(self.rerun), "re-run test")) + printlist(self.rerun) + def run_tests_sequential(self): if self.ns.trace: import trace @@ -432,6 +434,21 @@ class Regrtest: % (locale.getpreferredencoding(False), sys.getfilesystemencoding())) + def get_tests_result(self): + result = [] + if self.bad: + result.append("FAILURE") + elif self.ns.fail_env_changed and self.environment_changed: + result.append("ENV CHANGED") + + if self.interrupted: + result.append("INTERRUPTED") + + if not result: + result.append("SUCCESS") + + return ', '.join(result) + def run_tests(self): # For a partial run, we do not need to clutter the output. if (self.ns.header @@ -473,16 +490,7 @@ class Regrtest: print() duration = time.monotonic() - self.start_time print("Total duration: %s" % format_duration(duration)) - - if self.bad: - result = "FAILURE" - elif self.interrupted: - result = "INTERRUPTED" - elif self.ns.fail_env_changed and self.environment_changed: - result = "ENV CHANGED" - else: - result = "SUCCESS" - print("Tests result: %s" % result) + print("Tests result: %s" % self.get_tests_result()) if self.ns.runleaks: os.system("leaks %d" % os.getpid()) @@ -549,37 +557,6 @@ class Regrtest: sys.exit(0) -def removepy(names): - if not names: - return - for idx, name in enumerate(names): - basename, ext = os.path.splitext(name) - if ext == '.py': - names[idx] = basename - - -def count(n, word): - if n == 1: - return "%d %s" % (n, word) - else: - return "%d %ss" % (n, word) - - -def printlist(x, width=70, indent=4, file=None): - """Print the elements of iterable x to stdout. - - Optional arg width (default 70) is the maximum line length. - Optional arg indent (default 4) is the number of blanks with which to - begin each line. - """ - - blanks = ' ' * indent - # Print the sorted list: 'x' may be a '--random' list or a set() - print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width, - initial_indent=blanks, subsequent_indent=blanks), - file=file) - - def main(tests=None, **kwargs): """Run the Python suite.""" Regrtest().main(tests=tests, **kwargs) diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index 598754f279..f7fa10cf55 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -13,6 +13,7 @@ from test.libregrtest.runtest import ( runtest, INTERRUPTED, CHILD_ERROR, PROGRESS_MIN_TIME, format_test_result) from test.libregrtest.setup import setup_tests +from test.libregrtest.utils import format_duration # Display the running tests if nothing happened last N seconds @@ -167,7 +168,8 @@ def run_tests_multiprocess(regrtest): continue dt = time.monotonic() - worker.start_time if dt >= PROGRESS_MIN_TIME: - running.append('%s (%.0f sec)' % (current_test, dt)) + text = '%s (%s)' % (current_test, format_duration(dt)) + running.append(text) return running finished = 0 diff --git a/Lib/test/libregrtest/utils.py b/Lib/test/libregrtest/utils.py new file mode 100644 index 0000000000..85049cb06b --- /dev/null +++ b/Lib/test/libregrtest/utils.py @@ -0,0 +1,47 @@ +import os.path +import textwrap + + +def format_duration(seconds): + if seconds < 1.0: + return '%.0f ms' % (seconds * 1e3) + if seconds < 60.0: + return '%.0f sec' % seconds + + minutes, seconds = divmod(seconds, 60.0) + hours, minutes = divmod(minutes, 60.0) + if hours: + return '%.0f hour %.0f min' % (hours, minutes) + else: + return '%.0f min %.0f sec' % (minutes, seconds) + + +def removepy(names): + if not names: + return + for idx, name in enumerate(names): + basename, ext = os.path.splitext(name) + if ext == '.py': + names[idx] = basename + + +def count(n, word): + if n == 1: + return "%d %s" % (n, word) + else: + return "%d %ss" % (n, word) + + +def printlist(x, width=70, indent=4, file=None): + """Print the elements of iterable x to stdout. + + Optional arg width (default 70) is the maximum line length. + Optional arg indent (default 4) is the number of blanks with which to + begin each line. + """ + + blanks = ' ' * indent + # Print the sorted list: 'x' may be a '--random' list or a set() + print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width, + initial_indent=blanks, subsequent_indent=blanks), + file=file) -- 2.40.0