blob: 61a98763701d9680419e06f422f1975d2d625609 [file] [log] [blame]
Victor Stinner24f949e2016-03-22 15:14:09 +01001import datetime
Victor Stinner5f9d3ac2015-10-03 00:21:12 +02002import faulthandler
Victor Stinnerb96ef552016-09-08 21:46:56 -07003import locale
Victor Stinner3844fe52015-09-26 10:38:01 +02004import os
Victor Stinner3844fe52015-09-26 10:38:01 +02005import platform
Victor Stinnerdad20e42015-09-29 22:48:52 +02006import random
7import re
Victor Stinnerdad20e42015-09-29 22:48:52 +02008import sys
9import sysconfig
10import tempfile
11import textwrap
Victor Stinner24f949e2016-03-22 15:14:09 +010012import time
Victor Stinner3909e582015-10-11 10:37:25 +020013from test.libregrtest.cmdline import _parse_args
Victor Stinner3844fe52015-09-26 10:38:01 +020014from test.libregrtest.runtest import (
Victor Stinner6f20a2e2015-09-30 02:32:11 +020015 findtests, runtest,
Victor Stinner3909e582015-10-11 10:37:25 +020016 STDTESTS, NOTTESTS, PASSED, FAILED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED,
Victor Stinner69649f22016-03-23 12:14:10 +010017 INTERRUPTED, CHILD_ERROR,
Victor Stinner1b8b4232016-05-20 13:37:40 +020018 PROGRESS_MIN_TIME, format_test_result)
Victor Stinnera2045022015-09-30 02:17:28 +020019from test.libregrtest.setup import setup_tests
Victor Stinner3844fe52015-09-26 10:38:01 +020020from test import support
21try:
Victor Stinnerdad20e42015-09-29 22:48:52 +020022 import gc
23except ImportError:
24 gc = None
Victor Stinner3844fe52015-09-26 10:38:01 +020025
26
Victor Stinner3844fe52015-09-26 10:38:01 +020027# When tests are run from the Python build directory, it is best practice
28# to keep the test files in a subfolder. This eases the cleanup of leftover
29# files using the "make distclean" command.
30if sysconfig.is_python_build():
31 TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build')
32else:
33 TEMPDIR = tempfile.gettempdir()
34TEMPDIR = os.path.abspath(TEMPDIR)
35
36
Victor Stinner435eaf42016-08-17 12:22:52 +020037def format_duration(seconds):
38 if seconds < 1.0:
39 return '%.0f ms' % (seconds * 1e3)
40 if seconds < 60.0:
41 return '%.0f sec' % seconds
42
43 minutes, seconds = divmod(seconds, 60.0)
44 return '%.0f min %.0f sec' % (minutes, seconds)
45
46
Victor Stinnerdad20e42015-09-29 22:48:52 +020047class Regrtest:
Victor Stinner3844fe52015-09-26 10:38:01 +020048 """Execute a test suite.
49
50 This also parses command-line options and modifies its behavior
51 accordingly.
52
53 tests -- a list of strings containing test names (optional)
54 testdir -- the directory in which to look for tests (optional)
55
56 Users other than the Python test suite will certainly want to
57 specify testdir; if it's omitted, the directory containing the
58 Python test suite is searched for.
59
60 If the tests argument is omitted, the tests listed on the
61 command-line will be used. If that's empty, too, then all *.py
62 files beginning with test_ will be used.
63
64 The other default arguments (verbose, quiet, exclude,
65 single, randomize, findleaks, use_resources, trace, coverdir,
66 print_slow, and random_seed) allow programmers calling main()
67 directly to set the values that would normally be set by flags
68 on the command line.
69 """
Victor Stinnerdad20e42015-09-29 22:48:52 +020070 def __init__(self):
71 # Namespace of command line options
72 self.ns = None
Victor Stinner3844fe52015-09-26 10:38:01 +020073
Victor Stinnerdad20e42015-09-29 22:48:52 +020074 # tests
75 self.tests = []
76 self.selected = []
Victor Stinner3844fe52015-09-26 10:38:01 +020077
Victor Stinnerdad20e42015-09-29 22:48:52 +020078 # test results
79 self.good = []
80 self.bad = []
81 self.skipped = []
82 self.resource_denieds = []
83 self.environment_changed = []
84 self.interrupted = False
Victor Stinner3844fe52015-09-26 10:38:01 +020085
Victor Stinnerdad20e42015-09-29 22:48:52 +020086 # used by --slow
87 self.test_times = []
Victor Stinner3844fe52015-09-26 10:38:01 +020088
Victor Stinnerdad20e42015-09-29 22:48:52 +020089 # used by --coverage, trace.Trace instance
90 self.tracer = None
Victor Stinner3844fe52015-09-26 10:38:01 +020091
Victor Stinnerdad20e42015-09-29 22:48:52 +020092 # used by --findleaks, store for gc.garbage
93 self.found_garbage = []
Victor Stinner3844fe52015-09-26 10:38:01 +020094
Victor Stinnerdad20e42015-09-29 22:48:52 +020095 # used to display the progress bar "[ 3/100]"
Victor Stinner24f949e2016-03-22 15:14:09 +010096 self.start_time = time.monotonic()
Victor Stinnerdad20e42015-09-29 22:48:52 +020097 self.test_count = ''
98 self.test_count_width = 1
Victor Stinner3844fe52015-09-26 10:38:01 +020099
Victor Stinnerdad20e42015-09-29 22:48:52 +0200100 # used by --single
101 self.next_single_test = None
102 self.next_single_filename = None
Victor Stinner3844fe52015-09-26 10:38:01 +0200103
Victor Stinnerdad20e42015-09-29 22:48:52 +0200104 def accumulate_result(self, test, result):
Victor Stinner3844fe52015-09-26 10:38:01 +0200105 ok, test_time = result
Victor Stinner3909e582015-10-11 10:37:25 +0200106 if ok not in (CHILD_ERROR, INTERRUPTED):
107 self.test_times.append((test_time, test))
Victor Stinner3844fe52015-09-26 10:38:01 +0200108 if ok == PASSED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200109 self.good.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200110 elif ok == FAILED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200111 self.bad.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200112 elif ok == ENV_CHANGED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200113 self.environment_changed.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200114 elif ok == SKIPPED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200115 self.skipped.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200116 elif ok == RESOURCE_DENIED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200117 self.skipped.append(test)
118 self.resource_denieds.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200119
Victor Stinnerdad20e42015-09-29 22:48:52 +0200120 def display_progress(self, test_index, test):
121 if self.ns.quiet:
122 return
Brett Cannon11faa212015-10-02 16:20:49 -0700123 if self.bad and not self.ns.pgo:
Victor Stinner24f949e2016-03-22 15:14:09 +0100124 fmt = "{time} [{test_index:{count_width}}{test_count}/{nbad}] {test_name}"
Brett Cannon11faa212015-10-02 16:20:49 -0700125 else:
Victor Stinner24f949e2016-03-22 15:14:09 +0100126 fmt = "{time} [{test_index:{count_width}}{test_count}] {test_name}"
Victor Stinner435eaf42016-08-17 12:22:52 +0200127 test_time = time.monotonic() - self.start_time
128 test_time = datetime.timedelta(seconds=int(test_time))
Victor Stinner24f949e2016-03-22 15:14:09 +0100129 line = fmt.format(count_width=self.test_count_width,
130 test_index=test_index,
131 test_count=self.test_count,
132 nbad=len(self.bad),
133 test_name=test,
Victor Stinner435eaf42016-08-17 12:22:52 +0200134 time=test_time)
Victor Stinner24f949e2016-03-22 15:14:09 +0100135 print(line, flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200136
Victor Stinner234cbef2015-09-30 01:13:53 +0200137 def parse_args(self, kwargs):
138 ns = _parse_args(sys.argv[1:], **kwargs)
139
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200140 if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
141 print("Warning: The timeout option requires "
142 "faulthandler.dump_traceback_later", file=sys.stderr)
143 ns.timeout = None
144
Victor Stinner234cbef2015-09-30 01:13:53 +0200145 if ns.threshold is not None and gc is None:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200146 print('No GC available, ignore --threshold.', file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200147 ns.threshold = None
148
149 if ns.findleaks:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200150 if gc is not None:
151 # Uncomment the line below to report garbage that is not
152 # freeable by reference counting alone. By default only
153 # garbage that is not collectable by the GC is reported.
154 pass
155 #gc.set_debug(gc.DEBUG_SAVEALL)
156 else:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200157 print('No GC available, disabling --findleaks',
158 file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200159 ns.findleaks = False
Victor Stinnerdad20e42015-09-29 22:48:52 +0200160
Victor Stinnerdad20e42015-09-29 22:48:52 +0200161 # Strip .py extensions.
Victor Stinner234cbef2015-09-30 01:13:53 +0200162 removepy(ns.args)
163
164 return ns
Victor Stinnerdad20e42015-09-29 22:48:52 +0200165
Victor Stinnerdad20e42015-09-29 22:48:52 +0200166 def find_tests(self, tests):
167 self.tests = tests
168
169 if self.ns.single:
170 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
171 try:
172 with open(self.next_single_filename, 'r') as fp:
173 next_test = fp.read().strip()
174 self.tests = [next_test]
175 except OSError:
176 pass
177
178 if self.ns.fromfile:
179 self.tests = []
Victor Stinner5de16e82016-03-24 09:43:00 +0100180 # regex to match 'test_builtin' in line:
181 # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec'
Victor Stinnere8cfec52017-01-03 01:38:58 +0100182 regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b')
Victor Stinnerdad20e42015-09-29 22:48:52 +0200183 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200184 for line in fp:
Victor Stinnerc24217e2016-12-09 16:05:51 +0100185 line = line.split('#', 1)[0]
Victor Stinner5de16e82016-03-24 09:43:00 +0100186 line = line.strip()
Victor Stinnerc24217e2016-12-09 16:05:51 +0100187 match = regex.search(line)
188 if match is not None:
Victor Stinnere8cfec52017-01-03 01:38:58 +0100189 self.tests.append(match.group())
Victor Stinnerdad20e42015-09-29 22:48:52 +0200190
191 removepy(self.tests)
192
193 stdtests = STDTESTS[:]
194 nottests = NOTTESTS.copy()
195 if self.ns.exclude:
196 for arg in self.ns.args:
197 if arg in stdtests:
198 stdtests.remove(arg)
199 nottests.add(arg)
200 self.ns.args = []
201
Victor Stinnerdad20e42015-09-29 22:48:52 +0200202 # if testdir is set, then we are not running the python tests suite, so
203 # don't add default tests to be executed or skipped (pass empty values)
204 if self.ns.testdir:
205 alltests = findtests(self.ns.testdir, list(), set())
206 else:
207 alltests = findtests(self.ns.testdir, stdtests, nottests)
208
Victor Stinner5de16e82016-03-24 09:43:00 +0100209 if not self.ns.fromfile:
210 self.selected = self.tests or self.ns.args or alltests
211 else:
212 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200213 if self.ns.single:
214 self.selected = self.selected[:1]
215 try:
216 pos = alltests.index(self.selected[0])
217 self.next_single_test = alltests[pos + 1]
218 except IndexError:
219 pass
220
Victor Stinnerc7eab052015-09-30 00:59:35 +0200221 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200222 if self.ns.start:
223 try:
224 del self.selected[:self.selected.index(self.ns.start)]
225 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200226 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200227 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200228
229 if self.ns.randomize:
230 if self.ns.random_seed is None:
231 self.ns.random_seed = random.randrange(10000000)
232 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200233 random.shuffle(self.selected)
234
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200235 def list_tests(self):
236 for name in self.selected:
237 print(name)
238
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200239 def rerun_failed_tests(self):
240 self.ns.verbose = True
241 self.ns.failfast = False
242 self.ns.verbose3 = False
243 self.ns.match_tests = None
244
245 print("Re-running failed tests in verbose mode")
246 for test in self.bad[:]:
247 print("Re-running test %r in verbose mode" % test, flush=True)
248 try:
249 self.ns.verbose = True
250 ok = runtest(self.ns, test)
251 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200252 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200253 # print a newline separate from the ^C
254 print()
255 break
256 else:
257 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
258 self.bad.remove(test)
259 else:
260 if self.bad:
261 print(count(len(self.bad), 'test'), "failed again:")
262 printlist(self.bad)
263
Victor Stinnerdad20e42015-09-29 22:48:52 +0200264 def display_result(self):
265 if self.interrupted:
266 # print a newline after ^C
267 print()
268 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200269 executed = set(self.good) | set(self.bad) | set(self.skipped)
270 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200271 print(count(len(omitted), "test"), "omitted:")
272 printlist(omitted)
273
Brett Cannon11faa212015-10-02 16:20:49 -0700274 # If running the test suite for PGO then no one cares about
275 # results.
276 if self.ns.pgo:
277 return
278
Victor Stinnerdad20e42015-09-29 22:48:52 +0200279 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200280 if (not self.bad
281 and not self.skipped
282 and not self.interrupted
283 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200284 print("All", end=' ')
285 print(count(len(self.good), "test"), "OK.")
286
287 if self.ns.print_slow:
288 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200289 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200290 print("10 slowest tests:")
291 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200292 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200293
294 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200295 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200296 print(count(len(self.bad), "test"), "failed:")
297 printlist(self.bad)
298
299 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200300 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200301 print("{} altered the execution environment:".format(
302 count(len(self.environment_changed), "test")))
303 printlist(self.environment_changed)
304
305 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200306 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200307 print(count(len(self.skipped), "test"), "skipped:")
308 printlist(self.skipped)
309
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200310 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200311 if self.ns.trace:
312 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200313 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200314
Victor Stinnerdad20e42015-09-29 22:48:52 +0200315 save_modules = sys.modules.keys()
316
Victor Stinner2b60b722016-03-24 11:55:29 +0100317 print("Run tests sequentially")
318
Victor Stinner69649f22016-03-23 12:14:10 +0100319 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200320 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100321 start_time = time.monotonic()
322
323 text = test
324 if previous_test:
325 text = '%s -- %s' % (text, previous_test)
326 self.display_progress(test_index, text)
327
Victor Stinnerc7eab052015-09-30 00:59:35 +0200328 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200329 # If we're tracing code coverage, then we don't exit with status
330 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200331 cmd = ('result = runtest(self.ns, test); '
332 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200333 ns = dict(locals())
334 self.tracer.runctx(cmd, globals=globals(), locals=ns)
335 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200336 else:
337 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200338 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200339 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200340 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200341 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200342 break
Victor Stinner3909e582015-10-11 10:37:25 +0200343 else:
344 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200345
Victor Stinner1b8b4232016-05-20 13:37:40 +0200346 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100347 test_time = time.monotonic() - start_time
348 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200349 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200350 elif result[0] == PASSED:
351 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100352 previous_test = None
353
Victor Stinnerdad20e42015-09-29 22:48:52 +0200354 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200355 gc.collect()
356 if gc.garbage:
357 print("Warning: test created", len(gc.garbage), end=' ')
358 print("uncollectable object(s).")
359 # move the uncollectable objects somewhere so we don't see
360 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200361 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200362 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200363
Victor Stinner3844fe52015-09-26 10:38:01 +0200364 # Unload the newly imported modules (best effort finalization)
365 for module in sys.modules.keys():
366 if module not in save_modules and module.startswith("test."):
367 support.unload(module)
368
Victor Stinner69649f22016-03-23 12:14:10 +0100369 if previous_test:
370 print(previous_test)
371
Victor Stinnerb4084352015-09-30 02:39:22 +0200372 def _test_forever(self, tests):
373 while True:
374 for test in tests:
375 yield test
376 if self.bad:
377 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200378
Victor Stinnerb4084352015-09-30 02:39:22 +0200379 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200380 # For a partial run, we do not need to clutter the output.
381 if (self.ns.verbose
382 or self.ns.header
Brett Cannon11faa212015-10-02 16:20:49 -0700383 or not (self.ns.pgo or self.ns.quiet or self.ns.single
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200384 or self.tests or self.ns.args)):
385 # Print basic platform information
386 print("==", platform.python_implementation(), *sys.version.split())
387 print("== ", platform.platform(aliased=True),
388 "%s-endian" % sys.byteorder)
389 print("== ", "hash algorithm:", sys.hash_info.algorithm,
390 "64bit" if sys.maxsize > 2**32 else "32bit")
Victor Stinnerb96ef552016-09-08 21:46:56 -0700391 print("== cwd:", os.getcwd())
392 print("== encodings: locale=%s, FS=%s"
393 % (locale.getpreferredencoding(False),
394 sys.getfilesystemencoding()))
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200395 print("Testing with flags:", sys.flags)
396
397 if self.ns.randomize:
398 print("Using random seed", self.ns.random_seed)
399
Victor Stinnerdad20e42015-09-29 22:48:52 +0200400 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200401 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200402 self.test_count = ''
403 self.test_count_width = 3
404 else:
405 self.tests = iter(self.selected)
406 self.test_count = '/{}'.format(len(self.selected))
407 self.test_count_width = len(self.test_count) - 1
408
409 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200410 from test.libregrtest.runtest_mp import run_tests_multiprocess
411 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200412 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200413 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200414
415 def finalize(self):
416 if self.next_single_filename:
417 if self.next_single_test:
418 with open(self.next_single_filename, 'w') as fp:
419 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200420 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200421 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200422
Victor Stinnerc7eab052015-09-30 00:59:35 +0200423 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200424 r = self.tracer.results()
425 r.write_results(show_missing=True, summary=True,
426 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200427
Victor Stinner435eaf42016-08-17 12:22:52 +0200428 print()
429 duration = time.monotonic() - self.start_time
430 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100431
Victor Stinner63686032016-08-17 16:12:16 +0200432 if self.bad:
433 result = "FAILURE"
434 elif self.interrupted:
435 result = "INTERRUPTED"
436 else:
437 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200438 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200439
Victor Stinnerdad20e42015-09-29 22:48:52 +0200440 if self.ns.runleaks:
441 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200442
Victor Stinnerdad20e42015-09-29 22:48:52 +0200443 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100444 global TEMPDIR
445
446 if sysconfig.is_python_build():
447 try:
448 os.mkdir(TEMPDIR)
449 except FileExistsError:
450 pass
451
452 # Define a writable temp dir that will be used as cwd while running
453 # the tests. The name of the dir includes the pid to allow parallel
454 # testing (see the -j option).
455 test_cwd = 'test_python_{}'.format(os.getpid())
456 test_cwd = os.path.join(TEMPDIR, test_cwd)
457
458 # Run the tests in a context manager that temporarily changes the CWD to a
459 # temporary and writable directory. If it's not possible to create or
460 # change the CWD, the original CWD will be used. The original CWD is
461 # available from support.SAVEDCWD.
462 with support.temp_cwd(test_cwd, quiet=True):
463 self._main(tests, kwargs)
464
465 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200466 self.ns = self.parse_args(kwargs)
467
Victor Stinnerdad20e42015-09-29 22:48:52 +0200468 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200469 from test.libregrtest.runtest_mp import run_tests_slave
470 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200471
Victor Stinnerc7eab052015-09-30 00:59:35 +0200472 if self.ns.wait:
473 input("Press any key to continue...")
474
Steve Dower22d06982016-09-06 19:38:15 -0700475 support.PGO = self.ns.pgo
476
Victor Stinnera2045022015-09-30 02:17:28 +0200477 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200478
Victor Stinnerdad20e42015-09-29 22:48:52 +0200479 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200480
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200481 if self.ns.list_tests:
482 self.list_tests()
483 sys.exit(0)
484
485 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200486 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200487
488 if self.ns.verbose2 and self.bad:
489 self.rerun_failed_tests()
490
Victor Stinnerdad20e42015-09-29 22:48:52 +0200491 self.finalize()
492 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200493
494
Victor Stinner3844fe52015-09-26 10:38:01 +0200495def removepy(names):
496 if not names:
497 return
498 for idx, name in enumerate(names):
499 basename, ext = os.path.splitext(name)
500 if ext == '.py':
501 names[idx] = basename
502
503
504def count(n, word):
505 if n == 1:
506 return "%d %s" % (n, word)
507 else:
508 return "%d %ss" % (n, word)
509
510
511def printlist(x, width=70, indent=4):
512 """Print the elements of iterable x to stdout.
513
514 Optional arg width (default 70) is the maximum line length.
515 Optional arg indent (default 4) is the number of blanks with which to
516 begin each line.
517 """
518
Victor Stinner3844fe52015-09-26 10:38:01 +0200519 blanks = ' ' * indent
520 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200521 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
522 initial_indent=blanks, subsequent_indent=blanks))
523
524
525def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100526 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200527 Regrtest().main(tests=tests, **kwargs)