1#! /usr/bin/env python 2 3""" 4Usage: 5 6python -m test.regrtest [options] [test_name1 [test_name2 ...]] 7python path/to/Lib/test/regrtest.py [options] [test_name1 [test_name2 ...]] 8 9 10If no arguments or options are provided, finds all files matching 11the pattern "test_*" in the Lib/test subdirectory and runs 12them in alphabetical order (but see -M and -u, below, for exceptions). 13 14For more rigorous testing, it is useful to use the following 15command line: 16 17python -E -tt -Wd -3 -m test.regrtest [options] [test_name1 ...] 18 19 20Options: 21 22-h/--help -- print this text and exit 23 24Verbosity 25 26-v/--verbose -- run tests in verbose mode with output to stdout 27-w/--verbose2 -- re-run failed tests in verbose mode 28-W/--verbose3 -- re-run failed tests in verbose mode immediately 29-q/--quiet -- no output unless one or more tests fail 30-S/--slow -- print the slowest 10 tests 31 --header -- print header with interpreter info 32 33Selecting tests 34 35-r/--random -- randomize test execution order (see below) 36 --randseed -- pass a random seed to reproduce a previous random run 37-f/--fromfile -- read names of tests to run from a file (see below) 38-x/--exclude -- arguments are tests to *exclude* 39-s/--single -- single step through a set of tests (see below) 40-u/--use RES1,RES2,... 41 -- specify which special resource intensive tests to run 42-M/--memlimit LIMIT 43 -- run very large memory-consuming tests 44 45Special runs 46 47-l/--findleaks -- if GC is available detect tests that leak memory 48-L/--runleaks -- run the leaks(1) command just before exit 49-R/--huntrleaks RUNCOUNTS 50 -- search for reference leaks (needs debug build, v. slow) 51-j/--multiprocess PROCESSES 52 -- run PROCESSES processes at once 53-T/--coverage -- turn on code coverage tracing using the trace module 54-D/--coverdir DIRECTORY 55 -- Directory where coverage files are put 56-N/--nocoverdir -- Put coverage files alongside modules 57-t/--threshold THRESHOLD 58 -- call gc.set_threshold(THRESHOLD) 59-F/--forever -- run the specified tests in a loop, until an error happens 60 61 62Additional Option Details: 63 64-r randomizes test execution order. You can use --randseed=int to provide a 65int seed value for the randomizer; this is useful for reproducing troublesome 66test orders. 67 68-s On the first invocation of regrtest using -s, the first test file found 69or the first test file given on the command line is run, and the name of 70the next test is recorded in a file named pynexttest. If run from the 71Python build directory, pynexttest is located in the 'build' subdirectory, 72otherwise it is located in tempfile.gettempdir(). On subsequent runs, 73the test in pynexttest is run, and the next test is written to pynexttest. 74When the last test has been run, pynexttest is deleted. In this way it 75is possible to single step through the test files. This is useful when 76doing memory analysis on the Python interpreter, which process tends to 77consume too many resources to run the full regression test non-stop. 78 79-f reads the names of tests from the file given as f's argument, one 80or more test names per line. Whitespace is ignored. Blank lines and 81lines beginning with '#' are ignored. This is especially useful for 82whittling down failures involving interactions among tests. 83 84-L causes the leaks(1) command to be run just before exit if it exists. 85leaks(1) is available on Mac OS X and presumably on some other 86FreeBSD-derived systems. 87 88-R runs each test several times and examines sys.gettotalrefcount() to 89see if the test appears to be leaking references. The argument should 90be of the form stab:run:fname where 'stab' is the number of times the 91test is run to let gettotalrefcount settle down, 'run' is the number 92of times further it is run and 'fname' is the name of the file the 93reports are written to. These parameters all have defaults (5, 4 and 94"reflog.txt" respectively), and the minimal invocation is '-R :'. 95 96-M runs tests that require an exorbitant amount of memory. These tests 97typically try to ascertain containers keep working when containing more than 982 billion objects, which only works on 64-bit systems. There are also some 99tests that try to exhaust the address space of the process, which only makes 100sense on 32-bit systems with at least 2Gb of memory. The passed-in memlimit, 101which is a string in the form of '2.5Gb', determines howmuch memory the 102tests will limit themselves to (but they may go slightly over.) The number 103shouldn't be more memory than the machine has (including swap memory). You 104should also keep in mind that swap memory is generally much, much slower 105than RAM, and setting memlimit to all available RAM or higher will heavily 106tax the machine. On the other hand, it is no use running these tests with a 107limit of less than 2.5Gb, and many require more than 20Gb. Tests that expect 108to use more than memlimit memory will be skipped. The big-memory tests 109generally run very, very long. 110 111-u is used to specify which special resource intensive tests to run, 112such as those requiring large file support or network connectivity. 113The argument is a comma-separated list of words indicating the 114resources to test. Currently only the following are defined: 115 116 all - Enable all special resources. 117 118 audio - Tests that use the audio device. (There are known 119 cases of broken audio drivers that can crash Python or 120 even the Linux kernel.) 121 122 curses - Tests that use curses and will modify the terminal's 123 state and output modes. 124 125 largefile - It is okay to run some test that may create huge 126 files. These tests can take a long time and may 127 consume >2GB of disk space temporarily. 128 129 network - It is okay to run tests that use external network 130 resource, e.g. testing SSL support for sockets. 131 132 bsddb - It is okay to run the bsddb testsuite, which takes 133 a long time to complete. 134 135 decimal - Test the decimal module against a large suite that 136 verifies compliance with standards. 137 138 cpu - Used for certain CPU-heavy tests. 139 140 subprocess Run all tests for the subprocess module. 141 142 urlfetch - It is okay to download files required on testing. 143 144 gui - Run tests that require a running GUI. 145 146 xpickle - Test pickle and cPickle against Python 2.4, 2.5 and 2.6 to 147 test backwards compatibility. These tests take a long time 148 to run. 149 150To enable all resources except one, use '-uall,-<resource>'. For 151example, to run all the tests except for the bsddb tests, give the 152option '-uall,-bsddb'. 153""" 154 155import StringIO 156import getopt 157import json 158import os 159import random 160import re 161import sys 162import time 163import traceback 164import warnings 165import unittest 166import tempfile 167import imp 168import platform 169import sysconfig 170 171 172# Some times __path__ and __file__ are not absolute (e.g. while running from 173# Lib/) and, if we change the CWD to run the tests in a temporary dir, some 174# imports might fail. This affects only the modules imported before os.chdir(). 175# These modules are searched first in sys.path[0] (so '' -- the CWD) and if 176# they are found in the CWD their __file__ and __path__ will be relative (this 177# happens before the chdir). All the modules imported after the chdir, are 178# not found in the CWD, and since the other paths in sys.path[1:] are absolute 179# (site.py absolutize them), the __file__ and __path__ will be absolute too. 180# Therefore it is necessary to absolutize manually the __file__ and __path__ of 181# the packages to prevent later imports to fail when the CWD is different. 182for module in sys.modules.itervalues(): 183 if hasattr(module, '__path__'): 184 module.__path__ = [os.path.abspath(path) for path in module.__path__] 185 if hasattr(module, '__file__'): 186 module.__file__ = os.path.abspath(module.__file__) 187 188 189# MacOSX (a.k.a. Darwin) has a default stack size that is too small 190# for deeply recursive regular expressions. We see this as crashes in 191# the Python test suite when running test_re.py and test_sre.py. The 192# fix is to set the stack limit to 2048. 193# This approach may also be useful for other Unixy platforms that 194# suffer from small default stack limits. 195if sys.platform == 'darwin': 196 try: 197 import resource 198 except ImportError: 199 pass 200 else: 201 soft, hard = resource.getrlimit(resource.RLIMIT_STACK) 202 newsoft = min(hard, max(soft, 1024*2048)) 203 resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard)) 204 205# Test result constants. 206PASSED = 1 207FAILED = 0 208ENV_CHANGED = -1 209SKIPPED = -2 210RESOURCE_DENIED = -3 211INTERRUPTED = -4 212 213from test import test_support 214 215RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', 'bsddb', 216 'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui', 217 'xpickle') 218 219TEMPDIR = os.path.abspath(tempfile.gettempdir()) 220 221 222def usage(code, msg=''): 223 print __doc__ 224 if msg: print msg 225 sys.exit(code) 226 227 228def main(tests=None, testdir=None, verbose=0, quiet=False, 229 exclude=False, single=False, randomize=False, fromfile=None, 230 findleaks=False, use_resources=None, trace=False, coverdir='coverage', 231 runleaks=False, huntrleaks=False, verbose2=False, print_slow=False, 232 random_seed=None, use_mp=None, verbose3=False, forever=False, 233 header=False): 234 """Execute a test suite. 235 236 This also parses command-line options and modifies its behavior 237 accordingly. 238 239 tests -- a list of strings containing test names (optional) 240 testdir -- the directory in which to look for tests (optional) 241 242 Users other than the Python test suite will certainly want to 243 specify testdir; if it's omitted, the directory containing the 244 Python test suite is searched for. 245 246 If the tests argument is omitted, the tests listed on the 247 command-line will be used. If that's empty, too, then all *.py 248 files beginning with test_ will be used. 249 250 The other default arguments (verbose, quiet, exclude, 251 single, randomize, findleaks, use_resources, trace, coverdir, 252 print_slow, and random_seed) allow programmers calling main() 253 directly to set the values that would normally be set by flags 254 on the command line. 255 """ 256 257 test_support.record_original_stdout(sys.stdout) 258 try: 259 opts, args = getopt.getopt(sys.argv[1:], 'hvqxsSrf:lu:t:TD:NLR:FwWM:j:', 260 ['help', 'verbose', 'verbose2', 'verbose3', 'quiet', 261 'exclude', 'single', 'slow', 'random', 'fromfile', 'findleaks', 262 'use=', 'threshold=', 'trace', 'coverdir=', 'nocoverdir', 263 'runleaks', 'huntrleaks=', 'memlimit=', 'randseed=', 264 'multiprocess=', 'slaveargs=', 'forever', 'header']) 265 except getopt.error, msg: 266 usage(2, msg) 267 268 # Defaults 269 if random_seed is None: 270 random_seed = random.randrange(10000000) 271 if use_resources is None: 272 use_resources = [] 273 for o, a in opts: 274 if o in ('-h', '--help'): 275 usage(0) 276 elif o in ('-v', '--verbose'): 277 verbose += 1 278 elif o in ('-w', '--verbose2'): 279 verbose2 = True 280 elif o in ('-W', '--verbose3'): 281 verbose3 = True 282 elif o in ('-q', '--quiet'): 283 quiet = True; 284 verbose = 0 285 elif o in ('-x', '--exclude'): 286 exclude = True 287 elif o in ('-s', '--single'): 288 single = True 289 elif o in ('-S', '--slow'): 290 print_slow = True 291 elif o in ('-r', '--randomize'): 292 randomize = True 293 elif o == '--randseed': 294 random_seed = int(a) 295 elif o in ('-f', '--fromfile'): 296 fromfile = a 297 elif o in ('-l', '--findleaks'): 298 findleaks = True 299 elif o in ('-L', '--runleaks'): 300 runleaks = True 301 elif o in ('-t', '--threshold'): 302 import gc 303 gc.set_threshold(int(a)) 304 elif o in ('-T', '--coverage'): 305 trace = True 306 elif o in ('-D', '--coverdir'): 307 coverdir = os.path.join(os.getcwd(), a) 308 elif o in ('-N', '--nocoverdir'): 309 coverdir = None 310 elif o in ('-R', '--huntrleaks'): 311 huntrleaks = a.split(':') 312 if len(huntrleaks) not in (2, 3): 313 print a, huntrleaks 314 usage(2, '-R takes 2 or 3 colon-separated arguments') 315 if not huntrleaks[0]: 316 huntrleaks[0] = 5 317 else: 318 huntrleaks[0] = int(huntrleaks[0]) 319 if not huntrleaks[1]: 320 huntrleaks[1] = 4 321 else: 322 huntrleaks[1] = int(huntrleaks[1]) 323 if len(huntrleaks) == 2 or not huntrleaks[2]: 324 huntrleaks[2:] = ["reflog.txt"] 325 elif o in ('-M', '--memlimit'): 326 test_support.set_memlimit(a) 327 elif o in ('-u', '--use'): 328 u = [x.lower() for x in a.split(',')] 329 for r in u: 330 if r == 'all': 331 use_resources[:] = RESOURCE_NAMES 332 continue 333 remove = False 334 if r[0] == '-': 335 remove = True 336 r = r[1:] 337 if r not in RESOURCE_NAMES: 338 usage(1, 'Invalid -u/--use option: ' + a) 339 if remove: 340 if r in use_resources: 341 use_resources.remove(r) 342 elif r not in use_resources: 343 use_resources.append(r) 344 elif o in ('-F', '--forever'): 345 forever = True 346 elif o in ('-j', '--multiprocess'): 347 use_mp = int(a) 348 elif o == '--header': 349 header = True 350 elif o == '--slaveargs': 351 args, kwargs = json.loads(a) 352 try: 353 result = runtest(*args, **kwargs) 354 except BaseException, e: 355 result = INTERRUPTED, e.__class__.__name__ 356 print # Force a newline (just in case) 357 print json.dumps(result) 358 sys.exit(0) 359 else: 360 print >>sys.stderr, ("No handler for option {}. Please " 361 "report this as a bug at http://bugs.python.org.").format(o) 362 sys.exit(1) 363 if single and fromfile: 364 usage(2, "-s and -f don't go together!") 365 if use_mp and trace: 366 usage(2, "-T and -j don't go together!") 367 if use_mp and findleaks: 368 usage(2, "-l and -j don't go together!") 369 370 good = [] 371 bad = [] 372 skipped = [] 373 resource_denieds = [] 374 environment_changed = [] 375 interrupted = False 376 377 if findleaks: 378 try: 379 import gc 380 except ImportError: 381 print 'No GC available, disabling findleaks.' 382 findleaks = False 383 else: 384 # Uncomment the line below to report garbage that is not 385 # freeable by reference counting alone. By default only 386 # garbage that is not collectable by the GC is reported. 387 #gc.set_debug(gc.DEBUG_SAVEALL) 388 found_garbage = [] 389 390 if single: 391 filename = os.path.join(TEMPDIR, 'pynexttest') 392 try: 393 fp = open(filename, 'r') 394 next_test = fp.read().strip() 395 tests = [next_test] 396 fp.close() 397 except IOError: 398 pass 399 400 if fromfile: 401 tests = [] 402 fp = open(os.path.join(test_support.SAVEDCWD, fromfile)) 403 for line in fp: 404 guts = line.split() # assuming no test has whitespace in its name 405 if guts and not guts[0].startswith('#'): 406 tests.extend(guts) 407 fp.close() 408 409 # Strip .py extensions. 410 removepy(args) 411 removepy(tests) 412 413 stdtests = STDTESTS[:] 414 nottests = NOTTESTS.copy() 415 if exclude: 416 for arg in args: 417 if arg in stdtests: 418 stdtests.remove(arg) 419 nottests.add(arg) 420 args = [] 421 422 # For a partial run, we do not need to clutter the output. 423 if verbose or header or not (quiet or single or tests or args): 424 # Print basic platform information 425 print "==", platform.python_implementation(), \ 426 " ".join(sys.version.split()) 427 print "== ", platform.platform(aliased=True), \ 428 "%s-endian" % sys.byteorder 429 print "== ", os.getcwd() 430 print "Testing with flags:", sys.flags 431 432 alltests = findtests(testdir, stdtests, nottests) 433 selected = tests or args or alltests 434 if single: 435 selected = selected[:1] 436 try: 437 next_single_test = alltests[alltests.index(selected[0])+1] 438 except IndexError: 439 next_single_test = None 440 if randomize: 441 random.seed(random_seed) 442 print "Using random seed", random_seed 443 random.shuffle(selected) 444 if trace: 445 import trace 446 tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix], 447 trace=False, count=True) 448 449 test_times = [] 450 test_support.use_resources = use_resources 451 save_modules = sys.modules.keys() 452 453 def accumulate_result(test, result): 454 ok, test_time = result 455 test_times.append((test_time, test)) 456 if ok == PASSED: 457 good.append(test) 458 elif ok == FAILED: 459 bad.append(test) 460 elif ok == ENV_CHANGED: 461 bad.append(test) 462 environment_changed.append(test) 463 elif ok == SKIPPED: 464 skipped.append(test) 465 elif ok == RESOURCE_DENIED: 466 skipped.append(test) 467 resource_denieds.append(test) 468 469 if forever: 470 def test_forever(tests=list(selected)): 471 while True: 472 for test in tests: 473 yield test 474 if bad: 475 return 476 tests = test_forever() 477 else: 478 tests = iter(selected) 479 480 if use_mp: 481 try: 482 from threading import Thread 483 except ImportError: 484 print "Multiprocess option requires thread support" 485 sys.exit(2) 486 from Queue import Queue 487 from subprocess import Popen, PIPE 488 debug_output_pat = re.compile(r"\[\d+ refs\]$") 489 output = Queue() 490 def tests_and_args(): 491 for test in tests: 492 args_tuple = ( 493 (test, verbose, quiet), 494 dict(huntrleaks=huntrleaks, use_resources=use_resources) 495 ) 496 yield (test, args_tuple) 497 pending = tests_and_args() 498 opt_args = test_support.args_from_interpreter_flags() 499 base_cmd = [sys.executable] + opt_args + ['-m', 'test.regrtest'] 500 def work(): 501 # A worker thread. 502 try: 503 while True: 504 try: 505 test, args_tuple = next(pending) 506 except StopIteration: 507 output.put((None, None, None, None)) 508 return 509 # -E is needed by some tests, e.g. test_import 510 popen = Popen(base_cmd + ['--slaveargs', json.dumps(args_tuple)], 511 stdout=PIPE, stderr=PIPE, 512 universal_newlines=True, 513 close_fds=(os.name != 'nt')) 514 stdout, stderr = popen.communicate() 515 # Strip last refcount output line if it exists, since it 516 # comes from the shutdown of the interpreter in the subcommand. 517 stderr = debug_output_pat.sub("", stderr) 518 stdout, _, result = stdout.strip().rpartition("\n") 519 if not result: 520 output.put((None, None, None, None)) 521 return 522 result = json.loads(result) 523 if not quiet: 524 stdout = test+'\n'+stdout 525 output.put((test, stdout.rstrip(), stderr.rstrip(), result)) 526 except BaseException: 527 output.put((None, None, None, None)) 528 raise 529 workers = [Thread(target=work) for i in range(use_mp)] 530 for worker in workers: 531 worker.start() 532 finished = 0 533 try: 534 while finished < use_mp: 535 test, stdout, stderr, result = output.get() 536 if test is None: 537 finished += 1 538 continue 539 if stdout: 540 print stdout 541 if stderr: 542 print >>sys.stderr, stderr 543 if result[0] == INTERRUPTED: 544 assert result[1] == 'KeyboardInterrupt' 545 raise KeyboardInterrupt # What else? 546 accumulate_result(test, result) 547 except KeyboardInterrupt: 548 interrupted = True 549 pending.close() 550 for worker in workers: 551 worker.join() 552 else: 553 for test in tests: 554 if not quiet: 555 print test 556 sys.stdout.flush() 557 if trace: 558 # If we're tracing code coverage, then we don't exit with status 559 # if on a false return value from main. 560 tracer.runctx('runtest(test, verbose, quiet)', 561 globals=globals(), locals=vars()) 562 else: 563 try: 564 result = runtest(test, verbose, quiet, huntrleaks) 565 accumulate_result(test, result) 566 if verbose3 and result[0] == FAILED: 567 print "Re-running test %r in verbose mode" % test 568 runtest(test, True, quiet, huntrleaks) 569 except KeyboardInterrupt: 570 interrupted = True 571 break 572 except: 573 raise 574 if findleaks: 575 gc.collect() 576 if gc.garbage: 577 print "Warning: test created", len(gc.garbage), 578 print "uncollectable object(s)." 579 # move the uncollectable objects somewhere so we don't see 580 # them again 581 found_garbage.extend(gc.garbage) 582 del gc.garbage[:] 583 # Unload the newly imported modules (best effort finalization) 584 for module in sys.modules.keys(): 585 if module not in save_modules and module.startswith("test."): 586 test_support.unload(module) 587 588 if interrupted: 589 # print a newline after ^C 590 print 591 print "Test suite interrupted by signal SIGINT." 592 omitted = set(selected) - set(good) - set(bad) - set(skipped) 593 print count(len(omitted), "test"), "omitted:" 594 printlist(omitted) 595 if good and not quiet: 596 if not bad and not skipped and not interrupted and len(good) > 1: 597 print "All", 598 print count(len(good), "test"), "OK." 599 if print_slow: 600 test_times.sort(reverse=True) 601 print "10 slowest tests:" 602 for time, test in test_times[:10]: 603 print "%s: %.1fs" % (test, time) 604 if bad: 605 bad = set(bad) - set(environment_changed) 606 if bad: 607 print count(len(bad), "test"), "failed:" 608 printlist(bad) 609 if environment_changed: 610 print "{} altered the execution environment:".format( 611 count(len(environment_changed), "test")) 612 printlist(environment_changed) 613 if skipped and not quiet: 614 print count(len(skipped), "test"), "skipped:" 615 printlist(skipped) 616 617 e = _ExpectedSkips() 618 plat = sys.platform 619 if e.isvalid(): 620 surprise = set(skipped) - e.getexpected() - set(resource_denieds) 621 if surprise: 622 print count(len(surprise), "skip"), \ 623 "unexpected on", plat + ":" 624 printlist(surprise) 625 else: 626 print "Those skips are all expected on", plat + "." 627 else: 628 print "Ask someone to teach regrtest.py about which tests are" 629 print "expected to get skipped on", plat + "." 630 631 if verbose2 and bad: 632 print "Re-running failed tests in verbose mode" 633 for test in bad: 634 print "Re-running test %r in verbose mode" % test 635 sys.stdout.flush() 636 try: 637 test_support.verbose = True 638 ok = runtest(test, True, quiet, huntrleaks) 639 except KeyboardInterrupt: 640 # print a newline separate from the ^C 641 print 642 break 643 except: 644 raise 645 646 if single: 647 if next_single_test: 648 with open(filename, 'w') as fp: 649 fp.write(next_single_test + '\n') 650 else: 651 os.unlink(filename) 652 653 if trace: 654 r = tracer.results() 655 r.write_results(show_missing=True, summary=True, coverdir=coverdir) 656 657 if runleaks: 658 os.system("leaks %d" % os.getpid()) 659 660 sys.exit(len(bad) > 0 or interrupted) 661 662 663STDTESTS = [ 664 'test_grammar', 665 'test_opcodes', 666 'test_dict', 667 'test_builtin', 668 'test_exceptions', 669 'test_types', 670 'test_unittest', 671 'test_doctest', 672 'test_doctest2', 673] 674 675NOTTESTS = { 676 'test_support', 677 'test_future1', 678 'test_future2', 679} 680 681def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS): 682 """Return a list of all applicable test modules.""" 683 testdir = findtestdir(testdir) 684 names = os.listdir(testdir) 685 tests = [] 686 others = set(stdtests) | nottests 687 for name in names: 688 modname, ext = os.path.splitext(name) 689 if modname[:5] == "test_" and ext == ".py" and modname not in others: 690 tests.append(modname) 691 return stdtests + sorted(tests) 692 693def runtest(test, verbose, quiet, 694 huntrleaks=False, use_resources=None): 695 """Run a single test. 696 697 test -- the name of the test 698 verbose -- if true, print more messages 699 quiet -- if true, don't print 'skipped' messages (probably redundant) 700 test_times -- a list of (time, test_name) pairs 701 huntrleaks -- run multiple times to test for leaks; requires a debug 702 build; a triple corresponding to -R's three arguments 703 Returns one of the test result constants: 704 INTERRUPTED KeyboardInterrupt when run under -j 705 RESOURCE_DENIED test skipped because resource denied 706 SKIPPED test skipped for some other reason 707 ENV_CHANGED test failed because it changed the execution environment 708 FAILED test failed 709 PASSED test passed 710 """ 711 712 test_support.verbose = verbose # Tell tests to be moderately quiet 713 if use_resources is not None: 714 test_support.use_resources = use_resources 715 try: 716 return runtest_inner(test, verbose, quiet, huntrleaks) 717 finally: 718 cleanup_test_droppings(test, verbose) 719 720 721# Unit tests are supposed to leave the execution environment unchanged 722# once they complete. But sometimes tests have bugs, especially when 723# tests fail, and the changes to environment go on to mess up other 724# tests. This can cause issues with buildbot stability, since tests 725# are run in random order and so problems may appear to come and go. 726# There are a few things we can save and restore to mitigate this, and 727# the following context manager handles this task. 728 729class saved_test_environment: 730 """Save bits of the test environment and restore them at block exit. 731 732 with saved_test_environment(testname, verbose, quiet): 733 #stuff 734 735 Unless quiet is True, a warning is printed to stderr if any of 736 the saved items was changed by the test. The attribute 'changed' 737 is initially False, but is set to True if a change is detected. 738 739 If verbose is more than 1, the before and after state of changed 740 items is also printed. 741 """ 742 743 changed = False 744 745 def __init__(self, testname, verbose=0, quiet=False): 746 self.testname = testname 747 self.verbose = verbose 748 self.quiet = quiet 749 750 # To add things to save and restore, add a name XXX to the resources list 751 # and add corresponding get_XXX/restore_XXX functions. get_XXX should 752 # return the value to be saved and compared against a second call to the 753 # get function when test execution completes. restore_XXX should accept 754 # the saved value and restore the resource using it. It will be called if 755 # and only if a change in the value is detected. 756 # 757 # Note: XXX will have any '.' replaced with '_' characters when determining 758 # the corresponding method names. 759 760 resources = ('sys.argv', 'cwd', 'sys.stdin', 'sys.stdout', 'sys.stderr', 761 'os.environ', 'sys.path', 'asyncore.socket_map') 762 763 def get_sys_argv(self): 764 return id(sys.argv), sys.argv, sys.argv[:] 765 def restore_sys_argv(self, saved_argv): 766 sys.argv = saved_argv[1] 767 sys.argv[:] = saved_argv[2] 768 769 def get_cwd(self): 770 return os.getcwd() 771 def restore_cwd(self, saved_cwd): 772 os.chdir(saved_cwd) 773 774 def get_sys_stdout(self): 775 return sys.stdout 776 def restore_sys_stdout(self, saved_stdout): 777 sys.stdout = saved_stdout 778 779 def get_sys_stderr(self): 780 return sys.stderr 781 def restore_sys_stderr(self, saved_stderr): 782 sys.stderr = saved_stderr 783 784 def get_sys_stdin(self): 785 return sys.stdin 786 def restore_sys_stdin(self, saved_stdin): 787 sys.stdin = saved_stdin 788 789 def get_os_environ(self): 790 return id(os.environ), os.environ, dict(os.environ) 791 def restore_os_environ(self, saved_environ): 792 os.environ = saved_environ[1] 793 os.environ.clear() 794 os.environ.update(saved_environ[2]) 795 796 def get_sys_path(self): 797 return id(sys.path), sys.path, sys.path[:] 798 def restore_sys_path(self, saved_path): 799 sys.path = saved_path[1] 800 sys.path[:] = saved_path[2] 801 802 def get_asyncore_socket_map(self): 803 asyncore = sys.modules.get('asyncore') 804 # XXX Making a copy keeps objects alive until __exit__ gets called. 805 return asyncore and asyncore.socket_map.copy() or {} 806 def restore_asyncore_socket_map(self, saved_map): 807 asyncore = sys.modules.get('asyncore') 808 if asyncore is not None: 809 asyncore.close_all(ignore_all=True) 810 asyncore.socket_map.update(saved_map) 811 812 def resource_info(self): 813 for name in self.resources: 814 method_suffix = name.replace('.', '_') 815 get_name = 'get_' + method_suffix 816 restore_name = 'restore_' + method_suffix 817 yield name, getattr(self, get_name), getattr(self, restore_name) 818 819 def __enter__(self): 820 self.saved_values = dict((name, get()) for name, get, restore 821 in self.resource_info()) 822 return self 823 824 def __exit__(self, exc_type, exc_val, exc_tb): 825 saved_values = self.saved_values 826 del self.saved_values 827 for name, get, restore in self.resource_info(): 828 current = get() 829 original = saved_values.pop(name) 830 # Check for changes to the resource's value 831 if current != original: 832 self.changed = True 833 restore(original) 834 if not self.quiet: 835 print >>sys.stderr, ( 836 "Warning -- {} was modified by {}".format( 837 name, self.testname)) 838 if self.verbose > 1: 839 print >>sys.stderr, ( 840 " Before: {}\n After: {} ".format( 841 original, current)) 842 # XXX (ncoghlan): for most resources (e.g. sys.path) identity 843 # matters at least as much as value. For others (e.g. cwd), 844 # identity is irrelevant. Should we add a mechanism to check 845 # for substitution in the cases where it matters? 846 return False 847 848 849def runtest_inner(test, verbose, quiet, huntrleaks=False): 850 test_support.unload(test) 851 if verbose: 852 capture_stdout = None 853 else: 854 capture_stdout = StringIO.StringIO() 855 856 test_time = 0.0 857 refleak = False # True if the test leaked references. 858 try: 859 save_stdout = sys.stdout 860 try: 861 if capture_stdout: 862 sys.stdout = capture_stdout 863 if test.startswith('test.'): 864 abstest = test 865 else: 866 # Always import it from the test package 867 abstest = 'test.' + test 868 with saved_test_environment(test, verbose, quiet) as environment: 869 start_time = time.time() 870 the_package = __import__(abstest, globals(), locals(), []) 871 the_module = getattr(the_package, test) 872 # Old tests run to completion simply as a side-effect of 873 # being imported. For tests based on unittest or doctest, 874 # explicitly invoke their test_main() function (if it exists). 875 indirect_test = getattr(the_module, "test_main", None) 876 if indirect_test is not None: 877 indirect_test() 878 if huntrleaks: 879 refleak = dash_R(the_module, test, indirect_test, 880 huntrleaks) 881 test_time = time.time() - start_time 882 finally: 883 sys.stdout = save_stdout 884 except test_support.ResourceDenied, msg: 885 if not quiet: 886 print test, "skipped --", msg 887 sys.stdout.flush() 888 return RESOURCE_DENIED, test_time 889 except unittest.SkipTest, msg: 890 if not quiet: 891 print test, "skipped --", msg 892 sys.stdout.flush() 893 return SKIPPED, test_time 894 except KeyboardInterrupt: 895 raise 896 except test_support.TestFailed, msg: 897 print >>sys.stderr, "test", test, "failed --", msg 898 sys.stderr.flush() 899 return FAILED, test_time 900 except: 901 type, value = sys.exc_info()[:2] 902 print >>sys.stderr, "test", test, "crashed --", str(type) + ":", value 903 sys.stderr.flush() 904 if verbose: 905 traceback.print_exc(file=sys.stderr) 906 sys.stderr.flush() 907 return FAILED, test_time 908 else: 909 if refleak: 910 return FAILED, test_time 911 if environment.changed: 912 return ENV_CHANGED, test_time 913 # Except in verbose mode, tests should not print anything 914 if verbose or huntrleaks: 915 return PASSED, test_time 916 output = capture_stdout.getvalue() 917 if not output: 918 return PASSED, test_time 919 print "test", test, "produced unexpected output:" 920 print "*" * 70 921 print output 922 print "*" * 70 923 sys.stdout.flush() 924 return FAILED, test_time 925 926def cleanup_test_droppings(testname, verbose): 927 import shutil 928 import stat 929 import gc 930 931 # First kill any dangling references to open files etc. 932 gc.collect() 933 934 # Try to clean up junk commonly left behind. While tests shouldn't leave 935 # any files or directories behind, when a test fails that can be tedious 936 # for it to arrange. The consequences can be especially nasty on Windows, 937 # since if a test leaves a file open, it cannot be deleted by name (while 938 # there's nothing we can do about that here either, we can display the 939 # name of the offending test, which is a real help). 940 for name in (test_support.TESTFN, 941 "db_home", 942 ): 943 if not os.path.exists(name): 944 continue 945 946 if os.path.isdir(name): 947 kind, nuker = "directory", shutil.rmtree 948 elif os.path.isfile(name): 949 kind, nuker = "file", os.unlink 950 else: 951 raise SystemError("os.path says %r exists but is neither " 952 "directory nor file" % name) 953 954 if verbose: 955 print "%r left behind %s %r" % (testname, kind, name) 956 try: 957 # if we have chmod, fix possible permissions problems 958 # that might prevent cleanup 959 if (hasattr(os, 'chmod')): 960 os.chmod(name, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) 961 nuker(name) 962 except Exception, msg: 963 print >> sys.stderr, ("%r left behind %s %r and it couldn't be " 964 "removed: %s" % (testname, kind, name, msg)) 965 966def dash_R(the_module, test, indirect_test, huntrleaks): 967 """Run a test multiple times, looking for reference leaks. 968 969 Returns: 970 False if the test didn't leak references; True if we detected refleaks. 971 """ 972 # This code is hackish and inelegant, but it seems to do the job. 973 import copy_reg, _abcoll, _pyio 974 975 if not hasattr(sys, 'gettotalrefcount'): 976 raise Exception("Tracking reference leaks requires a debug build " 977 "of Python") 978 979 # Save current values for dash_R_cleanup() to restore. 980 fs = warnings.filters[:] 981 ps = copy_reg.dispatch_table.copy() 982 pic = sys.path_importer_cache.copy() 983 try: 984 import zipimport 985 except ImportError: 986 zdc = None # Run unmodified on platforms without zipimport support 987 else: 988 zdc = zipimport._zip_directory_cache.copy() 989 abcs = {} 990 modules = _abcoll, _pyio 991 for abc in [getattr(mod, a) for mod in modules for a in mod.__all__]: 992 # XXX isinstance(abc, ABCMeta) leads to infinite recursion 993 if not hasattr(abc, '_abc_registry'): 994 continue 995 for obj in abc.__subclasses__() + [abc]: 996 abcs[obj] = obj._abc_registry.copy() 997 998 if indirect_test: 999 def run_the_test(): 1000 indirect_test() 1001 else: 1002 def run_the_test(): 1003 imp.reload(the_module) 1004 1005 deltas = [] 1006 nwarmup, ntracked, fname = huntrleaks 1007 fname = os.path.join(test_support.SAVEDCWD, fname) 1008 repcount = nwarmup + ntracked 1009 print >> sys.stderr, "beginning", repcount, "repetitions" 1010 print >> sys.stderr, ("1234567890"*(repcount//10 + 1))[:repcount] 1011 dash_R_cleanup(fs, ps, pic, zdc, abcs) 1012 for i in range(repcount): 1013 rc_before = sys.gettotalrefcount() 1014 run_the_test() 1015 sys.stderr.write('.') 1016 dash_R_cleanup(fs, ps, pic, zdc, abcs) 1017 rc_after = sys.gettotalrefcount() 1018 if i >= nwarmup: 1019 deltas.append(rc_after - rc_before) 1020 print >> sys.stderr 1021 if any(deltas): 1022 msg = '%s leaked %s references, sum=%s' % (test, deltas, sum(deltas)) 1023 print >> sys.stderr, msg 1024 with open(fname, "a") as refrep: 1025 print >> refrep, msg 1026 refrep.flush() 1027 return True 1028 return False 1029 1030def dash_R_cleanup(fs, ps, pic, zdc, abcs): 1031 import gc, copy_reg 1032 import _strptime, linecache 1033 dircache = test_support.import_module('dircache', deprecated=True) 1034 import urlparse, urllib, urllib2, mimetypes, doctest 1035 import struct, filecmp 1036 from distutils.dir_util import _path_created 1037 1038 # Clear the warnings registry, so they can be displayed again 1039 for mod in sys.modules.values(): 1040 if hasattr(mod, '__warningregistry__'): 1041 del mod.__warningregistry__ 1042 1043 # Restore some original values. 1044 warnings.filters[:] = fs 1045 copy_reg.dispatch_table.clear() 1046 copy_reg.dispatch_table.update(ps) 1047 sys.path_importer_cache.clear() 1048 sys.path_importer_cache.update(pic) 1049 try: 1050 import zipimport 1051 except ImportError: 1052 pass # Run unmodified on platforms without zipimport support 1053 else: 1054 zipimport._zip_directory_cache.clear() 1055 zipimport._zip_directory_cache.update(zdc) 1056 1057 # clear type cache 1058 sys._clear_type_cache() 1059 1060 # Clear ABC registries, restoring previously saved ABC registries. 1061 for abc, registry in abcs.items(): 1062 abc._abc_registry = registry.copy() 1063 abc._abc_cache.clear() 1064 abc._abc_negative_cache.clear() 1065 1066 # Clear assorted module caches. 1067 _path_created.clear() 1068 re.purge() 1069 _strptime._regex_cache.clear() 1070 urlparse.clear_cache() 1071 urllib.urlcleanup() 1072 urllib2.install_opener(None) 1073 dircache.reset() 1074 linecache.clearcache() 1075 mimetypes._default_mime_types() 1076 filecmp._cache.clear() 1077 struct._clearcache() 1078 doctest.master = None 1079 1080 # Collect cyclic trash. 1081 gc.collect() 1082 1083def findtestdir(path=None): 1084 return path or os.path.dirname(__file__) or os.curdir 1085 1086def removepy(names): 1087 if not names: 1088 return 1089 for idx, name in enumerate(names): 1090 basename, ext = os.path.splitext(name) 1091 if ext == '.py': 1092 names[idx] = basename 1093 1094def count(n, word): 1095 if n == 1: 1096 return "%d %s" % (n, word) 1097 else: 1098 return "%d %ss" % (n, word) 1099 1100def printlist(x, width=70, indent=4): 1101 """Print the elements of iterable x to stdout. 1102 1103 Optional arg width (default 70) is the maximum line length. 1104 Optional arg indent (default 4) is the number of blanks with which to 1105 begin each line. 1106 """ 1107 1108 from textwrap import fill 1109 blanks = ' ' * indent 1110 # Print the sorted list: 'x' may be a '--random' list or a set() 1111 print fill(' '.join(str(elt) for elt in sorted(x)), width, 1112 initial_indent=blanks, subsequent_indent=blanks) 1113 1114# Map sys.platform to a string containing the basenames of tests 1115# expected to be skipped on that platform. 1116# 1117# Special cases: 1118# test_pep277 1119# The _ExpectedSkips constructor adds this to the set of expected 1120# skips if not os.path.supports_unicode_filenames. 1121# test_timeout 1122# Controlled by test_timeout.skip_expected. Requires the network 1123# resource and a socket module. 1124# 1125# Tests that are expected to be skipped everywhere except on one platform 1126# are also handled separately. 1127 1128_expectations = { 1129 'win32': 1130 """ 1131 test__locale 1132 test_bsddb185 1133 test_bsddb3 1134 test_commands 1135 test_crypt 1136 test_curses 1137 test_dbm 1138 test_dl 1139 test_fcntl 1140 test_fork1 1141 test_epoll 1142 test_gdbm 1143 test_grp 1144 test_ioctl 1145 test_largefile 1146 test_kqueue 1147 test_mhlib 1148 test_openpty 1149 test_ossaudiodev 1150 test_pipes 1151 test_poll 1152 test_posix 1153 test_pty 1154 test_pwd 1155 test_resource 1156 test_signal 1157 test_threadsignals 1158 test_timing 1159 test_wait3 1160 test_wait4 1161 """, 1162 'linux2': 1163 """ 1164 test_bsddb185 1165 test_curses 1166 test_dl 1167 test_largefile 1168 test_kqueue 1169 test_ossaudiodev 1170 """, 1171 'unixware7': 1172 """ 1173 test_bsddb 1174 test_bsddb185 1175 test_dl 1176 test_epoll 1177 test_largefile 1178 test_kqueue 1179 test_minidom 1180 test_openpty 1181 test_pyexpat 1182 test_sax 1183 test_sundry 1184 """, 1185 'openunix8': 1186 """ 1187 test_bsddb 1188 test_bsddb185 1189 test_dl 1190 test_epoll 1191 test_largefile 1192 test_kqueue 1193 test_minidom 1194 test_openpty 1195 test_pyexpat 1196 test_sax 1197 test_sundry 1198 """, 1199 'sco_sv3': 1200 """ 1201 test_asynchat 1202 test_bsddb 1203 test_bsddb185 1204 test_dl 1205 test_fork1 1206 test_epoll 1207 test_gettext 1208 test_largefile 1209 test_locale 1210 test_kqueue 1211 test_minidom 1212 test_openpty 1213 test_pyexpat 1214 test_queue 1215 test_sax 1216 test_sundry 1217 test_thread 1218 test_threaded_import 1219 test_threadedtempfile 1220 test_threading 1221 """, 1222 'riscos': 1223 """ 1224 test_asynchat 1225 test_atexit 1226 test_bsddb 1227 test_bsddb185 1228 test_bsddb3 1229 test_commands 1230 test_crypt 1231 test_dbm 1232 test_dl 1233 test_fcntl 1234 test_fork1 1235 test_epoll 1236 test_gdbm 1237 test_grp 1238 test_largefile 1239 test_locale 1240 test_kqueue 1241 test_mmap 1242 test_openpty 1243 test_poll 1244 test_popen2 1245 test_pty 1246 test_pwd 1247 test_strop 1248 test_sundry 1249 test_thread 1250 test_threaded_import 1251 test_threadedtempfile 1252 test_threading 1253 test_timing 1254 """, 1255 'darwin': 1256 """ 1257 test__locale 1258 test_bsddb 1259 test_bsddb3 1260 test_curses 1261 test_epoll 1262 test_gdb 1263 test_gdbm 1264 test_largefile 1265 test_locale 1266 test_kqueue 1267 test_minidom 1268 test_ossaudiodev 1269 test_poll 1270 """, 1271 'sunos5': 1272 """ 1273 test_bsddb 1274 test_bsddb185 1275 test_curses 1276 test_dbm 1277 test_epoll 1278 test_kqueue 1279 test_gdbm 1280 test_gzip 1281 test_openpty 1282 test_zipfile 1283 test_zlib 1284 """, 1285 'hp-ux11': 1286 """ 1287 test_bsddb 1288 test_bsddb185 1289 test_curses 1290 test_dl 1291 test_epoll 1292 test_gdbm 1293 test_gzip 1294 test_largefile 1295 test_locale 1296 test_kqueue 1297 test_minidom 1298 test_openpty 1299 test_pyexpat 1300 test_sax 1301 test_zipfile 1302 test_zlib 1303 """, 1304 'atheos': 1305 """ 1306 test_bsddb185 1307 test_curses 1308 test_dl 1309 test_gdbm 1310 test_epoll 1311 test_largefile 1312 test_locale 1313 test_kqueue 1314 test_mhlib 1315 test_mmap 1316 test_poll 1317 test_popen2 1318 test_resource 1319 """, 1320 'cygwin': 1321 """ 1322 test_bsddb185 1323 test_bsddb3 1324 test_curses 1325 test_dbm 1326 test_epoll 1327 test_ioctl 1328 test_kqueue 1329 test_largefile 1330 test_locale 1331 test_ossaudiodev 1332 test_socketserver 1333 """, 1334 'os2emx': 1335 """ 1336 test_audioop 1337 test_bsddb185 1338 test_bsddb3 1339 test_commands 1340 test_curses 1341 test_dl 1342 test_epoll 1343 test_kqueue 1344 test_largefile 1345 test_mhlib 1346 test_mmap 1347 test_openpty 1348 test_ossaudiodev 1349 test_pty 1350 test_resource 1351 test_signal 1352 """, 1353 'freebsd4': 1354 """ 1355 test_bsddb 1356 test_bsddb3 1357 test_epoll 1358 test_gdbm 1359 test_locale 1360 test_ossaudiodev 1361 test_pep277 1362 test_pty 1363 test_socketserver 1364 test_tcl 1365 test_tk 1366 test_ttk_guionly 1367 test_ttk_textonly 1368 test_timeout 1369 test_urllibnet 1370 test_multiprocessing 1371 """, 1372 'aix5': 1373 """ 1374 test_bsddb 1375 test_bsddb185 1376 test_bsddb3 1377 test_bz2 1378 test_dl 1379 test_epoll 1380 test_gdbm 1381 test_gzip 1382 test_kqueue 1383 test_ossaudiodev 1384 test_tcl 1385 test_tk 1386 test_ttk_guionly 1387 test_ttk_textonly 1388 test_zipimport 1389 test_zlib 1390 """, 1391 'openbsd3': 1392 """ 1393 test_ascii_formatd 1394 test_bsddb 1395 test_bsddb3 1396 test_ctypes 1397 test_dl 1398 test_epoll 1399 test_gdbm 1400 test_locale 1401 test_normalization 1402 test_ossaudiodev 1403 test_pep277 1404 test_tcl 1405 test_tk 1406 test_ttk_guionly 1407 test_ttk_textonly 1408 test_multiprocessing 1409 """, 1410 'netbsd3': 1411 """ 1412 test_ascii_formatd 1413 test_bsddb 1414 test_bsddb185 1415 test_bsddb3 1416 test_ctypes 1417 test_curses 1418 test_dl 1419 test_epoll 1420 test_gdbm 1421 test_locale 1422 test_ossaudiodev 1423 test_pep277 1424 test_tcl 1425 test_tk 1426 test_ttk_guionly 1427 test_ttk_textonly 1428 test_multiprocessing 1429 """, 1430} 1431_expectations['freebsd5'] = _expectations['freebsd4'] 1432_expectations['freebsd6'] = _expectations['freebsd4'] 1433_expectations['freebsd7'] = _expectations['freebsd4'] 1434_expectations['freebsd8'] = _expectations['freebsd4'] 1435 1436class _ExpectedSkips: 1437 def __init__(self): 1438 import os.path 1439 from test import test_timeout 1440 1441 self.valid = False 1442 if sys.platform in _expectations: 1443 s = _expectations[sys.platform] 1444 self.expected = set(s.split()) 1445 1446 # expected to be skipped on every platform, even Linux 1447 self.expected.add('test_linuxaudiodev') 1448 1449 if not os.path.supports_unicode_filenames: 1450 self.expected.add('test_pep277') 1451 1452 if test_timeout.skip_expected: 1453 self.expected.add('test_timeout') 1454 1455 if sys.maxint == 9223372036854775807L: 1456 self.expected.add('test_imageop') 1457 1458 if sys.platform != "darwin": 1459 MAC_ONLY = ["test_macos", "test_macostools", "test_aepack", 1460 "test_plistlib", "test_scriptpackages", 1461 "test_applesingle"] 1462 for skip in MAC_ONLY: 1463 self.expected.add(skip) 1464 elif len(u'\0'.encode('unicode-internal')) == 4: 1465 self.expected.add("test_macostools") 1466 1467 1468 if sys.platform != "win32": 1469 # test_sqlite is only reliable on Windows where the library 1470 # is distributed with Python 1471 WIN_ONLY = ["test_unicode_file", "test_winreg", 1472 "test_winsound", "test_startfile", 1473 "test_sqlite", "test_msilib"] 1474 for skip in WIN_ONLY: 1475 self.expected.add(skip) 1476 1477 if sys.platform != 'irix': 1478 IRIX_ONLY = ["test_imageop", "test_al", "test_cd", "test_cl", 1479 "test_gl", "test_imgfile"] 1480 for skip in IRIX_ONLY: 1481 self.expected.add(skip) 1482 1483 if sys.platform != 'sunos5': 1484 self.expected.add('test_sunaudiodev') 1485 self.expected.add('test_nis') 1486 1487 if not sys.py3kwarning: 1488 self.expected.add('test_py3kwarn') 1489 1490 self.valid = True 1491 1492 def isvalid(self): 1493 "Return true iff _ExpectedSkips knows about the current platform." 1494 return self.valid 1495 1496 def getexpected(self): 1497 """Return set of test names we expect to skip on current platform. 1498 1499 self.isvalid() must be true. 1500 """ 1501 1502 assert self.isvalid() 1503 return self.expected 1504 1505if __name__ == '__main__': 1506 # findtestdir() gets the dirname out of __file__, so we have to make it 1507 # absolute before changing the working directory. 1508 # For example __file__ may be relative when running trace or profile. 1509 # See issue #9323. 1510 __file__ = os.path.abspath(__file__) 1511 1512 # sanity check 1513 assert __file__ == os.path.abspath(sys.argv[0]) 1514 1515 # When tests are run from the Python build directory, it is best practice 1516 # to keep the test files in a subfolder. It eases the cleanup of leftover 1517 # files using command "make distclean". 1518 if sysconfig.is_python_build(): 1519 TEMPDIR = os.path.join(sysconfig.get_config_var('srcdir'), 'build') 1520 TEMPDIR = os.path.abspath(TEMPDIR) 1521 if not os.path.exists(TEMPDIR): 1522 os.mkdir(TEMPDIR) 1523 1524 # Define a writable temp dir that will be used as cwd while running 1525 # the tests. The name of the dir includes the pid to allow parallel 1526 # testing (see the -j option). 1527 TESTCWD = 'test_python_{}'.format(os.getpid()) 1528 1529 TESTCWD = os.path.join(TEMPDIR, TESTCWD) 1530 1531 # Run the tests in a context manager that temporary changes the CWD to a 1532 # temporary and writable directory. If it's not possible to create or 1533 # change the CWD, the original CWD will be used. The original CWD is 1534 # available from test_support.SAVEDCWD. 1535 with test_support.temp_cwd(TESTCWD, quiet=True): 1536 main() 1537