blob: bc8155bbff2b478a5de50ef84ee55e9dc84753ee [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
mlouielua49c9352017-06-16 17:36:19 +080013import unittest
Victor Stinner3909e582015-10-11 10:37:25 +020014from test.libregrtest.cmdline import _parse_args
Victor Stinner3844fe52015-09-26 10:38:01 +020015from test.libregrtest.runtest import (
mlouielua49c9352017-06-16 17:36:19 +080016 findtests, runtest, get_abs_module,
Victor Stinner3909e582015-10-11 10:37:25 +020017 STDTESTS, NOTTESTS, PASSED, FAILED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED,
Victor Stinner69649f22016-03-23 12:14:10 +010018 INTERRUPTED, CHILD_ERROR,
Victor Stinner1b8b4232016-05-20 13:37:40 +020019 PROGRESS_MIN_TIME, format_test_result)
Victor Stinnera2045022015-09-30 02:17:28 +020020from test.libregrtest.setup import setup_tests
Victor Stinner3844fe52015-09-26 10:38:01 +020021from test import support
22try:
Victor Stinnerdad20e42015-09-29 22:48:52 +020023 import gc
24except ImportError:
25 gc = None
Victor Stinner3844fe52015-09-26 10:38:01 +020026
27
Victor Stinner3844fe52015-09-26 10:38:01 +020028# When tests are run from the Python build directory, it is best practice
29# to keep the test files in a subfolder. This eases the cleanup of leftover
30# files using the "make distclean" command.
31if sysconfig.is_python_build():
Victor Stinnerf7e07842017-06-15 00:44:05 +020032 TEMPDIR = sysconfig.get_config_var('abs_builddir')
33 if TEMPDIR is None:
34 # bpo-30284: On Windows, only srcdir is available. Using abs_builddir
35 # mostly matters on UNIX when building Python out of the source tree,
36 # especially when the source tree is read only.
37 TEMPDIR = sysconfig.get_config_var('srcdir')
38 TEMPDIR = os.path.join(TEMPDIR, 'build')
Victor Stinner3844fe52015-09-26 10:38:01 +020039else:
40 TEMPDIR = tempfile.gettempdir()
41TEMPDIR = os.path.abspath(TEMPDIR)
42
43
Victor Stinner435eaf42016-08-17 12:22:52 +020044def format_duration(seconds):
45 if seconds < 1.0:
46 return '%.0f ms' % (seconds * 1e3)
47 if seconds < 60.0:
48 return '%.0f sec' % seconds
49
50 minutes, seconds = divmod(seconds, 60.0)
51 return '%.0f min %.0f sec' % (minutes, seconds)
52
53
Victor Stinnerdad20e42015-09-29 22:48:52 +020054class Regrtest:
Victor Stinner3844fe52015-09-26 10:38:01 +020055 """Execute a test suite.
56
57 This also parses command-line options and modifies its behavior
58 accordingly.
59
60 tests -- a list of strings containing test names (optional)
61 testdir -- the directory in which to look for tests (optional)
62
63 Users other than the Python test suite will certainly want to
64 specify testdir; if it's omitted, the directory containing the
65 Python test suite is searched for.
66
67 If the tests argument is omitted, the tests listed on the
68 command-line will be used. If that's empty, too, then all *.py
69 files beginning with test_ will be used.
70
71 The other default arguments (verbose, quiet, exclude,
72 single, randomize, findleaks, use_resources, trace, coverdir,
73 print_slow, and random_seed) allow programmers calling main()
74 directly to set the values that would normally be set by flags
75 on the command line.
76 """
Victor Stinnerdad20e42015-09-29 22:48:52 +020077 def __init__(self):
78 # Namespace of command line options
79 self.ns = None
Victor Stinner3844fe52015-09-26 10:38:01 +020080
Victor Stinnerdad20e42015-09-29 22:48:52 +020081 # tests
82 self.tests = []
83 self.selected = []
Victor Stinner3844fe52015-09-26 10:38:01 +020084
Victor Stinnerdad20e42015-09-29 22:48:52 +020085 # test results
86 self.good = []
87 self.bad = []
88 self.skipped = []
89 self.resource_denieds = []
90 self.environment_changed = []
91 self.interrupted = False
Victor Stinner3844fe52015-09-26 10:38:01 +020092
Victor Stinnerdad20e42015-09-29 22:48:52 +020093 # used by --slow
94 self.test_times = []
Victor Stinner3844fe52015-09-26 10:38:01 +020095
Victor Stinnerdad20e42015-09-29 22:48:52 +020096 # used by --coverage, trace.Trace instance
97 self.tracer = None
Victor Stinner3844fe52015-09-26 10:38:01 +020098
Victor Stinnerdad20e42015-09-29 22:48:52 +020099 # used by --findleaks, store for gc.garbage
100 self.found_garbage = []
Victor Stinner3844fe52015-09-26 10:38:01 +0200101
Victor Stinnerdad20e42015-09-29 22:48:52 +0200102 # used to display the progress bar "[ 3/100]"
Victor Stinner24f949e2016-03-22 15:14:09 +0100103 self.start_time = time.monotonic()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200104 self.test_count = ''
105 self.test_count_width = 1
Victor Stinner3844fe52015-09-26 10:38:01 +0200106
Victor Stinnerdad20e42015-09-29 22:48:52 +0200107 # used by --single
108 self.next_single_test = None
109 self.next_single_filename = None
Victor Stinner3844fe52015-09-26 10:38:01 +0200110
Victor Stinnerdad20e42015-09-29 22:48:52 +0200111 def accumulate_result(self, test, result):
Victor Stinner3844fe52015-09-26 10:38:01 +0200112 ok, test_time = result
Victor Stinner3909e582015-10-11 10:37:25 +0200113 if ok not in (CHILD_ERROR, INTERRUPTED):
114 self.test_times.append((test_time, test))
Victor Stinner3844fe52015-09-26 10:38:01 +0200115 if ok == PASSED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200116 self.good.append(test)
Victor Stinner5bad70d2017-02-06 12:42:00 +0100117 elif ok in (FAILED, CHILD_ERROR):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200118 self.bad.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200119 elif ok == ENV_CHANGED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200120 self.environment_changed.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200121 elif ok == SKIPPED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200122 self.skipped.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200123 elif ok == RESOURCE_DENIED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200124 self.skipped.append(test)
125 self.resource_denieds.append(test)
Victor Stinner74683fc2017-05-09 11:34:01 +0200126 elif ok != INTERRUPTED:
127 raise ValueError("invalid test result: %r" % ok)
Victor Stinner3844fe52015-09-26 10:38:01 +0200128
Victor Stinnerdad20e42015-09-29 22:48:52 +0200129 def display_progress(self, test_index, test):
130 if self.ns.quiet:
131 return
Victor Stinner3d005682017-05-04 15:21:12 +0200132
133 # "[ 51/405/1] test_tcl passed"
134 line = f"{test_index:{self.test_count_width}}{self.test_count}"
Brett Cannon11faa212015-10-02 16:20:49 -0700135 if self.bad and not self.ns.pgo:
Victor Stinner3d005682017-05-04 15:21:12 +0200136 line = f"{line}/{len(self.bad)}"
137 line = f"[{line}] {test}"
138
139 # add the system load prefix: "load avg: 1.80 "
140 if hasattr(os, 'getloadavg'):
141 load_avg_1min = os.getloadavg()[0]
142 line = f"load avg: {load_avg_1min:.2f} {line}"
143
144 # add the timestamp prefix: "0:01:05 "
Victor Stinner435eaf42016-08-17 12:22:52 +0200145 test_time = time.monotonic() - self.start_time
146 test_time = datetime.timedelta(seconds=int(test_time))
Victor Stinner3d005682017-05-04 15:21:12 +0200147 line = f"{test_time} {line}"
Victor Stinner24f949e2016-03-22 15:14:09 +0100148 print(line, flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200149
Victor Stinner234cbef2015-09-30 01:13:53 +0200150 def parse_args(self, kwargs):
151 ns = _parse_args(sys.argv[1:], **kwargs)
152
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200153 if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
154 print("Warning: The timeout option requires "
155 "faulthandler.dump_traceback_later", file=sys.stderr)
156 ns.timeout = None
157
Victor Stinner234cbef2015-09-30 01:13:53 +0200158 if ns.threshold is not None and gc is None:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200159 print('No GC available, ignore --threshold.', file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200160 ns.threshold = None
161
162 if ns.findleaks:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200163 if gc is not None:
164 # Uncomment the line below to report garbage that is not
165 # freeable by reference counting alone. By default only
166 # garbage that is not collectable by the GC is reported.
167 pass
168 #gc.set_debug(gc.DEBUG_SAVEALL)
169 else:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200170 print('No GC available, disabling --findleaks',
171 file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200172 ns.findleaks = False
Victor Stinnerdad20e42015-09-29 22:48:52 +0200173
Victor Stinnerdad20e42015-09-29 22:48:52 +0200174 # Strip .py extensions.
Victor Stinner234cbef2015-09-30 01:13:53 +0200175 removepy(ns.args)
176
177 return ns
Victor Stinnerdad20e42015-09-29 22:48:52 +0200178
Victor Stinnerdad20e42015-09-29 22:48:52 +0200179 def find_tests(self, tests):
180 self.tests = tests
181
182 if self.ns.single:
183 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
184 try:
185 with open(self.next_single_filename, 'r') as fp:
186 next_test = fp.read().strip()
187 self.tests = [next_test]
188 except OSError:
189 pass
190
191 if self.ns.fromfile:
192 self.tests = []
Victor Stinner5de16e82016-03-24 09:43:00 +0100193 # regex to match 'test_builtin' in line:
194 # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec'
Victor Stinnere8cfec52017-01-03 01:38:58 +0100195 regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b')
Victor Stinnerdad20e42015-09-29 22:48:52 +0200196 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200197 for line in fp:
Victor Stinnerc24217e2016-12-09 16:05:51 +0100198 line = line.split('#', 1)[0]
Victor Stinner5de16e82016-03-24 09:43:00 +0100199 line = line.strip()
Victor Stinnerc24217e2016-12-09 16:05:51 +0100200 match = regex.search(line)
201 if match is not None:
Victor Stinnere8cfec52017-01-03 01:38:58 +0100202 self.tests.append(match.group())
Victor Stinnerdad20e42015-09-29 22:48:52 +0200203
204 removepy(self.tests)
205
206 stdtests = STDTESTS[:]
207 nottests = NOTTESTS.copy()
208 if self.ns.exclude:
209 for arg in self.ns.args:
210 if arg in stdtests:
211 stdtests.remove(arg)
212 nottests.add(arg)
213 self.ns.args = []
214
Victor Stinnerdad20e42015-09-29 22:48:52 +0200215 # if testdir is set, then we are not running the python tests suite, so
216 # don't add default tests to be executed or skipped (pass empty values)
217 if self.ns.testdir:
218 alltests = findtests(self.ns.testdir, list(), set())
219 else:
220 alltests = findtests(self.ns.testdir, stdtests, nottests)
221
Victor Stinner5de16e82016-03-24 09:43:00 +0100222 if not self.ns.fromfile:
223 self.selected = self.tests or self.ns.args or alltests
224 else:
225 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200226 if self.ns.single:
227 self.selected = self.selected[:1]
228 try:
229 pos = alltests.index(self.selected[0])
230 self.next_single_test = alltests[pos + 1]
231 except IndexError:
232 pass
233
Victor Stinnerc7eab052015-09-30 00:59:35 +0200234 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200235 if self.ns.start:
236 try:
237 del self.selected[:self.selected.index(self.ns.start)]
238 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200239 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200240 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200241
242 if self.ns.randomize:
243 if self.ns.random_seed is None:
244 self.ns.random_seed = random.randrange(10000000)
245 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200246 random.shuffle(self.selected)
247
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200248 def list_tests(self):
249 for name in self.selected:
250 print(name)
251
mlouielua49c9352017-06-16 17:36:19 +0800252 def _list_cases(self, suite):
253 for test in suite:
254 if isinstance(test, unittest.loader._FailedTest):
255 continue
256 if isinstance(test, unittest.TestSuite):
257 self._list_cases(test)
258 elif isinstance(test, unittest.TestCase):
Victor Stinnerace56d52017-06-26 14:18:51 +0200259 if support._match_test(test):
260 print(test.id())
mlouielua49c9352017-06-16 17:36:19 +0800261
262 def list_cases(self):
Victor Stinnerace56d52017-06-26 14:18:51 +0200263 support.verbose = False
264 support.match_tests = self.ns.match_tests
265
mlouielua49c9352017-06-16 17:36:19 +0800266 for test in self.selected:
267 abstest = get_abs_module(self.ns, test)
268 try:
269 suite = unittest.defaultTestLoader.loadTestsFromName(abstest)
270 self._list_cases(suite)
271 except unittest.SkipTest:
272 self.skipped.append(test)
273
274 if self.skipped:
275 print(file=sys.stderr)
276 print(count(len(self.skipped), "test"), "skipped:", file=sys.stderr)
277 printlist(self.skipped, file=sys.stderr)
278
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200279 def rerun_failed_tests(self):
280 self.ns.verbose = True
281 self.ns.failfast = False
282 self.ns.verbose3 = False
283 self.ns.match_tests = None
284
285 print("Re-running failed tests in verbose mode")
286 for test in self.bad[:]:
287 print("Re-running test %r in verbose mode" % test, flush=True)
288 try:
289 self.ns.verbose = True
290 ok = runtest(self.ns, test)
291 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200292 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200293 # print a newline separate from the ^C
294 print()
295 break
296 else:
297 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
298 self.bad.remove(test)
299 else:
300 if self.bad:
301 print(count(len(self.bad), 'test'), "failed again:")
302 printlist(self.bad)
303
Victor Stinnerdad20e42015-09-29 22:48:52 +0200304 def display_result(self):
305 if self.interrupted:
306 # print a newline after ^C
307 print()
308 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200309 executed = set(self.good) | set(self.bad) | set(self.skipped)
310 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200311 print(count(len(omitted), "test"), "omitted:")
312 printlist(omitted)
313
Brett Cannon11faa212015-10-02 16:20:49 -0700314 # If running the test suite for PGO then no one cares about
315 # results.
316 if self.ns.pgo:
317 return
318
Victor Stinnerdad20e42015-09-29 22:48:52 +0200319 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200320 if (not self.bad
321 and not self.skipped
322 and not self.interrupted
323 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200324 print("All", end=' ')
325 print(count(len(self.good), "test"), "OK.")
326
327 if self.ns.print_slow:
328 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200329 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200330 print("10 slowest tests:")
331 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200332 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200333
334 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200335 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200336 print(count(len(self.bad), "test"), "failed:")
337 printlist(self.bad)
338
339 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200340 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200341 print("{} altered the execution environment:".format(
342 count(len(self.environment_changed), "test")))
343 printlist(self.environment_changed)
344
345 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200346 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200347 print(count(len(self.skipped), "test"), "skipped:")
348 printlist(self.skipped)
349
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200350 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200351 if self.ns.trace:
352 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200353 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200354
Victor Stinnerdad20e42015-09-29 22:48:52 +0200355 save_modules = sys.modules.keys()
356
Victor Stinner2b60b722016-03-24 11:55:29 +0100357 print("Run tests sequentially")
358
Victor Stinner69649f22016-03-23 12:14:10 +0100359 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200360 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100361 start_time = time.monotonic()
362
363 text = test
364 if previous_test:
365 text = '%s -- %s' % (text, previous_test)
366 self.display_progress(test_index, text)
367
Victor Stinnerc7eab052015-09-30 00:59:35 +0200368 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200369 # If we're tracing code coverage, then we don't exit with status
370 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200371 cmd = ('result = runtest(self.ns, test); '
372 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200373 ns = dict(locals())
374 self.tracer.runctx(cmd, globals=globals(), locals=ns)
375 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200376 else:
377 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200378 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200379 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200380 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200381 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200382 break
Victor Stinner3909e582015-10-11 10:37:25 +0200383 else:
384 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200385
Victor Stinner1b8b4232016-05-20 13:37:40 +0200386 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100387 test_time = time.monotonic() - start_time
388 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200389 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200390 elif result[0] == PASSED:
391 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100392 previous_test = None
393
Victor Stinnerdad20e42015-09-29 22:48:52 +0200394 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200395 gc.collect()
396 if gc.garbage:
397 print("Warning: test created", len(gc.garbage), end=' ')
398 print("uncollectable object(s).")
399 # move the uncollectable objects somewhere so we don't see
400 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200401 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200402 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200403
Victor Stinner3844fe52015-09-26 10:38:01 +0200404 # Unload the newly imported modules (best effort finalization)
405 for module in sys.modules.keys():
406 if module not in save_modules and module.startswith("test."):
407 support.unload(module)
408
Victor Stinner69649f22016-03-23 12:14:10 +0100409 if previous_test:
410 print(previous_test)
411
Victor Stinnerb4084352015-09-30 02:39:22 +0200412 def _test_forever(self, tests):
413 while True:
414 for test in tests:
415 yield test
416 if self.bad:
417 return
Victor Stinner5e875922017-07-03 11:15:58 +0200418 if self.ns.fail_env_changed and self.environment_changed:
419 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200420
Victor Stinner3d005682017-05-04 15:21:12 +0200421 def display_header(self):
422 # Print basic platform information
423 print("==", platform.python_implementation(), *sys.version.split())
424 print("==", platform.platform(aliased=True),
425 "%s-endian" % sys.byteorder)
426 print("== hash algorithm:", sys.hash_info.algorithm,
427 "64bit" if sys.maxsize > 2**32 else "32bit")
428 print("== cwd:", os.getcwd())
429 cpu_count = os.cpu_count()
430 if cpu_count:
431 print("== CPU count:", cpu_count)
432 print("== encodings: locale=%s, FS=%s"
433 % (locale.getpreferredencoding(False),
434 sys.getfilesystemencoding()))
435 print("Testing with flags:", sys.flags)
436
Victor Stinnerb4084352015-09-30 02:39:22 +0200437 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200438 # For a partial run, we do not need to clutter the output.
Victor Stinner3d005682017-05-04 15:21:12 +0200439 if (self.ns.header
440 or not(self.ns.pgo or self.ns.quiet or self.ns.single
441 or self.tests or self.ns.args)):
442 self.display_header()
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200443
444 if self.ns.randomize:
445 print("Using random seed", self.ns.random_seed)
446
Victor Stinnerdad20e42015-09-29 22:48:52 +0200447 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200448 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200449 self.test_count = ''
450 self.test_count_width = 3
451 else:
452 self.tests = iter(self.selected)
453 self.test_count = '/{}'.format(len(self.selected))
454 self.test_count_width = len(self.test_count) - 1
455
456 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200457 from test.libregrtest.runtest_mp import run_tests_multiprocess
458 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200459 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200460 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200461
462 def finalize(self):
463 if self.next_single_filename:
464 if self.next_single_test:
465 with open(self.next_single_filename, 'w') as fp:
466 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200467 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200468 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200469
Victor Stinnerc7eab052015-09-30 00:59:35 +0200470 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200471 r = self.tracer.results()
472 r.write_results(show_missing=True, summary=True,
473 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200474
Victor Stinner435eaf42016-08-17 12:22:52 +0200475 print()
476 duration = time.monotonic() - self.start_time
477 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100478
Victor Stinner63686032016-08-17 16:12:16 +0200479 if self.bad:
480 result = "FAILURE"
481 elif self.interrupted:
482 result = "INTERRUPTED"
Victor Stinner5e875922017-07-03 11:15:58 +0200483 elif self.ns.fail_env_changed and self.environment_changed:
Victor Stinner63f54c62017-06-26 18:33:19 +0200484 result = "ENV CHANGED"
Victor Stinner63686032016-08-17 16:12:16 +0200485 else:
486 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200487 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200488
Victor Stinnerdad20e42015-09-29 22:48:52 +0200489 if self.ns.runleaks:
490 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200491
Victor Stinnerdad20e42015-09-29 22:48:52 +0200492 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100493 global TEMPDIR
494
495 if sysconfig.is_python_build():
496 try:
497 os.mkdir(TEMPDIR)
498 except FileExistsError:
499 pass
500
501 # Define a writable temp dir that will be used as cwd while running
502 # the tests. The name of the dir includes the pid to allow parallel
503 # testing (see the -j option).
504 test_cwd = 'test_python_{}'.format(os.getpid())
505 test_cwd = os.path.join(TEMPDIR, test_cwd)
506
507 # Run the tests in a context manager that temporarily changes the CWD to a
508 # temporary and writable directory. If it's not possible to create or
509 # change the CWD, the original CWD will be used. The original CWD is
510 # available from support.SAVEDCWD.
511 with support.temp_cwd(test_cwd, quiet=True):
512 self._main(tests, kwargs)
513
514 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200515 self.ns = self.parse_args(kwargs)
516
Victor Stinnerdad20e42015-09-29 22:48:52 +0200517 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200518 from test.libregrtest.runtest_mp import run_tests_slave
519 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200520
Victor Stinnerc7eab052015-09-30 00:59:35 +0200521 if self.ns.wait:
522 input("Press any key to continue...")
523
Steve Dower22d06982016-09-06 19:38:15 -0700524 support.PGO = self.ns.pgo
525
Victor Stinnera2045022015-09-30 02:17:28 +0200526 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200527
Victor Stinnerdad20e42015-09-29 22:48:52 +0200528 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200529
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200530 if self.ns.list_tests:
531 self.list_tests()
532 sys.exit(0)
533
mlouielua49c9352017-06-16 17:36:19 +0800534 if self.ns.list_cases:
535 self.list_cases()
536 sys.exit(0)
537
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200538 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200539 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200540
541 if self.ns.verbose2 and self.bad:
542 self.rerun_failed_tests()
543
Victor Stinnerdad20e42015-09-29 22:48:52 +0200544 self.finalize()
Victor Stinner63f54c62017-06-26 18:33:19 +0200545 if self.bad:
546 sys.exit(2)
547 if self.interrupted:
548 sys.exit(130)
549 if self.ns.fail_env_changed and self.environment_changed:
550 sys.exit(3)
551 sys.exit(0)
Victor Stinner3844fe52015-09-26 10:38:01 +0200552
553
Victor Stinner3844fe52015-09-26 10:38:01 +0200554def removepy(names):
555 if not names:
556 return
557 for idx, name in enumerate(names):
558 basename, ext = os.path.splitext(name)
559 if ext == '.py':
560 names[idx] = basename
561
562
563def count(n, word):
564 if n == 1:
565 return "%d %s" % (n, word)
566 else:
567 return "%d %ss" % (n, word)
568
569
mlouielua49c9352017-06-16 17:36:19 +0800570def printlist(x, width=70, indent=4, file=None):
Victor Stinner3844fe52015-09-26 10:38:01 +0200571 """Print the elements of iterable x to stdout.
572
573 Optional arg width (default 70) is the maximum line length.
574 Optional arg indent (default 4) is the number of blanks with which to
575 begin each line.
576 """
577
Victor Stinner3844fe52015-09-26 10:38:01 +0200578 blanks = ' ' * indent
579 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200580 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
mlouielua49c9352017-06-16 17:36:19 +0800581 initial_indent=blanks, subsequent_indent=blanks),
582 file=file)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200583
584
585def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100586 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200587 Regrtest().main(tests=tests, **kwargs)