blob: e113ed63ddf3b69c4713be8892ae27b5d477ac7f [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 Stinnerc24217e2016-12-09 16:05:51 +0100182 regex = (r'(?:[0-9]+:[0-9]+:[0-9]+ *)?'
Victor Stinner5de16e82016-03-24 09:43:00 +0100183 r'(?:\[[0-9/ ]+\] *)?'
Victor Stinnerc24217e2016-12-09 16:05:51 +0100184 r'(test_[a-zA-Z0-9_]+)\b(?:\.py)?')
Victor Stinner5de16e82016-03-24 09:43:00 +0100185 regex = re.compile(regex)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200186 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200187 for line in fp:
Victor Stinnerc24217e2016-12-09 16:05:51 +0100188 line = line.split('#', 1)[0]
Victor Stinner5de16e82016-03-24 09:43:00 +0100189 line = line.strip()
Victor Stinnerc24217e2016-12-09 16:05:51 +0100190 match = regex.search(line)
191 if match is not None:
192 self.tests.append(match.group(1))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200193
194 removepy(self.tests)
195
196 stdtests = STDTESTS[:]
197 nottests = NOTTESTS.copy()
198 if self.ns.exclude:
199 for arg in self.ns.args:
200 if arg in stdtests:
201 stdtests.remove(arg)
202 nottests.add(arg)
203 self.ns.args = []
204
Victor Stinnerdad20e42015-09-29 22:48:52 +0200205 # if testdir is set, then we are not running the python tests suite, so
206 # don't add default tests to be executed or skipped (pass empty values)
207 if self.ns.testdir:
208 alltests = findtests(self.ns.testdir, list(), set())
209 else:
210 alltests = findtests(self.ns.testdir, stdtests, nottests)
211
Victor Stinner5de16e82016-03-24 09:43:00 +0100212 if not self.ns.fromfile:
213 self.selected = self.tests or self.ns.args or alltests
214 else:
215 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200216 if self.ns.single:
217 self.selected = self.selected[:1]
218 try:
219 pos = alltests.index(self.selected[0])
220 self.next_single_test = alltests[pos + 1]
221 except IndexError:
222 pass
223
Victor Stinnerc7eab052015-09-30 00:59:35 +0200224 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200225 if self.ns.start:
226 try:
227 del self.selected[:self.selected.index(self.ns.start)]
228 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200229 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200230 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200231
232 if self.ns.randomize:
233 if self.ns.random_seed is None:
234 self.ns.random_seed = random.randrange(10000000)
235 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200236 random.shuffle(self.selected)
237
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200238 def list_tests(self):
239 for name in self.selected:
240 print(name)
241
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200242 def rerun_failed_tests(self):
243 self.ns.verbose = True
244 self.ns.failfast = False
245 self.ns.verbose3 = False
246 self.ns.match_tests = None
247
248 print("Re-running failed tests in verbose mode")
249 for test in self.bad[:]:
250 print("Re-running test %r in verbose mode" % test, flush=True)
251 try:
252 self.ns.verbose = True
253 ok = runtest(self.ns, test)
254 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200255 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200256 # print a newline separate from the ^C
257 print()
258 break
259 else:
260 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
261 self.bad.remove(test)
262 else:
263 if self.bad:
264 print(count(len(self.bad), 'test'), "failed again:")
265 printlist(self.bad)
266
Victor Stinnerdad20e42015-09-29 22:48:52 +0200267 def display_result(self):
268 if self.interrupted:
269 # print a newline after ^C
270 print()
271 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200272 executed = set(self.good) | set(self.bad) | set(self.skipped)
273 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200274 print(count(len(omitted), "test"), "omitted:")
275 printlist(omitted)
276
Brett Cannon11faa212015-10-02 16:20:49 -0700277 # If running the test suite for PGO then no one cares about
278 # results.
279 if self.ns.pgo:
280 return
281
Victor Stinnerdad20e42015-09-29 22:48:52 +0200282 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200283 if (not self.bad
284 and not self.skipped
285 and not self.interrupted
286 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200287 print("All", end=' ')
288 print(count(len(self.good), "test"), "OK.")
289
290 if self.ns.print_slow:
291 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200292 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200293 print("10 slowest tests:")
294 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200295 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200296
297 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200298 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200299 print(count(len(self.bad), "test"), "failed:")
300 printlist(self.bad)
301
302 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200303 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200304 print("{} altered the execution environment:".format(
305 count(len(self.environment_changed), "test")))
306 printlist(self.environment_changed)
307
308 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200309 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200310 print(count(len(self.skipped), "test"), "skipped:")
311 printlist(self.skipped)
312
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200313 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200314 if self.ns.trace:
315 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200316 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200317
Victor Stinnerdad20e42015-09-29 22:48:52 +0200318 save_modules = sys.modules.keys()
319
Victor Stinner2b60b722016-03-24 11:55:29 +0100320 print("Run tests sequentially")
321
Victor Stinner69649f22016-03-23 12:14:10 +0100322 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200323 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100324 start_time = time.monotonic()
325
326 text = test
327 if previous_test:
328 text = '%s -- %s' % (text, previous_test)
329 self.display_progress(test_index, text)
330
Victor Stinnerc7eab052015-09-30 00:59:35 +0200331 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200332 # If we're tracing code coverage, then we don't exit with status
333 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200334 cmd = ('result = runtest(self.ns, test); '
335 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200336 ns = dict(locals())
337 self.tracer.runctx(cmd, globals=globals(), locals=ns)
338 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200339 else:
340 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200341 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200342 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200343 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200344 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200345 break
Victor Stinner3909e582015-10-11 10:37:25 +0200346 else:
347 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200348
Victor Stinner1b8b4232016-05-20 13:37:40 +0200349 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100350 test_time = time.monotonic() - start_time
351 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200352 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200353 elif result[0] == PASSED:
354 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100355 previous_test = None
356
Victor Stinnerdad20e42015-09-29 22:48:52 +0200357 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200358 gc.collect()
359 if gc.garbage:
360 print("Warning: test created", len(gc.garbage), end=' ')
361 print("uncollectable object(s).")
362 # move the uncollectable objects somewhere so we don't see
363 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200364 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200365 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200366
Victor Stinner3844fe52015-09-26 10:38:01 +0200367 # Unload the newly imported modules (best effort finalization)
368 for module in sys.modules.keys():
369 if module not in save_modules and module.startswith("test."):
370 support.unload(module)
371
Victor Stinner69649f22016-03-23 12:14:10 +0100372 if previous_test:
373 print(previous_test)
374
Victor Stinnerb4084352015-09-30 02:39:22 +0200375 def _test_forever(self, tests):
376 while True:
377 for test in tests:
378 yield test
379 if self.bad:
380 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200381
Victor Stinnerb4084352015-09-30 02:39:22 +0200382 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200383 # For a partial run, we do not need to clutter the output.
384 if (self.ns.verbose
385 or self.ns.header
Brett Cannon11faa212015-10-02 16:20:49 -0700386 or not (self.ns.pgo or self.ns.quiet or self.ns.single
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200387 or self.tests or self.ns.args)):
388 # Print basic platform information
389 print("==", platform.python_implementation(), *sys.version.split())
390 print("== ", platform.platform(aliased=True),
391 "%s-endian" % sys.byteorder)
392 print("== ", "hash algorithm:", sys.hash_info.algorithm,
393 "64bit" if sys.maxsize > 2**32 else "32bit")
Victor Stinnerb96ef552016-09-08 21:46:56 -0700394 print("== cwd:", os.getcwd())
395 print("== encodings: locale=%s, FS=%s"
396 % (locale.getpreferredencoding(False),
397 sys.getfilesystemencoding()))
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200398 print("Testing with flags:", sys.flags)
399
400 if self.ns.randomize:
401 print("Using random seed", self.ns.random_seed)
402
Victor Stinnerdad20e42015-09-29 22:48:52 +0200403 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200404 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200405 self.test_count = ''
406 self.test_count_width = 3
407 else:
408 self.tests = iter(self.selected)
409 self.test_count = '/{}'.format(len(self.selected))
410 self.test_count_width = len(self.test_count) - 1
411
412 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200413 from test.libregrtest.runtest_mp import run_tests_multiprocess
414 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200415 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200416 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200417
418 def finalize(self):
419 if self.next_single_filename:
420 if self.next_single_test:
421 with open(self.next_single_filename, 'w') as fp:
422 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200423 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200424 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200425
Victor Stinnerc7eab052015-09-30 00:59:35 +0200426 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200427 r = self.tracer.results()
428 r.write_results(show_missing=True, summary=True,
429 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200430
Victor Stinner435eaf42016-08-17 12:22:52 +0200431 print()
432 duration = time.monotonic() - self.start_time
433 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100434
Victor Stinner63686032016-08-17 16:12:16 +0200435 if self.bad:
436 result = "FAILURE"
437 elif self.interrupted:
438 result = "INTERRUPTED"
439 else:
440 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200441 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200442
Victor Stinnerdad20e42015-09-29 22:48:52 +0200443 if self.ns.runleaks:
444 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200445
Victor Stinnerdad20e42015-09-29 22:48:52 +0200446 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100447 global TEMPDIR
448
449 if sysconfig.is_python_build():
450 try:
451 os.mkdir(TEMPDIR)
452 except FileExistsError:
453 pass
454
455 # Define a writable temp dir that will be used as cwd while running
456 # the tests. The name of the dir includes the pid to allow parallel
457 # testing (see the -j option).
458 test_cwd = 'test_python_{}'.format(os.getpid())
459 test_cwd = os.path.join(TEMPDIR, test_cwd)
460
461 # Run the tests in a context manager that temporarily changes the CWD to a
462 # temporary and writable directory. If it's not possible to create or
463 # change the CWD, the original CWD will be used. The original CWD is
464 # available from support.SAVEDCWD.
465 with support.temp_cwd(test_cwd, quiet=True):
466 self._main(tests, kwargs)
467
468 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200469 self.ns = self.parse_args(kwargs)
470
Victor Stinnerdad20e42015-09-29 22:48:52 +0200471 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200472 from test.libregrtest.runtest_mp import run_tests_slave
473 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200474
Victor Stinnerc7eab052015-09-30 00:59:35 +0200475 if self.ns.wait:
476 input("Press any key to continue...")
477
Steve Dower22d06982016-09-06 19:38:15 -0700478 support.PGO = self.ns.pgo
479
Victor Stinnera2045022015-09-30 02:17:28 +0200480 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200481
Victor Stinnerdad20e42015-09-29 22:48:52 +0200482 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200483
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200484 if self.ns.list_tests:
485 self.list_tests()
486 sys.exit(0)
487
488 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200489 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200490
491 if self.ns.verbose2 and self.bad:
492 self.rerun_failed_tests()
493
Victor Stinnerdad20e42015-09-29 22:48:52 +0200494 self.finalize()
495 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200496
497
Victor Stinner3844fe52015-09-26 10:38:01 +0200498def removepy(names):
499 if not names:
500 return
501 for idx, name in enumerate(names):
502 basename, ext = os.path.splitext(name)
503 if ext == '.py':
504 names[idx] = basename
505
506
507def count(n, word):
508 if n == 1:
509 return "%d %s" % (n, word)
510 else:
511 return "%d %ss" % (n, word)
512
513
514def printlist(x, width=70, indent=4):
515 """Print the elements of iterable x to stdout.
516
517 Optional arg width (default 70) is the maximum line length.
518 Optional arg indent (default 4) is the number of blanks with which to
519 begin each line.
520 """
521
Victor Stinner3844fe52015-09-26 10:38:01 +0200522 blanks = ' ' * indent
523 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200524 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
525 initial_indent=blanks, subsequent_indent=blanks))
526
527
528def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100529 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200530 Regrtest().main(tests=tests, **kwargs)