blob: 527de177792ce5ab2ab3f3cf3804439dc3967195 [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):
259 print(test.id())
260
261 def list_cases(self):
262 for test in self.selected:
263 abstest = get_abs_module(self.ns, test)
264 try:
265 suite = unittest.defaultTestLoader.loadTestsFromName(abstest)
266 self._list_cases(suite)
267 except unittest.SkipTest:
268 self.skipped.append(test)
269
270 if self.skipped:
271 print(file=sys.stderr)
272 print(count(len(self.skipped), "test"), "skipped:", file=sys.stderr)
273 printlist(self.skipped, file=sys.stderr)
274
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200275 def rerun_failed_tests(self):
276 self.ns.verbose = True
277 self.ns.failfast = False
278 self.ns.verbose3 = False
279 self.ns.match_tests = None
280
281 print("Re-running failed tests in verbose mode")
282 for test in self.bad[:]:
283 print("Re-running test %r in verbose mode" % test, flush=True)
284 try:
285 self.ns.verbose = True
286 ok = runtest(self.ns, test)
287 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200288 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200289 # print a newline separate from the ^C
290 print()
291 break
292 else:
293 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
294 self.bad.remove(test)
295 else:
296 if self.bad:
297 print(count(len(self.bad), 'test'), "failed again:")
298 printlist(self.bad)
299
Victor Stinnerdad20e42015-09-29 22:48:52 +0200300 def display_result(self):
301 if self.interrupted:
302 # print a newline after ^C
303 print()
304 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200305 executed = set(self.good) | set(self.bad) | set(self.skipped)
306 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200307 print(count(len(omitted), "test"), "omitted:")
308 printlist(omitted)
309
Brett Cannon11faa212015-10-02 16:20:49 -0700310 # If running the test suite for PGO then no one cares about
311 # results.
312 if self.ns.pgo:
313 return
314
Victor Stinnerdad20e42015-09-29 22:48:52 +0200315 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200316 if (not self.bad
317 and not self.skipped
318 and not self.interrupted
319 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200320 print("All", end=' ')
321 print(count(len(self.good), "test"), "OK.")
322
323 if self.ns.print_slow:
324 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200325 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200326 print("10 slowest tests:")
327 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200328 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200329
330 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200331 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200332 print(count(len(self.bad), "test"), "failed:")
333 printlist(self.bad)
334
335 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200336 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200337 print("{} altered the execution environment:".format(
338 count(len(self.environment_changed), "test")))
339 printlist(self.environment_changed)
340
341 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200342 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200343 print(count(len(self.skipped), "test"), "skipped:")
344 printlist(self.skipped)
345
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200346 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200347 if self.ns.trace:
348 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200349 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200350
Victor Stinnerdad20e42015-09-29 22:48:52 +0200351 save_modules = sys.modules.keys()
352
Victor Stinner2b60b722016-03-24 11:55:29 +0100353 print("Run tests sequentially")
354
Victor Stinner69649f22016-03-23 12:14:10 +0100355 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200356 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100357 start_time = time.monotonic()
358
359 text = test
360 if previous_test:
361 text = '%s -- %s' % (text, previous_test)
362 self.display_progress(test_index, text)
363
Victor Stinnerc7eab052015-09-30 00:59:35 +0200364 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200365 # If we're tracing code coverage, then we don't exit with status
366 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200367 cmd = ('result = runtest(self.ns, test); '
368 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200369 ns = dict(locals())
370 self.tracer.runctx(cmd, globals=globals(), locals=ns)
371 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200372 else:
373 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200374 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200375 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200376 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200377 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200378 break
Victor Stinner3909e582015-10-11 10:37:25 +0200379 else:
380 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200381
Victor Stinner1b8b4232016-05-20 13:37:40 +0200382 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100383 test_time = time.monotonic() - start_time
384 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200385 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200386 elif result[0] == PASSED:
387 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100388 previous_test = None
389
Victor Stinnerdad20e42015-09-29 22:48:52 +0200390 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200391 gc.collect()
392 if gc.garbage:
393 print("Warning: test created", len(gc.garbage), end=' ')
394 print("uncollectable object(s).")
395 # move the uncollectable objects somewhere so we don't see
396 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200397 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200398 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200399
Victor Stinner3844fe52015-09-26 10:38:01 +0200400 # Unload the newly imported modules (best effort finalization)
401 for module in sys.modules.keys():
402 if module not in save_modules and module.startswith("test."):
403 support.unload(module)
404
Victor Stinner69649f22016-03-23 12:14:10 +0100405 if previous_test:
406 print(previous_test)
407
Victor Stinnerb4084352015-09-30 02:39:22 +0200408 def _test_forever(self, tests):
409 while True:
410 for test in tests:
411 yield test
412 if self.bad:
413 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200414
Victor Stinner3d005682017-05-04 15:21:12 +0200415 def display_header(self):
416 # Print basic platform information
417 print("==", platform.python_implementation(), *sys.version.split())
418 print("==", platform.platform(aliased=True),
419 "%s-endian" % sys.byteorder)
420 print("== hash algorithm:", sys.hash_info.algorithm,
421 "64bit" if sys.maxsize > 2**32 else "32bit")
422 print("== cwd:", os.getcwd())
423 cpu_count = os.cpu_count()
424 if cpu_count:
425 print("== CPU count:", cpu_count)
426 print("== encodings: locale=%s, FS=%s"
427 % (locale.getpreferredencoding(False),
428 sys.getfilesystemencoding()))
429 print("Testing with flags:", sys.flags)
430
Victor Stinnerb4084352015-09-30 02:39:22 +0200431 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200432 # For a partial run, we do not need to clutter the output.
Victor Stinner3d005682017-05-04 15:21:12 +0200433 if (self.ns.header
434 or not(self.ns.pgo or self.ns.quiet or self.ns.single
435 or self.tests or self.ns.args)):
436 self.display_header()
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200437
438 if self.ns.randomize:
439 print("Using random seed", self.ns.random_seed)
440
Victor Stinnerdad20e42015-09-29 22:48:52 +0200441 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200442 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200443 self.test_count = ''
444 self.test_count_width = 3
445 else:
446 self.tests = iter(self.selected)
447 self.test_count = '/{}'.format(len(self.selected))
448 self.test_count_width = len(self.test_count) - 1
449
450 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200451 from test.libregrtest.runtest_mp import run_tests_multiprocess
452 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200453 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200454 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200455
456 def finalize(self):
457 if self.next_single_filename:
458 if self.next_single_test:
459 with open(self.next_single_filename, 'w') as fp:
460 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200461 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200462 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200463
Victor Stinnerc7eab052015-09-30 00:59:35 +0200464 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200465 r = self.tracer.results()
466 r.write_results(show_missing=True, summary=True,
467 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200468
Victor Stinner435eaf42016-08-17 12:22:52 +0200469 print()
470 duration = time.monotonic() - self.start_time
471 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100472
Victor Stinner63686032016-08-17 16:12:16 +0200473 if self.bad:
474 result = "FAILURE"
475 elif self.interrupted:
476 result = "INTERRUPTED"
477 else:
478 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200479 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200480
Victor Stinnerdad20e42015-09-29 22:48:52 +0200481 if self.ns.runleaks:
482 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200483
Victor Stinnerdad20e42015-09-29 22:48:52 +0200484 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100485 global TEMPDIR
486
487 if sysconfig.is_python_build():
488 try:
489 os.mkdir(TEMPDIR)
490 except FileExistsError:
491 pass
492
493 # Define a writable temp dir that will be used as cwd while running
494 # the tests. The name of the dir includes the pid to allow parallel
495 # testing (see the -j option).
496 test_cwd = 'test_python_{}'.format(os.getpid())
497 test_cwd = os.path.join(TEMPDIR, test_cwd)
498
499 # Run the tests in a context manager that temporarily changes the CWD to a
500 # temporary and writable directory. If it's not possible to create or
501 # change the CWD, the original CWD will be used. The original CWD is
502 # available from support.SAVEDCWD.
503 with support.temp_cwd(test_cwd, quiet=True):
504 self._main(tests, kwargs)
505
506 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200507 self.ns = self.parse_args(kwargs)
508
Victor Stinnerdad20e42015-09-29 22:48:52 +0200509 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200510 from test.libregrtest.runtest_mp import run_tests_slave
511 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200512
Victor Stinnerc7eab052015-09-30 00:59:35 +0200513 if self.ns.wait:
514 input("Press any key to continue...")
515
Steve Dower22d06982016-09-06 19:38:15 -0700516 support.PGO = self.ns.pgo
517
Victor Stinnera2045022015-09-30 02:17:28 +0200518 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200519
Victor Stinnerdad20e42015-09-29 22:48:52 +0200520 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200521
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200522 if self.ns.list_tests:
523 self.list_tests()
524 sys.exit(0)
525
mlouielua49c9352017-06-16 17:36:19 +0800526 if self.ns.list_cases:
527 self.list_cases()
528 sys.exit(0)
529
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200530 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200531 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200532
533 if self.ns.verbose2 and self.bad:
534 self.rerun_failed_tests()
535
Victor Stinnerdad20e42015-09-29 22:48:52 +0200536 self.finalize()
537 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200538
539
Victor Stinner3844fe52015-09-26 10:38:01 +0200540def removepy(names):
541 if not names:
542 return
543 for idx, name in enumerate(names):
544 basename, ext = os.path.splitext(name)
545 if ext == '.py':
546 names[idx] = basename
547
548
549def count(n, word):
550 if n == 1:
551 return "%d %s" % (n, word)
552 else:
553 return "%d %ss" % (n, word)
554
555
mlouielua49c9352017-06-16 17:36:19 +0800556def printlist(x, width=70, indent=4, file=None):
Victor Stinner3844fe52015-09-26 10:38:01 +0200557 """Print the elements of iterable x to stdout.
558
559 Optional arg width (default 70) is the maximum line length.
560 Optional arg indent (default 4) is the number of blanks with which to
561 begin each line.
562 """
563
Victor Stinner3844fe52015-09-26 10:38:01 +0200564 blanks = ' ' * indent
565 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200566 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
mlouielua49c9352017-06-16 17:36:19 +0800567 initial_indent=blanks, subsequent_indent=blanks),
568 file=file)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200569
570
571def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100572 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200573 Regrtest().main(tests=tests, **kwargs)