blob: 7b11fe951b232564fd43c918caf2e9ccd3284daa [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():
Victor Stinnerf7e07842017-06-15 00:44:05 +020031 TEMPDIR = sysconfig.get_config_var('abs_builddir')
32 if TEMPDIR is None:
33 # bpo-30284: On Windows, only srcdir is available. Using abs_builddir
34 # mostly matters on UNIX when building Python out of the source tree,
35 # especially when the source tree is read only.
36 TEMPDIR = sysconfig.get_config_var('srcdir')
37 TEMPDIR = os.path.join(TEMPDIR, 'build')
Victor Stinner3844fe52015-09-26 10:38:01 +020038else:
39 TEMPDIR = tempfile.gettempdir()
40TEMPDIR = os.path.abspath(TEMPDIR)
41
42
Victor Stinner435eaf42016-08-17 12:22:52 +020043def format_duration(seconds):
44 if seconds < 1.0:
45 return '%.0f ms' % (seconds * 1e3)
46 if seconds < 60.0:
47 return '%.0f sec' % seconds
48
49 minutes, seconds = divmod(seconds, 60.0)
50 return '%.0f min %.0f sec' % (minutes, seconds)
51
52
Victor Stinnerdad20e42015-09-29 22:48:52 +020053class Regrtest:
Victor Stinner3844fe52015-09-26 10:38:01 +020054 """Execute a test suite.
55
56 This also parses command-line options and modifies its behavior
57 accordingly.
58
59 tests -- a list of strings containing test names (optional)
60 testdir -- the directory in which to look for tests (optional)
61
62 Users other than the Python test suite will certainly want to
63 specify testdir; if it's omitted, the directory containing the
64 Python test suite is searched for.
65
66 If the tests argument is omitted, the tests listed on the
67 command-line will be used. If that's empty, too, then all *.py
68 files beginning with test_ will be used.
69
70 The other default arguments (verbose, quiet, exclude,
71 single, randomize, findleaks, use_resources, trace, coverdir,
72 print_slow, and random_seed) allow programmers calling main()
73 directly to set the values that would normally be set by flags
74 on the command line.
75 """
Victor Stinnerdad20e42015-09-29 22:48:52 +020076 def __init__(self):
77 # Namespace of command line options
78 self.ns = None
Victor Stinner3844fe52015-09-26 10:38:01 +020079
Victor Stinnerdad20e42015-09-29 22:48:52 +020080 # tests
81 self.tests = []
82 self.selected = []
Victor Stinner3844fe52015-09-26 10:38:01 +020083
Victor Stinnerdad20e42015-09-29 22:48:52 +020084 # test results
85 self.good = []
86 self.bad = []
87 self.skipped = []
88 self.resource_denieds = []
89 self.environment_changed = []
90 self.interrupted = False
Victor Stinner3844fe52015-09-26 10:38:01 +020091
Victor Stinnerdad20e42015-09-29 22:48:52 +020092 # used by --slow
93 self.test_times = []
Victor Stinner3844fe52015-09-26 10:38:01 +020094
Victor Stinnerdad20e42015-09-29 22:48:52 +020095 # used by --coverage, trace.Trace instance
96 self.tracer = None
Victor Stinner3844fe52015-09-26 10:38:01 +020097
Victor Stinnerdad20e42015-09-29 22:48:52 +020098 # used by --findleaks, store for gc.garbage
99 self.found_garbage = []
Victor Stinner3844fe52015-09-26 10:38:01 +0200100
Victor Stinnerdad20e42015-09-29 22:48:52 +0200101 # used to display the progress bar "[ 3/100]"
Victor Stinner24f949e2016-03-22 15:14:09 +0100102 self.start_time = time.monotonic()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200103 self.test_count = ''
104 self.test_count_width = 1
Victor Stinner3844fe52015-09-26 10:38:01 +0200105
Victor Stinnerdad20e42015-09-29 22:48:52 +0200106 # used by --single
107 self.next_single_test = None
108 self.next_single_filename = None
Victor Stinner3844fe52015-09-26 10:38:01 +0200109
Victor Stinnerdad20e42015-09-29 22:48:52 +0200110 def accumulate_result(self, test, result):
Victor Stinner3844fe52015-09-26 10:38:01 +0200111 ok, test_time = result
Victor Stinner3909e582015-10-11 10:37:25 +0200112 if ok not in (CHILD_ERROR, INTERRUPTED):
113 self.test_times.append((test_time, test))
Victor Stinner3844fe52015-09-26 10:38:01 +0200114 if ok == PASSED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200115 self.good.append(test)
Victor Stinner5bad70d2017-02-06 12:42:00 +0100116 elif ok in (FAILED, CHILD_ERROR):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200117 self.bad.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200118 elif ok == ENV_CHANGED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200119 self.environment_changed.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200120 elif ok == SKIPPED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200121 self.skipped.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200122 elif ok == RESOURCE_DENIED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200123 self.skipped.append(test)
124 self.resource_denieds.append(test)
Victor Stinner74683fc2017-05-09 11:34:01 +0200125 elif ok != INTERRUPTED:
126 raise ValueError("invalid test result: %r" % ok)
Victor Stinner3844fe52015-09-26 10:38:01 +0200127
Victor Stinnerdad20e42015-09-29 22:48:52 +0200128 def display_progress(self, test_index, test):
129 if self.ns.quiet:
130 return
Victor Stinner3d005682017-05-04 15:21:12 +0200131
132 # "[ 51/405/1] test_tcl passed"
133 line = f"{test_index:{self.test_count_width}}{self.test_count}"
Brett Cannon11faa212015-10-02 16:20:49 -0700134 if self.bad and not self.ns.pgo:
Victor Stinner3d005682017-05-04 15:21:12 +0200135 line = f"{line}/{len(self.bad)}"
136 line = f"[{line}] {test}"
137
138 # add the system load prefix: "load avg: 1.80 "
139 if hasattr(os, 'getloadavg'):
140 load_avg_1min = os.getloadavg()[0]
141 line = f"load avg: {load_avg_1min:.2f} {line}"
142
143 # add the timestamp prefix: "0:01:05 "
Victor Stinner435eaf42016-08-17 12:22:52 +0200144 test_time = time.monotonic() - self.start_time
145 test_time = datetime.timedelta(seconds=int(test_time))
Victor Stinner3d005682017-05-04 15:21:12 +0200146 line = f"{test_time} {line}"
Victor Stinner24f949e2016-03-22 15:14:09 +0100147 print(line, flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200148
Victor Stinner234cbef2015-09-30 01:13:53 +0200149 def parse_args(self, kwargs):
150 ns = _parse_args(sys.argv[1:], **kwargs)
151
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200152 if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
153 print("Warning: The timeout option requires "
154 "faulthandler.dump_traceback_later", file=sys.stderr)
155 ns.timeout = None
156
Victor Stinner234cbef2015-09-30 01:13:53 +0200157 if ns.threshold is not None and gc is None:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200158 print('No GC available, ignore --threshold.', file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200159 ns.threshold = None
160
161 if ns.findleaks:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200162 if gc is not None:
163 # Uncomment the line below to report garbage that is not
164 # freeable by reference counting alone. By default only
165 # garbage that is not collectable by the GC is reported.
166 pass
167 #gc.set_debug(gc.DEBUG_SAVEALL)
168 else:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200169 print('No GC available, disabling --findleaks',
170 file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200171 ns.findleaks = False
Victor Stinnerdad20e42015-09-29 22:48:52 +0200172
Victor Stinnerdad20e42015-09-29 22:48:52 +0200173 # Strip .py extensions.
Victor Stinner234cbef2015-09-30 01:13:53 +0200174 removepy(ns.args)
175
176 return ns
Victor Stinnerdad20e42015-09-29 22:48:52 +0200177
Victor Stinnerdad20e42015-09-29 22:48:52 +0200178 def find_tests(self, tests):
179 self.tests = tests
180
181 if self.ns.single:
182 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
183 try:
184 with open(self.next_single_filename, 'r') as fp:
185 next_test = fp.read().strip()
186 self.tests = [next_test]
187 except OSError:
188 pass
189
190 if self.ns.fromfile:
191 self.tests = []
Victor Stinner5de16e82016-03-24 09:43:00 +0100192 # regex to match 'test_builtin' in line:
193 # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec'
Victor Stinnere8cfec52017-01-03 01:38:58 +0100194 regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b')
Victor Stinnerdad20e42015-09-29 22:48:52 +0200195 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200196 for line in fp:
Victor Stinnerc24217e2016-12-09 16:05:51 +0100197 line = line.split('#', 1)[0]
Victor Stinner5de16e82016-03-24 09:43:00 +0100198 line = line.strip()
Victor Stinnerc24217e2016-12-09 16:05:51 +0100199 match = regex.search(line)
200 if match is not None:
Victor Stinnere8cfec52017-01-03 01:38:58 +0100201 self.tests.append(match.group())
Victor Stinnerdad20e42015-09-29 22:48:52 +0200202
203 removepy(self.tests)
204
205 stdtests = STDTESTS[:]
206 nottests = NOTTESTS.copy()
207 if self.ns.exclude:
208 for arg in self.ns.args:
209 if arg in stdtests:
210 stdtests.remove(arg)
211 nottests.add(arg)
212 self.ns.args = []
213
Victor Stinnerdad20e42015-09-29 22:48:52 +0200214 # if testdir is set, then we are not running the python tests suite, so
215 # don't add default tests to be executed or skipped (pass empty values)
216 if self.ns.testdir:
217 alltests = findtests(self.ns.testdir, list(), set())
218 else:
219 alltests = findtests(self.ns.testdir, stdtests, nottests)
220
Victor Stinner5de16e82016-03-24 09:43:00 +0100221 if not self.ns.fromfile:
222 self.selected = self.tests or self.ns.args or alltests
223 else:
224 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200225 if self.ns.single:
226 self.selected = self.selected[:1]
227 try:
228 pos = alltests.index(self.selected[0])
229 self.next_single_test = alltests[pos + 1]
230 except IndexError:
231 pass
232
Victor Stinnerc7eab052015-09-30 00:59:35 +0200233 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200234 if self.ns.start:
235 try:
236 del self.selected[:self.selected.index(self.ns.start)]
237 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200238 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200239 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200240
241 if self.ns.randomize:
242 if self.ns.random_seed is None:
243 self.ns.random_seed = random.randrange(10000000)
244 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200245 random.shuffle(self.selected)
246
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200247 def list_tests(self):
248 for name in self.selected:
249 print(name)
250
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200251 def rerun_failed_tests(self):
252 self.ns.verbose = True
253 self.ns.failfast = False
254 self.ns.verbose3 = False
255 self.ns.match_tests = None
256
257 print("Re-running failed tests in verbose mode")
258 for test in self.bad[:]:
259 print("Re-running test %r in verbose mode" % test, flush=True)
260 try:
261 self.ns.verbose = True
262 ok = runtest(self.ns, test)
263 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200264 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200265 # print a newline separate from the ^C
266 print()
267 break
268 else:
269 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
270 self.bad.remove(test)
271 else:
272 if self.bad:
273 print(count(len(self.bad), 'test'), "failed again:")
274 printlist(self.bad)
275
Victor Stinnerdad20e42015-09-29 22:48:52 +0200276 def display_result(self):
277 if self.interrupted:
278 # print a newline after ^C
279 print()
280 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200281 executed = set(self.good) | set(self.bad) | set(self.skipped)
282 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200283 print(count(len(omitted), "test"), "omitted:")
284 printlist(omitted)
285
Brett Cannon11faa212015-10-02 16:20:49 -0700286 # If running the test suite for PGO then no one cares about
287 # results.
288 if self.ns.pgo:
289 return
290
Victor Stinnerdad20e42015-09-29 22:48:52 +0200291 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200292 if (not self.bad
293 and not self.skipped
294 and not self.interrupted
295 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200296 print("All", end=' ')
297 print(count(len(self.good), "test"), "OK.")
298
299 if self.ns.print_slow:
300 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200301 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200302 print("10 slowest tests:")
303 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200304 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200305
306 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200307 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200308 print(count(len(self.bad), "test"), "failed:")
309 printlist(self.bad)
310
311 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200312 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200313 print("{} altered the execution environment:".format(
314 count(len(self.environment_changed), "test")))
315 printlist(self.environment_changed)
316
317 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200318 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200319 print(count(len(self.skipped), "test"), "skipped:")
320 printlist(self.skipped)
321
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200322 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200323 if self.ns.trace:
324 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200325 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200326
Victor Stinnerdad20e42015-09-29 22:48:52 +0200327 save_modules = sys.modules.keys()
328
Victor Stinner2b60b722016-03-24 11:55:29 +0100329 print("Run tests sequentially")
330
Victor Stinner69649f22016-03-23 12:14:10 +0100331 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200332 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100333 start_time = time.monotonic()
334
335 text = test
336 if previous_test:
337 text = '%s -- %s' % (text, previous_test)
338 self.display_progress(test_index, text)
339
Victor Stinnerc7eab052015-09-30 00:59:35 +0200340 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200341 # If we're tracing code coverage, then we don't exit with status
342 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200343 cmd = ('result = runtest(self.ns, test); '
344 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200345 ns = dict(locals())
346 self.tracer.runctx(cmd, globals=globals(), locals=ns)
347 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200348 else:
349 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200350 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200351 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200352 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200353 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200354 break
Victor Stinner3909e582015-10-11 10:37:25 +0200355 else:
356 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200357
Victor Stinner1b8b4232016-05-20 13:37:40 +0200358 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100359 test_time = time.monotonic() - start_time
360 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200361 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200362 elif result[0] == PASSED:
363 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100364 previous_test = None
365
Victor Stinnerdad20e42015-09-29 22:48:52 +0200366 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200367 gc.collect()
368 if gc.garbage:
369 print("Warning: test created", len(gc.garbage), end=' ')
370 print("uncollectable object(s).")
371 # move the uncollectable objects somewhere so we don't see
372 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200373 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200374 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200375
Victor Stinner3844fe52015-09-26 10:38:01 +0200376 # Unload the newly imported modules (best effort finalization)
377 for module in sys.modules.keys():
378 if module not in save_modules and module.startswith("test."):
379 support.unload(module)
380
Victor Stinner69649f22016-03-23 12:14:10 +0100381 if previous_test:
382 print(previous_test)
383
Victor Stinnerb4084352015-09-30 02:39:22 +0200384 def _test_forever(self, tests):
385 while True:
386 for test in tests:
387 yield test
388 if self.bad:
389 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200390
Victor Stinner3d005682017-05-04 15:21:12 +0200391 def display_header(self):
392 # Print basic platform information
393 print("==", platform.python_implementation(), *sys.version.split())
394 print("==", platform.platform(aliased=True),
395 "%s-endian" % sys.byteorder)
396 print("== hash algorithm:", sys.hash_info.algorithm,
397 "64bit" if sys.maxsize > 2**32 else "32bit")
398 print("== cwd:", os.getcwd())
399 cpu_count = os.cpu_count()
400 if cpu_count:
401 print("== CPU count:", cpu_count)
402 print("== encodings: locale=%s, FS=%s"
403 % (locale.getpreferredencoding(False),
404 sys.getfilesystemencoding()))
405 print("Testing with flags:", sys.flags)
406
Victor Stinnerb4084352015-09-30 02:39:22 +0200407 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200408 # For a partial run, we do not need to clutter the output.
Victor Stinner3d005682017-05-04 15:21:12 +0200409 if (self.ns.header
410 or not(self.ns.pgo or self.ns.quiet or self.ns.single
411 or self.tests or self.ns.args)):
412 self.display_header()
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200413
414 if self.ns.randomize:
415 print("Using random seed", self.ns.random_seed)
416
Victor Stinnerdad20e42015-09-29 22:48:52 +0200417 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200418 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200419 self.test_count = ''
420 self.test_count_width = 3
421 else:
422 self.tests = iter(self.selected)
423 self.test_count = '/{}'.format(len(self.selected))
424 self.test_count_width = len(self.test_count) - 1
425
426 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200427 from test.libregrtest.runtest_mp import run_tests_multiprocess
428 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200429 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200430 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200431
432 def finalize(self):
433 if self.next_single_filename:
434 if self.next_single_test:
435 with open(self.next_single_filename, 'w') as fp:
436 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200437 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200438 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200439
Victor Stinnerc7eab052015-09-30 00:59:35 +0200440 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200441 r = self.tracer.results()
442 r.write_results(show_missing=True, summary=True,
443 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200444
Victor Stinner435eaf42016-08-17 12:22:52 +0200445 print()
446 duration = time.monotonic() - self.start_time
447 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100448
Victor Stinner63686032016-08-17 16:12:16 +0200449 if self.bad:
450 result = "FAILURE"
451 elif self.interrupted:
452 result = "INTERRUPTED"
453 else:
454 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200455 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200456
Victor Stinnerdad20e42015-09-29 22:48:52 +0200457 if self.ns.runleaks:
458 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200459
Victor Stinnerdad20e42015-09-29 22:48:52 +0200460 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100461 global TEMPDIR
462
463 if sysconfig.is_python_build():
464 try:
465 os.mkdir(TEMPDIR)
466 except FileExistsError:
467 pass
468
469 # Define a writable temp dir that will be used as cwd while running
470 # the tests. The name of the dir includes the pid to allow parallel
471 # testing (see the -j option).
472 test_cwd = 'test_python_{}'.format(os.getpid())
473 test_cwd = os.path.join(TEMPDIR, test_cwd)
474
475 # Run the tests in a context manager that temporarily changes the CWD to a
476 # temporary and writable directory. If it's not possible to create or
477 # change the CWD, the original CWD will be used. The original CWD is
478 # available from support.SAVEDCWD.
479 with support.temp_cwd(test_cwd, quiet=True):
480 self._main(tests, kwargs)
481
482 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200483 self.ns = self.parse_args(kwargs)
484
Victor Stinnerdad20e42015-09-29 22:48:52 +0200485 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200486 from test.libregrtest.runtest_mp import run_tests_slave
487 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200488
Victor Stinnerc7eab052015-09-30 00:59:35 +0200489 if self.ns.wait:
490 input("Press any key to continue...")
491
Steve Dower22d06982016-09-06 19:38:15 -0700492 support.PGO = self.ns.pgo
493
Victor Stinnera2045022015-09-30 02:17:28 +0200494 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200495
Victor Stinnerdad20e42015-09-29 22:48:52 +0200496 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200497
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200498 if self.ns.list_tests:
499 self.list_tests()
500 sys.exit(0)
501
502 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200503 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200504
505 if self.ns.verbose2 and self.bad:
506 self.rerun_failed_tests()
507
Victor Stinnerdad20e42015-09-29 22:48:52 +0200508 self.finalize()
509 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200510
511
Victor Stinner3844fe52015-09-26 10:38:01 +0200512def removepy(names):
513 if not names:
514 return
515 for idx, name in enumerate(names):
516 basename, ext = os.path.splitext(name)
517 if ext == '.py':
518 names[idx] = basename
519
520
521def count(n, word):
522 if n == 1:
523 return "%d %s" % (n, word)
524 else:
525 return "%d %ss" % (n, word)
526
527
528def printlist(x, width=70, indent=4):
529 """Print the elements of iterable x to stdout.
530
531 Optional arg width (default 70) is the maximum line length.
532 Optional arg indent (default 4) is the number of blanks with which to
533 begin each line.
534 """
535
Victor Stinner3844fe52015-09-26 10:38:01 +0200536 blanks = ' ' * indent
537 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200538 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
539 initial_indent=blanks, subsequent_indent=blanks))
540
541
542def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100543 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200544 Regrtest().main(tests=tests, **kwargs)