blob: f0effc973c1b3abdc281da3cca25a8cc0025cce8 [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'
182 regex = (r'^(?:[0-9]+:[0-9]+:[0-9]+ *)?'
183 r'(?:\[[0-9/ ]+\] *)?'
184 r'(test_[a-zA-Z0-9_]+)')
185 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 Stinner5de16e82016-03-24 09:43:00 +0100188 line = line.strip()
189 if line.startswith('#'):
190 continue
191 match = regex.match(line)
192 if match is None:
193 continue
194 self.tests.append(match.group(1))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200195
196 removepy(self.tests)
197
198 stdtests = STDTESTS[:]
199 nottests = NOTTESTS.copy()
200 if self.ns.exclude:
201 for arg in self.ns.args:
202 if arg in stdtests:
203 stdtests.remove(arg)
204 nottests.add(arg)
205 self.ns.args = []
206
Victor Stinnerdad20e42015-09-29 22:48:52 +0200207 # if testdir is set, then we are not running the python tests suite, so
208 # don't add default tests to be executed or skipped (pass empty values)
209 if self.ns.testdir:
210 alltests = findtests(self.ns.testdir, list(), set())
211 else:
212 alltests = findtests(self.ns.testdir, stdtests, nottests)
213
Victor Stinner5de16e82016-03-24 09:43:00 +0100214 if not self.ns.fromfile:
215 self.selected = self.tests or self.ns.args or alltests
216 else:
217 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200218 if self.ns.single:
219 self.selected = self.selected[:1]
220 try:
221 pos = alltests.index(self.selected[0])
222 self.next_single_test = alltests[pos + 1]
223 except IndexError:
224 pass
225
Victor Stinnerc7eab052015-09-30 00:59:35 +0200226 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200227 if self.ns.start:
228 try:
229 del self.selected[:self.selected.index(self.ns.start)]
230 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200231 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200232 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200233
234 if self.ns.randomize:
235 if self.ns.random_seed is None:
236 self.ns.random_seed = random.randrange(10000000)
237 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200238 random.shuffle(self.selected)
239
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200240 def list_tests(self):
241 for name in self.selected:
242 print(name)
243
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200244 def rerun_failed_tests(self):
245 self.ns.verbose = True
246 self.ns.failfast = False
247 self.ns.verbose3 = False
248 self.ns.match_tests = None
249
250 print("Re-running failed tests in verbose mode")
251 for test in self.bad[:]:
252 print("Re-running test %r in verbose mode" % test, flush=True)
253 try:
254 self.ns.verbose = True
255 ok = runtest(self.ns, test)
256 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200257 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200258 # print a newline separate from the ^C
259 print()
260 break
261 else:
262 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
263 self.bad.remove(test)
264 else:
265 if self.bad:
266 print(count(len(self.bad), 'test'), "failed again:")
267 printlist(self.bad)
268
Victor Stinnerdad20e42015-09-29 22:48:52 +0200269 def display_result(self):
270 if self.interrupted:
271 # print a newline after ^C
272 print()
273 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200274 executed = set(self.good) | set(self.bad) | set(self.skipped)
275 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200276 print(count(len(omitted), "test"), "omitted:")
277 printlist(omitted)
278
Brett Cannon11faa212015-10-02 16:20:49 -0700279 # If running the test suite for PGO then no one cares about
280 # results.
281 if self.ns.pgo:
282 return
283
Victor Stinnerdad20e42015-09-29 22:48:52 +0200284 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200285 if (not self.bad
286 and not self.skipped
287 and not self.interrupted
288 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200289 print("All", end=' ')
290 print(count(len(self.good), "test"), "OK.")
291
292 if self.ns.print_slow:
293 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200294 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200295 print("10 slowest tests:")
296 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200297 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200298
299 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200300 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200301 print(count(len(self.bad), "test"), "failed:")
302 printlist(self.bad)
303
304 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200305 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200306 print("{} altered the execution environment:".format(
307 count(len(self.environment_changed), "test")))
308 printlist(self.environment_changed)
309
310 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200311 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200312 print(count(len(self.skipped), "test"), "skipped:")
313 printlist(self.skipped)
314
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200315 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200316 if self.ns.trace:
317 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200318 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200319
Victor Stinnerdad20e42015-09-29 22:48:52 +0200320 save_modules = sys.modules.keys()
321
Victor Stinner2b60b722016-03-24 11:55:29 +0100322 print("Run tests sequentially")
323
Victor Stinner69649f22016-03-23 12:14:10 +0100324 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200325 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100326 start_time = time.monotonic()
327
328 text = test
329 if previous_test:
330 text = '%s -- %s' % (text, previous_test)
331 self.display_progress(test_index, text)
332
Victor Stinnerc7eab052015-09-30 00:59:35 +0200333 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200334 # If we're tracing code coverage, then we don't exit with status
335 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200336 cmd = ('result = runtest(self.ns, test); '
337 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200338 ns = dict(locals())
339 self.tracer.runctx(cmd, globals=globals(), locals=ns)
340 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200341 else:
342 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200343 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200344 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200345 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200346 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200347 break
Victor Stinner3909e582015-10-11 10:37:25 +0200348 else:
349 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200350
Victor Stinner1b8b4232016-05-20 13:37:40 +0200351 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100352 test_time = time.monotonic() - start_time
353 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200354 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200355 elif result[0] == PASSED:
356 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100357 previous_test = None
358
Victor Stinnerdad20e42015-09-29 22:48:52 +0200359 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200360 gc.collect()
361 if gc.garbage:
362 print("Warning: test created", len(gc.garbage), end=' ')
363 print("uncollectable object(s).")
364 # move the uncollectable objects somewhere so we don't see
365 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200366 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200367 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200368
Victor Stinner3844fe52015-09-26 10:38:01 +0200369 # Unload the newly imported modules (best effort finalization)
370 for module in sys.modules.keys():
371 if module not in save_modules and module.startswith("test."):
372 support.unload(module)
373
Victor Stinner69649f22016-03-23 12:14:10 +0100374 if previous_test:
375 print(previous_test)
376
Victor Stinnerb4084352015-09-30 02:39:22 +0200377 def _test_forever(self, tests):
378 while True:
379 for test in tests:
380 yield test
381 if self.bad:
382 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200383
Victor Stinnerb4084352015-09-30 02:39:22 +0200384 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200385 # For a partial run, we do not need to clutter the output.
386 if (self.ns.verbose
387 or self.ns.header
Brett Cannon11faa212015-10-02 16:20:49 -0700388 or not (self.ns.pgo or self.ns.quiet or self.ns.single
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200389 or self.tests or self.ns.args)):
390 # Print basic platform information
391 print("==", platform.python_implementation(), *sys.version.split())
392 print("== ", platform.platform(aliased=True),
393 "%s-endian" % sys.byteorder)
394 print("== ", "hash algorithm:", sys.hash_info.algorithm,
395 "64bit" if sys.maxsize > 2**32 else "32bit")
Victor Stinnerb96ef552016-09-08 21:46:56 -0700396 print("== cwd:", os.getcwd())
397 print("== encodings: locale=%s, FS=%s"
398 % (locale.getpreferredencoding(False),
399 sys.getfilesystemencoding()))
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200400 print("Testing with flags:", sys.flags)
401
402 if self.ns.randomize:
403 print("Using random seed", self.ns.random_seed)
404
Victor Stinnerdad20e42015-09-29 22:48:52 +0200405 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200406 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200407 self.test_count = ''
408 self.test_count_width = 3
409 else:
410 self.tests = iter(self.selected)
411 self.test_count = '/{}'.format(len(self.selected))
412 self.test_count_width = len(self.test_count) - 1
413
414 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200415 from test.libregrtest.runtest_mp import run_tests_multiprocess
416 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200417 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200418 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200419
420 def finalize(self):
421 if self.next_single_filename:
422 if self.next_single_test:
423 with open(self.next_single_filename, 'w') as fp:
424 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200425 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200426 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200427
Victor Stinnerc7eab052015-09-30 00:59:35 +0200428 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200429 r = self.tracer.results()
430 r.write_results(show_missing=True, summary=True,
431 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200432
Victor Stinner435eaf42016-08-17 12:22:52 +0200433 print()
434 duration = time.monotonic() - self.start_time
435 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100436
Victor Stinner63686032016-08-17 16:12:16 +0200437 if self.bad:
438 result = "FAILURE"
439 elif self.interrupted:
440 result = "INTERRUPTED"
441 else:
442 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200443 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200444
Victor Stinnerdad20e42015-09-29 22:48:52 +0200445 if self.ns.runleaks:
446 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200447
Victor Stinnerdad20e42015-09-29 22:48:52 +0200448 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100449 global TEMPDIR
450
451 if sysconfig.is_python_build():
452 try:
453 os.mkdir(TEMPDIR)
454 except FileExistsError:
455 pass
456
457 # Define a writable temp dir that will be used as cwd while running
458 # the tests. The name of the dir includes the pid to allow parallel
459 # testing (see the -j option).
460 test_cwd = 'test_python_{}'.format(os.getpid())
461 test_cwd = os.path.join(TEMPDIR, test_cwd)
462
463 # Run the tests in a context manager that temporarily changes the CWD to a
464 # temporary and writable directory. If it's not possible to create or
465 # change the CWD, the original CWD will be used. The original CWD is
466 # available from support.SAVEDCWD.
467 with support.temp_cwd(test_cwd, quiet=True):
468 self._main(tests, kwargs)
469
470 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200471 self.ns = self.parse_args(kwargs)
472
Victor Stinnerdad20e42015-09-29 22:48:52 +0200473 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200474 from test.libregrtest.runtest_mp import run_tests_slave
475 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200476
Victor Stinnerc7eab052015-09-30 00:59:35 +0200477 if self.ns.wait:
478 input("Press any key to continue...")
479
Steve Dower22d06982016-09-06 19:38:15 -0700480 support.PGO = self.ns.pgo
481
Victor Stinnera2045022015-09-30 02:17:28 +0200482 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200483
Victor Stinnerdad20e42015-09-29 22:48:52 +0200484 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200485
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200486 if self.ns.list_tests:
487 self.list_tests()
488 sys.exit(0)
489
490 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200491 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200492
493 if self.ns.verbose2 and self.bad:
494 self.rerun_failed_tests()
495
Victor Stinnerdad20e42015-09-29 22:48:52 +0200496 self.finalize()
497 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200498
499
Victor Stinner3844fe52015-09-26 10:38:01 +0200500def removepy(names):
501 if not names:
502 return
503 for idx, name in enumerate(names):
504 basename, ext = os.path.splitext(name)
505 if ext == '.py':
506 names[idx] = basename
507
508
509def count(n, word):
510 if n == 1:
511 return "%d %s" % (n, word)
512 else:
513 return "%d %ss" % (n, word)
514
515
516def printlist(x, width=70, indent=4):
517 """Print the elements of iterable x to stdout.
518
519 Optional arg width (default 70) is the maximum line length.
520 Optional arg indent (default 4) is the number of blanks with which to
521 begin each line.
522 """
523
Victor Stinner3844fe52015-09-26 10:38:01 +0200524 blanks = ' ' * indent
525 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200526 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
527 initial_indent=blanks, subsequent_indent=blanks))
528
529
530def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100531 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200532 Regrtest().main(tests=tests, **kwargs)