blob: 9c832215e4d92125a70957d1ede8aff4d78982ba [file] [log] [blame]
Guido van Rossum152494a1996-12-20 03:12:20 +00001#! /usr/bin/env python
2
3"""Regression test.
4
5This will find all modules whose name is "test_*" in the test
6directory, and run them. Various command line options provide
7additional facilities.
8
9Command line options:
10
Barry Warsawa873b032000-08-03 15:50:37 +000011-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
Neil Schemenauer8a00abc2000-10-13 01:32:42 +000017-l: findleaks -- if GC is available detect tests that leak memory
Trent Mickf29f47b2000-08-11 19:02:59 +000018--have-resources -- run tests that require large resources (time/space)
Guido van Rossum152494a1996-12-20 03:12:20 +000019
20If non-option arguments are present, they are names for tests to run,
21unless -x is given, in which case they are names for tests not to run.
22If no test names are given, all tests are run.
Guido van Rossumf58ed251997-03-07 21:04:33 +000023
Guido van Rossuma4122201997-08-18 20:08:24 +000024-v is incompatible with -g and does not compare test output files.
Barry Warsawe11e3de1999-01-28 19:51:51 +000025
Barry Warsaw22e41822001-02-23 18:31:40 +000026-s means to run only a single test and exit. This is useful when doing memory
27analysis on the Python interpreter (which tend to consume to many resources to
28run the full regression test non-stop). The file /tmp/pynexttest is read to
29find the next test to run. If this file is missing, the first test_*.py file
30in testdir or on the command line is used. (actually tempfile.gettempdir() is
31used instead of /tmp).
Barry Warsawe11e3de1999-01-28 19:51:51 +000032
Guido van Rossum152494a1996-12-20 03:12:20 +000033"""
34
35import sys
Guido van Rossum152494a1996-12-20 03:12:20 +000036import os
37import getopt
Guido van Rossum9e48b271997-07-16 01:56:13 +000038import traceback
Skip Montanaroab1c7912000-06-30 16:39:27 +000039import random
Fred Drakeae1bb172001-05-21 21:08:12 +000040import StringIO
Guido van Rossum152494a1996-12-20 03:12:20 +000041
42import test_support
43
Skip Montanaroab1c7912000-06-30 16:39:27 +000044def main(tests=None, testdir=None, verbose=0, quiet=0, generate=0,
Neil Schemenauerd569f232000-09-22 15:29:28 +000045 exclude=0, single=0, randomize=0, findleaks=0,
Trent Mickf29f47b2000-08-11 19:02:59 +000046 use_large_resources=0):
Guido van Rossum6fd83b71998-08-01 17:04:08 +000047 """Execute a test suite.
48
Thomas Wouters7e474022000-07-16 12:04:32 +000049 This also parses command-line options and modifies its behavior
Fred Drake004d5e62000-10-23 17:22:08 +000050 accordingly.
Guido van Rossum6fd83b71998-08-01 17:04:08 +000051
52 tests -- a list of strings containing test names (optional)
53 testdir -- the directory in which to look for tests (optional)
54
55 Users other than the Python test suite will certainly want to
56 specify testdir; if it's omitted, the directory containing the
Fred Drake004d5e62000-10-23 17:22:08 +000057 Python test suite is searched for.
Guido van Rossum6fd83b71998-08-01 17:04:08 +000058
59 If the tests argument is omitted, the tests listed on the
60 command-line will be used. If that's empty, too, then all *.py
61 files beginning with test_ will be used.
Skip Montanaroab1c7912000-06-30 16:39:27 +000062
Barry Warsawa873b032000-08-03 15:50:37 +000063 The other seven default arguments (verbose, quiet, generate, exclude,
Neil Schemenauerd569f232000-09-22 15:29:28 +000064 single, randomize, and findleaks) allow programmers calling main()
Barry Warsawa873b032000-08-03 15:50:37 +000065 directly to set the values that would normally be set by flags on the
66 command line.
67
Guido van Rossum6fd83b71998-08-01 17:04:08 +000068 """
Fred Drake004d5e62000-10-23 17:22:08 +000069
Guido van Rossum152494a1996-12-20 03:12:20 +000070 try:
Trent Mickf29f47b2000-08-11 19:02:59 +000071 opts, args = getopt.getopt(sys.argv[1:], 'vgqxsrl', ['have-resources'])
Guido van Rossum152494a1996-12-20 03:12:20 +000072 except getopt.error, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +000073 print msg
74 print __doc__
75 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000076 for o, a in opts:
Guido van Rossum41360a41998-03-26 19:42:58 +000077 if o == '-v': verbose = verbose+1
78 if o == '-q': quiet = 1; verbose = 0
79 if o == '-g': generate = 1
80 if o == '-x': exclude = 1
Barry Warsawe11e3de1999-01-28 19:51:51 +000081 if o == '-s': single = 1
Skip Montanaroab1c7912000-06-30 16:39:27 +000082 if o == '-r': randomize = 1
Neil Schemenauerd569f232000-09-22 15:29:28 +000083 if o == '-l': findleaks = 1
Trent Mickf29f47b2000-08-11 19:02:59 +000084 if o == '--have-resources': use_large_resources = 1
Guido van Rossuma4122201997-08-18 20:08:24 +000085 if generate and verbose:
Guido van Rossum41360a41998-03-26 19:42:58 +000086 print "-g and -v don't go together!"
87 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000088 good = []
89 bad = []
90 skipped = []
Barry Warsawe11e3de1999-01-28 19:51:51 +000091
Neil Schemenauerd569f232000-09-22 15:29:28 +000092 if findleaks:
Barry Warsawa873b032000-08-03 15:50:37 +000093 try:
94 import gc
95 except ImportError:
Neil Schemenauer8a00abc2000-10-13 01:32:42 +000096 print 'No GC available, disabling findleaks.'
Neil Schemenauerd569f232000-09-22 15:29:28 +000097 findleaks = 0
Barry Warsawa873b032000-08-03 15:50:37 +000098 else:
Neil Schemenauer8a00abc2000-10-13 01:32:42 +000099 # Uncomment the line below to report garbage that is not
100 # freeable by reference counting alone. By default only
101 # garbage that is not collectable by the GC is reported.
102 #gc.set_debug(gc.DEBUG_SAVEALL)
Neil Schemenauerd569f232000-09-22 15:29:28 +0000103 found_garbage = []
Barry Warsawa873b032000-08-03 15:50:37 +0000104
Barry Warsawe11e3de1999-01-28 19:51:51 +0000105 if single:
106 from tempfile import gettempdir
107 filename = os.path.join(gettempdir(), 'pynexttest')
108 try:
109 fp = open(filename, 'r')
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000110 next = fp.read().strip()
Barry Warsawe11e3de1999-01-28 19:51:51 +0000111 tests = [next]
112 fp.close()
113 except IOError:
114 pass
Guido van Rossuma4122201997-08-18 20:08:24 +0000115 for i in range(len(args)):
Guido van Rossum41360a41998-03-26 19:42:58 +0000116 # Strip trailing ".py" from arguments
117 if args[i][-3:] == '.py':
118 args[i] = args[i][:-3]
Guido van Rossum6c74fea1998-08-25 12:29:08 +0000119 stdtests = STDTESTS[:]
120 nottests = NOTTESTS[:]
Guido van Rossum152494a1996-12-20 03:12:20 +0000121 if exclude:
Guido van Rossum6c74fea1998-08-25 12:29:08 +0000122 for arg in args:
123 if arg in stdtests:
124 stdtests.remove(arg)
125 nottests[:0] = args
Guido van Rossum41360a41998-03-26 19:42:58 +0000126 args = []
Guido van Rossum747e1ca1998-08-24 13:48:36 +0000127 tests = tests or args or findtests(testdir, stdtests, nottests)
Barry Warsawe11e3de1999-01-28 19:51:51 +0000128 if single:
129 tests = tests[:1]
Skip Montanaroab1c7912000-06-30 16:39:27 +0000130 if randomize:
131 random.shuffle(tests)
Guido van Rossum41360a41998-03-26 19:42:58 +0000132 test_support.verbose = verbose # Tell tests to be moderately quiet
Trent Mickf29f47b2000-08-11 19:02:59 +0000133 test_support.use_large_resources = use_large_resources
Guido van Rossum5796d262000-04-21 21:35:06 +0000134 save_modules = sys.modules.keys()
Guido van Rossum152494a1996-12-20 03:12:20 +0000135 for test in tests:
Guido van Rossum41360a41998-03-26 19:42:58 +0000136 if not quiet:
137 print test
Trent Mickf29f47b2000-08-11 19:02:59 +0000138 ok = runtest(test, generate, verbose, quiet, testdir)
Guido van Rossum41360a41998-03-26 19:42:58 +0000139 if ok > 0:
140 good.append(test)
141 elif ok == 0:
142 bad.append(test)
143 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000144 skipped.append(test)
Neil Schemenauerd569f232000-09-22 15:29:28 +0000145 if findleaks:
146 gc.collect()
147 if gc.garbage:
Neil Schemenauer8a00abc2000-10-13 01:32:42 +0000148 print "Warning: test created", len(gc.garbage),
149 print "uncollectable object(s)."
150 # move the uncollectable objects somewhere so we don't see
151 # them again
Neil Schemenauerd569f232000-09-22 15:29:28 +0000152 found_garbage.extend(gc.garbage)
153 del gc.garbage[:]
Guido van Rossum5796d262000-04-21 21:35:06 +0000154 # Unload the newly imported modules (best effort finalization)
155 for module in sys.modules.keys():
Guido van Rossum51931142000-05-05 14:27:39 +0000156 if module not in save_modules and module.startswith("test."):
Guido van Rossum5796d262000-04-21 21:35:06 +0000157 test_support.unload(module)
Guido van Rossum152494a1996-12-20 03:12:20 +0000158 if good and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000159 if not bad and not skipped and len(good) > 1:
160 print "All",
161 print count(len(good), "test"), "OK."
Tim Peters1a4d77b2000-12-30 22:21:22 +0000162 if verbose:
163 print "CAUTION: stdout isn't compared in verbose mode: a test"
164 print "that passes in verbose mode may fail without it."
Guido van Rossum152494a1996-12-20 03:12:20 +0000165 if bad:
Guido van Rossum41360a41998-03-26 19:42:58 +0000166 print count(len(bad), "test"), "failed:",
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000167 print " ".join(bad)
Guido van Rossum152494a1996-12-20 03:12:20 +0000168 if skipped and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000169 print count(len(skipped), "test"), "skipped:",
Eric S. Raymondfc170b12001-02-09 11:51:27 +0000170 print " ".join(skipped)
Barry Warsawe11e3de1999-01-28 19:51:51 +0000171
172 if single:
173 alltests = findtests(testdir, stdtests, nottests)
174 for i in range(len(alltests)):
175 if tests[0] == alltests[i]:
176 if i == len(alltests) - 1:
177 os.unlink(filename)
178 else:
179 fp = open(filename, 'w')
180 fp.write(alltests[i+1] + '\n')
181 fp.close()
182 break
183 else:
184 os.unlink(filename)
185
Guido van Rossume8387011997-08-14 19:40:34 +0000186 return len(bad) > 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000187
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000188STDTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000189 'test_grammar',
190 'test_opcodes',
191 'test_operations',
192 'test_builtin',
193 'test_exceptions',
194 'test_types',
195 ]
196
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000197NOTTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000198 'test_support',
199 'test_b1',
200 'test_b2',
Jeremy Hylton62e2c7e2001-02-28 17:48:06 +0000201 'test_future1',
202 'test_future2',
Guido van Rossum152494a1996-12-20 03:12:20 +0000203 ]
204
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000205def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
Guido van Rossum152494a1996-12-20 03:12:20 +0000206 """Return a list of all applicable test modules."""
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000207 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000208 names = os.listdir(testdir)
209 tests = []
210 for name in names:
Guido van Rossum41360a41998-03-26 19:42:58 +0000211 if name[:5] == "test_" and name[-3:] == ".py":
212 modname = name[:-3]
213 if modname not in stdtests and modname not in nottests:
214 tests.append(modname)
Guido van Rossum152494a1996-12-20 03:12:20 +0000215 tests.sort()
216 return stdtests + tests
217
Trent Mickf29f47b2000-08-11 19:02:59 +0000218def runtest(test, generate, verbose, quiet, testdir = None):
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000219 """Run a single test.
220 test -- the name of the test
221 generate -- if true, generate output, instead of running the test
222 and comparing it to a previously created output file
223 verbose -- if true, print more messages
Trent Mickf29f47b2000-08-11 19:02:59 +0000224 quiet -- if true, don't print 'skipped' messages (probably redundant)
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000225 testdir -- test directory
226 """
Guido van Rossum152494a1996-12-20 03:12:20 +0000227 test_support.unload(test)
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000228 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000229 outputdir = os.path.join(testdir, "output")
230 outputfile = os.path.join(outputdir, test)
231 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000232 if generate:
233 cfp = open(outputfile, "w")
234 elif verbose:
235 cfp = sys.stdout
236 else:
237 cfp = Compare(outputfile)
Guido van Rossum152494a1996-12-20 03:12:20 +0000238 except IOError:
Guido van Rossum41360a41998-03-26 19:42:58 +0000239 cfp = None
240 print "Warning: can't open", outputfile
Guido van Rossum152494a1996-12-20 03:12:20 +0000241 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000242 save_stdout = sys.stdout
243 try:
244 if cfp:
245 sys.stdout = cfp
246 print test # Output file starts with test name
Tim Petersd9742212001-05-22 18:28:25 +0000247 the_module = __import__(test, globals(), locals(), [])
248 # Most tests run to completion simply as a side-effect of
249 # being imported. For the benefit of tests that can't run
250 # that way (like test_threaded_import), explicitly invoke
251 # their test_main() function (if it exists).
252 indirect_test = getattr(the_module, "test_main", None)
253 if indirect_test is not None:
254 indirect_test()
Jeremy Hyltonfff9e202000-07-11 15:15:31 +0000255 if cfp and not (generate or verbose):
256 cfp.close()
Guido van Rossum41360a41998-03-26 19:42:58 +0000257 finally:
258 sys.stdout = save_stdout
Thomas Wouters3af826e2000-08-04 13:17:51 +0000259 except (ImportError, test_support.TestSkipped), msg:
Trent Mickf29f47b2000-08-11 19:02:59 +0000260 if not quiet:
261 print "test", test,
262 print "skipped -- ", msg
Guido van Rossum41360a41998-03-26 19:42:58 +0000263 return -1
Fred Drakefe5c22a2000-08-18 16:04:05 +0000264 except KeyboardInterrupt:
265 raise
Guido van Rossum152494a1996-12-20 03:12:20 +0000266 except test_support.TestFailed, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000267 print "test", test, "failed --", msg
268 return 0
Guido van Rossum9e48b271997-07-16 01:56:13 +0000269 except:
Guido van Rossum41360a41998-03-26 19:42:58 +0000270 type, value = sys.exc_info()[:2]
Fred Drake27c4b392000-08-23 20:34:40 +0000271 print "test", test, "crashed --", str(type) + ":", value
Guido van Rossum41360a41998-03-26 19:42:58 +0000272 if verbose:
273 traceback.print_exc(file=sys.stdout)
274 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000275 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000276 return 1
Guido van Rossum152494a1996-12-20 03:12:20 +0000277
278def findtestdir():
279 if __name__ == '__main__':
Guido van Rossum41360a41998-03-26 19:42:58 +0000280 file = sys.argv[0]
Guido van Rossum152494a1996-12-20 03:12:20 +0000281 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000282 file = __file__
Guido van Rossum152494a1996-12-20 03:12:20 +0000283 testdir = os.path.dirname(file) or os.curdir
284 return testdir
285
286def count(n, word):
287 if n == 1:
Guido van Rossum41360a41998-03-26 19:42:58 +0000288 return "%d %s" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000289 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000290 return "%d %ss" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000291
292class Compare:
293
294 def __init__(self, filename):
Fred Drakeae1bb172001-05-21 21:08:12 +0000295 if os.path.exists(filename):
296 self.fp = open(filename, 'r')
297 else:
298 self.fp = StringIO.StringIO(
299 os.path.basename(filename) + "\n")
Tim Peters1a4d77b2000-12-30 22:21:22 +0000300 self.stuffthatmatched = []
Guido van Rossum152494a1996-12-20 03:12:20 +0000301
302 def write(self, data):
Guido van Rossum41360a41998-03-26 19:42:58 +0000303 expected = self.fp.read(len(data))
Tim Peters1a4d77b2000-12-30 22:21:22 +0000304 if data == expected:
305 self.stuffthatmatched.append(expected)
306 else:
307 # This Compare instance is spoofing stdout, so we need to write
308 # to stderr instead.
309 from sys import stderr as e
310 print >> e, "The actual stdout doesn't match the expected stdout."
311 if self.stuffthatmatched:
312 print >> e, "This much did match (between asterisk lines):"
313 print >> e, "*" * 70
314 good = "".join(self.stuffthatmatched)
315 e.write(good)
316 if not good.endswith("\n"):
317 e.write("\n")
318 print >> e, "*" * 70
319 print >> e, "Then ..."
320 else:
321 print >> e, "The first write to stdout clashed:"
322 # Note that the prompts are the same length in next two lines.
323 # This is so what we expected and what we got line up.
324 print >> e, "We expected (repr):", `expected`
325 print >> e, "But instead we got:", `data`
326 raise test_support.TestFailed('Writing: ' + `data`+
327 ', expected: ' + `expected`)
Guido van Rossum152494a1996-12-20 03:12:20 +0000328
Guido van Rossume87ed5f1998-04-23 13:33:21 +0000329 def writelines(self, listoflines):
330 map(self.write, listoflines)
331
Guido van Rossum75fce301997-07-17 14:51:37 +0000332 def flush(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000333 pass
Guido van Rossum75fce301997-07-17 14:51:37 +0000334
Guido van Rossum152494a1996-12-20 03:12:20 +0000335 def close(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000336 leftover = self.fp.read()
337 if leftover:
Tim Peters1a4d77b2000-12-30 22:21:22 +0000338 raise test_support.TestFailed('Tail of expected stdout unseen: ' +
339 `leftover`)
Guido van Rossum41360a41998-03-26 19:42:58 +0000340 self.fp.close()
Guido van Rossum152494a1996-12-20 03:12:20 +0000341
342 def isatty(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000343 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000344
345if __name__ == '__main__':
Guido van Rossume8387011997-08-14 19:40:34 +0000346 sys.exit(main())