blob: 1a776556929f28a2c7af6563c4d5274d82fbf5d0 [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 Stinner3844fe52015-09-26 10:38:01 +0200418
Victor Stinner3d005682017-05-04 15:21:12 +0200419 def display_header(self):
420 # Print basic platform information
421 print("==", platform.python_implementation(), *sys.version.split())
422 print("==", platform.platform(aliased=True),
423 "%s-endian" % sys.byteorder)
424 print("== hash algorithm:", sys.hash_info.algorithm,
425 "64bit" if sys.maxsize > 2**32 else "32bit")
426 print("== cwd:", os.getcwd())
427 cpu_count = os.cpu_count()
428 if cpu_count:
429 print("== CPU count:", cpu_count)
430 print("== encodings: locale=%s, FS=%s"
431 % (locale.getpreferredencoding(False),
432 sys.getfilesystemencoding()))
433 print("Testing with flags:", sys.flags)
434
Victor Stinnerb4084352015-09-30 02:39:22 +0200435 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200436 # For a partial run, we do not need to clutter the output.
Victor Stinner3d005682017-05-04 15:21:12 +0200437 if (self.ns.header
438 or not(self.ns.pgo or self.ns.quiet or self.ns.single
439 or self.tests or self.ns.args)):
440 self.display_header()
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200441
442 if self.ns.randomize:
443 print("Using random seed", self.ns.random_seed)
444
Victor Stinnerdad20e42015-09-29 22:48:52 +0200445 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200446 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200447 self.test_count = ''
448 self.test_count_width = 3
449 else:
450 self.tests = iter(self.selected)
451 self.test_count = '/{}'.format(len(self.selected))
452 self.test_count_width = len(self.test_count) - 1
453
454 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200455 from test.libregrtest.runtest_mp import run_tests_multiprocess
456 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200457 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200458 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200459
460 def finalize(self):
461 if self.next_single_filename:
462 if self.next_single_test:
463 with open(self.next_single_filename, 'w') as fp:
464 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200465 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200466 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200467
Victor Stinnerc7eab052015-09-30 00:59:35 +0200468 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200469 r = self.tracer.results()
470 r.write_results(show_missing=True, summary=True,
471 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200472
Victor Stinner435eaf42016-08-17 12:22:52 +0200473 print()
474 duration = time.monotonic() - self.start_time
475 print("Total duration: %s" % format_duration(duration))
Victor Stinner24f949e2016-03-22 15:14:09 +0100476
Victor Stinner63686032016-08-17 16:12:16 +0200477 if self.bad:
478 result = "FAILURE"
479 elif self.interrupted:
480 result = "INTERRUPTED"
481 else:
482 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200483 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200484
Victor Stinnerdad20e42015-09-29 22:48:52 +0200485 if self.ns.runleaks:
486 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200487
Victor Stinnerdad20e42015-09-29 22:48:52 +0200488 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100489 global TEMPDIR
490
491 if sysconfig.is_python_build():
492 try:
493 os.mkdir(TEMPDIR)
494 except FileExistsError:
495 pass
496
497 # Define a writable temp dir that will be used as cwd while running
498 # the tests. The name of the dir includes the pid to allow parallel
499 # testing (see the -j option).
500 test_cwd = 'test_python_{}'.format(os.getpid())
501 test_cwd = os.path.join(TEMPDIR, test_cwd)
502
503 # Run the tests in a context manager that temporarily changes the CWD to a
504 # temporary and writable directory. If it's not possible to create or
505 # change the CWD, the original CWD will be used. The original CWD is
506 # available from support.SAVEDCWD.
507 with support.temp_cwd(test_cwd, quiet=True):
508 self._main(tests, kwargs)
509
510 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200511 self.ns = self.parse_args(kwargs)
512
Victor Stinnerdad20e42015-09-29 22:48:52 +0200513 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200514 from test.libregrtest.runtest_mp import run_tests_slave
515 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200516
Victor Stinnerc7eab052015-09-30 00:59:35 +0200517 if self.ns.wait:
518 input("Press any key to continue...")
519
Steve Dower22d06982016-09-06 19:38:15 -0700520 support.PGO = self.ns.pgo
521
Victor Stinnera2045022015-09-30 02:17:28 +0200522 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200523
Victor Stinnerdad20e42015-09-29 22:48:52 +0200524 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200525
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200526 if self.ns.list_tests:
527 self.list_tests()
528 sys.exit(0)
529
mlouielua49c9352017-06-16 17:36:19 +0800530 if self.ns.list_cases:
531 self.list_cases()
532 sys.exit(0)
533
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200534 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200535 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200536
537 if self.ns.verbose2 and self.bad:
538 self.rerun_failed_tests()
539
Victor Stinnerdad20e42015-09-29 22:48:52 +0200540 self.finalize()
541 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200542
543
Victor Stinner3844fe52015-09-26 10:38:01 +0200544def removepy(names):
545 if not names:
546 return
547 for idx, name in enumerate(names):
548 basename, ext = os.path.splitext(name)
549 if ext == '.py':
550 names[idx] = basename
551
552
553def count(n, word):
554 if n == 1:
555 return "%d %s" % (n, word)
556 else:
557 return "%d %ss" % (n, word)
558
559
mlouielua49c9352017-06-16 17:36:19 +0800560def printlist(x, width=70, indent=4, file=None):
Victor Stinner3844fe52015-09-26 10:38:01 +0200561 """Print the elements of iterable x to stdout.
562
563 Optional arg width (default 70) is the maximum line length.
564 Optional arg indent (default 4) is the number of blanks with which to
565 begin each line.
566 """
567
Victor Stinner3844fe52015-09-26 10:38:01 +0200568 blanks = ' ' * indent
569 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200570 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
mlouielua49c9352017-06-16 17:36:19 +0800571 initial_indent=blanks, subsequent_indent=blanks),
572 file=file)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200573
574
575def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100576 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200577 Regrtest().main(tests=tests, **kwargs)