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