Home | History | Annotate | Download | only in test
      1 #! /usr/bin/env python

      2 
      3 """
      4 Usage:
      5 
      6 python -m test.regrtest [options] [test_name1 [test_name2 ...]]
      7 python path/to/Lib/test/regrtest.py [options] [test_name1 [test_name2 ...]]
      8 
      9 
     10 If no arguments or options are provided, finds all files matching
     11 the pattern "test_*" in the Lib/test subdirectory and runs
     12 them in alphabetical order (but see -M and -u, below, for exceptions).
     13 
     14 For more rigorous testing, it is useful to use the following
     15 command line:
     16 
     17 python -E -tt -Wd -3 -m test.regrtest [options] [test_name1 ...]
     18 
     19 
     20 Options:
     21 
     22 -h/--help       -- print this text and exit
     23 
     24 Verbosity
     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 
     33 Selecting 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 
     45 Special 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 
     62 Additional Option Details:
     63 
     64 -r randomizes test execution order. You can use --randseed=int to provide a
     65 int seed value for the randomizer; this is useful for reproducing troublesome
     66 test orders.
     67 
     68 -s On the first invocation of regrtest using -s, the first test file found
     69 or the first test file given on the command line is run, and the name of
     70 the next test is recorded in a file named pynexttest.  If run from the
     71 Python build directory, pynexttest is located in the 'build' subdirectory,
     72 otherwise it is located in tempfile.gettempdir().  On subsequent runs,
     73 the test in pynexttest is run, and the next test is written to pynexttest.
     74 When the last test has been run, pynexttest is deleted.  In this way it
     75 is possible to single step through the test files.  This is useful when
     76 doing memory analysis on the Python interpreter, which process tends to
     77 consume 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
     80 or more test names per line.  Whitespace is ignored.  Blank lines and
     81 lines beginning with '#' are ignored.  This is especially useful for
     82 whittling down failures involving interactions among tests.
     83 
     84 -L causes the leaks(1) command to be run just before exit if it exists.
     85 leaks(1) is available on Mac OS X and presumably on some other
     86 FreeBSD-derived systems.
     87 
     88 -R runs each test several times and examines sys.gettotalrefcount() to
     89 see if the test appears to be leaking references.  The argument should
     90 be of the form stab:run:fname where 'stab' is the number of times the
     91 test is run to let gettotalrefcount settle down, 'run' is the number
     92 of times further it is run and 'fname' is the name of the file the
     93 reports 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
     97 typically try to ascertain containers keep working when containing more than
     98 2 billion objects, which only works on 64-bit systems. There are also some
     99 tests that try to exhaust the address space of the process, which only makes
    100 sense on 32-bit systems with at least 2Gb of memory. The passed-in memlimit,
    101 which is a string in the form of '2.5Gb', determines howmuch memory the
    102 tests will limit themselves to (but they may go slightly over.) The number
    103 shouldn't be more memory than the machine has (including swap memory). You
    104 should also keep in mind that swap memory is generally much, much slower
    105 than RAM, and setting memlimit to all available RAM or higher will heavily
    106 tax the machine. On the other hand, it is no use running these tests with a
    107 limit of less than 2.5Gb, and many require more than 20Gb. Tests that expect
    108 to use more than memlimit memory will be skipped. The big-memory tests
    109 generally run very, very long.
    110 
    111 -u is used to specify which special resource intensive tests to run,
    112 such as those requiring large file support or network connectivity.
    113 The argument is a comma-separated list of words indicating the
    114 resources 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 
    150 To enable all resources except one, use '-uall,-<resource>'.  For
    151 example, to run all the tests except for the bsddb tests, give the
    152 option '-uall,-bsddb'.
    153 """
    154 
    155 import StringIO
    156 import getopt
    157 import json
    158 import os
    159 import random
    160 import re
    161 import sys
    162 import time
    163 import traceback
    164 import warnings
    165 import unittest
    166 import tempfile
    167 import imp
    168 import platform
    169 import 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.

    182 for 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.

    195 if 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.

    206 PASSED = 1
    207 FAILED = 0
    208 ENV_CHANGED = -1
    209 SKIPPED = -2
    210 RESOURCE_DENIED = -3
    211 INTERRUPTED = -4
    212 
    213 from test import test_support
    214 
    215 RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', 'bsddb',
    216                   'decimal', 'cpu', 'subprocess', 'urlfetch', 'gui',
    217                   'xpickle')
    218 
    219 TEMPDIR = os.path.abspath(tempfile.gettempdir())
    220 
    221 
    222 def usage(code, msg=''):
    223     print __doc__
    224     if msg: print msg
    225     sys.exit(code)
    226 
    227 
    228 def 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 
    663 STDTESTS = [
    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 
    675 NOTTESTS = {
    676     'test_support',
    677     'test_future1',
    678     'test_future2',
    679 }
    680 
    681 def 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 
    693 def 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 
    729 class 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 
    849 def 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 
    926 def 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 
    966 def 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 
   1030 def 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 
   1083 def findtestdir(path=None):
   1084     return path or os.path.dirname(__file__) or os.curdir
   1085 
   1086 def 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 
   1094 def count(n, word):
   1095     if n == 1:
   1096         return "%d %s" % (n, word)
   1097     else:
   1098         return "%d %ss" % (n, word)
   1099 
   1100 def 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 
   1436 class _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 
   1505 if __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