blob: e068b925d57af004860ea6ed9c08a6a865032e60 [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 Stinner74683fc2017-05-09 11:34:01 +0200119 elif ok != INTERRUPTED:
120 raise ValueError("invalid test result: %r" % ok)
Victor Stinner3844fe52015-09-26 10:38:01 +0200121
Victor Stinnerdad20e42015-09-29 22:48:52 +0200122 def display_progress(self, test_index, test):
123 if self.ns.quiet:
124 return
Victor Stinner3d005682017-05-04 15:21:12 +0200125
126 # "[ 51/405/1] test_tcl passed"
127 line = f"{test_index:{self.test_count_width}}{self.test_count}"
Brett Cannon11faa212015-10-02 16:20:49 -0700128 if self.bad and not self.ns.pgo:
Victor Stinner3d005682017-05-04 15:21:12 +0200129 line = f"{line}/{len(self.bad)}"
130 line = f"[{line}] {test}"
131
132 # add the system load prefix: "load avg: 1.80 "
133 if hasattr(os, 'getloadavg'):
134 load_avg_1min = os.getloadavg()[0]
135 line = f"load avg: {load_avg_1min:.2f} {line}"
136
137 # add the timestamp prefix: "0:01:05 "
Victor Stinner435eaf42016-08-17 12:22:52 +0200138 test_time = time.monotonic() - self.start_time
139 test_time = datetime.timedelta(seconds=int(test_time))
Victor Stinner3d005682017-05-04 15:21:12 +0200140 line = f"{test_time} {line}"
Victor Stinner24f949e2016-03-22 15:14:09 +0100141 print(line, flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200142
Victor Stinner234cbef2015-09-30 01:13:53 +0200143 def parse_args(self, kwargs):
144 ns = _parse_args(sys.argv[1:], **kwargs)
145
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200146 if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
147 print("Warning: The timeout option requires "
148 "faulthandler.dump_traceback_later", file=sys.stderr)
149 ns.timeout = None
150
Victor Stinner234cbef2015-09-30 01:13:53 +0200151 if ns.threshold is not None and gc is None:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200152 print('No GC available, ignore --threshold.', file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200153 ns.threshold = None
154
155 if ns.findleaks:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200156 if gc is not None:
157 # Uncomment the line below to report garbage that is not
158 # freeable by reference counting alone. By default only
159 # garbage that is not collectable by the GC is reported.
160 pass
161 #gc.set_debug(gc.DEBUG_SAVEALL)
162 else:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200163 print('No GC available, disabling --findleaks',
164 file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200165 ns.findleaks = False
Victor Stinnerdad20e42015-09-29 22:48:52 +0200166
Victor Stinnerdad20e42015-09-29 22:48:52 +0200167 # Strip .py extensions.
Victor Stinner234cbef2015-09-30 01:13:53 +0200168 removepy(ns.args)
169
170 return ns
Victor Stinnerdad20e42015-09-29 22:48:52 +0200171
Victor Stinnerdad20e42015-09-29 22:48:52 +0200172 def find_tests(self, tests):
173 self.tests = tests
174
175 if self.ns.single:
176 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
177 try:
178 with open(self.next_single_filename, 'r') as fp:
179 next_test = fp.read().strip()
180 self.tests = [next_test]
181 except OSError:
182 pass
183
184 if self.ns.fromfile:
185 self.tests = []
Victor Stinner5de16e82016-03-24 09:43:00 +0100186 # regex to match 'test_builtin' in line:
187 # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec'
Victor Stinnere8cfec52017-01-03 01:38:58 +0100188 regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b')
Victor Stinnerdad20e42015-09-29 22:48:52 +0200189 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200190 for line in fp:
Victor Stinnerc24217e2016-12-09 16:05:51 +0100191 line = line.split('#', 1)[0]
Victor Stinner5de16e82016-03-24 09:43:00 +0100192 line = line.strip()
Victor Stinnerc24217e2016-12-09 16:05:51 +0100193 match = regex.search(line)
194 if match is not None:
Victor Stinnere8cfec52017-01-03 01:38:58 +0100195 self.tests.append(match.group())
Victor Stinnerdad20e42015-09-29 22:48:52 +0200196
197 removepy(self.tests)
198
199 stdtests = STDTESTS[:]
200 nottests = NOTTESTS.copy()
201 if self.ns.exclude:
202 for arg in self.ns.args:
203 if arg in stdtests:
204 stdtests.remove(arg)
205 nottests.add(arg)
206 self.ns.args = []
207
Victor Stinnerdad20e42015-09-29 22:48:52 +0200208 # if testdir is set, then we are not running the python tests suite, so
209 # don't add default tests to be executed or skipped (pass empty values)
210 if self.ns.testdir:
211 alltests = findtests(self.ns.testdir, list(), set())
212 else:
213 alltests = findtests(self.ns.testdir, stdtests, nottests)
214
Victor Stinner5de16e82016-03-24 09:43:00 +0100215 if not self.ns.fromfile:
216 self.selected = self.tests or self.ns.args or alltests
217 else:
218 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200219 if self.ns.single:
220 self.selected = self.selected[:1]
221 try:
222 pos = alltests.index(self.selected[0])
223 self.next_single_test = alltests[pos + 1]
224 except IndexError:
225 pass
226
Victor Stinnerc7eab052015-09-30 00:59:35 +0200227 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200228 if self.ns.start:
229 try:
230 del self.selected[:self.selected.index(self.ns.start)]
231 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200232 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200233 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200234
235 if self.ns.randomize:
236 if self.ns.random_seed is None:
237 self.ns.random_seed = random.randrange(10000000)
238 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200239 random.shuffle(self.selected)
240
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200241 def list_tests(self):
242 for name in self.selected:
243 print(name)
244
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200245 def rerun_failed_tests(self):
246 self.ns.verbose = True
247 self.ns.failfast = False
248 self.ns.verbose3 = False
249 self.ns.match_tests = None
250
251 print("Re-running failed tests in verbose mode")
252 for test in self.bad[:]:
253 print("Re-running test %r in verbose mode" % test, flush=True)
254 try:
255 self.ns.verbose = True
256 ok = runtest(self.ns, test)
257 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200258 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200259 # print a newline separate from the ^C
260 print()
261 break
262 else:
263 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
264 self.bad.remove(test)
265 else:
266 if self.bad:
267 print(count(len(self.bad), 'test'), "failed again:")
268 printlist(self.bad)
269
Victor Stinnerdad20e42015-09-29 22:48:52 +0200270 def display_result(self):
271 if self.interrupted:
272 # print a newline after ^C
273 print()
274 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200275 executed = set(self.good) | set(self.bad) | set(self.skipped)
276 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200277 print(count(len(omitted), "test"), "omitted:")
278 printlist(omitted)
279
Brett Cannon11faa212015-10-02 16:20:49 -0700280 # If running the test suite for PGO then no one cares about
281 # results.
282 if self.ns.pgo:
283 return
284
Victor Stinnerdad20e42015-09-29 22:48:52 +0200285 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200286 if (not self.bad
287 and not self.skipped
288 and not self.interrupted
289 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200290 print("All", end=' ')
291 print(count(len(self.good), "test"), "OK.")
292
293 if self.ns.print_slow:
294 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200295 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200296 print("10 slowest tests:")
297 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200298 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200299
300 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200301 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200302 print(count(len(self.bad), "test"), "failed:")
303 printlist(self.bad)
304
305 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200306 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200307 print("{} altered the execution environment:".format(
308 count(len(self.environment_changed), "test")))
309 printlist(self.environment_changed)
310
311 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200312 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200313 print(count(len(self.skipped), "test"), "skipped:")
314 printlist(self.skipped)
315
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200316 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200317 if self.ns.trace:
318 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200319 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200320
Victor Stinnerdad20e42015-09-29 22:48:52 +0200321 save_modules = sys.modules.keys()
322
Victor Stinner2b60b722016-03-24 11:55:29 +0100323 print("Run tests sequentially")
324
Victor Stinner69649f22016-03-23 12:14:10 +0100325 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200326 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100327 start_time = time.monotonic()
328
329 text = test
330 if previous_test:
331 text = '%s -- %s' % (text, previous_test)
332 self.display_progress(test_index, text)
333
Victor Stinnerc7eab052015-09-30 00:59:35 +0200334 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200335 # If we're tracing code coverage, then we don't exit with status
336 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200337 cmd = ('result = runtest(self.ns, test); '
338 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200339 ns = dict(locals())
340 self.tracer.runctx(cmd, globals=globals(), locals=ns)
341 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200342 else:
343 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200344 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200345 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200346 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200347 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200348 break
Victor Stinner3909e582015-10-11 10:37:25 +0200349 else:
350 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200351
Victor Stinner1b8b4232016-05-20 13:37:40 +0200352 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100353 test_time = time.monotonic() - start_time
354 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200355 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200356 elif result[0] == PASSED:
357 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100358 previous_test = None
359
Victor Stinnerdad20e42015-09-29 22:48:52 +0200360 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200361 gc.collect()
362 if gc.garbage:
363 print("Warning: test created", len(gc.garbage), end=' ')
364 print("uncollectable object(s).")
365 # move the uncollectable objects somewhere so we don't see
366 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200367 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200368 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200369
Victor Stinner3844fe52015-09-26 10:38:01 +0200370 # Unload the newly imported modules (best effort finalization)
371 for module in sys.modules.keys():
372 if module not in save_modules and module.startswith("test."):
373 support.unload(module)
374
Victor Stinner69649f22016-03-23 12:14:10 +0100375 if previous_test:
376 print(previous_test)
377
Victor Stinnerb4084352015-09-30 02:39:22 +0200378 def _test_forever(self, tests):
379 while True:
380 for test in tests:
381 yield test
382 if self.bad:
383 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200384
Victor Stinner3d005682017-05-04 15:21:12 +0200385 def display_header(self):
386 # Print basic platform information
387 print("==", platform.python_implementation(), *sys.version.split())
388 print("==", platform.platform(aliased=True),
389 "%s-endian" % sys.byteorder)
390 print("== hash algorithm:", sys.hash_info.algorithm,
391 "64bit" if sys.maxsize > 2**32 else "32bit")
392 print("== cwd:", os.getcwd())
393 cpu_count = os.cpu_count()
394 if cpu_count:
395 print("== CPU count:", cpu_count)
396 print("== encodings: locale=%s, FS=%s"
397 % (locale.getpreferredencoding(False),
398 sys.getfilesystemencoding()))
399 print("Testing with flags:", sys.flags)
400
Victor Stinnerb4084352015-09-30 02:39:22 +0200401 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200402 # For a partial run, we do not need to clutter the output.
Victor Stinner3d005682017-05-04 15:21:12 +0200403 if (self.ns.header
404 or not(self.ns.pgo or self.ns.quiet or self.ns.single
405 or self.tests or self.ns.args)):
406 self.display_header()
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200407
408 if self.ns.randomize:
409 print("Using random seed", self.ns.random_seed)
410
Victor Stinnerdad20e42015-09-29 22:48:52 +0200411 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200412 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200413 self.test_count = ''
414 self.test_count_width = 3
415 else:
416 self.tests = iter(self.selected)
417 self.test_count = '/{}'.format(len(self.selected))
418 self.test_count_width = len(self.test_count) - 1
419
420 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200421 from test.libregrtest.runtest_mp import run_tests_multiprocess
422 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200423 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200424 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200425
426 def finalize(self):
427 if self.next_single_filename:
428 if self.next_single_test:
429 with open(self.next_single_filename, 'w') as fp:
430 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200431 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200432 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200433
Victor Stinnerc7eab052015-09-30 00:59:35 +0200434 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200435 r = self.tracer.results()
436 r.write_results(show_missing=True, summary=True,
437 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200438
Victor Stinner435eaf42016-08-17 12:22:52 +0200439 print()
440 duration = time.monotonic() - self.start_time
441 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100442
Victor Stinner63686032016-08-17 16:12:16 +0200443 if self.bad:
444 result = "FAILURE"
445 elif self.interrupted:
446 result = "INTERRUPTED"
447 else:
448 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200449 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200450
Victor Stinnerdad20e42015-09-29 22:48:52 +0200451 if self.ns.runleaks:
452 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200453
Victor Stinnerdad20e42015-09-29 22:48:52 +0200454 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100455 global TEMPDIR
456
457 if sysconfig.is_python_build():
458 try:
459 os.mkdir(TEMPDIR)
460 except FileExistsError:
461 pass
462
463 # Define a writable temp dir that will be used as cwd while running
464 # the tests. The name of the dir includes the pid to allow parallel
465 # testing (see the -j option).
466 test_cwd = 'test_python_{}'.format(os.getpid())
467 test_cwd = os.path.join(TEMPDIR, test_cwd)
468
469 # Run the tests in a context manager that temporarily changes the CWD to a
470 # temporary and writable directory. If it's not possible to create or
471 # change the CWD, the original CWD will be used. The original CWD is
472 # available from support.SAVEDCWD.
473 with support.temp_cwd(test_cwd, quiet=True):
474 self._main(tests, kwargs)
475
476 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200477 self.ns = self.parse_args(kwargs)
478
Victor Stinnerdad20e42015-09-29 22:48:52 +0200479 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200480 from test.libregrtest.runtest_mp import run_tests_slave
481 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200482
Victor Stinnerc7eab052015-09-30 00:59:35 +0200483 if self.ns.wait:
484 input("Press any key to continue...")
485
Steve Dower22d06982016-09-06 19:38:15 -0700486 support.PGO = self.ns.pgo
487
Victor Stinnera2045022015-09-30 02:17:28 +0200488 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200489
Victor Stinnerdad20e42015-09-29 22:48:52 +0200490 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200491
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200492 if self.ns.list_tests:
493 self.list_tests()
494 sys.exit(0)
495
496 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200497 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200498
499 if self.ns.verbose2 and self.bad:
500 self.rerun_failed_tests()
501
Victor Stinnerdad20e42015-09-29 22:48:52 +0200502 self.finalize()
503 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200504
505
Victor Stinner3844fe52015-09-26 10:38:01 +0200506def removepy(names):
507 if not names:
508 return
509 for idx, name in enumerate(names):
510 basename, ext = os.path.splitext(name)
511 if ext == '.py':
512 names[idx] = basename
513
514
515def count(n, word):
516 if n == 1:
517 return "%d %s" % (n, word)
518 else:
519 return "%d %ss" % (n, word)
520
521
522def printlist(x, width=70, indent=4):
523 """Print the elements of iterable x to stdout.
524
525 Optional arg width (default 70) is the maximum line length.
526 Optional arg indent (default 4) is the number of blanks with which to
527 begin each line.
528 """
529
Victor Stinner3844fe52015-09-26 10:38:01 +0200530 blanks = ' ' * indent
531 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200532 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
533 initial_indent=blanks, subsequent_indent=blanks))
534
535
536def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100537 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200538 Regrtest().main(tests=tests, **kwargs)