~ubuntu-branches/ubuntu/karmic/pypy/karmic

« back to all changes in this revision

Viewing changes to lib-python/2.4.1/test/regrtest.py

  • Committer: Bazaar Package Importer
  • Author(s): Alexandre Fayolle
  • Date: 2007-04-13 09:33:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070413093309-yoojh4jcoocu2krz
Tags: upstream-1.0.0
ImportĀ upstreamĀ versionĀ 1.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/env python
 
2
 
 
3
"""Regression test.
 
4
 
 
5
This will find all modules whose name is "test_*" in the test
 
6
directory, and run them.  Various command line options provide
 
7
additional facilities.
 
8
 
 
9
Command line options:
 
10
 
 
11
-v: verbose    -- run tests in verbose mode with output to stdout
 
12
-q: quiet      -- don't print anything except if a test fails
 
13
-g: generate   -- write the output file for a test instead of comparing it
 
14
-x: exclude    -- arguments are tests to *exclude*
 
15
-s: single     -- run only a single test (see below)
 
16
-r: random     -- randomize test execution order
 
17
-f: fromfile   -- read names of tests to run from a file (see below)
 
18
-l: findleaks  -- if GC is available detect tests that leak memory
 
19
-u: use        -- specify which special resource intensive tests to run
 
20
-h: help       -- print this text and exit
 
21
-t: threshold  -- call gc.set_threshold(N)
 
22
-T: coverage   -- turn on code coverage using the trace module
 
23
-D: coverdir   -- Directory where coverage files are put
 
24
-N: nocoverdir -- Put coverage files alongside modules
 
25
-L: runleaks   -- run the leaks(1) command just before exit
 
26
-R: huntrleaks -- search for reference leaks (needs debug build, v. slow)
 
27
 
 
28
If non-option arguments are present, they are names for tests to run,
 
29
unless -x is given, in which case they are names for tests not to run.
 
30
If no test names are given, all tests are run.
 
31
 
 
32
-v is incompatible with -g and does not compare test output files.
 
33
 
 
34
-T turns on code coverage tracing with the trace module.
 
35
 
 
36
-D specifies the directory where coverage files are put.
 
37
 
 
38
-N Put coverage files alongside modules.
 
39
 
 
40
-s means to run only a single test and exit.  This is useful when
 
41
doing memory analysis on the Python interpreter (which tend to consume
 
42
too many resources to run the full regression test non-stop).  The
 
43
file /tmp/pynexttest is read to find the next test to run.  If this
 
44
file is missing, the first test_*.py file in testdir or on the command
 
45
line is used.  (actually tempfile.gettempdir() is used instead of
 
46
/tmp).
 
47
 
 
48
-f reads the names of tests from the file given as f's argument, one
 
49
or more test names per line.  Whitespace is ignored.  Blank lines and
 
50
lines beginning with '#' are ignored.  This is especially useful for
 
51
whittling down failures involving interactions among tests.
 
52
 
 
53
-L causes the leaks(1) command to be run just before exit if it exists.
 
54
leaks(1) is available on Mac OS X and presumably on some other
 
55
FreeBSD-derived systems.
 
56
 
 
57
-R runs each test several times and examines sys.gettotalrefcount() to
 
58
see if the test appears to be leaking references.  The argument should
 
59
be of the form stab:run:fname where 'stab' is the number of times the
 
60
test is run to let gettotalrefcount settle down, 'run' is the number
 
61
of times further it is run and 'fname' is the name of the file the
 
62
reports are written to.  These parameters all have defaults (5, 4 and
 
63
"reflog.txt" respectively), so the minimal invocation is '-R ::'.
 
64
 
 
65
-u is used to specify which special resource intensive tests to run,
 
66
such as those requiring large file support or network connectivity.
 
67
The argument is a comma-separated list of words indicating the
 
68
resources to test.  Currently only the following are defined:
 
69
 
 
70
    all -       Enable all special resources.
 
71
 
 
72
    audio -     Tests that use the audio device.  (There are known
 
73
                cases of broken audio drivers that can crash Python or
 
74
                even the Linux kernel.)
 
75
 
 
76
    curses -    Tests that use curses and will modify the terminal's
 
77
                state and output modes.
 
78
 
 
79
    largefile - It is okay to run some test that may create huge
 
80
                files.  These tests can take a long time and may
 
81
                consume >2GB of disk space temporarily.
 
82
 
 
83
    network -   It is okay to run tests that use external network
 
84
                resource, e.g. testing SSL support for sockets.
 
85
 
 
86
    bsddb -     It is okay to run the bsddb testsuite, which takes
 
87
                a long time to complete.
 
88
 
 
89
    decimal -   Test the decimal module against a large suite that
 
90
                verifies compliance with standards.
 
91
 
 
92
    compiler -  Test the compiler package by compiling all the source
 
93
                in the standard library and test suite.  This takes
 
94
                a long time.
 
95
 
 
96
    subprocess  Run all tests for the subprocess module. 
 
97
 
 
98
To enable all resources except one, use '-uall,-<resource>'.  For
 
99
example, to run all the tests except for the bsddb tests, give the
 
100
option '-uall,-bsddb'.
 
101
"""
 
102
 
 
103
import os
 
104
import sys
 
105
import getopt
 
106
import random
 
107
import warnings
 
108
import sre
 
109
import cStringIO
 
110
import traceback
 
111
 
 
112
# I see no other way to suppress these warnings;
 
113
# putting them in test_grammar.py has no effect:
 
114
warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning,
 
115
                        ".*test.test_grammar$")
 
116
if sys.maxint > 0x7fffffff:
 
117
    # Also suppress them in <string>, because for 64-bit platforms,
 
118
    # that's where test_grammar.py hides them.
 
119
    warnings.filterwarnings("ignore", "hex/oct constants", FutureWarning,
 
120
                            "<string>")
 
121
 
 
122
# MacOSX (a.k.a. Darwin) has a default stack size that is too small
 
123
# for deeply recursive regular expressions.  We see this as crashes in
 
124
# the Python test suite when running test_re.py and test_sre.py.  The
 
125
# fix is to set the stack limit to 2048.
 
126
# This approach may also be useful for other Unixy platforms that
 
127
# suffer from small default stack limits.
 
128
if sys.platform == 'darwin':
 
129
    try:
 
130
        import resource
 
131
    except ImportError:
 
132
        pass
 
133
    else:
 
134
        soft, hard = resource.getrlimit(resource.RLIMIT_STACK)
 
135
        newsoft = min(hard, max(soft, 1024*2048))
 
136
        resource.setrlimit(resource.RLIMIT_STACK, (newsoft, hard))
 
137
 
 
138
from test import test_support
 
139
 
 
140
RESOURCE_NAMES = ('audio', 'curses', 'largefile', 'network', 'bsddb',
 
141
                  'decimal', 'compiler', 'subprocess')
 
142
 
 
143
 
 
144
def usage(code, msg=''):
 
145
    print __doc__
 
146
    if msg: print msg
 
147
    sys.exit(code)
 
148
 
 
149
 
 
150
def main(tests=None, testdir=None, verbose=0, quiet=False, generate=False,
 
151
         exclude=False, single=False, randomize=False, fromfile=None,
 
152
         findleaks=False, use_resources=None, trace=False, coverdir='coverage',
 
153
         runleaks=False, huntrleaks=False):
 
154
    """Execute a test suite.
 
155
 
 
156
    This also parses command-line options and modifies its behavior
 
157
    accordingly.
 
158
 
 
159
    tests -- a list of strings containing test names (optional)
 
160
    testdir -- the directory in which to look for tests (optional)
 
161
 
 
162
    Users other than the Python test suite will certainly want to
 
163
    specify testdir; if it's omitted, the directory containing the
 
164
    Python test suite is searched for.
 
165
 
 
166
    If the tests argument is omitted, the tests listed on the
 
167
    command-line will be used.  If that's empty, too, then all *.py
 
168
    files beginning with test_ will be used.
 
169
 
 
170
    The other default arguments (verbose, quiet, generate, exclude, single,
 
171
    randomize, findleaks, use_resources, trace and coverdir) allow programmers
 
172
    calling main() directly to set the values that would normally be set by
 
173
    flags on the command line.
 
174
    """
 
175
 
 
176
    test_support.record_original_stdout(sys.stdout)
 
177
    try:
 
178
        opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsrf:lu:t:TD:NLR:',
 
179
                                   ['help', 'verbose', 'quiet', 'generate',
 
180
                                    'exclude', 'single', 'random', 'fromfile',
 
181
                                    'findleaks', 'use=', 'threshold=', 'trace',
 
182
                                    'coverdir=', 'nocoverdir', 'runleaks',
 
183
                                    'huntrleaks='
 
184
                                    ])
 
185
    except getopt.error, msg:
 
186
        usage(2, msg)
 
187
 
 
188
    # Defaults
 
189
    if use_resources is None:
 
190
        use_resources = []
 
191
    for o, a in opts:
 
192
        if o in ('-h', '--help'):
 
193
            usage(0)
 
194
        elif o in ('-v', '--verbose'):
 
195
            verbose += 1
 
196
        elif o in ('-q', '--quiet'):
 
197
            quiet = True;
 
198
            verbose = 0
 
199
        elif o in ('-g', '--generate'):
 
200
            generate = True
 
201
        elif o in ('-x', '--exclude'):
 
202
            exclude = True
 
203
        elif o in ('-s', '--single'):
 
204
            single = True
 
205
        elif o in ('-r', '--randomize'):
 
206
            randomize = True
 
207
        elif o in ('-f', '--fromfile'):
 
208
            fromfile = a
 
209
        elif o in ('-l', '--findleaks'):
 
210
            findleaks = True
 
211
        elif o in ('-L', '--runleaks'):
 
212
            runleaks = True
 
213
        elif o in ('-t', '--threshold'):
 
214
            import gc
 
215
            gc.set_threshold(int(a))
 
216
        elif o in ('-T', '--coverage'):
 
217
            trace = True
 
218
        elif o in ('-D', '--coverdir'):
 
219
            coverdir = os.path.join(os.getcwd(), a)
 
220
        elif o in ('-N', '--nocoverdir'):
 
221
            coverdir = None
 
222
        elif o in ('-R', '--huntrleaks'):
 
223
            huntrleaks = a.split(':')
 
224
            if len(huntrleaks) != 3:
 
225
                print a, huntrleaks
 
226
                usage(2, '-R takes three colon-separated arguments')
 
227
            if len(huntrleaks[0]) == 0:
 
228
                huntrleaks[0] = 5
 
229
            else:
 
230
                huntrleaks[0] = int(huntrleaks[0])
 
231
            if len(huntrleaks[1]) == 0:
 
232
                huntrleaks[1] = 4
 
233
            else:
 
234
                huntrleaks[1] = int(huntrleaks[1])
 
235
            if len(huntrleaks[2]) == 0:
 
236
                huntrleaks[2] = "reflog.txt"
 
237
        elif o in ('-u', '--use'):
 
238
            u = [x.lower() for x in a.split(',')]
 
239
            for r in u:
 
240
                if r == 'all':
 
241
                    use_resources[:] = RESOURCE_NAMES
 
242
                    continue
 
243
                remove = False
 
244
                if r[0] == '-':
 
245
                    remove = True
 
246
                    r = r[1:]
 
247
                if r not in RESOURCE_NAMES:
 
248
                    usage(1, 'Invalid -u/--use option: ' + a)
 
249
                if remove:
 
250
                    if r in use_resources:
 
251
                        use_resources.remove(r)
 
252
                elif r not in use_resources:
 
253
                    use_resources.append(r)
 
254
    if generate and verbose:
 
255
        usage(2, "-g and -v don't go together!")
 
256
    if single and fromfile:
 
257
        usage(2, "-s and -f don't go together!")
 
258
 
 
259
    good = []
 
260
    bad = []
 
261
    skipped = []
 
262
    resource_denieds = []
 
263
 
 
264
    if findleaks:
 
265
        try:
 
266
            import gc
 
267
        except ImportError:
 
268
            print 'No GC available, disabling findleaks.'
 
269
            findleaks = False
 
270
        else:
 
271
            # Uncomment the line below to report garbage that is not
 
272
            # freeable by reference counting alone.  By default only
 
273
            # garbage that is not collectable by the GC is reported.
 
274
            #gc.set_debug(gc.DEBUG_SAVEALL)
 
275
            found_garbage = []
 
276
 
 
277
    if single:
 
278
        from tempfile import gettempdir
 
279
        filename = os.path.join(gettempdir(), 'pynexttest')
 
280
        try:
 
281
            fp = open(filename, 'r')
 
282
            next = fp.read().strip()
 
283
            tests = [next]
 
284
            fp.close()
 
285
        except IOError:
 
286
            pass
 
287
 
 
288
    if fromfile:
 
289
        tests = []
 
290
        fp = open(fromfile)
 
291
        for line in fp:
 
292
            guts = line.split() # assuming no test has whitespace in its name
 
293
            if guts and not guts[0].startswith('#'):
 
294
                tests.extend(guts)
 
295
        fp.close()
 
296
 
 
297
    # Strip .py extensions.
 
298
    if args:
 
299
        args = map(removepy, args)
 
300
    if tests:
 
301
        tests = map(removepy, tests)
 
302
 
 
303
    stdtests = STDTESTS[:]
 
304
    nottests = NOTTESTS[:]
 
305
    if exclude:
 
306
        for arg in args:
 
307
            if arg in stdtests:
 
308
                stdtests.remove(arg)
 
309
        nottests[:0] = args
 
310
        args = []
 
311
    tests = tests or args or findtests(testdir, stdtests, nottests)
 
312
    if single:
 
313
        tests = tests[:1]
 
314
    if randomize:
 
315
        random.shuffle(tests)
 
316
    if trace:
 
317
        import trace
 
318
        tracer = trace.Trace(ignoredirs=[sys.prefix, sys.exec_prefix],
 
319
                             trace=False, count=True)
 
320
    test_support.verbose = verbose      # Tell tests to be moderately quiet
 
321
    test_support.use_resources = use_resources
 
322
    save_modules = sys.modules.keys()
 
323
    for test in tests:
 
324
        if not quiet:
 
325
            print test
 
326
            sys.stdout.flush()
 
327
        if trace:
 
328
            # If we're tracing code coverage, then we don't exit with status
 
329
            # if on a false return value from main.
 
330
            tracer.runctx('runtest(test, generate, verbose, quiet, testdir)',
 
331
                          globals=globals(), locals=vars())
 
332
        else:
 
333
            ok = runtest(test, generate, verbose, quiet, testdir, huntrleaks)
 
334
            if ok > 0:
 
335
                good.append(test)
 
336
            elif ok == 0:
 
337
                bad.append(test)
 
338
            else:
 
339
                skipped.append(test)
 
340
                if ok == -2:
 
341
                    resource_denieds.append(test)
 
342
        if findleaks:
 
343
            gc.collect()
 
344
            if gc.garbage:
 
345
                print "Warning: test created", len(gc.garbage),
 
346
                print "uncollectable object(s)."
 
347
                # move the uncollectable objects somewhere so we don't see
 
348
                # them again
 
349
                found_garbage.extend(gc.garbage)
 
350
                del gc.garbage[:]
 
351
        # Unload the newly imported modules (best effort finalization)
 
352
        for module in sys.modules.keys():
 
353
            if module not in save_modules and module.startswith("test."):
 
354
                test_support.unload(module)
 
355
 
 
356
    # The lists won't be sorted if running with -r
 
357
    good.sort()
 
358
    bad.sort()
 
359
    skipped.sort()
 
360
 
 
361
    if good and not quiet:
 
362
        if not bad and not skipped and len(good) > 1:
 
363
            print "All",
 
364
        print count(len(good), "test"), "OK."
 
365
        if verbose:
 
366
            print "CAUTION:  stdout isn't compared in verbose mode:"
 
367
            print "a test that passes in verbose mode may fail without it."
 
368
    if bad:
 
369
        print count(len(bad), "test"), "failed:"
 
370
        printlist(bad)
 
371
    if skipped and not quiet:
 
372
        print count(len(skipped), "test"), "skipped:"
 
373
        printlist(skipped)
 
374
 
 
375
        e = _ExpectedSkips()
 
376
        plat = sys.platform
 
377
        if e.isvalid():
 
378
            surprise = set(skipped) - e.getexpected() - set(resource_denieds)
 
379
            if surprise:
 
380
                print count(len(surprise), "skip"), \
 
381
                      "unexpected on", plat + ":"
 
382
                printlist(surprise)
 
383
            else:
 
384
                print "Those skips are all expected on", plat + "."
 
385
        else:
 
386
            print "Ask someone to teach regrtest.py about which tests are"
 
387
            print "expected to get skipped on", plat + "."
 
388
 
 
389
    if single:
 
390
        alltests = findtests(testdir, stdtests, nottests)
 
391
        for i in range(len(alltests)):
 
392
            if tests[0] == alltests[i]:
 
393
                if i == len(alltests) - 1:
 
394
                    os.unlink(filename)
 
395
                else:
 
396
                    fp = open(filename, 'w')
 
397
                    fp.write(alltests[i+1] + '\n')
 
398
                    fp.close()
 
399
                break
 
400
        else:
 
401
            os.unlink(filename)
 
402
 
 
403
    if trace:
 
404
        r = tracer.results()
 
405
        r.write_results(show_missing=True, summary=True, coverdir=coverdir)
 
406
 
 
407
    if runleaks:
 
408
        os.system("leaks %d" % os.getpid())
 
409
 
 
410
    sys.exit(len(bad) > 0)
 
411
 
 
412
 
 
413
STDTESTS = [
 
414
    'test_grammar',
 
415
    'test_opcodes',
 
416
    'test_operations',
 
417
    'test_builtin',
 
418
    'test_exceptions',
 
419
    'test_types',
 
420
   ]
 
421
 
 
422
NOTTESTS = [
 
423
    'test_support',
 
424
    'test_future1',
 
425
    'test_future2',
 
426
    'test_future3',
 
427
    ]
 
428
 
 
429
def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
 
430
    """Return a list of all applicable test modules."""
 
431
    if not testdir: testdir = findtestdir()
 
432
    names = os.listdir(testdir)
 
433
    tests = []
 
434
    for name in names:
 
435
        if name[:5] == "test_" and name[-3:] == os.extsep+"py":
 
436
            modname = name[:-3]
 
437
            if modname not in stdtests and modname not in nottests:
 
438
                tests.append(modname)
 
439
    tests.sort()
 
440
    return stdtests + tests
 
441
 
 
442
def runtest(test, generate, verbose, quiet, testdir=None, huntrleaks=False):
 
443
    """Run a single test.
 
444
    test -- the name of the test
 
445
    generate -- if true, generate output, instead of running the test
 
446
    and comparing it to a previously created output file
 
447
    verbose -- if true, print more messages
 
448
    quiet -- if true, don't print 'skipped' messages (probably redundant)
 
449
    testdir -- test directory
 
450
    """
 
451
    test_support.unload(test)
 
452
    if not testdir:
 
453
        testdir = findtestdir()
 
454
    outputdir = os.path.join(testdir, "output")
 
455
    outputfile = os.path.join(outputdir, test)
 
456
    if verbose:
 
457
        cfp = None
 
458
    else:
 
459
        cfp = cStringIO.StringIO()
 
460
    if huntrleaks:
 
461
        refrep = open(huntrleaks[2], "a")
 
462
    try:
 
463
        save_stdout = sys.stdout
 
464
        try:
 
465
            if cfp:
 
466
                sys.stdout = cfp
 
467
                print test              # Output file starts with test name
 
468
            if test.startswith('test.'):
 
469
                abstest = test
 
470
            else:
 
471
                # Always import it from the test package
 
472
                abstest = 'test.' + test
 
473
            the_package = __import__(abstest, globals(), locals(), [])
 
474
            the_module = getattr(the_package, test)
 
475
            # Most tests run to completion simply as a side-effect of
 
476
            # being imported.  For the benefit of tests that can't run
 
477
            # that way (like test_threaded_import), explicitly invoke
 
478
            # their test_main() function (if it exists).
 
479
            indirect_test = getattr(the_module, "test_main", None)
 
480
            if indirect_test is not None:
 
481
                indirect_test()
 
482
            if huntrleaks:
 
483
                # This code *is* hackish and inelegant, yes.
 
484
                # But it seems to do the job.
 
485
                import copy_reg
 
486
                fs = warnings.filters[:]
 
487
                ps = copy_reg.dispatch_table.copy()
 
488
                pic = sys.path_importer_cache.copy()
 
489
                import gc
 
490
                def cleanup():
 
491
                    import _strptime, urlparse, warnings, dircache
 
492
                    from distutils.dir_util import _path_created
 
493
                    _path_created.clear()
 
494
                    warnings.filters[:] = fs
 
495
                    gc.collect()
 
496
                    sre.purge()
 
497
                    _strptime._regex_cache.clear()
 
498
                    urlparse.clear_cache()
 
499
                    copy_reg.dispatch_table.clear()
 
500
                    copy_reg.dispatch_table.update(ps)
 
501
                    sys.path_importer_cache.clear()
 
502
                    sys.path_importer_cache.update(pic)
 
503
                    dircache.reset()
 
504
                if indirect_test:
 
505
                    def run_the_test():
 
506
                        indirect_test()
 
507
                else:
 
508
                    def run_the_test():
 
509
                        reload(the_module)
 
510
                deltas = []
 
511
                repcount = huntrleaks[0] + huntrleaks[1]
 
512
                print >> sys.stderr, "beginning", repcount, "repetitions"
 
513
                print >> sys.stderr, \
 
514
                      ("1234567890"*(repcount//10 + 1))[:repcount]
 
515
                for i in range(repcount):
 
516
                    rc = sys.gettotalrefcount()
 
517
                    run_the_test()
 
518
                    sys.stderr.write('.')
 
519
                    cleanup()
 
520
                    deltas.append(sys.gettotalrefcount() - rc - 2)
 
521
                print >>sys.stderr
 
522
                if max(map(abs, deltas[-huntrleaks[1]:])) > 0:
 
523
                    print >>sys.stderr, test, 'leaked', \
 
524
                          deltas[-huntrleaks[1]:], 'references'
 
525
                    print >>refrep, test, 'leaked', \
 
526
                          deltas[-huntrleaks[1]:], 'references'
 
527
                # The end of the huntrleaks hackishness.
 
528
        finally:
 
529
            sys.stdout = save_stdout
 
530
    except test_support.ResourceDenied, msg:
 
531
        if not quiet:
 
532
            print test, "skipped --", msg
 
533
            sys.stdout.flush()
 
534
        return -2
 
535
    except (ImportError, test_support.TestSkipped), msg:
 
536
        if not quiet:
 
537
            print test, "skipped --", msg
 
538
            sys.stdout.flush()
 
539
        return -1
 
540
    except KeyboardInterrupt:
 
541
        raise
 
542
    except test_support.TestFailed, msg:
 
543
        print "test", test, "failed --", msg
 
544
        sys.stdout.flush()
 
545
        return 0
 
546
    except:
 
547
        type, value = sys.exc_info()[:2]
 
548
        print "test", test, "crashed --", str(type) + ":", value
 
549
        sys.stdout.flush()
 
550
        if verbose:
 
551
            traceback.print_exc(file=sys.stdout)
 
552
            sys.stdout.flush()
 
553
        return 0
 
554
    else:
 
555
        if not cfp:
 
556
            return 1
 
557
        output = cfp.getvalue()
 
558
        if generate:
 
559
            if output == test + "\n":
 
560
                if os.path.exists(outputfile):
 
561
                    # Write it since it already exists (and the contents
 
562
                    # may have changed), but let the user know it isn't
 
563
                    # needed:
 
564
                    print "output file", outputfile, \
 
565
                          "is no longer needed; consider removing it"
 
566
                else:
 
567
                    # We don't need it, so don't create it.
 
568
                    return 1
 
569
            fp = open(outputfile, "w")
 
570
            fp.write(output)
 
571
            fp.close()
 
572
            return 1
 
573
        if os.path.exists(outputfile):
 
574
            fp = open(outputfile, "r")
 
575
            expected = fp.read()
 
576
            fp.close()
 
577
        else:
 
578
            expected = test + "\n"
 
579
        if output == expected or huntrleaks:
 
580
            return 1
 
581
        print "test", test, "produced unexpected output:"
 
582
        sys.stdout.flush()
 
583
        reportdiff(expected, output)
 
584
        sys.stdout.flush()
 
585
        return 0
 
586
 
 
587
def reportdiff(expected, output):
 
588
    import difflib
 
589
    print "*" * 70
 
590
    a = expected.splitlines(1)
 
591
    b = output.splitlines(1)
 
592
    sm = difflib.SequenceMatcher(a=a, b=b)
 
593
    tuples = sm.get_opcodes()
 
594
 
 
595
    def pair(x0, x1):
 
596
        # x0:x1 are 0-based slice indices; convert to 1-based line indices.
 
597
        x0 += 1
 
598
        if x0 >= x1:
 
599
            return "line " + str(x0)
 
600
        else:
 
601
            return "lines %d-%d" % (x0, x1)
 
602
 
 
603
    for op, a0, a1, b0, b1 in tuples:
 
604
        if op == 'equal':
 
605
            pass
 
606
 
 
607
        elif op == 'delete':
 
608
            print "***", pair(a0, a1), "of expected output missing:"
 
609
            for line in a[a0:a1]:
 
610
                print "-", line,
 
611
 
 
612
        elif op == 'replace':
 
613
            print "*** mismatch between", pair(a0, a1), "of expected", \
 
614
                  "output and", pair(b0, b1), "of actual output:"
 
615
            for line in difflib.ndiff(a[a0:a1], b[b0:b1]):
 
616
                print line,
 
617
 
 
618
        elif op == 'insert':
 
619
            print "***", pair(b0, b1), "of actual output doesn't appear", \
 
620
                  "in expected output after line", str(a1)+":"
 
621
            for line in b[b0:b1]:
 
622
                print "+", line,
 
623
 
 
624
        else:
 
625
            print "get_opcodes() returned bad tuple?!?!", (op, a0, a1, b0, b1)
 
626
 
 
627
    print "*" * 70
 
628
 
 
629
def findtestdir():
 
630
    if __name__ == '__main__':
 
631
        file = sys.argv[0]
 
632
    else:
 
633
        file = __file__
 
634
    testdir = os.path.dirname(file) or os.curdir
 
635
    return testdir
 
636
 
 
637
def removepy(name):
 
638
    if name.endswith(os.extsep + "py"):
 
639
        name = name[:-3]
 
640
    return name
 
641
 
 
642
def count(n, word):
 
643
    if n == 1:
 
644
        return "%d %s" % (n, word)
 
645
    else:
 
646
        return "%d %ss" % (n, word)
 
647
 
 
648
def printlist(x, width=70, indent=4):
 
649
    """Print the elements of iterable x to stdout.
 
650
 
 
651
    Optional arg width (default 70) is the maximum line length.
 
652
    Optional arg indent (default 4) is the number of blanks with which to
 
653
    begin each line.
 
654
    """
 
655
 
 
656
    from textwrap import fill
 
657
    blanks = ' ' * indent
 
658
    print fill(' '.join(map(str, x)), width,
 
659
               initial_indent=blanks, subsequent_indent=blanks)
 
660
 
 
661
# Map sys.platform to a string containing the basenames of tests
 
662
# expected to be skipped on that platform.
 
663
#
 
664
# Special cases:
 
665
#     test_pep277
 
666
#         The _ExpectedSkips constructor adds this to the set of expected
 
667
#         skips if not os.path.supports_unicode_filenames.
 
668
#     test_normalization
 
669
#         Whether a skip is expected here depends on whether a large test
 
670
#         input file has been downloaded.  test_normalization.skip_expected
 
671
#         controls that.
 
672
#     test_socket_ssl
 
673
#         Controlled by test_socket_ssl.skip_expected.  Requires the network
 
674
#         resource, and a socket module with ssl support.
 
675
#     test_timeout
 
676
#         Controlled by test_timeout.skip_expected.  Requires the network
 
677
#         resource and a socket module.
 
678
#     test_codecmaps_*
 
679
#         Whether a skip is expected here depends on whether a large test
 
680
#         input file has been downloaded.  test_codecmaps_*.skip_expected
 
681
#         controls that.
 
682
 
 
683
_expectations = {
 
684
    'win32':
 
685
        """
 
686
        test__locale
 
687
        test_applesingle
 
688
        test_al
 
689
        test_bsddb185
 
690
        test_bsddb3
 
691
        test_cd
 
692
        test_cl
 
693
        test_commands
 
694
        test_crypt
 
695
        test_curses
 
696
        test_dbm
 
697
        test_dl
 
698
        test_fcntl
 
699
        test_fork1
 
700
        test_gdbm
 
701
        test_gl
 
702
        test_grp
 
703
        test_imgfile
 
704
        test_ioctl
 
705
        test_largefile
 
706
        test_linuxaudiodev
 
707
        test_mhlib
 
708
        test_nis
 
709
        test_openpty
 
710
        test_ossaudiodev
 
711
        test_poll
 
712
        test_posix
 
713
        test_pty
 
714
        test_pwd
 
715
        test_resource
 
716
        test_signal
 
717
        test_sunaudiodev
 
718
        test_threadsignals
 
719
        test_timing
 
720
        """,
 
721
    'linux2':
 
722
        """
 
723
        test_al
 
724
        test_applesingle
 
725
        test_bsddb185
 
726
        test_cd
 
727
        test_cl
 
728
        test_curses
 
729
        test_dl
 
730
        test_gl
 
731
        test_imgfile
 
732
        test_largefile
 
733
        test_linuxaudiodev
 
734
        test_nis
 
735
        test_ntpath
 
736
        test_ossaudiodev
 
737
        test_sunaudiodev
 
738
        """,
 
739
   'mac':
 
740
        """
 
741
        test_al
 
742
        test_atexit
 
743
        test_bsddb
 
744
        test_bsddb185
 
745
        test_bsddb3
 
746
        test_bz2
 
747
        test_cd
 
748
        test_cl
 
749
        test_commands
 
750
        test_crypt
 
751
        test_curses
 
752
        test_dbm
 
753
        test_dl
 
754
        test_fcntl
 
755
        test_fork1
 
756
        test_gl
 
757
        test_grp
 
758
        test_ioctl
 
759
        test_imgfile
 
760
        test_largefile
 
761
        test_linuxaudiodev
 
762
        test_locale
 
763
        test_mmap
 
764
        test_nis
 
765
        test_ntpath
 
766
        test_openpty
 
767
        test_ossaudiodev
 
768
        test_poll
 
769
        test_popen
 
770
        test_popen2
 
771
        test_posix
 
772
        test_pty
 
773
        test_pwd
 
774
        test_resource
 
775
        test_signal
 
776
        test_sunaudiodev
 
777
        test_sundry
 
778
        test_tarfile
 
779
        test_timing
 
780
        """,
 
781
    'unixware7':
 
782
        """
 
783
        test_al
 
784
        test_applesingle
 
785
        test_bsddb
 
786
        test_bsddb185
 
787
        test_cd
 
788
        test_cl
 
789
        test_dl
 
790
        test_gl
 
791
        test_imgfile
 
792
        test_largefile
 
793
        test_linuxaudiodev
 
794
        test_minidom
 
795
        test_nis
 
796
        test_ntpath
 
797
        test_openpty
 
798
        test_pyexpat
 
799
        test_sax
 
800
        test_sunaudiodev
 
801
        test_sundry
 
802
        """,
 
803
    'openunix8':
 
804
        """
 
805
        test_al
 
806
        test_applesingle
 
807
        test_bsddb
 
808
        test_bsddb185
 
809
        test_cd
 
810
        test_cl
 
811
        test_dl
 
812
        test_gl
 
813
        test_imgfile
 
814
        test_largefile
 
815
        test_linuxaudiodev
 
816
        test_minidom
 
817
        test_nis
 
818
        test_ntpath
 
819
        test_openpty
 
820
        test_pyexpat
 
821
        test_sax
 
822
        test_sunaudiodev
 
823
        test_sundry
 
824
        """,
 
825
    'sco_sv3':
 
826
        """
 
827
        test_al
 
828
        test_applesingle
 
829
        test_asynchat
 
830
        test_bsddb
 
831
        test_bsddb185
 
832
        test_cd
 
833
        test_cl
 
834
        test_dl
 
835
        test_fork1
 
836
        test_gettext
 
837
        test_gl
 
838
        test_imgfile
 
839
        test_largefile
 
840
        test_linuxaudiodev
 
841
        test_locale
 
842
        test_minidom
 
843
        test_nis
 
844
        test_ntpath
 
845
        test_openpty
 
846
        test_pyexpat
 
847
        test_queue
 
848
        test_sax
 
849
        test_sunaudiodev
 
850
        test_sundry
 
851
        test_thread
 
852
        test_threaded_import
 
853
        test_threadedtempfile
 
854
        test_threading
 
855
        """,
 
856
    'riscos':
 
857
        """
 
858
        test_al
 
859
        test_applesingle
 
860
        test_asynchat
 
861
        test_atexit
 
862
        test_bsddb
 
863
        test_bsddb185
 
864
        test_bsddb3
 
865
        test_cd
 
866
        test_cl
 
867
        test_commands
 
868
        test_crypt
 
869
        test_dbm
 
870
        test_dl
 
871
        test_fcntl
 
872
        test_fork1
 
873
        test_gdbm
 
874
        test_gl
 
875
        test_grp
 
876
        test_imgfile
 
877
        test_largefile
 
878
        test_linuxaudiodev
 
879
        test_locale
 
880
        test_mmap
 
881
        test_nis
 
882
        test_ntpath
 
883
        test_openpty
 
884
        test_poll
 
885
        test_popen2
 
886
        test_pty
 
887
        test_pwd
 
888
        test_strop
 
889
        test_sunaudiodev
 
890
        test_sundry
 
891
        test_thread
 
892
        test_threaded_import
 
893
        test_threadedtempfile
 
894
        test_threading
 
895
        test_timing
 
896
        """,
 
897
    'darwin':
 
898
        """
 
899
        test__locale
 
900
        test_al
 
901
        test_bsddb
 
902
        test_bsddb3
 
903
        test_cd
 
904
        test_cl
 
905
        test_curses
 
906
        test_dl
 
907
        test_gdbm
 
908
        test_gl
 
909
        test_imgfile
 
910
        test_largefile
 
911
        test_linuxaudiodev
 
912
        test_locale
 
913
        test_minidom
 
914
        test_nis
 
915
        test_ntpath
 
916
        test_ossaudiodev
 
917
        test_poll
 
918
        test_sunaudiodev
 
919
        """,
 
920
    'sunos5':
 
921
        """
 
922
        test_al
 
923
        test_applesingle
 
924
        test_bsddb
 
925
        test_bsddb185
 
926
        test_cd
 
927
        test_cl
 
928
        test_curses
 
929
        test_dbm
 
930
        test_gdbm
 
931
        test_gl
 
932
        test_gzip
 
933
        test_imgfile
 
934
        test_linuxaudiodev
 
935
        test_openpty
 
936
        test_zipfile
 
937
        test_zlib
 
938
        """,
 
939
    'hp-ux11':
 
940
        """
 
941
        test_al
 
942
        test_applesingle
 
943
        test_bsddb
 
944
        test_bsddb185
 
945
        test_cd
 
946
        test_cl
 
947
        test_curses
 
948
        test_dl
 
949
        test_gdbm
 
950
        test_gl
 
951
        test_gzip
 
952
        test_imgfile
 
953
        test_largefile
 
954
        test_linuxaudiodev
 
955
        test_locale
 
956
        test_minidom
 
957
        test_nis
 
958
        test_ntpath
 
959
        test_openpty
 
960
        test_pyexpat
 
961
        test_sax
 
962
        test_sunaudiodev
 
963
        test_zipfile
 
964
        test_zlib
 
965
        """,
 
966
    'atheos':
 
967
        """
 
968
        test_al
 
969
        test_applesingle
 
970
        test_bsddb185
 
971
        test_cd
 
972
        test_cl
 
973
        test_curses
 
974
        test_dl
 
975
        test_gdbm
 
976
        test_gl
 
977
        test_imgfile
 
978
        test_largefile
 
979
        test_linuxaudiodev
 
980
        test_locale
 
981
        test_mhlib
 
982
        test_mmap
 
983
        test_nis
 
984
        test_poll
 
985
        test_popen2
 
986
        test_resource
 
987
        test_sunaudiodev
 
988
        """,
 
989
    'cygwin':
 
990
        """
 
991
        test_al
 
992
        test_applesingle
 
993
        test_bsddb185
 
994
        test_bsddb3
 
995
        test_cd
 
996
        test_cl
 
997
        test_curses
 
998
        test_dbm
 
999
        test_gl
 
1000
        test_imgfile
 
1001
        test_ioctl
 
1002
        test_largefile
 
1003
        test_linuxaudiodev
 
1004
        test_locale
 
1005
        test_nis
 
1006
        test_ossaudiodev
 
1007
        test_socketserver
 
1008
        test_sunaudiodev
 
1009
        """,
 
1010
    'os2emx':
 
1011
        """
 
1012
        test_al
 
1013
        test_applesingle
 
1014
        test_audioop
 
1015
        test_bsddb185
 
1016
        test_bsddb3
 
1017
        test_cd
 
1018
        test_cl
 
1019
        test_commands
 
1020
        test_curses
 
1021
        test_dl
 
1022
        test_gl
 
1023
        test_imgfile
 
1024
        test_largefile
 
1025
        test_linuxaudiodev
 
1026
        test_mhlib
 
1027
        test_mmap
 
1028
        test_nis
 
1029
        test_openpty
 
1030
        test_ossaudiodev
 
1031
        test_pty
 
1032
        test_resource
 
1033
        test_signal
 
1034
        test_sunaudiodev
 
1035
        """,
 
1036
    'freebsd4':
 
1037
        """
 
1038
        test_aepack
 
1039
        test_al
 
1040
        test_applesingle
 
1041
        test_bsddb
 
1042
        test_bsddb3
 
1043
        test_cd
 
1044
        test_cl
 
1045
        test_gdbm
 
1046
        test_gl
 
1047
        test_imgfile
 
1048
        test_linuxaudiodev
 
1049
        test_locale
 
1050
        test_macfs
 
1051
        test_macostools
 
1052
        test_nis
 
1053
        test_normalization
 
1054
        test_ossaudiodev
 
1055
        test_pep277
 
1056
        test_plistlib
 
1057
        test_pty
 
1058
        test_scriptpackages
 
1059
        test_socket_ssl
 
1060
        test_socketserver
 
1061
        test_sunaudiodev
 
1062
        test_tcl
 
1063
        test_timeout
 
1064
        test_unicode_file
 
1065
        test_urllibnet
 
1066
        test_winreg
 
1067
        test_winsound
 
1068
        """,
 
1069
}
 
1070
_expectations['freebsd5'] = _expectations['freebsd4']
 
1071
_expectations['freebsd6'] = _expectations['freebsd4']
 
1072
 
 
1073
class _ExpectedSkips:
 
1074
    def __init__(self):
 
1075
        import os.path
 
1076
        from test import test_normalization
 
1077
        from test import test_socket_ssl
 
1078
        from test import test_timeout
 
1079
        from test import test_codecmaps_cn, test_codecmaps_jp
 
1080
        from test import test_codecmaps_kr, test_codecmaps_tw
 
1081
        from test import test_codecmaps_hk
 
1082
 
 
1083
        self.valid = False
 
1084
        if sys.platform in _expectations:
 
1085
            s = _expectations[sys.platform]
 
1086
            self.expected = set(s.split())
 
1087
 
 
1088
            if not os.path.supports_unicode_filenames:
 
1089
                self.expected.add('test_pep277')
 
1090
 
 
1091
            if test_normalization.skip_expected:
 
1092
                self.expected.add('test_normalization')
 
1093
 
 
1094
            if test_socket_ssl.skip_expected:
 
1095
                self.expected.add('test_socket_ssl')
 
1096
 
 
1097
            if test_timeout.skip_expected:
 
1098
                self.expected.add('test_timeout')
 
1099
 
 
1100
            for cc in ('cn', 'jp', 'kr', 'tw', 'hk'):
 
1101
                if eval('test_codecmaps_' + cc).skip_expected:
 
1102
                    self.expected.add('test_codecmaps_' + cc)
 
1103
 
 
1104
            if sys.maxint == 9223372036854775807L:
 
1105
                self.expected.add('test_rgbimg')
 
1106
                self.expected.add('test_imageop')
 
1107
 
 
1108
            if not sys.platform in ("mac", "darwin"):
 
1109
                MAC_ONLY = ["test_macostools", "test_macfs", "test_aepack",
 
1110
                            "test_plistlib", "test_scriptpackages"]
 
1111
                for skip in MAC_ONLY:
 
1112
                    self.expected.add(skip)
 
1113
 
 
1114
            if sys.platform != "win32":
 
1115
                WIN_ONLY = ["test_unicode_file", "test_winreg",
 
1116
                            "test_winsound"]
 
1117
                for skip in WIN_ONLY:
 
1118
                    self.expected.add(skip)
 
1119
 
 
1120
            self.valid = True
 
1121
 
 
1122
    def isvalid(self):
 
1123
        "Return true iff _ExpectedSkips knows about the current platform."
 
1124
        return self.valid
 
1125
 
 
1126
    def getexpected(self):
 
1127
        """Return set of test names we expect to skip on current platform.
 
1128
 
 
1129
        self.isvalid() must be true.
 
1130
        """
 
1131
 
 
1132
        assert self.isvalid()
 
1133
        return self.expected
 
1134
 
 
1135
if __name__ == '__main__':
 
1136
    # Remove regrtest.py's own directory from the module search path.  This
 
1137
    # prevents relative imports from working, and relative imports will screw
 
1138
    # up the testing framework.  E.g. if both test.test_support and
 
1139
    # test_support are imported, they will not contain the same globals, and
 
1140
    # much of the testing framework relies on the globals in the
 
1141
    # test.test_support module.
 
1142
    mydir = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
 
1143
    i = pathlen = len(sys.path)
 
1144
    while i >= 0:
 
1145
        i -= 1
 
1146
        if os.path.abspath(os.path.normpath(sys.path[i])) == mydir:
 
1147
            del sys.path[i]
 
1148
    if len(sys.path) == pathlen:
 
1149
        print 'Could not find %r in sys.path to remove it' % mydir
 
1150
    main()