blob: e96ba818fdab2c95fc412dfa7ecaa8243938b697 [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 Warsawe11e3de1999-01-28 19:51:51 +000011-v: verbose -- run tests in verbose mode with output to stdout
12-q: quiet -- don't print anything except if a test fails
Guido van Rossum152494a1996-12-20 03:12:20 +000013-g: generate -- write the output file for a test instead of comparing it
Barry Warsawe11e3de1999-01-28 19:51:51 +000014-x: exclude -- arguments are tests to *exclude*
15-s: single -- run only a single test (see below)
Skip Montanaroab1c7912000-06-30 16:39:27 +000016-r: random -- randomize test execution order
Guido van Rossum152494a1996-12-20 03:12:20 +000017
18If non-option arguments are present, they are names for tests to run,
19unless -x is given, in which case they are names for tests not to run.
20If no test names are given, all tests are run.
Guido van Rossumf58ed251997-03-07 21:04:33 +000021
Guido van Rossuma4122201997-08-18 20:08:24 +000022-v is incompatible with -g and does not compare test output files.
Barry Warsawe11e3de1999-01-28 19:51:51 +000023
24-s means to run only a single test and exit. This is useful when Purifying
25the Python interpreter. The file /tmp/pynexttest is read to find the next
26test to run. If this file is missing, the first test_*.py file in testdir or
27on the command line is used. (actually tempfile.gettempdir() is used instead
28of /tmp).
29
Guido van Rossum152494a1996-12-20 03:12:20 +000030"""
31
32import sys
33import string
34import os
35import getopt
Guido van Rossum9e48b271997-07-16 01:56:13 +000036import traceback
Skip Montanaroab1c7912000-06-30 16:39:27 +000037import random
Guido van Rossum152494a1996-12-20 03:12:20 +000038
39import test_support
40
Skip Montanaroab1c7912000-06-30 16:39:27 +000041def main(tests=None, testdir=None, verbose=0, quiet=0, generate=0,
42 exclude=0, single=0, randomize=0):
Guido van Rossum6fd83b71998-08-01 17:04:08 +000043 """Execute a test suite.
44
Thomas Wouters7e474022000-07-16 12:04:32 +000045 This also parses command-line options and modifies its behavior
Guido van Rossum6fd83b71998-08-01 17:04:08 +000046 accordingly.
47
48 tests -- a list of strings containing test names (optional)
49 testdir -- the directory in which to look for tests (optional)
50
51 Users other than the Python test suite will certainly want to
52 specify testdir; if it's omitted, the directory containing the
53 Python test suite is searched for.
54
55 If the tests argument is omitted, the tests listed on the
56 command-line will be used. If that's empty, too, then all *.py
57 files beginning with test_ will be used.
Skip Montanaroab1c7912000-06-30 16:39:27 +000058
59 The other six default arguments (verbose, quiet, generate, exclude,
60 single, and randomize) allow programmers calling main() directly to
61 set the values that would normally be set by flags on the command
62 line.
Guido van Rossum6fd83b71998-08-01 17:04:08 +000063 """
64
Guido van Rossum152494a1996-12-20 03:12:20 +000065 try:
Skip Montanaroab1c7912000-06-30 16:39:27 +000066 opts, args = getopt.getopt(sys.argv[1:], 'vgqxsr')
Guido van Rossum152494a1996-12-20 03:12:20 +000067 except getopt.error, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +000068 print msg
69 print __doc__
70 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000071 for o, a in opts:
Guido van Rossum41360a41998-03-26 19:42:58 +000072 if o == '-v': verbose = verbose+1
73 if o == '-q': quiet = 1; verbose = 0
74 if o == '-g': generate = 1
75 if o == '-x': exclude = 1
Barry Warsawe11e3de1999-01-28 19:51:51 +000076 if o == '-s': single = 1
Skip Montanaroab1c7912000-06-30 16:39:27 +000077 if o == '-r': randomize = 1
Guido van Rossuma4122201997-08-18 20:08:24 +000078 if generate and verbose:
Guido van Rossum41360a41998-03-26 19:42:58 +000079 print "-g and -v don't go together!"
80 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000081 good = []
82 bad = []
83 skipped = []
Barry Warsawe11e3de1999-01-28 19:51:51 +000084
85 if single:
86 from tempfile import gettempdir
87 filename = os.path.join(gettempdir(), 'pynexttest')
88 try:
89 fp = open(filename, 'r')
90 next = string.strip(fp.read())
91 tests = [next]
92 fp.close()
93 except IOError:
94 pass
Guido van Rossuma4122201997-08-18 20:08:24 +000095 for i in range(len(args)):
Guido van Rossum41360a41998-03-26 19:42:58 +000096 # Strip trailing ".py" from arguments
97 if args[i][-3:] == '.py':
98 args[i] = args[i][:-3]
Guido van Rossum6c74fea1998-08-25 12:29:08 +000099 stdtests = STDTESTS[:]
100 nottests = NOTTESTS[:]
Guido van Rossum152494a1996-12-20 03:12:20 +0000101 if exclude:
Guido van Rossum6c74fea1998-08-25 12:29:08 +0000102 for arg in args:
103 if arg in stdtests:
104 stdtests.remove(arg)
105 nottests[:0] = args
Guido van Rossum41360a41998-03-26 19:42:58 +0000106 args = []
Guido van Rossum747e1ca1998-08-24 13:48:36 +0000107 tests = tests or args or findtests(testdir, stdtests, nottests)
Barry Warsawe11e3de1999-01-28 19:51:51 +0000108 if single:
109 tests = tests[:1]
Skip Montanaroab1c7912000-06-30 16:39:27 +0000110 if randomize:
111 random.shuffle(tests)
Guido van Rossum41360a41998-03-26 19:42:58 +0000112 test_support.verbose = verbose # Tell tests to be moderately quiet
Guido van Rossum5796d262000-04-21 21:35:06 +0000113 save_modules = sys.modules.keys()
Guido van Rossum152494a1996-12-20 03:12:20 +0000114 for test in tests:
Guido van Rossum41360a41998-03-26 19:42:58 +0000115 if not quiet:
116 print test
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000117 ok = runtest(test, generate, verbose, testdir)
Guido van Rossum41360a41998-03-26 19:42:58 +0000118 if ok > 0:
119 good.append(test)
120 elif ok == 0:
121 bad.append(test)
122 else:
123 if not quiet:
124 print "test", test,
125 print "skipped -- an optional feature could not be imported"
126 skipped.append(test)
Guido van Rossum5796d262000-04-21 21:35:06 +0000127 # Unload the newly imported modules (best effort finalization)
128 for module in sys.modules.keys():
Guido van Rossum51931142000-05-05 14:27:39 +0000129 if module not in save_modules and module.startswith("test."):
Guido van Rossum5796d262000-04-21 21:35:06 +0000130 test_support.unload(module)
Guido van Rossum152494a1996-12-20 03:12:20 +0000131 if good and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000132 if not bad and not skipped and len(good) > 1:
133 print "All",
134 print count(len(good), "test"), "OK."
Guido van Rossum152494a1996-12-20 03:12:20 +0000135 if bad:
Guido van Rossum41360a41998-03-26 19:42:58 +0000136 print count(len(bad), "test"), "failed:",
137 print string.join(bad)
Guido van Rossum152494a1996-12-20 03:12:20 +0000138 if skipped and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000139 print count(len(skipped), "test"), "skipped:",
140 print string.join(skipped)
Barry Warsawe11e3de1999-01-28 19:51:51 +0000141
142 if single:
143 alltests = findtests(testdir, stdtests, nottests)
144 for i in range(len(alltests)):
145 if tests[0] == alltests[i]:
146 if i == len(alltests) - 1:
147 os.unlink(filename)
148 else:
149 fp = open(filename, 'w')
150 fp.write(alltests[i+1] + '\n')
151 fp.close()
152 break
153 else:
154 os.unlink(filename)
155
Guido van Rossume8387011997-08-14 19:40:34 +0000156 return len(bad) > 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000157
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000158STDTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000159 'test_grammar',
160 'test_opcodes',
161 'test_operations',
162 'test_builtin',
163 'test_exceptions',
164 'test_types',
165 ]
166
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000167NOTTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000168 'test_support',
169 'test_b1',
170 'test_b2',
171 ]
172
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000173def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
Guido van Rossum152494a1996-12-20 03:12:20 +0000174 """Return a list of all applicable test modules."""
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000175 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000176 names = os.listdir(testdir)
177 tests = []
178 for name in names:
Guido van Rossum41360a41998-03-26 19:42:58 +0000179 if name[:5] == "test_" and name[-3:] == ".py":
180 modname = name[:-3]
181 if modname not in stdtests and modname not in nottests:
182 tests.append(modname)
Guido van Rossum152494a1996-12-20 03:12:20 +0000183 tests.sort()
184 return stdtests + tests
185
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000186def runtest(test, generate, verbose, testdir = None):
187 """Run a single test.
188 test -- the name of the test
189 generate -- if true, generate output, instead of running the test
190 and comparing it to a previously created output file
191 verbose -- if true, print more messages
192 testdir -- test directory
193 """
Guido van Rossum152494a1996-12-20 03:12:20 +0000194 test_support.unload(test)
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000195 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000196 outputdir = os.path.join(testdir, "output")
197 outputfile = os.path.join(outputdir, test)
198 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000199 if generate:
200 cfp = open(outputfile, "w")
201 elif verbose:
202 cfp = sys.stdout
203 else:
204 cfp = Compare(outputfile)
Guido van Rossum152494a1996-12-20 03:12:20 +0000205 except IOError:
Guido van Rossum41360a41998-03-26 19:42:58 +0000206 cfp = None
207 print "Warning: can't open", outputfile
Guido van Rossum152494a1996-12-20 03:12:20 +0000208 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000209 save_stdout = sys.stdout
210 try:
211 if cfp:
212 sys.stdout = cfp
213 print test # Output file starts with test name
214 __import__(test, globals(), locals(), [])
Jeremy Hyltonfff9e202000-07-11 15:15:31 +0000215 if cfp and not (generate or verbose):
216 cfp.close()
Guido van Rossum41360a41998-03-26 19:42:58 +0000217 finally:
218 sys.stdout = save_stdout
Guido van Rossum152494a1996-12-20 03:12:20 +0000219 except ImportError, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000220 return -1
Guido van Rossum4e8ef5f1997-10-20 23:46:54 +0000221 except KeyboardInterrupt, v:
Guido van Rossum41360a41998-03-26 19:42:58 +0000222 raise KeyboardInterrupt, v, sys.exc_info()[2]
Guido van Rossum152494a1996-12-20 03:12:20 +0000223 except test_support.TestFailed, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000224 print "test", test, "failed --", msg
225 return 0
Guido van Rossum9e48b271997-07-16 01:56:13 +0000226 except:
Guido van Rossum41360a41998-03-26 19:42:58 +0000227 type, value = sys.exc_info()[:2]
228 print "test", test, "crashed --", type, ":", value
229 if verbose:
230 traceback.print_exc(file=sys.stdout)
231 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000232 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000233 return 1
Guido van Rossum152494a1996-12-20 03:12:20 +0000234
235def findtestdir():
236 if __name__ == '__main__':
Guido van Rossum41360a41998-03-26 19:42:58 +0000237 file = sys.argv[0]
Guido van Rossum152494a1996-12-20 03:12:20 +0000238 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000239 file = __file__
Guido van Rossum152494a1996-12-20 03:12:20 +0000240 testdir = os.path.dirname(file) or os.curdir
241 return testdir
242
243def count(n, word):
244 if n == 1:
Guido van Rossum41360a41998-03-26 19:42:58 +0000245 return "%d %s" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000246 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000247 return "%d %ss" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000248
249class Compare:
250
251 def __init__(self, filename):
Guido van Rossum41360a41998-03-26 19:42:58 +0000252 self.fp = open(filename, 'r')
Guido van Rossum152494a1996-12-20 03:12:20 +0000253
254 def write(self, data):
Guido van Rossum41360a41998-03-26 19:42:58 +0000255 expected = self.fp.read(len(data))
256 if data <> expected:
257 raise test_support.TestFailed, \
258 'Writing: '+`data`+', expected: '+`expected`
Guido van Rossum152494a1996-12-20 03:12:20 +0000259
Guido van Rossume87ed5f1998-04-23 13:33:21 +0000260 def writelines(self, listoflines):
261 map(self.write, listoflines)
262
Guido van Rossum75fce301997-07-17 14:51:37 +0000263 def flush(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000264 pass
Guido van Rossum75fce301997-07-17 14:51:37 +0000265
Guido van Rossum152494a1996-12-20 03:12:20 +0000266 def close(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000267 leftover = self.fp.read()
268 if leftover:
269 raise test_support.TestFailed, 'Unread: '+`leftover`
270 self.fp.close()
Guido van Rossum152494a1996-12-20 03:12:20 +0000271
272 def isatty(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000273 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000274
275if __name__ == '__main__':
Guido van Rossume8387011997-08-14 19:40:34 +0000276 sys.exit(main())