blob: f410bfd4187adaab7278b86a2ae42f621bac4f37 [file] [log] [blame]
Victor Stinner3844fe52015-09-26 10:38:01 +02001import faulthandler
Victor Stinner3844fe52015-09-26 10:38:01 +02002import os
Victor Stinner3844fe52015-09-26 10:38:01 +02003import platform
Victor Stinnerdad20e42015-09-29 22:48:52 +02004import random
5import re
6import signal
7import sys
8import sysconfig
9import tempfile
10import textwrap
Victor Stinner3844fe52015-09-26 10:38:01 +020011import unittest
12from test.libregrtest.runtest import (
Victor Stinner56e05dd2015-09-29 23:15:38 +020013 findtests, runtest,
14 STDTESTS, NOTTESTS, PASSED, FAILED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED)
Victor Stinner3844fe52015-09-26 10:38:01 +020015from test.libregrtest.refleak import warm_caches
16from test.libregrtest.cmdline import _parse_args
17from test import support
18try:
Victor Stinnerdad20e42015-09-29 22:48:52 +020019 import gc
20except ImportError:
21 gc = None
Victor Stinner3844fe52015-09-26 10:38:01 +020022
23
Victor Stinner3844fe52015-09-26 10:38:01 +020024# When tests are run from the Python build directory, it is best practice
25# to keep the test files in a subfolder. This eases the cleanup of leftover
26# files using the "make distclean" command.
27if sysconfig.is_python_build():
28 TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build')
29else:
30 TEMPDIR = tempfile.gettempdir()
31TEMPDIR = os.path.abspath(TEMPDIR)
32
33
Victor Stinnerc7eab052015-09-30 00:59:35 +020034def setup_python(ns):
Victor Stinnerdad20e42015-09-29 22:48:52 +020035 # Display the Python traceback on fatal errors (e.g. segfault)
36 faulthandler.enable(all_threads=True)
37
38 # Display the Python traceback on SIGALRM or SIGUSR1 signal
39 signals = []
40 if hasattr(signal, 'SIGALRM'):
41 signals.append(signal.SIGALRM)
42 if hasattr(signal, 'SIGUSR1'):
43 signals.append(signal.SIGUSR1)
44 for signum in signals:
45 faulthandler.register(signum, chain=True)
46
47 replace_stdout()
48 support.record_original_stdout(sys.stdout)
49
50 # Some times __path__ and __file__ are not absolute (e.g. while running from
51 # Lib/) and, if we change the CWD to run the tests in a temporary dir, some
52 # imports might fail. This affects only the modules imported before os.chdir().
53 # These modules are searched first in sys.path[0] (so '' -- the CWD) and if
54 # they are found in the CWD their __file__ and __path__ will be relative (this
55 # happens before the chdir). All the modules imported after the chdir, are
56 # not found in the CWD, and since the other paths in sys.path[1:] are absolute
57 # (site.py absolutize them), the __file__ and __path__ will be absolute too.
58 # Therefore it is necessary to absolutize manually the __file__ and __path__ of
59 # the packages to prevent later imports to fail when the CWD is different.
60 for module in sys.modules.values():
61 if hasattr(module, '__path__'):
Victor Stinner6448b802015-09-29 23:43:33 +020062 module.__path__ = [os.path.abspath(path)
63 for path in module.__path__]
Victor Stinnerdad20e42015-09-29 22:48:52 +020064 if hasattr(module, '__file__'):
65 module.__file__ = os.path.abspath(module.__file__)
66
67 # MacOSX (a.k.a. Darwin) has a default stack size that is too small
68 # for deeply recursive regular expressions. We see this as crashes in
69 # the Python test suite when running test_re.py and test_sre.py. The
70 # fix is to set the stack limit to 2048.
71 # This approach may also be useful for other Unixy platforms that
72 # suffer from small default stack limits.
73 if sys.platform == 'darwin':
74 try:
75 import resource
76 except ImportError:
77 pass
78 else:
79 soft, hard = resource.getrlimit(resource.RLIMIT_STACK)
80 newsoft = min(hard, max(soft, 1024*2048))
81 resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard))
82
Victor Stinnerc7eab052015-09-30 00:59:35 +020083 if ns.huntrleaks:
84 unittest.BaseTestSuite._cleanup = False
85
86 # Avoid false positives due to various caches
87 # filling slowly with random data:
88 warm_caches()
89
90 if ns.memlimit is not None:
91 support.set_memlimit(ns.memlimit)
92
93 if ns.threshold is not None:
94 if gc is not None:
95 gc.set_threshold(ns.threshold)
96 else:
97 print('No GC available, ignore --threshold.')
98
99 if ns.nowindows:
100 import msvcrt
101 msvcrt.SetErrorMode(msvcrt.SEM_FAILCRITICALERRORS|
102 msvcrt.SEM_NOALIGNMENTFAULTEXCEPT|
103 msvcrt.SEM_NOGPFAULTERRORBOX|
104 msvcrt.SEM_NOOPENFILEERRORBOX)
105 try:
106 msvcrt.CrtSetReportMode
107 except AttributeError:
108 # release build
109 pass
110 else:
111 for m in [msvcrt.CRT_WARN, msvcrt.CRT_ERROR, msvcrt.CRT_ASSERT]:
112 msvcrt.CrtSetReportMode(m, msvcrt.CRTDBG_MODE_FILE)
113 msvcrt.CrtSetReportFile(m, msvcrt.CRTDBG_FILE_STDERR)
114
Victor Stinnerdad20e42015-09-29 22:48:52 +0200115
116class Regrtest:
Victor Stinner3844fe52015-09-26 10:38:01 +0200117 """Execute a test suite.
118
119 This also parses command-line options and modifies its behavior
120 accordingly.
121
122 tests -- a list of strings containing test names (optional)
123 testdir -- the directory in which to look for tests (optional)
124
125 Users other than the Python test suite will certainly want to
126 specify testdir; if it's omitted, the directory containing the
127 Python test suite is searched for.
128
129 If the tests argument is omitted, the tests listed on the
130 command-line will be used. If that's empty, too, then all *.py
131 files beginning with test_ will be used.
132
133 The other default arguments (verbose, quiet, exclude,
134 single, randomize, findleaks, use_resources, trace, coverdir,
135 print_slow, and random_seed) allow programmers calling main()
136 directly to set the values that would normally be set by flags
137 on the command line.
138 """
Victor Stinnerdad20e42015-09-29 22:48:52 +0200139 def __init__(self):
140 # Namespace of command line options
141 self.ns = None
Victor Stinner3844fe52015-09-26 10:38:01 +0200142
Victor Stinnerdad20e42015-09-29 22:48:52 +0200143 # tests
144 self.tests = []
145 self.selected = []
Victor Stinner3844fe52015-09-26 10:38:01 +0200146
Victor Stinnerdad20e42015-09-29 22:48:52 +0200147 # test results
148 self.good = []
149 self.bad = []
150 self.skipped = []
151 self.resource_denieds = []
152 self.environment_changed = []
153 self.interrupted = False
Victor Stinner3844fe52015-09-26 10:38:01 +0200154
Victor Stinnerdad20e42015-09-29 22:48:52 +0200155 # used by --slow
156 self.test_times = []
Victor Stinner3844fe52015-09-26 10:38:01 +0200157
Victor Stinnerdad20e42015-09-29 22:48:52 +0200158 # used by --coverage, trace.Trace instance
159 self.tracer = None
Victor Stinner3844fe52015-09-26 10:38:01 +0200160
Victor Stinnerdad20e42015-09-29 22:48:52 +0200161 # used by --findleaks, store for gc.garbage
162 self.found_garbage = []
Victor Stinner3844fe52015-09-26 10:38:01 +0200163
Victor Stinnerdad20e42015-09-29 22:48:52 +0200164 # used to display the progress bar "[ 3/100]"
165 self.test_count = ''
166 self.test_count_width = 1
Victor Stinner3844fe52015-09-26 10:38:01 +0200167
Victor Stinnerdad20e42015-09-29 22:48:52 +0200168 # used by --single
169 self.next_single_test = None
170 self.next_single_filename = None
Victor Stinner3844fe52015-09-26 10:38:01 +0200171
Victor Stinnerdad20e42015-09-29 22:48:52 +0200172 def accumulate_result(self, test, result):
Victor Stinner3844fe52015-09-26 10:38:01 +0200173 ok, test_time = result
Victor Stinnerdad20e42015-09-29 22:48:52 +0200174 self.test_times.append((test_time, test))
Victor Stinner3844fe52015-09-26 10:38:01 +0200175 if ok == PASSED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200176 self.good.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200177 elif ok == FAILED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200178 self.bad.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200179 elif ok == ENV_CHANGED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200180 self.environment_changed.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200181 elif ok == SKIPPED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200182 self.skipped.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200183 elif ok == RESOURCE_DENIED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200184 self.skipped.append(test)
185 self.resource_denieds.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200186
Victor Stinnerdad20e42015-09-29 22:48:52 +0200187 def display_progress(self, test_index, test):
188 if self.ns.quiet:
189 return
190 fmt = "[{1:{0}}{2}/{3}] {4}" if self.bad else "[{1:{0}}{2}] {4}"
Victor Stinner6448b802015-09-29 23:43:33 +0200191 print(fmt.format(self.test_count_width, test_index,
Victor Stinnerf33536c2015-09-30 00:48:27 +0200192 self.test_count, len(self.bad), test),
193 flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200194
Victor Stinnerdad20e42015-09-29 22:48:52 +0200195 def setup_regrtest(self):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200196 if self.ns.findleaks:
197 if gc is not None:
198 # Uncomment the line below to report garbage that is not
199 # freeable by reference counting alone. By default only
200 # garbage that is not collectable by the GC is reported.
201 pass
202 #gc.set_debug(gc.DEBUG_SAVEALL)
203 else:
204 print('No GC available, disabling --findleaks')
205 self.ns.findleaks = False
206
Victor Stinnerdad20e42015-09-29 22:48:52 +0200207 # Strip .py extensions.
208 removepy(self.ns.args)
209
Victor Stinnerdad20e42015-09-29 22:48:52 +0200210 def find_tests(self, tests):
211 self.tests = tests
212
213 if self.ns.single:
214 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
215 try:
216 with open(self.next_single_filename, 'r') as fp:
217 next_test = fp.read().strip()
218 self.tests = [next_test]
219 except OSError:
220 pass
221
222 if self.ns.fromfile:
223 self.tests = []
224 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
225 count_pat = re.compile(r'\[\s*\d+/\s*\d+\]')
226 for line in fp:
227 line = count_pat.sub('', line)
228 guts = line.split() # assuming no test has whitespace in its name
229 if guts and not guts[0].startswith('#'):
230 self.tests.extend(guts)
231
232 removepy(self.tests)
233
234 stdtests = STDTESTS[:]
235 nottests = NOTTESTS.copy()
236 if self.ns.exclude:
237 for arg in self.ns.args:
238 if arg in stdtests:
239 stdtests.remove(arg)
240 nottests.add(arg)
241 self.ns.args = []
242
243 # For a partial run, we do not need to clutter the output.
Victor Stinner6448b802015-09-29 23:43:33 +0200244 if (self.ns.verbose
245 or self.ns.header
246 or not (self.ns.quiet or self.ns.single
247 or self.tests or self.ns.args)):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200248 # Print basic platform information
249 print("==", platform.python_implementation(), *sys.version.split())
250 print("== ", platform.platform(aliased=True),
251 "%s-endian" % sys.byteorder)
252 print("== ", "hash algorithm:", sys.hash_info.algorithm,
253 "64bit" if sys.maxsize > 2**32 else "32bit")
254 print("== ", os.getcwd())
255 print("Testing with flags:", sys.flags)
256
257 # if testdir is set, then we are not running the python tests suite, so
258 # don't add default tests to be executed or skipped (pass empty values)
259 if self.ns.testdir:
260 alltests = findtests(self.ns.testdir, list(), set())
261 else:
262 alltests = findtests(self.ns.testdir, stdtests, nottests)
263
264 self.selected = self.tests or self.ns.args or alltests
265 if self.ns.single:
266 self.selected = self.selected[:1]
267 try:
268 pos = alltests.index(self.selected[0])
269 self.next_single_test = alltests[pos + 1]
270 except IndexError:
271 pass
272
Victor Stinnerc7eab052015-09-30 00:59:35 +0200273 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200274 if self.ns.start:
275 try:
276 del self.selected[:self.selected.index(self.ns.start)]
277 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200278 print("Couldn't find starting test (%s), using all tests"
279 % self.ns.start)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200280
281 if self.ns.randomize:
282 if self.ns.random_seed is None:
283 self.ns.random_seed = random.randrange(10000000)
284 random.seed(self.ns.random_seed)
285 print("Using random seed", self.ns.random_seed)
286 random.shuffle(self.selected)
287
288 def display_result(self):
289 if self.interrupted:
290 # print a newline after ^C
291 print()
292 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200293 executed = set(self.good) | set(self.bad) | set(self.skipped)
294 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200295 print(count(len(omitted), "test"), "omitted:")
296 printlist(omitted)
297
298 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200299 if (not self.bad
300 and not self.skipped
301 and not self.interrupted
302 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200303 print("All", end=' ')
304 print(count(len(self.good), "test"), "OK.")
305
306 if self.ns.print_slow:
307 self.test_times.sort(reverse=True)
308 print("10 slowest tests:")
309 for time, test in self.test_times[:10]:
310 print("%s: %.1fs" % (test, time))
311
312 if self.bad:
313 print(count(len(self.bad), "test"), "failed:")
314 printlist(self.bad)
315
316 if self.environment_changed:
317 print("{} altered the execution environment:".format(
318 count(len(self.environment_changed), "test")))
319 printlist(self.environment_changed)
320
321 if self.skipped and not self.ns.quiet:
322 print(count(len(self.skipped), "test"), "skipped:")
323 printlist(self.skipped)
324
325 if self.ns.verbose2 and self.bad:
326 print("Re-running failed tests in verbose mode")
327 for test in self.bad[:]:
Victor Stinnerf33536c2015-09-30 00:48:27 +0200328 print("Re-running test %r in verbose mode" % test, flush=True)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200329 try:
330 self.ns.verbose = True
331 ok = runtest(test, True, self.ns.quiet, self.ns.huntrleaks,
332 timeout=self.ns.timeout)
333 except KeyboardInterrupt:
334 # print a newline separate from the ^C
335 print()
336 break
337 else:
338 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
339 self.bad.remove(test)
340 else:
341 if self.bad:
342 print(count(len(self.bad), 'test'), "failed again:")
343 printlist(self.bad)
344
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200345 def run_test(self, test):
346 result = runtest(test,
347 self.ns.verbose,
348 self.ns.quiet,
349 self.ns.huntrleaks,
350 output_on_failure=self.ns.verbose3,
351 timeout=self.ns.timeout,
352 failfast=self.ns.failfast,
353 match_tests=self.ns.match_tests)
354 self.accumulate_result(test, result)
355
356 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200357 if self.ns.trace:
358 import trace
359 self.tracer = trace.Trace(ignoredirs=[sys.base_prefix,
360 sys.base_exec_prefix,
361 tempfile.gettempdir()],
362 trace=False, count=True)
363
Victor Stinnerdad20e42015-09-29 22:48:52 +0200364 save_modules = sys.modules.keys()
365
366 for test_index, test in enumerate(self.tests, 1):
367 self.display_progress(test_index, test)
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 Stinnerbd1a72c2015-09-29 23:36:27 +0200371 cmd = 'self.run_test(test)'
Victor Stinnerdad20e42015-09-29 22:48:52 +0200372 self.tracer.runctx(cmd, globals=globals(), locals=vars())
Victor Stinner3844fe52015-09-26 10:38:01 +0200373 else:
374 try:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200375 self.run_test(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200376 except KeyboardInterrupt:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200377 self.interrupted = True
Victor Stinner3844fe52015-09-26 10:38:01 +0200378 break
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200379
Victor Stinnerdad20e42015-09-29 22:48:52 +0200380 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200381 gc.collect()
382 if gc.garbage:
383 print("Warning: test created", len(gc.garbage), end=' ')
384 print("uncollectable object(s).")
385 # move the uncollectable objects somewhere so we don't see
386 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200387 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200388 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200389
Victor Stinner3844fe52015-09-26 10:38:01 +0200390 # Unload the newly imported modules (best effort finalization)
391 for module in sys.modules.keys():
392 if module not in save_modules and module.startswith("test."):
393 support.unload(module)
394
Victor Stinnerdad20e42015-09-29 22:48:52 +0200395 def run_tests(self):
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200396 support.verbose = self.ns.verbose # Tell tests to be moderately quiet
Victor Stinnerdad20e42015-09-29 22:48:52 +0200397 support.use_resources = self.ns.use_resources
Victor Stinner3844fe52015-09-26 10:38:01 +0200398
Victor Stinnerdad20e42015-09-29 22:48:52 +0200399 if self.ns.forever:
400 def test_forever(tests):
401 while True:
402 for test in tests:
403 yield test
404 if self.bad:
405 return
406 self.tests = test_forever(list(self.selected))
407 self.test_count = ''
408 self.test_count_width = 3
409 else:
410 self.tests = iter(self.selected)
411 self.test_count = '/{}'.format(len(self.selected))
412 self.test_count_width = len(self.test_count) - 1
413
414 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200415 from test.libregrtest.runtest_mp import run_tests_multiprocess
416 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200417 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200418 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200419
420 def finalize(self):
421 if self.next_single_filename:
422 if self.next_single_test:
423 with open(self.next_single_filename, 'w') as fp:
424 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200425 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200426 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200427
Victor Stinnerc7eab052015-09-30 00:59:35 +0200428 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200429 r = self.tracer.results()
430 r.write_results(show_missing=True, summary=True,
431 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200432
Victor Stinnerdad20e42015-09-29 22:48:52 +0200433 if self.ns.runleaks:
434 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200435
Victor Stinnerdad20e42015-09-29 22:48:52 +0200436 def main(self, tests=None, **kwargs):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200437 self.ns = _parse_args(sys.argv[1:], **kwargs)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200438 setup_python(self.ns)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200439 self.setup_regrtest()
Victor Stinnerc7eab052015-09-30 00:59:35 +0200440
Victor Stinnerdad20e42015-09-29 22:48:52 +0200441 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200442 from test.libregrtest.runtest_mp import run_tests_slave
443 run_tests_slave(self.ns.slaveargs)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200444 if self.ns.wait:
445 input("Press any key to continue...")
446
Victor Stinnerdad20e42015-09-29 22:48:52 +0200447 self.find_tests(tests)
448 self.run_tests()
Victor Stinnerc7eab052015-09-30 00:59:35 +0200449
Victor Stinnerdad20e42015-09-29 22:48:52 +0200450 self.display_result()
451 self.finalize()
452 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200453
454
Victor Stinner3844fe52015-09-26 10:38:01 +0200455def replace_stdout():
456 """Set stdout encoder error handler to backslashreplace (as stderr error
457 handler) to avoid UnicodeEncodeError when printing a traceback"""
458 import atexit
459
460 stdout = sys.stdout
461 sys.stdout = open(stdout.fileno(), 'w',
462 encoding=stdout.encoding,
463 errors="backslashreplace",
464 closefd=False,
465 newline='\n')
466
467 def restore_stdout():
468 sys.stdout.close()
469 sys.stdout = stdout
470 atexit.register(restore_stdout)
471
472
473def removepy(names):
474 if not names:
475 return
476 for idx, name in enumerate(names):
477 basename, ext = os.path.splitext(name)
478 if ext == '.py':
479 names[idx] = basename
480
481
482def count(n, word):
483 if n == 1:
484 return "%d %s" % (n, word)
485 else:
486 return "%d %ss" % (n, word)
487
488
489def printlist(x, width=70, indent=4):
490 """Print the elements of iterable x to stdout.
491
492 Optional arg width (default 70) is the maximum line length.
493 Optional arg indent (default 4) is the number of blanks with which to
494 begin each line.
495 """
496
Victor Stinner3844fe52015-09-26 10:38:01 +0200497 blanks = ' ' * indent
498 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200499 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
500 initial_indent=blanks, subsequent_indent=blanks))
501
502
503def main(tests=None, **kwargs):
504 Regrtest().main(tests=tests, **kwargs)
Victor Stinner3844fe52015-09-26 10:38:01 +0200505
506
507def main_in_temp_cwd():
508 """Run main() in a temporary working directory."""
509 if sysconfig.is_python_build():
510 try:
511 os.mkdir(TEMPDIR)
512 except FileExistsError:
513 pass
514
515 # Define a writable temp dir that will be used as cwd while running
516 # the tests. The name of the dir includes the pid to allow parallel
517 # testing (see the -j option).
518 test_cwd = 'test_python_{}'.format(os.getpid())
519 test_cwd = os.path.join(TEMPDIR, test_cwd)
520
521 # Run the tests in a context manager that temporarily changes the CWD to a
522 # temporary and writable directory. If it's not possible to create or
523 # change the CWD, the original CWD will be used. The original CWD is
524 # available from support.SAVEDCWD.
525 with support.temp_cwd(test_cwd, quiet=True):
526 main()