@@ -642,17 +642,18 @@ class Test(object):
class PythonTest(Test):
"""A Python-based test."""
def _run(self, testtmp, replacements, env):
py3kswitch = self._options.py3k_warnings and ' -3' or ''
cmd = '%s%s "%s"' % (PYTHON, py3kswitch, self._path)
vlog("# Running", cmd)
if os.name == 'nt':
replacements.append((r'\r\n', '\n'))
- return run(cmd, testtmp, self._options, replacements, env)
+ return run(cmd, testtmp, self._options, replacements, env,
+ self._runner.abort)
needescape = re.compile(r'[\x00-\x08\x0b-\x1f\x7f-\xff]').search
escapesub = re.compile(r'[\x00-\x08\x0b-\x1f\\\x7f-\xff]').sub
escapemap = dict((chr(i), r'\x%02x' % i) for i in range(256))
escapemap.update({'\\': '\\\\', '\r': r'\r'})
def escapef(m):
return escapemap[m.group(0)]
@@ -674,17 +675,18 @@ class TTest(Test):
f = open(fname, 'w')
for l in script:
f.write(l)
f.close()
cmd = '%s "%s"' % (self._options.shell, fname)
vlog("# Running", cmd)
- exitcode, output = run(cmd, testtmp, self._options, replacements, env)
+ exitcode, output = run(cmd, testtmp, self._options, replacements, env,
+ self._runner.abort)
# Do not merge output if skipped. Return hghave message instead.
# Similarly, with --debug, output is None.
if exitcode == SKIPPED_STATUS or output is None:
return exitcode, output
return self._processoutput(exitcode, output, salt, after, expected)
def _hghave(self, reqs, testtmp):
@@ -922,17 +924,17 @@ class TTest(Test):
return TTest.rematch(el[:-6], l)
if el.endswith(" (glob)\n"):
return TTest.globmatch(el[:-8], l)
if os.altsep and l.replace('\\', '/') == el:
return '+glob'
return False
wifexited = getattr(os, "WIFEXITED", lambda x: False)
-def run(cmd, wd, options, replacements, env):
+def run(cmd, wd, options, replacements, env, abort):
"""Run command in a sub-process, capturing the output (stdout and stderr).
Return a tuple (exitcode, output). output is None in debug mode."""
# TODO: Use subprocess.Popen if we're running on Python 2.4
if options.debug:
proc = subprocess.Popen(cmd, shell=True, cwd=wd, env=env)
ret = proc.wait()
return (ret, None)
@@ -960,17 +962,17 @@ def run(cmd, wd, options, replacements,
ret = os.WEXITSTATUS(ret)
if proc.timeout:
ret = 'timeout'
if ret:
killdaemons(env['DAEMON_PIDS'])
- if abort:
+ if abort[0]:
raise KeyboardInterrupt()
for s, r in replacements:
output = re.sub(s, r, output)
return ret, output.splitlines(True)
_hgpath = None
@@ -985,24 +987,22 @@ def _gethgpath():
pipe = os.popen(cmd % PYTHON)
try:
_hgpath = pipe.read().strip()
finally:
pipe.close()
return _hgpath
iolock = threading.Lock()
-abort = False
def scheduletests(runner, tests):
jobs = runner.options.jobs
done = queue.Queue()
running = 0
count = 0
- global abort
def job(test, count):
try:
t = runner.gettest(test, count)
done.put(t.run())
del t # For side-effects.
except KeyboardInterrupt:
pass
@@ -1025,17 +1025,17 @@ def scheduletests(runner, tests):
test = tests.pop(0)
if runner.options.loop:
tests.append(test)
t = threading.Thread(target=job, name=test, args=(test, count))
t.start()
running += 1
count += 1
except KeyboardInterrupt:
- abort = True
+ runner.abort[0] = True
class TestRunner(object):
"""Holds context for executing tests.
Tests rely on a lot of state. This object holds it for them.
"""
TESTTYPES = [
@@ -1055,16 +1055,17 @@ class TestRunner(object):
self.times = [] # Holds execution times of tests.
self.results = {
'.': [],
'!': [],
'~': [],
's': [],
'i': [],
}
+ self.abort = [False]
self._createdfiles = []
def runtests(self, tests):
try:
if self.inst:
self.installhg()
self.checkhglib("Testing")
else: