blob: 86b3d9a2c227d3020cfcf86725647ec4862068c5 [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)
Guido van Rossum152494a1996-12-20 03:12:20 +000016
17If non-option arguments are present, they are names for tests to run,
18unless -x is given, in which case they are names for tests not to run.
19If no test names are given, all tests are run.
Guido van Rossumf58ed251997-03-07 21:04:33 +000020
Guido van Rossuma4122201997-08-18 20:08:24 +000021-v is incompatible with -g and does not compare test output files.
Barry Warsawe11e3de1999-01-28 19:51:51 +000022
23-s means to run only a single test and exit. This is useful when Purifying
24the Python interpreter. The file /tmp/pynexttest is read to find the next
25test to run. If this file is missing, the first test_*.py file in testdir or
26on the command line is used. (actually tempfile.gettempdir() is used instead
27of /tmp).
28
Guido van Rossum152494a1996-12-20 03:12:20 +000029"""
30
31import sys
32import string
33import os
34import getopt
Guido van Rossum9e48b271997-07-16 01:56:13 +000035import traceback
Guido van Rossum152494a1996-12-20 03:12:20 +000036
37import test_support
38
Guido van Rossum6fd83b71998-08-01 17:04:08 +000039def main(tests=None, testdir=None):
40 """Execute a test suite.
41
42 This also parses command-line options and modifies its behaviour
43 accordingly.
44
45 tests -- a list of strings containing test names (optional)
46 testdir -- the directory in which to look for tests (optional)
47
48 Users other than the Python test suite will certainly want to
49 specify testdir; if it's omitted, the directory containing the
50 Python test suite is searched for.
51
52 If the tests argument is omitted, the tests listed on the
53 command-line will be used. If that's empty, too, then all *.py
54 files beginning with test_ will be used.
55
56 """
57
Guido van Rossum152494a1996-12-20 03:12:20 +000058 try:
Barry Warsawe11e3de1999-01-28 19:51:51 +000059 opts, args = getopt.getopt(sys.argv[1:], 'vgqxs')
Guido van Rossum152494a1996-12-20 03:12:20 +000060 except getopt.error, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +000061 print msg
62 print __doc__
63 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000064 verbose = 0
65 quiet = 0
66 generate = 0
67 exclude = 0
Barry Warsawe11e3de1999-01-28 19:51:51 +000068 single = 0
Guido van Rossum152494a1996-12-20 03:12:20 +000069 for o, a in opts:
Guido van Rossum41360a41998-03-26 19:42:58 +000070 if o == '-v': verbose = verbose+1
71 if o == '-q': quiet = 1; verbose = 0
72 if o == '-g': generate = 1
73 if o == '-x': exclude = 1
Barry Warsawe11e3de1999-01-28 19:51:51 +000074 if o == '-s': single = 1
Guido van Rossuma4122201997-08-18 20:08:24 +000075 if generate and verbose:
Guido van Rossum41360a41998-03-26 19:42:58 +000076 print "-g and -v don't go together!"
77 return 2
Guido van Rossum152494a1996-12-20 03:12:20 +000078 good = []
79 bad = []
80 skipped = []
Barry Warsawe11e3de1999-01-28 19:51:51 +000081
82 if single:
83 from tempfile import gettempdir
84 filename = os.path.join(gettempdir(), 'pynexttest')
85 try:
86 fp = open(filename, 'r')
87 next = string.strip(fp.read())
88 tests = [next]
89 fp.close()
90 except IOError:
91 pass
Guido van Rossuma4122201997-08-18 20:08:24 +000092 for i in range(len(args)):
Guido van Rossum41360a41998-03-26 19:42:58 +000093 # Strip trailing ".py" from arguments
94 if args[i][-3:] == '.py':
95 args[i] = args[i][:-3]
Guido van Rossum6c74fea1998-08-25 12:29:08 +000096 stdtests = STDTESTS[:]
97 nottests = NOTTESTS[:]
Guido van Rossum152494a1996-12-20 03:12:20 +000098 if exclude:
Guido van Rossum6c74fea1998-08-25 12:29:08 +000099 for arg in args:
100 if arg in stdtests:
101 stdtests.remove(arg)
102 nottests[:0] = args
Guido van Rossum41360a41998-03-26 19:42:58 +0000103 args = []
Guido van Rossum747e1ca1998-08-24 13:48:36 +0000104 tests = tests or args or findtests(testdir, stdtests, nottests)
Barry Warsawe11e3de1999-01-28 19:51:51 +0000105 if single:
106 tests = tests[:1]
Guido van Rossum41360a41998-03-26 19:42:58 +0000107 test_support.verbose = verbose # Tell tests to be moderately quiet
Guido van Rossum5796d262000-04-21 21:35:06 +0000108 save_modules = sys.modules.keys()
Guido van Rossum152494a1996-12-20 03:12:20 +0000109 for test in tests:
Guido van Rossum41360a41998-03-26 19:42:58 +0000110 if not quiet:
111 print test
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000112 ok = runtest(test, generate, verbose, testdir)
Guido van Rossum41360a41998-03-26 19:42:58 +0000113 if ok > 0:
114 good.append(test)
115 elif ok == 0:
116 bad.append(test)
117 else:
118 if not quiet:
119 print "test", test,
120 print "skipped -- an optional feature could not be imported"
121 skipped.append(test)
Guido van Rossum5796d262000-04-21 21:35:06 +0000122 # Unload the newly imported modules (best effort finalization)
123 for module in sys.modules.keys():
Guido van Rossum51931142000-05-05 14:27:39 +0000124 if module not in save_modules and module.startswith("test."):
Guido van Rossum5796d262000-04-21 21:35:06 +0000125 test_support.unload(module)
Guido van Rossum152494a1996-12-20 03:12:20 +0000126 if good and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000127 if not bad and not skipped and len(good) > 1:
128 print "All",
129 print count(len(good), "test"), "OK."
Guido van Rossum152494a1996-12-20 03:12:20 +0000130 if bad:
Guido van Rossum41360a41998-03-26 19:42:58 +0000131 print count(len(bad), "test"), "failed:",
132 print string.join(bad)
Guido van Rossum152494a1996-12-20 03:12:20 +0000133 if skipped and not quiet:
Guido van Rossum41360a41998-03-26 19:42:58 +0000134 print count(len(skipped), "test"), "skipped:",
135 print string.join(skipped)
Barry Warsawe11e3de1999-01-28 19:51:51 +0000136
137 if single:
138 alltests = findtests(testdir, stdtests, nottests)
139 for i in range(len(alltests)):
140 if tests[0] == alltests[i]:
141 if i == len(alltests) - 1:
142 os.unlink(filename)
143 else:
144 fp = open(filename, 'w')
145 fp.write(alltests[i+1] + '\n')
146 fp.close()
147 break
148 else:
149 os.unlink(filename)
150
Guido van Rossume8387011997-08-14 19:40:34 +0000151 return len(bad) > 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000152
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000153STDTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000154 'test_grammar',
155 'test_opcodes',
156 'test_operations',
157 'test_builtin',
158 'test_exceptions',
159 'test_types',
160 ]
161
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000162NOTTESTS = [
Guido van Rossum152494a1996-12-20 03:12:20 +0000163 'test_support',
164 'test_b1',
165 'test_b2',
166 ]
167
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000168def findtests(testdir=None, stdtests=STDTESTS, nottests=NOTTESTS):
Guido van Rossum152494a1996-12-20 03:12:20 +0000169 """Return a list of all applicable test modules."""
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000170 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000171 names = os.listdir(testdir)
172 tests = []
173 for name in names:
Guido van Rossum41360a41998-03-26 19:42:58 +0000174 if name[:5] == "test_" and name[-3:] == ".py":
175 modname = name[:-3]
176 if modname not in stdtests and modname not in nottests:
177 tests.append(modname)
Guido van Rossum152494a1996-12-20 03:12:20 +0000178 tests.sort()
179 return stdtests + tests
180
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000181def runtest(test, generate, verbose, testdir = None):
182 """Run a single test.
183 test -- the name of the test
184 generate -- if true, generate output, instead of running the test
185 and comparing it to a previously created output file
186 verbose -- if true, print more messages
187 testdir -- test directory
188 """
Guido van Rossum152494a1996-12-20 03:12:20 +0000189 test_support.unload(test)
Guido van Rossum6fd83b71998-08-01 17:04:08 +0000190 if not testdir: testdir = findtestdir()
Guido van Rossum152494a1996-12-20 03:12:20 +0000191 outputdir = os.path.join(testdir, "output")
192 outputfile = os.path.join(outputdir, test)
193 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000194 if generate:
195 cfp = open(outputfile, "w")
196 elif verbose:
197 cfp = sys.stdout
198 else:
199 cfp = Compare(outputfile)
Guido van Rossum152494a1996-12-20 03:12:20 +0000200 except IOError:
Guido van Rossum41360a41998-03-26 19:42:58 +0000201 cfp = None
202 print "Warning: can't open", outputfile
Guido van Rossum152494a1996-12-20 03:12:20 +0000203 try:
Guido van Rossum41360a41998-03-26 19:42:58 +0000204 save_stdout = sys.stdout
205 try:
206 if cfp:
207 sys.stdout = cfp
208 print test # Output file starts with test name
209 __import__(test, globals(), locals(), [])
210 finally:
211 sys.stdout = save_stdout
Guido van Rossum152494a1996-12-20 03:12:20 +0000212 except ImportError, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000213 return -1
Guido van Rossum4e8ef5f1997-10-20 23:46:54 +0000214 except KeyboardInterrupt, v:
Guido van Rossum41360a41998-03-26 19:42:58 +0000215 raise KeyboardInterrupt, v, sys.exc_info()[2]
Guido van Rossum152494a1996-12-20 03:12:20 +0000216 except test_support.TestFailed, msg:
Guido van Rossum41360a41998-03-26 19:42:58 +0000217 print "test", test, "failed --", msg
218 return 0
Guido van Rossum9e48b271997-07-16 01:56:13 +0000219 except:
Guido van Rossum41360a41998-03-26 19:42:58 +0000220 type, value = sys.exc_info()[:2]
221 print "test", test, "crashed --", type, ":", value
222 if verbose:
223 traceback.print_exc(file=sys.stdout)
224 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000225 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000226 return 1
Guido van Rossum152494a1996-12-20 03:12:20 +0000227
228def findtestdir():
229 if __name__ == '__main__':
Guido van Rossum41360a41998-03-26 19:42:58 +0000230 file = sys.argv[0]
Guido van Rossum152494a1996-12-20 03:12:20 +0000231 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000232 file = __file__
Guido van Rossum152494a1996-12-20 03:12:20 +0000233 testdir = os.path.dirname(file) or os.curdir
234 return testdir
235
236def count(n, word):
237 if n == 1:
Guido van Rossum41360a41998-03-26 19:42:58 +0000238 return "%d %s" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000239 else:
Guido van Rossum41360a41998-03-26 19:42:58 +0000240 return "%d %ss" % (n, word)
Guido van Rossum152494a1996-12-20 03:12:20 +0000241
242class Compare:
243
244 def __init__(self, filename):
Guido van Rossum41360a41998-03-26 19:42:58 +0000245 self.fp = open(filename, 'r')
Guido van Rossum152494a1996-12-20 03:12:20 +0000246
247 def write(self, data):
Guido van Rossum41360a41998-03-26 19:42:58 +0000248 expected = self.fp.read(len(data))
249 if data <> expected:
250 raise test_support.TestFailed, \
251 'Writing: '+`data`+', expected: '+`expected`
Guido van Rossum152494a1996-12-20 03:12:20 +0000252
Guido van Rossume87ed5f1998-04-23 13:33:21 +0000253 def writelines(self, listoflines):
254 map(self.write, listoflines)
255
Guido van Rossum75fce301997-07-17 14:51:37 +0000256 def flush(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000257 pass
Guido van Rossum75fce301997-07-17 14:51:37 +0000258
Guido van Rossum152494a1996-12-20 03:12:20 +0000259 def close(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000260 leftover = self.fp.read()
261 if leftover:
262 raise test_support.TestFailed, 'Unread: '+`leftover`
263 self.fp.close()
Guido van Rossum152494a1996-12-20 03:12:20 +0000264
265 def isatty(self):
Guido van Rossum41360a41998-03-26 19:42:58 +0000266 return 0
Guido van Rossum152494a1996-12-20 03:12:20 +0000267
268if __name__ == '__main__':
Guido van Rossume8387011997-08-14 19:40:34 +0000269 sys.exit(main())