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