##// END OF EJS Templates
tests: add -R switch...
Matt Mackall -
r3625:cc0cd594 default
parent child Browse files
Show More
@@ -1,393 +1,410 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # run-tests.py - Run a set of tests on Mercurial
3 # run-tests.py - Run a set of tests on Mercurial
4 #
4 #
5 # Copyright 2006 Matt Mackall <mpm@selenic.com>
5 # Copyright 2006 Matt Mackall <mpm@selenic.com>
6 #
6 #
7 # This software may be used and distributed according to the terms
7 # This software may be used and distributed according to the terms
8 # of the GNU General Public License, incorporated herein by reference.
8 # of the GNU General Public License, incorporated herein by reference.
9
9
10 import difflib
10 import difflib
11 import errno
11 import errno
12 import optparse
12 import optparse
13 import os
13 import os
14 import popen2
14 import popen2
15 import re
15 import re
16 import shutil
16 import shutil
17 import signal
17 import signal
18 import sys
18 import sys
19 import tempfile
19 import tempfile
20 import time
20 import time
21
21
22 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed", "merge"]
22 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed", "merge"]
23
23
24 parser = optparse.OptionParser("%prog [options] [tests]")
24 parser = optparse.OptionParser("%prog [options] [tests]")
25 parser.add_option("-v", "--verbose", action="store_true",
25 parser.add_option("-v", "--verbose", action="store_true",
26 help="output verbose messages")
26 help="output verbose messages")
27 parser.add_option("-t", "--timeout", type="int",
27 parser.add_option("-t", "--timeout", type="int",
28 help="kill errant tests after TIMEOUT seconds")
28 help="kill errant tests after TIMEOUT seconds")
29 parser.add_option("-c", "--cover", action="store_true",
29 parser.add_option("-c", "--cover", action="store_true",
30 help="print a test coverage report")
30 help="print a test coverage report")
31 parser.add_option("-s", "--cover_stdlib", action="store_true",
31 parser.add_option("-s", "--cover_stdlib", action="store_true",
32 help="print a test coverage report inc. standard libraries")
32 help="print a test coverage report inc. standard libraries")
33 parser.add_option("-C", "--annotate", action="store_true",
33 parser.add_option("-C", "--annotate", action="store_true",
34 help="output files annotated with coverage")
34 help="output files annotated with coverage")
35 parser.add_option("-r", "--retest", action="store_true",
35 parser.add_option("-r", "--retest", action="store_true",
36 help="retest failed tests")
36 help="retest failed tests")
37 parser.add_option("-f", "--first", action="store_true",
37 parser.add_option("-f", "--first", action="store_true",
38 help="exit on the first test failure")
38 help="exit on the first test failure")
39 parser.add_option("-R", "--restart", action="store_true",
40 help="restart at last error")
39
41
40 parser.set_defaults(timeout=180)
42 parser.set_defaults(timeout=180)
41 (options, args) = parser.parse_args()
43 (options, args) = parser.parse_args()
42 verbose = options.verbose
44 verbose = options.verbose
43 coverage = options.cover or options.cover_stdlib or options.annotate
45 coverage = options.cover or options.cover_stdlib or options.annotate
44
46
45 def vlog(*msg):
47 def vlog(*msg):
46 if verbose:
48 if verbose:
47 for m in msg:
49 for m in msg:
48 print m,
50 print m,
49 print
51 print
50
52
51 def splitnewlines(text):
53 def splitnewlines(text):
52 '''like str.splitlines, but only split on newlines.
54 '''like str.splitlines, but only split on newlines.
53 keep line endings.'''
55 keep line endings.'''
54 i = 0
56 i = 0
55 lines = []
57 lines = []
56 while True:
58 while True:
57 n = text.find('\n', i)
59 n = text.find('\n', i)
58 if n == -1:
60 if n == -1:
59 last = text[i:]
61 last = text[i:]
60 if last:
62 if last:
61 lines.append(last)
63 lines.append(last)
62 return lines
64 return lines
63 lines.append(text[i:n+1])
65 lines.append(text[i:n+1])
64 i = n + 1
66 i = n + 1
65
67
66 def show_diff(expected, output):
68 def show_diff(expected, output):
67 for line in difflib.unified_diff(expected, output,
69 for line in difflib.unified_diff(expected, output,
68 "Expected output", "Test output"):
70 "Expected output", "Test output"):
69 sys.stdout.write(line)
71 sys.stdout.write(line)
70
72
71 def find_program(program):
73 def find_program(program):
72 """Search PATH for a executable program"""
74 """Search PATH for a executable program"""
73 for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
75 for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
74 name = os.path.join(p, program)
76 name = os.path.join(p, program)
75 if os.access(name, os.X_OK):
77 if os.access(name, os.X_OK):
76 return name
78 return name
77 return None
79 return None
78
80
79 def check_required_tools():
81 def check_required_tools():
80 # Before we go any further, check for pre-requisite tools
82 # Before we go any further, check for pre-requisite tools
81 # stuff from coreutils (cat, rm, etc) are not tested
83 # stuff from coreutils (cat, rm, etc) are not tested
82 for p in required_tools:
84 for p in required_tools:
83 if os.name == 'nt':
85 if os.name == 'nt':
84 p += '.exe'
86 p += '.exe'
85 found = find_program(p)
87 found = find_program(p)
86 if found:
88 if found:
87 vlog("# Found prerequisite", p, "at", found)
89 vlog("# Found prerequisite", p, "at", found)
88 else:
90 else:
89 print "WARNING: Did not find prerequisite tool: "+p
91 print "WARNING: Did not find prerequisite tool: "+p
90
92
91 def cleanup_exit():
93 def cleanup_exit():
92 if verbose:
94 if verbose:
93 print "# Cleaning up HGTMP", HGTMP
95 print "# Cleaning up HGTMP", HGTMP
94 shutil.rmtree(HGTMP, True)
96 shutil.rmtree(HGTMP, True)
95
97
96 def use_correct_python():
98 def use_correct_python():
97 # some tests run python interpreter. they must use same
99 # some tests run python interpreter. they must use same
98 # interpreter we use or bad things will happen.
100 # interpreter we use or bad things will happen.
99 exedir, exename = os.path.split(sys.executable)
101 exedir, exename = os.path.split(sys.executable)
100 if exename == 'python':
102 if exename == 'python':
101 path = find_program('python')
103 path = find_program('python')
102 if os.path.dirname(path) == exedir:
104 if os.path.dirname(path) == exedir:
103 return
105 return
104 vlog('# Making python executable in test path use correct Python')
106 vlog('# Making python executable in test path use correct Python')
105 my_python = os.path.join(BINDIR, 'python')
107 my_python = os.path.join(BINDIR, 'python')
106 try:
108 try:
107 os.symlink(sys.executable, my_python)
109 os.symlink(sys.executable, my_python)
108 except AttributeError:
110 except AttributeError:
109 # windows fallback
111 # windows fallback
110 shutil.copyfile(sys.executable, my_python)
112 shutil.copyfile(sys.executable, my_python)
111 shutil.copymode(sys.executable, my_python)
113 shutil.copymode(sys.executable, my_python)
112
114
113 def install_hg():
115 def install_hg():
114 vlog("# Performing temporary installation of HG")
116 vlog("# Performing temporary installation of HG")
115 installerrs = os.path.join("tests", "install.err")
117 installerrs = os.path.join("tests", "install.err")
116
118
117 os.chdir("..") # Get back to hg root
119 os.chdir("..") # Get back to hg root
118 cmd = ('%s setup.py clean --all'
120 cmd = ('%s setup.py clean --all'
119 ' install --force --home="%s" --install-lib="%s" >%s 2>&1'
121 ' install --force --home="%s" --install-lib="%s" >%s 2>&1'
120 % (sys.executable, INST, PYTHONDIR, installerrs))
122 % (sys.executable, INST, PYTHONDIR, installerrs))
121 vlog("# Running", cmd)
123 vlog("# Running", cmd)
122 if os.system(cmd) == 0:
124 if os.system(cmd) == 0:
123 if not verbose:
125 if not verbose:
124 os.remove(installerrs)
126 os.remove(installerrs)
125 else:
127 else:
126 f = open(installerrs)
128 f = open(installerrs)
127 for line in f:
129 for line in f:
128 print line,
130 print line,
129 f.close()
131 f.close()
130 sys.exit(1)
132 sys.exit(1)
131 os.chdir(TESTDIR)
133 os.chdir(TESTDIR)
132
134
133 os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
135 os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
134 os.environ["PYTHONPATH"] = PYTHONDIR
136 os.environ["PYTHONPATH"] = PYTHONDIR
135
137
136 use_correct_python()
138 use_correct_python()
137
139
138 if coverage:
140 if coverage:
139 vlog("# Installing coverage wrapper")
141 vlog("# Installing coverage wrapper")
140 os.environ['COVERAGE_FILE'] = COVERAGE_FILE
142 os.environ['COVERAGE_FILE'] = COVERAGE_FILE
141 if os.path.exists(COVERAGE_FILE):
143 if os.path.exists(COVERAGE_FILE):
142 os.unlink(COVERAGE_FILE)
144 os.unlink(COVERAGE_FILE)
143 # Create a wrapper script to invoke hg via coverage.py
145 # Create a wrapper script to invoke hg via coverage.py
144 os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
146 os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
145 f = open(os.path.join(BINDIR, 'hg'), 'w')
147 f = open(os.path.join(BINDIR, 'hg'), 'w')
146 f.write('#!' + sys.executable + '\n')
148 f.write('#!' + sys.executable + '\n')
147 f.write('import sys, os; os.execv(sys.executable, [sys.executable, '+ \
149 f.write('import sys, os; os.execv(sys.executable, [sys.executable, '+ \
148 '"%s", "-x", "%s"] + sys.argv[1:])\n' % (
150 '"%s", "-x", "%s"] + sys.argv[1:])\n' % (
149 os.path.join(TESTDIR, 'coverage.py'),
151 os.path.join(TESTDIR, 'coverage.py'),
150 os.path.join(BINDIR, '_hg.py')))
152 os.path.join(BINDIR, '_hg.py')))
151 f.close()
153 f.close()
152 os.chmod(os.path.join(BINDIR, 'hg'), 0700)
154 os.chmod(os.path.join(BINDIR, 'hg'), 0700)
153
155
154 def output_coverage():
156 def output_coverage():
155 vlog("# Producing coverage report")
157 vlog("# Producing coverage report")
156 omit = [BINDIR, TESTDIR, PYTHONDIR]
158 omit = [BINDIR, TESTDIR, PYTHONDIR]
157 if not options.cover_stdlib:
159 if not options.cover_stdlib:
158 # Exclude as system paths (ignoring empty strings seen on win)
160 # Exclude as system paths (ignoring empty strings seen on win)
159 omit += [x for x in sys.path if x != '']
161 omit += [x for x in sys.path if x != '']
160 omit = ','.join(omit)
162 omit = ','.join(omit)
161 os.chdir(PYTHONDIR)
163 os.chdir(PYTHONDIR)
162 cmd = '"%s" "%s" -r "--omit=%s"' % (
164 cmd = '"%s" "%s" -r "--omit=%s"' % (
163 sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
165 sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
164 vlog("# Running: "+cmd)
166 vlog("# Running: "+cmd)
165 os.system(cmd)
167 os.system(cmd)
166 if options.annotate:
168 if options.annotate:
167 adir = os.path.join(TESTDIR, 'annotated')
169 adir = os.path.join(TESTDIR, 'annotated')
168 if not os.path.isdir(adir):
170 if not os.path.isdir(adir):
169 os.mkdir(adir)
171 os.mkdir(adir)
170 cmd = '"%s" "%s" -a "--directory=%s" "--omit=%s"' % (
172 cmd = '"%s" "%s" -a "--directory=%s" "--omit=%s"' % (
171 sys.executable, os.path.join(TESTDIR, 'coverage.py'),
173 sys.executable, os.path.join(TESTDIR, 'coverage.py'),
172 adir, omit)
174 adir, omit)
173 vlog("# Running: "+cmd)
175 vlog("# Running: "+cmd)
174 os.system(cmd)
176 os.system(cmd)
175
177
176 class Timeout(Exception):
178 class Timeout(Exception):
177 pass
179 pass
178
180
179 def alarmed(signum, frame):
181 def alarmed(signum, frame):
180 raise Timeout
182 raise Timeout
181
183
182 def run(cmd):
184 def run(cmd):
183 """Run command in a sub-process, capturing the output (stdout and stderr).
185 """Run command in a sub-process, capturing the output (stdout and stderr).
184 Return the exist code, and output."""
186 Return the exist code, and output."""
185 # TODO: Use subprocess.Popen if we're running on Python 2.4
187 # TODO: Use subprocess.Popen if we're running on Python 2.4
186 if os.name == 'nt':
188 if os.name == 'nt':
187 tochild, fromchild = os.popen4(cmd)
189 tochild, fromchild = os.popen4(cmd)
188 tochild.close()
190 tochild.close()
189 output = fromchild.read()
191 output = fromchild.read()
190 ret = fromchild.close()
192 ret = fromchild.close()
191 if ret == None:
193 if ret == None:
192 ret = 0
194 ret = 0
193 else:
195 else:
194 proc = popen2.Popen4(cmd)
196 proc = popen2.Popen4(cmd)
195 try:
197 try:
196 output = ''
198 output = ''
197 proc.tochild.close()
199 proc.tochild.close()
198 output = proc.fromchild.read()
200 output = proc.fromchild.read()
199 ret = proc.wait()
201 ret = proc.wait()
200 except Timeout:
202 except Timeout:
201 vlog('# Process %d timed out - killing it' % proc.pid)
203 vlog('# Process %d timed out - killing it' % proc.pid)
202 os.kill(proc.pid, signal.SIGTERM)
204 os.kill(proc.pid, signal.SIGTERM)
203 ret = proc.wait()
205 ret = proc.wait()
204 if ret == 0:
206 if ret == 0:
205 ret = signal.SIGTERM << 8
207 ret = signal.SIGTERM << 8
206 return ret, splitnewlines(output)
208 return ret, splitnewlines(output)
207
209
208 def run_one(test):
210 def run_one(test):
209 '''tristate output:
211 '''tristate output:
210 None -> skipped
212 None -> skipped
211 True -> passed
213 True -> passed
212 False -> failed'''
214 False -> failed'''
213
215
214 vlog("# Test", test)
216 vlog("# Test", test)
215 if not verbose:
217 if not verbose:
216 sys.stdout.write('.')
218 sys.stdout.write('.')
217 sys.stdout.flush()
219 sys.stdout.flush()
218
220
219 # create a fresh hgrc
221 # create a fresh hgrc
220 hgrc = file(HGRCPATH, 'w+')
222 hgrc = file(HGRCPATH, 'w+')
221 hgrc.close()
223 hgrc.close()
222
224
223 err = os.path.join(TESTDIR, test+".err")
225 err = os.path.join(TESTDIR, test+".err")
224 ref = os.path.join(TESTDIR, test+".out")
226 ref = os.path.join(TESTDIR, test+".out")
225
227
226 if os.path.exists(err):
228 if os.path.exists(err):
227 os.remove(err) # Remove any previous output files
229 os.remove(err) # Remove any previous output files
228
230
229 # Make a tmp subdirectory to work in
231 # Make a tmp subdirectory to work in
230 tmpd = os.path.join(HGTMP, test)
232 tmpd = os.path.join(HGTMP, test)
231 os.mkdir(tmpd)
233 os.mkdir(tmpd)
232 os.chdir(tmpd)
234 os.chdir(tmpd)
233
235
234 lctest = test.lower()
236 lctest = test.lower()
235
237
236 if lctest.endswith('.py'):
238 if lctest.endswith('.py'):
237 cmd = '%s "%s"' % (sys.executable, os.path.join(TESTDIR, test))
239 cmd = '%s "%s"' % (sys.executable, os.path.join(TESTDIR, test))
238 elif lctest.endswith('.bat'):
240 elif lctest.endswith('.bat'):
239 # do not run batch scripts on non-windows
241 # do not run batch scripts on non-windows
240 if os.name != 'nt':
242 if os.name != 'nt':
241 print '\nSkipping %s: batch script' % test
243 print '\nSkipping %s: batch script' % test
242 return None
244 return None
243 # To reliably get the error code from batch files on WinXP,
245 # To reliably get the error code from batch files on WinXP,
244 # the "cmd /c call" prefix is needed. Grrr
246 # the "cmd /c call" prefix is needed. Grrr
245 cmd = 'cmd /c call "%s"' % (os.path.join(TESTDIR, test))
247 cmd = 'cmd /c call "%s"' % (os.path.join(TESTDIR, test))
246 else:
248 else:
247 # do not run shell scripts on windows
249 # do not run shell scripts on windows
248 if os.name == 'nt':
250 if os.name == 'nt':
249 print '\nSkipping %s: shell script' % test
251 print '\nSkipping %s: shell script' % test
250 return None
252 return None
251 # do not try to run non-executable programs
253 # do not try to run non-executable programs
252 if not os.access(os.path.join(TESTDIR, test), os.X_OK):
254 if not os.access(os.path.join(TESTDIR, test), os.X_OK):
253 print '\nSkipping %s: not executable' % test
255 print '\nSkipping %s: not executable' % test
254 return None
256 return None
255 cmd = '"%s"' % (os.path.join(TESTDIR, test))
257 cmd = '"%s"' % (os.path.join(TESTDIR, test))
256
258
257 if options.timeout > 0:
259 if options.timeout > 0:
258 signal.alarm(options.timeout)
260 signal.alarm(options.timeout)
259
261
260 vlog("# Running", cmd)
262 vlog("# Running", cmd)
261 ret, out = run(cmd)
263 ret, out = run(cmd)
262 vlog("# Ret was:", ret)
264 vlog("# Ret was:", ret)
263
265
264 if options.timeout > 0:
266 if options.timeout > 0:
265 signal.alarm(0)
267 signal.alarm(0)
266
268
267 diffret = 0
269 diffret = 0
268 # If reference output file exists, check test output against it
270 # If reference output file exists, check test output against it
269 if os.path.exists(ref):
271 if os.path.exists(ref):
270 f = open(ref, "r")
272 f = open(ref, "r")
271 ref_out = splitnewlines(f.read())
273 ref_out = splitnewlines(f.read())
272 f.close()
274 f.close()
273 else:
275 else:
274 ref_out = []
276 ref_out = []
275 if out != ref_out:
277 if out != ref_out:
276 diffret = 1
278 diffret = 1
277 print "\nERROR: %s output changed" % (test)
279 print "\nERROR: %s output changed" % (test)
278 show_diff(ref_out, out)
280 show_diff(ref_out, out)
279 if ret:
281 if ret:
280 print "\nERROR: %s failed with error code %d" % (test, ret)
282 print "\nERROR: %s failed with error code %d" % (test, ret)
281 elif diffret:
283 elif diffret:
282 ret = diffret
284 ret = diffret
283
285
284 if ret != 0: # Save errors to a file for diagnosis
286 if ret != 0: # Save errors to a file for diagnosis
285 f = open(err, "wb")
287 f = open(err, "wb")
286 for line in out:
288 for line in out:
287 f.write(line)
289 f.write(line)
288 f.close()
290 f.close()
289
291
290 # Kill off any leftover daemon processes
292 # Kill off any leftover daemon processes
291 try:
293 try:
292 fp = file(DAEMON_PIDS)
294 fp = file(DAEMON_PIDS)
293 for line in fp:
295 for line in fp:
294 try:
296 try:
295 pid = int(line)
297 pid = int(line)
296 except ValueError:
298 except ValueError:
297 continue
299 continue
298 try:
300 try:
299 os.kill(pid, 0)
301 os.kill(pid, 0)
300 vlog('# Killing daemon process %d' % pid)
302 vlog('# Killing daemon process %d' % pid)
301 os.kill(pid, signal.SIGTERM)
303 os.kill(pid, signal.SIGTERM)
302 time.sleep(0.25)
304 time.sleep(0.25)
303 os.kill(pid, 0)
305 os.kill(pid, 0)
304 vlog('# Daemon process %d is stuck - really killing it' % pid)
306 vlog('# Daemon process %d is stuck - really killing it' % pid)
305 os.kill(pid, signal.SIGKILL)
307 os.kill(pid, signal.SIGKILL)
306 except OSError, err:
308 except OSError, err:
307 if err.errno != errno.ESRCH:
309 if err.errno != errno.ESRCH:
308 raise
310 raise
309 fp.close()
311 fp.close()
310 os.unlink(DAEMON_PIDS)
312 os.unlink(DAEMON_PIDS)
311 except IOError:
313 except IOError:
312 pass
314 pass
313
315
314 os.chdir(TESTDIR)
316 os.chdir(TESTDIR)
315 shutil.rmtree(tmpd, True)
317 shutil.rmtree(tmpd, True)
316 return ret == 0
318 return ret == 0
317
319
318
320
319 os.umask(022)
321 os.umask(022)
320
322
321 check_required_tools()
323 check_required_tools()
322
324
323 # Reset some environment variables to well-known values so that
325 # Reset some environment variables to well-known values so that
324 # the tests produce repeatable output.
326 # the tests produce repeatable output.
325 os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
327 os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
326 os.environ['TZ'] = 'GMT'
328 os.environ['TZ'] = 'GMT'
327
329
328 os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
330 os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
329 os.environ["HGMERGE"] = sys.executable + ' -c "import sys; sys.exit(0)"'
331 os.environ["HGMERGE"] = sys.executable + ' -c "import sys; sys.exit(0)"'
330 os.environ["HGUSER"] = "test"
332 os.environ["HGUSER"] = "test"
331
333
332 TESTDIR = os.environ["TESTDIR"] = os.getcwd()
334 TESTDIR = os.environ["TESTDIR"] = os.getcwd()
333 HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.")
335 HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.")
334 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
336 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
335 HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
337 HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
336
338
337 vlog("# Using TESTDIR", TESTDIR)
339 vlog("# Using TESTDIR", TESTDIR)
338 vlog("# Using HGTMP", HGTMP)
340 vlog("# Using HGTMP", HGTMP)
339
341
340 INST = os.path.join(HGTMP, "install")
342 INST = os.path.join(HGTMP, "install")
341 BINDIR = os.path.join(INST, "bin")
343 BINDIR = os.path.join(INST, "bin")
342 PYTHONDIR = os.path.join(INST, "lib", "python")
344 PYTHONDIR = os.path.join(INST, "lib", "python")
343 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
345 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
344
346
345 try:
347 try:
346 try:
348 try:
347 install_hg()
349 install_hg()
348
350
349 if options.timeout > 0:
351 if options.timeout > 0:
350 try:
352 try:
351 signal.signal(signal.SIGALRM, alarmed)
353 signal.signal(signal.SIGALRM, alarmed)
352 vlog('# Running tests with %d-second timeout' %
354 vlog('# Running tests with %d-second timeout' %
353 options.timeout)
355 options.timeout)
354 except AttributeError:
356 except AttributeError:
355 print 'WARNING: cannot run tests with timeouts'
357 print 'WARNING: cannot run tests with timeouts'
356 options.timeout = 0
358 options.timeout = 0
357
359
358 tests = 0
360 tested = 0
359 failed = 0
361 failed = 0
360 skipped = 0
362 skipped = 0
361
363
362 if len(args) == 0:
364 if len(args) == 0:
363 args = os.listdir(".")
365 args = os.listdir(".")
364 args.sort()
366 args.sort()
365
367
368
369 tests = []
366 for test in args:
370 for test in args:
367 if (test.startswith("test-") and '~' not in test and
371 if (test.startswith("test-") and '~' not in test and
368 ('.' not in test or test.endswith('.py') or
372 ('.' not in test or test.endswith('.py') or
369 test.endswith('.bat'))):
373 test.endswith('.bat'))):
370 if options.retest and not os.path.exists(test + ".err"):
374 tests.append(test)
371 skipped += 1
375
372 continue
376 if options.restart:
373 ret = run_one(test)
377 orig = list(tests)
374 if ret is None:
378 while tests:
375 skipped += 1
379 if os.path.exists(tests[0] + ".err"):
376 elif not ret:
380 break
377 failed += 1
381 tests.pop(0)
378 if options.first:
382 if not tests:
379 break
383 print "running all tests"
380 tests += 1
384 tests = orig
381
385
382 print "\n# Ran %d tests, %d skipped, %d failed." % (tests, skipped,
386 for test in tests:
387 if options.retest and not os.path.exists(test + ".err"):
388 skipped += 1
389 continue
390 ret = run_one(test)
391 if ret is None:
392 skipped += 1
393 elif not ret:
394 failed += 1
395 if options.first:
396 break
397 tested += 1
398
399 print "\n# Ran %d tests, %d skipped, %d failed." % (tested, skipped,
383 failed)
400 failed)
384 if coverage:
401 if coverage:
385 output_coverage()
402 output_coverage()
386 except KeyboardInterrupt:
403 except KeyboardInterrupt:
387 failed = True
404 failed = True
388 print "\ninterrupted!"
405 print "\ninterrupted!"
389 finally:
406 finally:
390 cleanup_exit()
407 cleanup_exit()
391
408
392 if failed:
409 if failed:
393 sys.exit(1)
410 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now