blob: ce01c8ce586d659fa91bd995b98970fc8dca6217 [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}"
Victor Stinnerb97d99c2017-08-10 16:19:03 +0200135 fails = len(self.bad) + len(self.environment_changed)
136 if fails and not self.ns.pgo:
137 line = f"{line}/{fails}"
Victor Stinner3d005682017-05-04 15:21:12 +0200138 line = f"[{line}] {test}"
139
140 # add the system load prefix: "load avg: 1.80 "
141 if hasattr(os, 'getloadavg'):
142 load_avg_1min = os.getloadavg()[0]
143 line = f"load avg: {load_avg_1min:.2f} {line}"
144
145 # add the timestamp prefix: "0:01:05 "
Victor Stinner435eaf42016-08-17 12:22:52 +0200146 test_time = time.monotonic() - self.start_time
147 test_time = datetime.timedelta(seconds=int(test_time))
Victor Stinner3d005682017-05-04 15:21:12 +0200148 line = f"{test_time} {line}"
Victor Stinner24f949e2016-03-22 15:14:09 +0100149 print(line, flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200150
Victor Stinner234cbef2015-09-30 01:13:53 +0200151 def parse_args(self, kwargs):
152 ns = _parse_args(sys.argv[1:], **kwargs)
153
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200154 if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
155 print("Warning: The timeout option requires "
156 "faulthandler.dump_traceback_later", file=sys.stderr)
157 ns.timeout = None
158
Victor Stinner234cbef2015-09-30 01:13:53 +0200159 if ns.threshold is not None and gc is None:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200160 print('No GC available, ignore --threshold.', file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200161 ns.threshold = None
162
163 if ns.findleaks:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200164 if gc is not None:
165 # Uncomment the line below to report garbage that is not
166 # freeable by reference counting alone. By default only
167 # garbage that is not collectable by the GC is reported.
168 pass
169 #gc.set_debug(gc.DEBUG_SAVEALL)
170 else:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200171 print('No GC available, disabling --findleaks',
172 file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200173 ns.findleaks = False
Victor Stinnerdad20e42015-09-29 22:48:52 +0200174
Victor Stinnerdad20e42015-09-29 22:48:52 +0200175 # Strip .py extensions.
Victor Stinner234cbef2015-09-30 01:13:53 +0200176 removepy(ns.args)
177
178 return ns
Victor Stinnerdad20e42015-09-29 22:48:52 +0200179
Victor Stinnerdad20e42015-09-29 22:48:52 +0200180 def find_tests(self, tests):
181 self.tests = tests
182
183 if self.ns.single:
184 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
185 try:
186 with open(self.next_single_filename, 'r') as fp:
187 next_test = fp.read().strip()
188 self.tests = [next_test]
189 except OSError:
190 pass
191
192 if self.ns.fromfile:
193 self.tests = []
Victor Stinner5de16e82016-03-24 09:43:00 +0100194 # regex to match 'test_builtin' in line:
195 # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec'
Victor Stinnere8cfec52017-01-03 01:38:58 +0100196 regex = re.compile(r'\btest_[a-zA-Z0-9_]+\b')
Victor Stinnerdad20e42015-09-29 22:48:52 +0200197 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200198 for line in fp:
Victor Stinnerc24217e2016-12-09 16:05:51 +0100199 line = line.split('#', 1)[0]
Victor Stinner5de16e82016-03-24 09:43:00 +0100200 line = line.strip()
Victor Stinnerc24217e2016-12-09 16:05:51 +0100201 match = regex.search(line)
202 if match is not None:
Victor Stinnere8cfec52017-01-03 01:38:58 +0100203 self.tests.append(match.group())
Victor Stinnerdad20e42015-09-29 22:48:52 +0200204
205 removepy(self.tests)
206
207 stdtests = STDTESTS[:]
208 nottests = NOTTESTS.copy()
209 if self.ns.exclude:
210 for arg in self.ns.args:
211 if arg in stdtests:
212 stdtests.remove(arg)
213 nottests.add(arg)
214 self.ns.args = []
215
Victor Stinnerdad20e42015-09-29 22:48:52 +0200216 # if testdir is set, then we are not running the python tests suite, so
217 # don't add default tests to be executed or skipped (pass empty values)
218 if self.ns.testdir:
219 alltests = findtests(self.ns.testdir, list(), set())
220 else:
221 alltests = findtests(self.ns.testdir, stdtests, nottests)
222
Victor Stinner5de16e82016-03-24 09:43:00 +0100223 if not self.ns.fromfile:
224 self.selected = self.tests or self.ns.args or alltests
225 else:
226 self.selected = self.tests
Victor Stinnerdad20e42015-09-29 22:48:52 +0200227 if self.ns.single:
228 self.selected = self.selected[:1]
229 try:
230 pos = alltests.index(self.selected[0])
231 self.next_single_test = alltests[pos + 1]
232 except IndexError:
233 pass
234
Victor Stinnerc7eab052015-09-30 00:59:35 +0200235 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200236 if self.ns.start:
237 try:
238 del self.selected[:self.selected.index(self.ns.start)]
239 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200240 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200241 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200242
243 if self.ns.randomize:
244 if self.ns.random_seed is None:
245 self.ns.random_seed = random.randrange(10000000)
246 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200247 random.shuffle(self.selected)
248
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200249 def list_tests(self):
250 for name in self.selected:
251 print(name)
252
mlouielua49c9352017-06-16 17:36:19 +0800253 def _list_cases(self, suite):
254 for test in suite:
255 if isinstance(test, unittest.loader._FailedTest):
256 continue
257 if isinstance(test, unittest.TestSuite):
258 self._list_cases(test)
259 elif isinstance(test, unittest.TestCase):
Victor Stinner803ddd82017-11-21 15:34:02 -0800260 if support.match_test(test):
Victor Stinnerace56d52017-06-26 14:18:51 +0200261 print(test.id())
mlouielua49c9352017-06-16 17:36:19 +0800262
263 def list_cases(self):
Victor Stinnerace56d52017-06-26 14:18:51 +0200264 support.verbose = False
Victor Stinner803ddd82017-11-21 15:34:02 -0800265 support.set_match_tests(self.ns.match_tests)
Victor Stinnerace56d52017-06-26 14:18:51 +0200266
mlouielua49c9352017-06-16 17:36:19 +0800267 for test in self.selected:
268 abstest = get_abs_module(self.ns, test)
269 try:
270 suite = unittest.defaultTestLoader.loadTestsFromName(abstest)
271 self._list_cases(suite)
272 except unittest.SkipTest:
273 self.skipped.append(test)
274
275 if self.skipped:
276 print(file=sys.stderr)
277 print(count(len(self.skipped), "test"), "skipped:", file=sys.stderr)
278 printlist(self.skipped, file=sys.stderr)
279
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200280 def rerun_failed_tests(self):
281 self.ns.verbose = True
282 self.ns.failfast = False
283 self.ns.verbose3 = False
284 self.ns.match_tests = None
285
286 print("Re-running failed tests in verbose mode")
287 for test in self.bad[:]:
288 print("Re-running test %r in verbose mode" % test, flush=True)
289 try:
290 self.ns.verbose = True
291 ok = runtest(self.ns, test)
292 except KeyboardInterrupt:
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200293 self.interrupted = True
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200294 # print a newline separate from the ^C
295 print()
296 break
297 else:
298 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
299 self.bad.remove(test)
300 else:
301 if self.bad:
302 print(count(len(self.bad), 'test'), "failed again:")
303 printlist(self.bad)
304
Victor Stinnerdad20e42015-09-29 22:48:52 +0200305 def display_result(self):
306 if self.interrupted:
307 # print a newline after ^C
308 print()
309 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200310 executed = set(self.good) | set(self.bad) | set(self.skipped)
311 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200312 print(count(len(omitted), "test"), "omitted:")
313 printlist(omitted)
314
Brett Cannon11faa212015-10-02 16:20:49 -0700315 # If running the test suite for PGO then no one cares about
316 # results.
317 if self.ns.pgo:
318 return
319
Victor Stinnerdad20e42015-09-29 22:48:52 +0200320 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200321 if (not self.bad
322 and not self.skipped
323 and not self.interrupted
324 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200325 print("All", end=' ')
326 print(count(len(self.good), "test"), "OK.")
327
328 if self.ns.print_slow:
329 self.test_times.sort(reverse=True)
Victor Stinner435eaf42016-08-17 12:22:52 +0200330 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200331 print("10 slowest tests:")
332 for time, test in self.test_times[:10]:
Victor Stinner435eaf42016-08-17 12:22:52 +0200333 print("- %s: %s" % (test, format_duration(time)))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200334
335 if self.bad:
Victor Stinner8f003192016-08-17 15:42:21 +0200336 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200337 print(count(len(self.bad), "test"), "failed:")
338 printlist(self.bad)
339
340 if self.environment_changed:
Victor Stinner8f003192016-08-17 15:42:21 +0200341 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200342 print("{} altered the execution environment:".format(
343 count(len(self.environment_changed), "test")))
344 printlist(self.environment_changed)
345
346 if self.skipped and not self.ns.quiet:
Victor Stinner8f003192016-08-17 15:42:21 +0200347 print()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200348 print(count(len(self.skipped), "test"), "skipped:")
349 printlist(self.skipped)
350
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200351 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200352 if self.ns.trace:
353 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200354 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200355
Victor Stinnerdad20e42015-09-29 22:48:52 +0200356 save_modules = sys.modules.keys()
357
Victor Stinner2b60b722016-03-24 11:55:29 +0100358 print("Run tests sequentially")
359
Victor Stinner69649f22016-03-23 12:14:10 +0100360 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200361 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100362 start_time = time.monotonic()
363
364 text = test
365 if previous_test:
366 text = '%s -- %s' % (text, previous_test)
367 self.display_progress(test_index, text)
368
Victor Stinnerc7eab052015-09-30 00:59:35 +0200369 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200370 # If we're tracing code coverage, then we don't exit with status
371 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200372 cmd = ('result = runtest(self.ns, test); '
373 'self.accumulate_result(test, result)')
Victor Stinner1b8b4232016-05-20 13:37:40 +0200374 ns = dict(locals())
375 self.tracer.runctx(cmd, globals=globals(), locals=ns)
376 result = ns['result']
Victor Stinner3844fe52015-09-26 10:38:01 +0200377 else:
378 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200379 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200380 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200381 self.interrupted = True
Victor Stinnerc5a01f82016-08-17 16:00:12 +0200382 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinner3844fe52015-09-26 10:38:01 +0200383 break
Victor Stinner3909e582015-10-11 10:37:25 +0200384 else:
385 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200386
Victor Stinner1b8b4232016-05-20 13:37:40 +0200387 previous_test = format_test_result(test, result[0])
Victor Stinner69649f22016-03-23 12:14:10 +0100388 test_time = time.monotonic() - start_time
389 if test_time >= PROGRESS_MIN_TIME:
Victor Stinner435eaf42016-08-17 12:22:52 +0200390 previous_test = "%s in %s" % (previous_test, format_duration(test_time))
Victor Stinner1b8b4232016-05-20 13:37:40 +0200391 elif result[0] == PASSED:
392 # be quiet: say nothing if the test passed shortly
Victor Stinner69649f22016-03-23 12:14:10 +0100393 previous_test = None
394
Victor Stinnerdad20e42015-09-29 22:48:52 +0200395 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200396 gc.collect()
397 if gc.garbage:
398 print("Warning: test created", len(gc.garbage), end=' ')
399 print("uncollectable object(s).")
400 # move the uncollectable objects somewhere so we don't see
401 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200402 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200403 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200404
Victor Stinner3844fe52015-09-26 10:38:01 +0200405 # Unload the newly imported modules (best effort finalization)
406 for module in sys.modules.keys():
407 if module not in save_modules and module.startswith("test."):
408 support.unload(module)
409
Victor Stinner69649f22016-03-23 12:14:10 +0100410 if previous_test:
411 print(previous_test)
412
Victor Stinnerb4084352015-09-30 02:39:22 +0200413 def _test_forever(self, tests):
414 while True:
415 for test in tests:
416 yield test
417 if self.bad:
418 return
Victor Stinner5e875922017-07-03 11:15:58 +0200419 if self.ns.fail_env_changed and self.environment_changed:
420 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200421
Victor Stinner3d005682017-05-04 15:21:12 +0200422 def display_header(self):
423 # Print basic platform information
424 print("==", platform.python_implementation(), *sys.version.split())
425 print("==", platform.platform(aliased=True),
426 "%s-endian" % sys.byteorder)
Victor Stinner3d005682017-05-04 15:21:12 +0200427 print("== cwd:", os.getcwd())
428 cpu_count = os.cpu_count()
429 if cpu_count:
430 print("== CPU count:", cpu_count)
431 print("== encodings: locale=%s, FS=%s"
432 % (locale.getpreferredencoding(False),
433 sys.getfilesystemencoding()))
Victor Stinner3d005682017-05-04 15:21:12 +0200434
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"
Victor Stinner5e875922017-07-03 11:15:58 +0200481 elif self.ns.fail_env_changed and self.environment_changed:
Victor Stinner63f54c62017-06-26 18:33:19 +0200482 result = "ENV CHANGED"
Victor Stinner63686032016-08-17 16:12:16 +0200483 else:
484 result = "SUCCESS"
Victor Stinnerf2abf5c2016-08-19 17:54:25 +0200485 print("Tests result: %s" % result)
Victor Stinner63686032016-08-17 16:12:16 +0200486
Victor Stinnerdad20e42015-09-29 22:48:52 +0200487 if self.ns.runleaks:
488 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200489
Victor Stinnerdad20e42015-09-29 22:48:52 +0200490 def main(self, tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100491 global TEMPDIR
492
493 if sysconfig.is_python_build():
494 try:
495 os.mkdir(TEMPDIR)
496 except FileExistsError:
497 pass
498
499 # Define a writable temp dir that will be used as cwd while running
500 # the tests. The name of the dir includes the pid to allow parallel
501 # testing (see the -j option).
502 test_cwd = 'test_python_{}'.format(os.getpid())
503 test_cwd = os.path.join(TEMPDIR, test_cwd)
504
505 # Run the tests in a context manager that temporarily changes the CWD to a
506 # temporary and writable directory. If it's not possible to create or
507 # change the CWD, the original CWD will be used. The original CWD is
508 # available from support.SAVEDCWD.
509 with support.temp_cwd(test_cwd, quiet=True):
510 self._main(tests, kwargs)
511
512 def _main(self, tests, kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200513 self.ns = self.parse_args(kwargs)
514
Victor Stinnerdad20e42015-09-29 22:48:52 +0200515 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200516 from test.libregrtest.runtest_mp import run_tests_slave
517 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200518
Victor Stinnerc7eab052015-09-30 00:59:35 +0200519 if self.ns.wait:
520 input("Press any key to continue...")
521
Steve Dower22d06982016-09-06 19:38:15 -0700522 support.PGO = self.ns.pgo
523
Victor Stinnera2045022015-09-30 02:17:28 +0200524 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200525
Victor Stinnerdad20e42015-09-29 22:48:52 +0200526 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200527
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200528 if self.ns.list_tests:
529 self.list_tests()
530 sys.exit(0)
531
mlouielua49c9352017-06-16 17:36:19 +0800532 if self.ns.list_cases:
533 self.list_cases()
534 sys.exit(0)
535
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200536 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200537 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200538
539 if self.ns.verbose2 and self.bad:
540 self.rerun_failed_tests()
541
Victor Stinnerdad20e42015-09-29 22:48:52 +0200542 self.finalize()
Victor Stinner63f54c62017-06-26 18:33:19 +0200543 if self.bad:
544 sys.exit(2)
545 if self.interrupted:
546 sys.exit(130)
547 if self.ns.fail_env_changed and self.environment_changed:
548 sys.exit(3)
549 sys.exit(0)
Victor Stinner3844fe52015-09-26 10:38:01 +0200550
551
Victor Stinner3844fe52015-09-26 10:38:01 +0200552def removepy(names):
553 if not names:
554 return
555 for idx, name in enumerate(names):
556 basename, ext = os.path.splitext(name)
557 if ext == '.py':
558 names[idx] = basename
559
560
561def count(n, word):
562 if n == 1:
563 return "%d %s" % (n, word)
564 else:
565 return "%d %ss" % (n, word)
566
567
mlouielua49c9352017-06-16 17:36:19 +0800568def printlist(x, width=70, indent=4, file=None):
Victor Stinner3844fe52015-09-26 10:38:01 +0200569 """Print the elements of iterable x to stdout.
570
571 Optional arg width (default 70) is the maximum line length.
572 Optional arg indent (default 4) is the number of blanks with which to
573 begin each line.
574 """
575
Victor Stinner3844fe52015-09-26 10:38:01 +0200576 blanks = ' ' * indent
577 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200578 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
mlouielua49c9352017-06-16 17:36:19 +0800579 initial_indent=blanks, subsequent_indent=blanks),
580 file=file)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200581
582
583def main(tests=None, **kwargs):
Victor Stinner3aac0ad2016-03-24 17:53:20 +0100584 """Run the Python suite."""
Victor Stinnerdad20e42015-09-29 22:48:52 +0200585 Regrtest().main(tests=tests, **kwargs)