blob: b954db5c9d68ef6365f1595b1c4f685b903f786c [file] [log] [blame]
Victor Stinner24f949e2016-03-22 15:14:09 +01001import datetime
Victor Stinner5f9d3ac2015-10-03 00:21:12 +02002import faulthandler
Victor Stinner3844fe52015-09-26 10:38:01 +02003import os
Victor Stinner3844fe52015-09-26 10:38:01 +02004import platform
Victor Stinnerdad20e42015-09-29 22:48:52 +02005import random
6import re
Victor Stinnerdad20e42015-09-29 22:48:52 +02007import sys
8import sysconfig
9import tempfile
10import textwrap
Victor Stinner24f949e2016-03-22 15:14:09 +010011import time
Victor Stinner3909e582015-10-11 10:37:25 +020012from test.libregrtest.cmdline import _parse_args
Victor Stinner3844fe52015-09-26 10:38:01 +020013from test.libregrtest.runtest import (
Victor Stinner6f20a2e2015-09-30 02:32:11 +020014 findtests, runtest,
Victor Stinner3909e582015-10-11 10:37:25 +020015 STDTESTS, NOTTESTS, PASSED, FAILED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED,
Victor Stinner69649f22016-03-23 12:14:10 +010016 INTERRUPTED, CHILD_ERROR,
17 PROGRESS_MIN_TIME)
Victor Stinnera2045022015-09-30 02:17:28 +020018from test.libregrtest.setup import setup_tests
Victor Stinner3844fe52015-09-26 10:38:01 +020019from test import support
20try:
Victor Stinnerdad20e42015-09-29 22:48:52 +020021 import gc
22except ImportError:
23 gc = None
Victor Stinner3844fe52015-09-26 10:38:01 +020024
25
Victor Stinner3844fe52015-09-26 10:38:01 +020026# When tests are run from the Python build directory, it is best practice
27# to keep the test files in a subfolder. This eases the cleanup of leftover
28# files using the "make distclean" command.
29if sysconfig.is_python_build():
30 TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build')
31else:
32 TEMPDIR = tempfile.gettempdir()
33TEMPDIR = os.path.abspath(TEMPDIR)
34
35
Victor Stinnerdad20e42015-09-29 22:48:52 +020036class Regrtest:
Victor Stinner3844fe52015-09-26 10:38:01 +020037 """Execute a test suite.
38
39 This also parses command-line options and modifies its behavior
40 accordingly.
41
42 tests -- a list of strings containing test names (optional)
43 testdir -- the directory in which to look for tests (optional)
44
45 Users other than the Python test suite will certainly want to
46 specify testdir; if it's omitted, the directory containing the
47 Python test suite is searched for.
48
49 If the tests argument is omitted, the tests listed on the
50 command-line will be used. If that's empty, too, then all *.py
51 files beginning with test_ will be used.
52
53 The other default arguments (verbose, quiet, exclude,
54 single, randomize, findleaks, use_resources, trace, coverdir,
55 print_slow, and random_seed) allow programmers calling main()
56 directly to set the values that would normally be set by flags
57 on the command line.
58 """
Victor Stinnerdad20e42015-09-29 22:48:52 +020059 def __init__(self):
60 # Namespace of command line options
61 self.ns = None
Victor Stinner3844fe52015-09-26 10:38:01 +020062
Victor Stinnerdad20e42015-09-29 22:48:52 +020063 # tests
64 self.tests = []
65 self.selected = []
Victor Stinner3844fe52015-09-26 10:38:01 +020066
Victor Stinnerdad20e42015-09-29 22:48:52 +020067 # test results
68 self.good = []
69 self.bad = []
70 self.skipped = []
71 self.resource_denieds = []
72 self.environment_changed = []
73 self.interrupted = False
Victor Stinner3844fe52015-09-26 10:38:01 +020074
Victor Stinnerdad20e42015-09-29 22:48:52 +020075 # used by --slow
76 self.test_times = []
Victor Stinner3844fe52015-09-26 10:38:01 +020077
Victor Stinnerdad20e42015-09-29 22:48:52 +020078 # used by --coverage, trace.Trace instance
79 self.tracer = None
Victor Stinner3844fe52015-09-26 10:38:01 +020080
Victor Stinnerdad20e42015-09-29 22:48:52 +020081 # used by --findleaks, store for gc.garbage
82 self.found_garbage = []
Victor Stinner3844fe52015-09-26 10:38:01 +020083
Victor Stinnerdad20e42015-09-29 22:48:52 +020084 # used to display the progress bar "[ 3/100]"
Victor Stinner24f949e2016-03-22 15:14:09 +010085 self.start_time = time.monotonic()
Victor Stinnerdad20e42015-09-29 22:48:52 +020086 self.test_count = ''
87 self.test_count_width = 1
Victor Stinner3844fe52015-09-26 10:38:01 +020088
Victor Stinnerdad20e42015-09-29 22:48:52 +020089 # used by --single
90 self.next_single_test = None
91 self.next_single_filename = None
Victor Stinner3844fe52015-09-26 10:38:01 +020092
Victor Stinnerdad20e42015-09-29 22:48:52 +020093 def accumulate_result(self, test, result):
Victor Stinner3844fe52015-09-26 10:38:01 +020094 ok, test_time = result
Victor Stinner3909e582015-10-11 10:37:25 +020095 if ok not in (CHILD_ERROR, INTERRUPTED):
96 self.test_times.append((test_time, test))
Victor Stinner3844fe52015-09-26 10:38:01 +020097 if ok == PASSED:
Victor Stinnerdad20e42015-09-29 22:48:52 +020098 self.good.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +020099 elif ok == FAILED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200100 self.bad.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200101 elif ok == ENV_CHANGED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200102 self.environment_changed.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200103 elif ok == SKIPPED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200104 self.skipped.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200105 elif ok == RESOURCE_DENIED:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200106 self.skipped.append(test)
107 self.resource_denieds.append(test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200108
Victor Stinner24f949e2016-03-22 15:14:09 +0100109 def time_delta(self):
110 seconds = time.monotonic() - self.start_time
111 return datetime.timedelta(seconds=int(seconds))
112
Victor Stinnerdad20e42015-09-29 22:48:52 +0200113 def display_progress(self, test_index, test):
114 if self.ns.quiet:
115 return
Brett Cannon11faa212015-10-02 16:20:49 -0700116 if self.bad and not self.ns.pgo:
Victor Stinner24f949e2016-03-22 15:14:09 +0100117 fmt = "{time} [{test_index:{count_width}}{test_count}/{nbad}] {test_name}"
Brett Cannon11faa212015-10-02 16:20:49 -0700118 else:
Victor Stinner24f949e2016-03-22 15:14:09 +0100119 fmt = "{time} [{test_index:{count_width}}{test_count}] {test_name}"
120 line = fmt.format(count_width=self.test_count_width,
121 test_index=test_index,
122 test_count=self.test_count,
123 nbad=len(self.bad),
124 test_name=test,
125 time=self.time_delta())
126 print(line, flush=True)
Victor Stinner3844fe52015-09-26 10:38:01 +0200127
Victor Stinner234cbef2015-09-30 01:13:53 +0200128 def parse_args(self, kwargs):
129 ns = _parse_args(sys.argv[1:], **kwargs)
130
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200131 if ns.timeout and not hasattr(faulthandler, 'dump_traceback_later'):
132 print("Warning: The timeout option requires "
133 "faulthandler.dump_traceback_later", file=sys.stderr)
134 ns.timeout = None
135
Victor Stinner234cbef2015-09-30 01:13:53 +0200136 if ns.threshold is not None and gc is None:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200137 print('No GC available, ignore --threshold.', file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200138 ns.threshold = None
139
140 if ns.findleaks:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200141 if gc is not None:
142 # Uncomment the line below to report garbage that is not
143 # freeable by reference counting alone. By default only
144 # garbage that is not collectable by the GC is reported.
145 pass
146 #gc.set_debug(gc.DEBUG_SAVEALL)
147 else:
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200148 print('No GC available, disabling --findleaks',
149 file=sys.stderr)
Victor Stinner234cbef2015-09-30 01:13:53 +0200150 ns.findleaks = False
Victor Stinnerdad20e42015-09-29 22:48:52 +0200151
Victor Stinnerdad20e42015-09-29 22:48:52 +0200152 # Strip .py extensions.
Victor Stinner234cbef2015-09-30 01:13:53 +0200153 removepy(ns.args)
154
155 return ns
Victor Stinnerdad20e42015-09-29 22:48:52 +0200156
Victor Stinnerdad20e42015-09-29 22:48:52 +0200157 def find_tests(self, tests):
158 self.tests = tests
159
160 if self.ns.single:
161 self.next_single_filename = os.path.join(TEMPDIR, 'pynexttest')
162 try:
163 with open(self.next_single_filename, 'r') as fp:
164 next_test = fp.read().strip()
165 self.tests = [next_test]
166 except OSError:
167 pass
168
169 if self.ns.fromfile:
170 self.tests = []
171 with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp:
172 count_pat = re.compile(r'\[\s*\d+/\s*\d+\]')
173 for line in fp:
174 line = count_pat.sub('', line)
175 guts = line.split() # assuming no test has whitespace in its name
176 if guts and not guts[0].startswith('#'):
177 self.tests.extend(guts)
178
179 removepy(self.tests)
180
181 stdtests = STDTESTS[:]
182 nottests = NOTTESTS.copy()
183 if self.ns.exclude:
184 for arg in self.ns.args:
185 if arg in stdtests:
186 stdtests.remove(arg)
187 nottests.add(arg)
188 self.ns.args = []
189
Victor Stinnerdad20e42015-09-29 22:48:52 +0200190 # if testdir is set, then we are not running the python tests suite, so
191 # don't add default tests to be executed or skipped (pass empty values)
192 if self.ns.testdir:
193 alltests = findtests(self.ns.testdir, list(), set())
194 else:
195 alltests = findtests(self.ns.testdir, stdtests, nottests)
196
197 self.selected = self.tests or self.ns.args or alltests
198 if self.ns.single:
199 self.selected = self.selected[:1]
200 try:
201 pos = alltests.index(self.selected[0])
202 self.next_single_test = alltests[pos + 1]
203 except IndexError:
204 pass
205
Victor Stinnerc7eab052015-09-30 00:59:35 +0200206 # Remove all the selected tests that precede start if it's set.
Victor Stinnerdad20e42015-09-29 22:48:52 +0200207 if self.ns.start:
208 try:
209 del self.selected[:self.selected.index(self.ns.start)]
210 except ValueError:
Victor Stinner6448b802015-09-29 23:43:33 +0200211 print("Couldn't find starting test (%s), using all tests"
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200212 % self.ns.start, file=sys.stderr)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200213
214 if self.ns.randomize:
215 if self.ns.random_seed is None:
216 self.ns.random_seed = random.randrange(10000000)
217 random.seed(self.ns.random_seed)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200218 random.shuffle(self.selected)
219
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200220 def list_tests(self):
221 for name in self.selected:
222 print(name)
223
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200224 def rerun_failed_tests(self):
225 self.ns.verbose = True
226 self.ns.failfast = False
227 self.ns.verbose3 = False
228 self.ns.match_tests = None
229
230 print("Re-running failed tests in verbose mode")
231 for test in self.bad[:]:
232 print("Re-running test %r in verbose mode" % test, flush=True)
233 try:
234 self.ns.verbose = True
235 ok = runtest(self.ns, test)
236 except KeyboardInterrupt:
237 # print a newline separate from the ^C
238 print()
239 break
240 else:
241 if ok[0] in {PASSED, ENV_CHANGED, SKIPPED, RESOURCE_DENIED}:
242 self.bad.remove(test)
243 else:
244 if self.bad:
245 print(count(len(self.bad), 'test'), "failed again:")
246 printlist(self.bad)
247
Victor Stinnerdad20e42015-09-29 22:48:52 +0200248 def display_result(self):
249 if self.interrupted:
250 # print a newline after ^C
251 print()
252 print("Test suite interrupted by signal SIGINT.")
Victor Stinner6448b802015-09-29 23:43:33 +0200253 executed = set(self.good) | set(self.bad) | set(self.skipped)
254 omitted = set(self.selected) - executed
Victor Stinnerdad20e42015-09-29 22:48:52 +0200255 print(count(len(omitted), "test"), "omitted:")
256 printlist(omitted)
257
Brett Cannon11faa212015-10-02 16:20:49 -0700258 # If running the test suite for PGO then no one cares about
259 # results.
260 if self.ns.pgo:
261 return
262
Victor Stinnerdad20e42015-09-29 22:48:52 +0200263 if self.good and not self.ns.quiet:
Victor Stinner6448b802015-09-29 23:43:33 +0200264 if (not self.bad
265 and not self.skipped
266 and not self.interrupted
267 and len(self.good) > 1):
Victor Stinnerdad20e42015-09-29 22:48:52 +0200268 print("All", end=' ')
269 print(count(len(self.good), "test"), "OK.")
270
271 if self.ns.print_slow:
272 self.test_times.sort(reverse=True)
273 print("10 slowest tests:")
274 for time, test in self.test_times[:10]:
275 print("%s: %.1fs" % (test, time))
276
277 if self.bad:
278 print(count(len(self.bad), "test"), "failed:")
279 printlist(self.bad)
280
281 if self.environment_changed:
282 print("{} altered the execution environment:".format(
283 count(len(self.environment_changed), "test")))
284 printlist(self.environment_changed)
285
286 if self.skipped and not self.ns.quiet:
287 print(count(len(self.skipped), "test"), "skipped:")
288 printlist(self.skipped)
289
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200290 def run_tests_sequential(self):
Victor Stinnerc7eab052015-09-30 00:59:35 +0200291 if self.ns.trace:
292 import trace
Victor Stinnera53a8182015-10-01 00:53:09 +0200293 self.tracer = trace.Trace(trace=False, count=True)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200294
Victor Stinnerdad20e42015-09-29 22:48:52 +0200295 save_modules = sys.modules.keys()
296
Victor Stinner69649f22016-03-23 12:14:10 +0100297 previous_test = None
Victor Stinnerdad20e42015-09-29 22:48:52 +0200298 for test_index, test in enumerate(self.tests, 1):
Victor Stinner69649f22016-03-23 12:14:10 +0100299 start_time = time.monotonic()
300
301 text = test
302 if previous_test:
303 text = '%s -- %s' % (text, previous_test)
304 self.display_progress(test_index, text)
305
Victor Stinnerc7eab052015-09-30 00:59:35 +0200306 if self.tracer:
Victor Stinner3844fe52015-09-26 10:38:01 +0200307 # If we're tracing code coverage, then we don't exit with status
308 # if on a false return value from main.
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200309 cmd = ('result = runtest(self.ns, test); '
310 'self.accumulate_result(test, result)')
Victor Stinnerdad20e42015-09-29 22:48:52 +0200311 self.tracer.runctx(cmd, globals=globals(), locals=vars())
Victor Stinner3844fe52015-09-26 10:38:01 +0200312 else:
313 try:
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200314 result = runtest(self.ns, test)
Victor Stinner3844fe52015-09-26 10:38:01 +0200315 except KeyboardInterrupt:
Victor Stinner3909e582015-10-11 10:37:25 +0200316 self.accumulate_result(test, (INTERRUPTED, None))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200317 self.interrupted = True
Victor Stinner3844fe52015-09-26 10:38:01 +0200318 break
Victor Stinner3909e582015-10-11 10:37:25 +0200319 else:
320 self.accumulate_result(test, result)
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200321
Victor Stinner69649f22016-03-23 12:14:10 +0100322 test_time = time.monotonic() - start_time
323 if test_time >= PROGRESS_MIN_TIME:
324 previous_test = '%s took %.0f sec' % (test, test_time)
325 else:
326 previous_test = None
327
Victor Stinnerdad20e42015-09-29 22:48:52 +0200328 if self.ns.findleaks:
Victor Stinner3844fe52015-09-26 10:38:01 +0200329 gc.collect()
330 if gc.garbage:
331 print("Warning: test created", len(gc.garbage), end=' ')
332 print("uncollectable object(s).")
333 # move the uncollectable objects somewhere so we don't see
334 # them again
Victor Stinnerdad20e42015-09-29 22:48:52 +0200335 self.found_garbage.extend(gc.garbage)
Victor Stinner3844fe52015-09-26 10:38:01 +0200336 del gc.garbage[:]
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200337
Victor Stinner3844fe52015-09-26 10:38:01 +0200338 # Unload the newly imported modules (best effort finalization)
339 for module in sys.modules.keys():
340 if module not in save_modules and module.startswith("test."):
341 support.unload(module)
342
Victor Stinner69649f22016-03-23 12:14:10 +0100343 if previous_test:
344 print(previous_test)
345
Victor Stinnerb4084352015-09-30 02:39:22 +0200346 def _test_forever(self, tests):
347 while True:
348 for test in tests:
349 yield test
350 if self.bad:
351 return
Victor Stinner3844fe52015-09-26 10:38:01 +0200352
Victor Stinnerb4084352015-09-30 02:39:22 +0200353 def run_tests(self):
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200354 # For a partial run, we do not need to clutter the output.
355 if (self.ns.verbose
356 or self.ns.header
Brett Cannon11faa212015-10-02 16:20:49 -0700357 or not (self.ns.pgo or self.ns.quiet or self.ns.single
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200358 or self.tests or self.ns.args)):
359 # Print basic platform information
360 print("==", platform.python_implementation(), *sys.version.split())
361 print("== ", platform.platform(aliased=True),
362 "%s-endian" % sys.byteorder)
363 print("== ", "hash algorithm:", sys.hash_info.algorithm,
364 "64bit" if sys.maxsize > 2**32 else "32bit")
365 print("== ", os.getcwd())
366 print("Testing with flags:", sys.flags)
367
368 if self.ns.randomize:
369 print("Using random seed", self.ns.random_seed)
370
Victor Stinnerdad20e42015-09-29 22:48:52 +0200371 if self.ns.forever:
Victor Stinner9a142142015-09-30 13:51:17 +0200372 self.tests = self._test_forever(list(self.selected))
Victor Stinnerdad20e42015-09-29 22:48:52 +0200373 self.test_count = ''
374 self.test_count_width = 3
375 else:
376 self.tests = iter(self.selected)
377 self.test_count = '/{}'.format(len(self.selected))
378 self.test_count_width = len(self.test_count) - 1
379
380 if self.ns.use_mp:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200381 from test.libregrtest.runtest_mp import run_tests_multiprocess
382 run_tests_multiprocess(self)
Victor Stinnerdad20e42015-09-29 22:48:52 +0200383 else:
Victor Stinnerbd1a72c2015-09-29 23:36:27 +0200384 self.run_tests_sequential()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200385
386 def finalize(self):
387 if self.next_single_filename:
388 if self.next_single_test:
389 with open(self.next_single_filename, 'w') as fp:
390 fp.write(self.next_single_test + '\n')
Victor Stinner3844fe52015-09-26 10:38:01 +0200391 else:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200392 os.unlink(self.next_single_filename)
Victor Stinner3844fe52015-09-26 10:38:01 +0200393
Victor Stinnerc7eab052015-09-30 00:59:35 +0200394 if self.tracer:
Victor Stinnerdad20e42015-09-29 22:48:52 +0200395 r = self.tracer.results()
396 r.write_results(show_missing=True, summary=True,
397 coverdir=self.ns.coverdir)
Victor Stinner3844fe52015-09-26 10:38:01 +0200398
Victor Stinner24f949e2016-03-22 15:14:09 +0100399 print("Total duration: %s" % self.time_delta())
400
Victor Stinnerdad20e42015-09-29 22:48:52 +0200401 if self.ns.runleaks:
402 os.system("leaks %d" % os.getpid())
Victor Stinner3844fe52015-09-26 10:38:01 +0200403
Victor Stinnerdad20e42015-09-29 22:48:52 +0200404 def main(self, tests=None, **kwargs):
Victor Stinner234cbef2015-09-30 01:13:53 +0200405 self.ns = self.parse_args(kwargs)
406
Victor Stinnerdad20e42015-09-29 22:48:52 +0200407 if self.ns.slaveargs is not None:
Victor Stinner56e05dd2015-09-29 23:15:38 +0200408 from test.libregrtest.runtest_mp import run_tests_slave
409 run_tests_slave(self.ns.slaveargs)
Victor Stinnerecef6222015-09-30 01:39:28 +0200410
Victor Stinnerc7eab052015-09-30 00:59:35 +0200411 if self.ns.wait:
412 input("Press any key to continue...")
413
Victor Stinnera2045022015-09-30 02:17:28 +0200414 setup_tests(self.ns)
Victor Stinnerecef6222015-09-30 01:39:28 +0200415
Victor Stinnerdad20e42015-09-29 22:48:52 +0200416 self.find_tests(tests)
Victor Stinnerc7eab052015-09-30 00:59:35 +0200417
Victor Stinner5f9d3ac2015-10-03 00:21:12 +0200418 if self.ns.list_tests:
419 self.list_tests()
420 sys.exit(0)
421
422 self.run_tests()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200423 self.display_result()
Victor Stinner6f20a2e2015-09-30 02:32:11 +0200424
425 if self.ns.verbose2 and self.bad:
426 self.rerun_failed_tests()
427
Victor Stinnerdad20e42015-09-29 22:48:52 +0200428 self.finalize()
429 sys.exit(len(self.bad) > 0 or self.interrupted)
Victor Stinner3844fe52015-09-26 10:38:01 +0200430
431
Victor Stinner3844fe52015-09-26 10:38:01 +0200432def removepy(names):
433 if not names:
434 return
435 for idx, name in enumerate(names):
436 basename, ext = os.path.splitext(name)
437 if ext == '.py':
438 names[idx] = basename
439
440
441def count(n, word):
442 if n == 1:
443 return "%d %s" % (n, word)
444 else:
445 return "%d %ss" % (n, word)
446
447
448def printlist(x, width=70, indent=4):
449 """Print the elements of iterable x to stdout.
450
451 Optional arg width (default 70) is the maximum line length.
452 Optional arg indent (default 4) is the number of blanks with which to
453 begin each line.
454 """
455
Victor Stinner3844fe52015-09-26 10:38:01 +0200456 blanks = ' ' * indent
457 # Print the sorted list: 'x' may be a '--random' list or a set()
Victor Stinnerdad20e42015-09-29 22:48:52 +0200458 print(textwrap.fill(' '.join(str(elt) for elt in sorted(x)), width,
459 initial_indent=blanks, subsequent_indent=blanks))
460
461
462def main(tests=None, **kwargs):
463 Regrtest().main(tests=tests, **kwargs)
Victor Stinner3844fe52015-09-26 10:38:01 +0200464
465
466def main_in_temp_cwd():
467 """Run main() in a temporary working directory."""
468 if sysconfig.is_python_build():
469 try:
470 os.mkdir(TEMPDIR)
471 except FileExistsError:
472 pass
473
474 # Define a writable temp dir that will be used as cwd while running
475 # the tests. The name of the dir includes the pid to allow parallel
476 # testing (see the -j option).
477 test_cwd = 'test_python_{}'.format(os.getpid())
478 test_cwd = os.path.join(TEMPDIR, test_cwd)
479
480 # Run the tests in a context manager that temporarily changes the CWD to a
481 # temporary and writable directory. If it's not possible to create or
482 # change the CWD, the original CWD will be used. The original CWD is
483 # available from support.SAVEDCWD.
484 with support.temp_cwd(test_cwd, quiet=True):
485 main()