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