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 os, sys, shutil, re |
10 import difflib |
|
11 import errno |
|
12 import optparse |
|
13 import os |
|
14 import popen2 |
|
15 import re |
|
16 import shutil |
|
17 import signal |
|
18 import sys |
11 import tempfile |
19 import tempfile |
12 import difflib |
20 import time |
13 import popen2 |
|
14 from optparse import OptionParser |
|
15 |
21 |
16 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] |
22 required_tools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"] |
17 |
23 |
18 parser = OptionParser("%prog [options] [tests]") |
24 parser = optparse.OptionParser("%prog [options] [tests]") |
19 parser.add_option("-v", "--verbose", action="store_true", |
25 parser.add_option("-v", "--verbose", action="store_true", |
|
26 help="output verbose messages") |
|
27 parser.add_option("-t", "--timeout", type="int", |
20 help="output verbose messages") |
28 help="output verbose messages") |
21 parser.add_option("-c", "--cover", action="store_true", |
29 parser.add_option("-c", "--cover", action="store_true", |
22 help="print a test coverage report") |
30 help="print a test coverage report") |
23 parser.add_option("-s", "--cover_stdlib", action="store_true", |
31 parser.add_option("-s", "--cover_stdlib", action="store_true", |
24 help="print a test coverage report inc. standard libraries") |
32 help="print a test coverage report inc. standard libraries") |
25 parser.add_option("-C", "--annotate", action="store_true", |
33 parser.add_option("-C", "--annotate", action="store_true", |
26 help="output files annotated with coverage") |
34 help="output files annotated with coverage") |
|
35 parser.set_defaults(timeout=30) |
27 (options, args) = parser.parse_args() |
36 (options, args) = parser.parse_args() |
28 verbose = options.verbose |
37 verbose = options.verbose |
29 coverage = options.cover or options.cover_stdlib or options.annotate |
38 coverage = options.cover or options.cover_stdlib or options.annotate |
30 |
39 |
31 def vlog(*msg): |
40 def vlog(*msg): |
157 sys.executable, os.path.join(TESTDIR, 'coverage.py'), |
166 sys.executable, os.path.join(TESTDIR, 'coverage.py'), |
158 adir, omit) |
167 adir, omit) |
159 vlog("# Running: "+cmd) |
168 vlog("# Running: "+cmd) |
160 os.system(cmd) |
169 os.system(cmd) |
161 |
170 |
|
171 class Timeout(Exception): |
|
172 pass |
|
173 |
|
174 def alarmed(signum, frame): |
|
175 raise Timeout |
|
176 |
162 def run(cmd): |
177 def run(cmd): |
163 """Run command in a sub-process, capturing the output (stdout and stderr). |
178 """Run command in a sub-process, capturing the output (stdout and stderr). |
164 Return the exist code, and output.""" |
179 Return the exist code, and output.""" |
165 # TODO: Use subprocess.Popen if we're running on Python 2.4 |
180 # TODO: Use subprocess.Popen if we're running on Python 2.4 |
166 if os.name == 'nt': |
181 if os.name == 'nt': |
202 # To reliably get the error code from batch files on WinXP, |
225 # To reliably get the error code from batch files on WinXP, |
203 # the "cmd /c call" prefix is needed. Grrr |
226 # the "cmd /c call" prefix is needed. Grrr |
204 if os.name == 'nt' and test.endswith(".bat"): |
227 if os.name == 'nt' and test.endswith(".bat"): |
205 cmd = 'cmd /c call "%s"' % (os.path.join(TESTDIR, test)) |
228 cmd = 'cmd /c call "%s"' % (os.path.join(TESTDIR, test)) |
206 |
229 |
|
230 if options.timeout > 0: |
|
231 signal.alarm(options.timeout) |
|
232 |
207 vlog("# Running", cmd) |
233 vlog("# Running", cmd) |
208 ret, out = run(cmd) |
234 ret, out = run(cmd) |
209 vlog("# Ret was:", ret) |
235 vlog("# Ret was:", ret) |
|
236 |
|
237 if options.timeout > 0: |
|
238 signal.alarm(0) |
210 |
239 |
211 diffret = 0 |
240 diffret = 0 |
212 # If reference output file exists, check test output against it |
241 # If reference output file exists, check test output against it |
213 if os.path.exists(ref): |
242 if os.path.exists(ref): |
214 f = open(ref, "r") |
243 f = open(ref, "r") |
250 os.environ["HGUSER"] = "test" |
303 os.environ["HGUSER"] = "test" |
251 os.environ["HGRCPATH"] = "" |
304 os.environ["HGRCPATH"] = "" |
252 |
305 |
253 TESTDIR = os.environ["TESTDIR"] = os.getcwd() |
306 TESTDIR = os.environ["TESTDIR"] = os.getcwd() |
254 HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.") |
307 HGTMP = os.environ["HGTMP"] = tempfile.mkdtemp("", "hgtests.") |
|
308 DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids') |
|
309 |
255 vlog("# Using TESTDIR", TESTDIR) |
310 vlog("# Using TESTDIR", TESTDIR) |
256 vlog("# Using HGTMP", HGTMP) |
311 vlog("# Using HGTMP", HGTMP) |
257 |
312 |
258 INST = os.path.join(HGTMP, "install") |
313 INST = os.path.join(HGTMP, "install") |
259 BINDIR = os.path.join(INST, "bin") |
314 BINDIR = os.path.join(INST, "bin") |