--- a/tests/run-tests.py Mon Jul 26 12:32:45 2010 +0200
+++ b/tests/run-tests.py Sat Aug 14 09:47:41 2010 +0100
@@ -52,6 +52,7 @@
import sys
import tempfile
import time
+import re
closefds = os.name == 'posix'
def Popen4(cmd, bufsize=-1):
@@ -441,6 +442,94 @@
def alarmed(signum, frame):
raise Timeout
+def pytest(test, options):
+ py3kswitch = options.py3k_warnings and ' -3' or ''
+ cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
+ vlog("# Running", cmd)
+ return run(cmd, options)
+
+def shtest(test, options):
+ cmd = '"%s"' % test
+ vlog("# Running", cmd)
+ return run(cmd, options)
+
+def battest(test, options):
+ # To reliably get the error code from batch files on WinXP,
+ # the "cmd /c call" prefix is needed. Grrr
+ cmd = 'cmd /c call "%s"' % testpath
+ vlog("# Running", cmd)
+ return run(cmd, options)
+
+def tsttest(test, options):
+ t = open(test)
+ out = []
+ script = []
+ salt = "SALT" + str(time.time())
+
+ pos = prepos = -1
+ after = {}
+ expected = {}
+ for n, l in enumerate(t):
+ if l.startswith(' $ '): # commands
+ after.setdefault(pos, []).append(l)
+ prepos = pos
+ pos = n
+ script.append('echo %s %s\n' % (salt, n))
+ script.append(l[4:])
+ elif l.startswith(' > '): # continuations
+ after.setdefault(prepos, []).append(l)
+ script.append(l[4:])
+ elif l.startswith(' '): # results
+ # queue up a list of expected results
+ expected.setdefault(pos, []).append(l[2:])
+ else:
+ # non-command/result - queue up for merged output
+ after.setdefault(pos, []).append(l)
+
+ fd, name = tempfile.mkstemp(suffix='hg-tst')
+
+ try:
+ for l in script:
+ os.write(fd, l)
+ os.close(fd)
+
+ cmd = '/bin/sh "%s"' % name
+ vlog("# Running", cmd)
+ exitcode, output = run(cmd, options)
+ finally:
+ os.remove(name)
+
+ def rematch(el, l):
+ try:
+ return re.match(el, l)
+ except re.error:
+ # el is an invalid regex
+ return False
+
+ pos = -1
+ postout = []
+ for n, l in enumerate(output):
+ if l.startswith(salt):
+ if pos in after:
+ postout += after.pop(pos)
+ pos = int(l.split()[1])
+ else:
+ el = None
+ if pos in expected and expected[pos]:
+ el = expected[pos].pop(0)
+
+ if el == l: # perfect match (fast)
+ postout.append(" " + l)
+ elif el and rematch(el, l): # fallback regex match
+ postout.append(" " + el)
+ else: # mismatch - let diff deal with it
+ postout.append(" " + l)
+
+ if pos in after:
+ postout += after.pop(pos)
+
+ return exitcode, postout
+
def run(cmd, options):
"""Run command in a sub-process, capturing the output (stdout and stderr).
Return a tuple (exitcode, output). output is None in debug mode."""
@@ -537,15 +626,15 @@
lctest = test.lower()
if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
- py3kswitch = options.py3k_warnings and ' -3' or ''
- cmd = '%s%s "%s"' % (PYTHON, py3kswitch, testpath)
+ runner = pytest
elif lctest.endswith('.bat'):
# do not run batch scripts on non-windows
if os.name != 'nt':
return skip("batch script")
- # To reliably get the error code from batch files on WinXP,
- # the "cmd /c call" prefix is needed. Grrr
- cmd = 'cmd /c call "%s"' % testpath
+ runner = battest
+ elif lctest.endswith('.t'):
+ runner = tsttest
+ ref = testpath
else:
# do not run shell scripts on windows
if os.name == 'nt':
@@ -555,7 +644,7 @@
return fail("does not exist")
elif not os.access(testpath, os.X_OK):
return skip("not executable")
- cmd = '"%s"' % testpath
+ runner = shtest
# Make a tmp subdirectory to work in
tmpd = os.path.join(HGTMP, test)
@@ -565,8 +654,7 @@
if options.timeout > 0:
signal.alarm(options.timeout)
- vlog("# Running", cmd)
- ret, out = run(cmd, options)
+ ret, out = runner(testpath, options)
vlog("# Ret was:", ret)
if options.timeout > 0:
@@ -807,7 +895,10 @@
print "Accept this change? [n] ",
answer = sys.stdin.readline().strip()
if answer.lower() in "y yes".split():
- rename(test + ".err", test + ".out")
+ if test.endswith(".t"):
+ rename(test + ".err", test)
+ else:
+ rename(test + ".err", test + ".out")
tested += 1
fails.pop()
continue
@@ -944,7 +1035,7 @@
for test in args:
if (test.startswith("test-") and '~' not in test and
('.' not in test or test.endswith('.py') or
- test.endswith('.bat'))):
+ test.endswith('.bat') or test.endswith('.t'))):
tests.append(test)
if not tests:
print "# Ran 0 tests, 0 skipped, 0 failed."