blob: 2cfbdd12b2a58d29c587728e169c7d3889efaf92 [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 Stinner5bad70d2017-02-06 12:42:00 +0100110 elif ok in (FAILED, CHILD_ERROR):
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
Victor Stinner3d005682017-05-04 15:21:12 +0200123
124 # "[ 51/405/1] test_tcl passed"
125 line = f"{test_index:{self.test_count_width}}{self.test_count}"
Brett Cannon11faa212015-10-02 16:20:49 -0700126 if self.bad and not self.ns.pgo:
Victor Stinner3d005682017-05-04 15:21:12 +0200127 line = f"{line}/{len(self.bad)}"
128 line = f"[{line}] {test}"
129
130 # add the system load prefix: "load avg: 1.80 "
131 if hasattr(os, 'getloadavg'):
132 load_avg_1min = os.getloadavg()[0]
133 line = f"load avg: {load_avg_1min:.2f} {line}"
134
135 # add the timestamp prefix: "0:01:05 "
Victor Stinner435eaf42016-08-17 12:22:52 +0200136 test_time = time.monotonic() - self.start_time
137 test_time = datetime.timedelta(seconds=int(test_time))
Victor Stinner3d005682017-05-04 15:21:12 +0200138 line = f"{test_time} {line}"
Victor Stinner24f949e2016-03-22 15:14:09 +0100139 print(line, flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200140
Victor Stinner234cbef2015-09-30 01:13:53 +0200141 def parse_args(self, kwargs):
142 ns = _parse_args(sys.argv[1:], **kwargs)
143
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200144 if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
145 print("Warning: The timeout option requires "
146 "faulthandler.dump_traceback_later", file=sys.stderr)
147 ns.timeout = None
148
Victor Stinner234cbef2015-09-30 01:13:53 +0200149 if ns.threshold is not None and gc is None:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200150 print('No GC available, ignore --threshold.', file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200151 ns.threshold = None
152
153 if ns.findleaks:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200154 if gc is not None:
155 # Uncomment the line below to report garbage that is not
156 # freeable by reference counting alone. By default only
157 # garbage that is not collectable by the GC is reported.
158 pass
159 #gc.set_debug(gc.DEBUG_SAVEALL)
160 else:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200161 print('No GC available, disabling --findleaks',
162 file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200163 ns.findleaks = False
Victor Stinnerdad20e42015-09-29 22:48:52 +0200164
Victor Stinnerdad20e42015-09-29 22:48:52 +0200165 # Strip .py extensions.
Victor Stinner234cbef2015-09-30 01:13:53 +0200166 removepy(ns.args)
167
168 return ns
Victor Stinnerdad20e42015-09-29 22:48:52 +0200169
Victor Stinnerdad20e42015-09-29 22:48:52 +0200170 def find_tests(self, tests):
171 self.tests = tests
172
173 if self.ns.single:
174 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
175 try:
176 with open(self.next_single_filename, 'r') as fp:
177 next_test = fp.read().strip()
178 self.tests = [next_test]
179 except OSError:
180 pass
181
182 if self.ns.fromfile:
183 self.tests = []
Victor Stinner5de16e82016-03-24 09:43:00 +0100184 # regex to match 'test_builtin' in line:
185 # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec'
Victor Stinnere8cfec52017-01-03 01:38:58 +0100186 regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b')
Victor Stinnerdad20e42015-09-29 22:48:52 +0200187 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200188 for line in fp:
Victor Stinnerc24217e2016-12-09 16:05:51 +0100189 line = line.split('#', 1)[0]
Victor Stinner5de16e82016-03-24 09:43:00 +0100190 line = line.strip()
Victor Stinnerc24217e2016-12-09 16:05:51 +0100191 match = regex.search(line)
192 if match is not None:
Victor Stinnere8cfec52017-01-03 01:38:58 +0100193 self.tests.append(match.group())
Victor Stinnerdad20e42015-09-29 22:48:52 +0200194
195 removepy(self.tests)
196
197 stdtests = STDTESTS[:]
198 nottests = NOTTESTS.copy()
199 if self.ns.exclude:
200 for arg in self.ns.args:
201 if arg in stdtests:
202 stdtests.remove(arg)
203 nottests.add(arg)
204 self.ns.args = []
205
Victor Stinnerdad20e42015-09-29 22:48:52 +0200206 # if testdir is set, then we are not running the python tests suite, so
207 # don't add default tests to be executed or skipped (pass empty values)
208 if self.ns.testdir:
209 alltests = findtests(self.ns.testdir, list(), set())
210 else:
211 alltests = findtests(self.ns.testdir, stdtests, nottests)
212
Victor Stinner5de16e82016-03-24 09:43:00 +0100213 if not self.ns.fromfile:
214 self.selected = self.tests or self.ns.args or alltests
215 else:
216 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200217 if self.ns.single:
218 self.selected = self.selected[:1]
219 try:
220 pos = alltests.index(self.selected[0])
221 self.next_single_test = alltests[pos + 1]
222 except IndexError:
223 pass
224
Victor Stinnerc7eab052015-09-30 00:59:35 +0200225 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200226 if self.ns.start:
227 try:
228 del self.selected[:self.selected.index(self.ns.start)]
229 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200230 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200231 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200232
233 if self.ns.randomize:
234 if self.ns.random_seed is None:
235 self.ns.random_seed = random.randrange(10000000)
236 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200237 random.shuffle(self.selected)
238
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200239 def list_tests(self):
240 for name in self.selected:
241 print(name)
242
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200243 def rerun_failed_tests(self):
244 self.ns.verbose = True
245 self.ns.failfast = False
246 self.ns.verbose3 = False
247 self.ns.match_tests = None
248
249 print("Re-running failed tests in verbose mode")
250 for test in self.bad[:]:
251 print("Re-running test %r in verbose mode" % test, flush=True)
252 try:
253 self.ns.verbose = True
254 ok = runtest(self.ns, test)
255 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200256 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200257 # print a newline separate from the ^C
258 print()
259 break
260 else:
261 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
262 self.bad.remove(test)
263 else:
264 if self.bad:
265 print(count(len(self.bad), 'test'), "failed again:")
266 printlist(self.bad)
267
Victor Stinnerdad20e42015-09-29 22:48:52 +0200268 def display_result(self):
269 if self.interrupted:
270 # print a newline after ^C
271 print()
272 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200273 executed = set(self.good) | set(self.bad) | set(self.skipped)
274 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200275 print(count(len(omitted), "test"), "omitted:")
276 printlist(omitted)
277
Brett Cannon11faa212015-10-02 16:20:49 -0700278 # If running the test suite for PGO then no one cares about
279 # results.
280 if self.ns.pgo:
281 return
282
Victor Stinnerdad20e42015-09-29 22:48:52 +0200283 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200284 if (not self.bad
285 and not self.skipped
286 and not self.interrupted
287 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200288 print("All", end=' ')
289 print(count(len(self.good), "test"), "OK.")
290
291 if self.ns.print_slow:
292 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200293 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200294 print("10 slowest tests:")
295 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200296 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200297
298 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200299 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200300 print(count(len(self.bad), "test"), "failed:")
301 printlist(self.bad)
302
303 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200304 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200305 print("{} altered the execution environment:".format(
306 count(len(self.environment_changed), "test")))
307 printlist(self.environment_changed)
308
309 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200310 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200311 print(count(len(self.skipped), "test"), "skipped:")
312 printlist(self.skipped)
313
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200314 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200315 if self.ns.trace:
316 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200317 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200318
Victor Stinnerdad20e42015-09-29 22:48:52 +0200319 save_modules = sys.modules.keys()
320
Victor Stinner2b60b722016-03-24 11:55:29 +0100321 print("Run tests sequentially")
322
Victor Stinner69649f22016-03-23 12:14:10 +0100323 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200324 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100325 start_time = time.monotonic()
326
327 text = test
328 if previous_test:
329 text = '%s -- %s' % (text, previous_test)
330 self.display_progress(test_index, text)
331
Victor Stinnerc7eab052015-09-30 00:59:35 +0200332 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200333 # If we're tracing code coverage, then we don't exit with status
334 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200335 cmd = ('result = runtest(self.ns, test); '
336 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200337 ns = dict(locals())
338 self.tracer.runctx(cmd, globals=globals(), locals=ns)
339 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200340 else:
341 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200342 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200343 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200344 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200345 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200346 break
Victor Stinner3909e582015-10-11 10:37:25 +0200347 else:
348 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200349
Victor Stinner1b8b4232016-05-20 13:37:40 +0200350 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100351 test_time = time.monotonic() - start_time
352 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200353 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200354 elif result[0] == PASSED:
355 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100356 previous_test = None
357
Victor Stinnerdad20e42015-09-29 22:48:52 +0200358 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200359 gc.collect()
360 if gc.garbage:
361 print("Warning: test created", len(gc.garbage), end=' ')
362 print("uncollectable object(s).")
363 # move the uncollectable objects somewhere so we don't see
364 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200365 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200366 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200367
Victor Stinner3844fe52015-09-26 10:38:01 +0200368 # Unload the newly imported modules (best effort finalization)
369 for module in sys.modules.keys():
370 if module not in save_modules and module.startswith("test."):
371 support.unload(module)
372
Victor Stinner69649f22016-03-23 12:14:10 +0100373 if previous_test:
374 print(previous_test)
375
Victor Stinnerb4084352015-09-30 02:39:22 +0200376 def _test_forever(self, tests):
377 while True:
378 for test in tests:
379 yield test
380 if self.bad:
381 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200382
Victor Stinner3d005682017-05-04 15:21:12 +0200383 def display_header(self):
384 # Print basic platform information
385 print("==", platform.python_implementation(), *sys.version.split())
386 print("==", platform.platform(aliased=True),
387 "%s-endian" % sys.byteorder)
388 print("== hash algorithm:", sys.hash_info.algorithm,
389 "64bit" if sys.maxsize > 2**32 else "32bit")
390 print("== cwd:", os.getcwd())
391 cpu_count = os.cpu_count()
392 if cpu_count:
393 print("== CPU count:", cpu_count)
394 print("== encodings: locale=%s, FS=%s"
395 % (locale.getpreferredencoding(False),
396 sys.getfilesystemencoding()))
397 print("Testing with flags:", sys.flags)
398
Victor Stinnerb4084352015-09-30 02:39:22 +0200399 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200400 # For a partial run, we do not need to clutter the output.
Victor Stinner3d005682017-05-04 15:21:12 +0200401 if (self.ns.header
402 or not(self.ns.pgo or self.ns.quiet or self.ns.single
403 or self.tests or self.ns.args)):
404 self.display_header()
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200405
406 if self.ns.randomize:
407 print("Using random seed", self.ns.random_seed)
408
Victor Stinnerdad20e42015-09-29 22:48:52 +0200409 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200410 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200411 self.test_count = ''
412 self.test_count_width = 3
413 else:
414 self.tests = iter(self.selected)
415 self.test_count = '/{}'.format(len(self.selected))
416 self.test_count_width = len(self.test_count) - 1
417
418 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200419 from test.libregrtest.runtest_mp import run_tests_multiprocess
420 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200421 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200422 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200423
424 def finalize(self):
425 if self.next_single_filename:
426 if self.next_single_test:
427 with open(self.next_single_filename, 'w') as fp:
428 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200429 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200430 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200431
Victor Stinnerc7eab052015-09-30 00:59:35 +0200432 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200433 r = self.tracer.results()
434 r.write_results(show_missing=True, summary=True,
435 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200436
Victor Stinner435eaf42016-08-17 12:22:52 +0200437 print()
438 duration = time.monotonic() - self.start_time
439 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100440
Victor Stinner63686032016-08-17 16:12:16 +0200441 if self.bad:
442 result = "FAILURE"
443 elif self.interrupted:
444 result = "INTERRUPTED"
445 else:
446 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200447 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200448
Victor Stinnerdad20e42015-09-29 22:48:52 +0200449 if self.ns.runleaks:
450 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200451
Victor Stinnerdad20e42015-09-29 22:48:52 +0200452 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100453 global TEMPDIR
454
455 if sysconfig.is_python_build():
456 try:
457 os.mkdir(TEMPDIR)
458 except FileExistsError:
459 pass
460
461 # Define a writable temp dir that will be used as cwd while running
462 # the tests. The name of the dir includes the pid to allow parallel
463 # testing (see the -j option).
464 test_cwd = 'test_python_{}'.format(os.getpid())
465 test_cwd = os.path.join(TEMPDIR, test_cwd)
466
467 # Run the tests in a context manager that temporarily changes the CWD to a
468 # temporary and writable directory. If it's not possible to create or
469 # change the CWD, the original CWD will be used. The original CWD is
470 # available from support.SAVEDCWD.
471 with support.temp_cwd(test_cwd, quiet=True):
472 self._main(tests, kwargs)
473
474 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200475 self.ns = self.parse_args(kwargs)
476
Victor Stinnerdad20e42015-09-29 22:48:52 +0200477 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200478 from test.libregrtest.runtest_mp import run_tests_slave
479 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200480
Victor Stinnerc7eab052015-09-30 00:59:35 +0200481 if self.ns.wait:
482 input("Press any key to continue...")
483
Steve Dower22d06982016-09-06 19:38:15 -0700484 support.PGO = self.ns.pgo
485
Victor Stinnera2045022015-09-30 02:17:28 +0200486 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200487
Victor Stinnerdad20e42015-09-29 22:48:52 +0200488 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200489
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200490 if self.ns.list_tests:
491 self.list_tests()
492 sys.exit(0)
493
494 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200495 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200496
497 if self.ns.verbose2 and self.bad:
498 self.rerun_failed_tests()
499
Victor Stinnerdad20e42015-09-29 22:48:52 +0200500 self.finalize()
501 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200502
503
Victor Stinner3844fe52015-09-26 10:38:01 +0200504def removepy(names):
505 if not names:
506 return
507 for idx, name in enumerate(names):
508 basename, ext = os.path.splitext(name)
509 if ext == '.py':
510 names[idx] = basename
511
512
513def count(n, word):
514 if n == 1:
515 return "%d %s" % (n, word)
516 else:
517 return "%d %ss" % (n, word)
518
519
520def printlist(x, width=70, indent=4):
521 """Print the elements of iterable x to stdout.
522
523 Optional arg width (default 70) is the maximum line length.
524 Optional arg indent (default 4) is the number of blanks with which to
525 begin each line.
526 """
527
Victor Stinner3844fe52015-09-26 10:38:01 +0200528 blanks = ' ' * indent
529 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200530 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
531 initial_indent=blanks, subsequent_indent=blanks))
532
533
534def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100535 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200536 Regrtest().main(tests=tests, **kwargs)