##// END OF EJS Templates
graphlog: always sort revisions topologically...
graphlog: always sort revisions topologically The grapher cannot really handled revisions if they are not emitted in topological order. The previous 'reverse()' revset was not enough to achieve that and was replaced by an explicit sort call for simplicity. The --limit option is now also handled as usual with cmdutil.loglimit() instead of a 'limit' revset.

File last commit:

r14062:64338128 default
r14133:28085b82 default
Show More
run-tests.py
1151 lines | 36.6 KiB | text/x-python | PythonLexer
Stephen Darnell
Add a pure python version of run-tests....
r2110 #!/usr/bin/env python
#
# run-tests.py - Run a set of tests on Mercurial
#
# Copyright 2006 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Stephen Darnell
Add a pure python version of run-tests....
r2110
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 # Modifying this script is tricky because it has many modes:
# - serial (default) vs parallel (-jN, N > 1)
# - no coverage (default) vs coverage (-c, -C, -s)
# - temp install (default) vs specific hg script (--with-hg, --local)
# - tests are a mix of shell scripts and Python scripts
#
# If you change this script, it is recommended that you ensure you
# haven't broken it by running it in various modes with a representative
# sample of test scripts. For example:
Dirkjan Ochtman
kill trailing whitespace
r8843 #
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 # 1) serial, no coverage, temp install:
# ./run-tests.py test-s*
# 2) serial, no coverage, local hg:
# ./run-tests.py --local test-s*
# 3) serial, coverage, temp install:
# ./run-tests.py -c test-s*
# 4) serial, coverage, local hg:
# ./run-tests.py -c --local test-s* # unsupported
# 5) parallel, no coverage, temp install:
# ./run-tests.py -j2 test-s*
# 6) parallel, no coverage, local hg:
# ./run-tests.py -j2 --local test-s*
# 7) parallel, coverage, temp install:
# ./run-tests.py -j2 -c test-s* # currently broken
Greg Ward
run-tests: give each child its own tmp dir (issue1911)...
r9899 # 8) parallel, coverage, local install:
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 # ./run-tests.py -j2 -c --local test-s* # unsupported (and broken)
Greg Ward
run-tests: give each child its own tmp dir (issue1911)...
r9899 # 9) parallel, custom tmp dir:
# ./run-tests.py -j2 --tmpdir /tmp/myhgtests
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 #
# (You could use any subset of the tests: test-s* happens to match
# enough that it's worth doing parallel runs, few enough that it
# completes fairly quickly, includes both shell and Python scripts, and
# includes some scripts that run daemon processes.)
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 from distutils import version
Vadim Gelfer
tests: add timeouts, make run-tests.py clean up dead daemon processes...
r2571 import difflib
import errno
import optparse
import os
Nicolas Dumazet
pylint, pyflakes: remove unused or duplicate imports
r10905 import shutil
Martin Geisler
util: always use subprocess
r8280 import subprocess
Vadim Gelfer
tests: add timeouts, make run-tests.py clean up dead daemon processes...
r2571 import signal
import sys
Stephen Darnell
Add a pure python version of run-tests....
r2110 import tempfile
Vadim Gelfer
tests: add timeouts, make run-tests.py clean up dead daemon processes...
r2571 import time
Matt Mackall
tests: basic support for unified tests
r11741 import re
Matt Mackall
run-tests: add locking on results struct
r14000 import threading
Stephen Darnell
Add a pure python version of run-tests....
r2110
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 processlock = threading.Lock()
Martin Geisler
util: always use subprocess
r8280 closefds = os.name == 'posix'
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 def Popen4(cmd, wd, timeout):
processlock.acquire()
orig = os.getcwd()
os.chdir(wd)
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 p = subprocess.Popen(cmd, shell=True, bufsize=-1,
Martin Geisler
util: always use subprocess
r8280 close_fds=closefds,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 os.chdir(orig)
processlock.release()
Martin Geisler
util: always use subprocess
r8280 p.fromchild = p.stdout
p.tochild = p.stdin
p.childerr = p.stderr
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001
if timeout:
p.timeout = False
def t():
start = time.time()
while time.time() - start < timeout and p.returncode is None:
time.sleep(1)
p.timeout = True
if p.returncode is None:
try:
p.terminate()
except OSError:
pass
threading.Thread(target=t).start()
Martin Geisler
util: always use subprocess
r8280 return p
Thomas Arendsen Hein
Use skipped: instead of hghave: for skipping tests, use this in test-merge-types
r5685 # reserved exit code to skip test (used by hghave)
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 SKIPPED_STATUS = 80
Thomas Arendsen Hein
Use skipped: instead of hghave: for skipping tests, use this in test-merge-types
r5685 SKIPPED_PREFIX = 'skipped: '
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 FAILED_PREFIX = 'hghave check failed: '
Martin Geisler
run-tests: upper-case global PYTHON variable
r8096 PYTHON = sys.executable
Ronny Pfannschmidt
tests: adapt the test runner to work with jython
r10758 IMPL_PATH = 'PYTHONPATH'
if 'java' in sys.platform:
IMPL_PATH = 'JYTHONPATH'
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
Stephen Darnell
Add a pure python version of run-tests....
r2110
Thomas Arendsen Hein
run-tests.py: Allow environment variables to set jobs/timeout/port.
r6366 defaults = {
'jobs': ('HGTEST_JOBS', 1),
'timeout': ('HGTEST_TIMEOUT', 180),
'port': ('HGTEST_PORT', 20059),
}
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def parseargs():
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser = optparse.OptionParser("%prog [options] [tests]")
Matt Mackall
run-tests: sort options
r11039
# keep these sorted
parser.add_option("--blacklist", action="append",
help="skip tests listed in the specified blacklist file")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("-C", "--annotate", action="store_true",
help="output files annotated with coverage")
parser.add_option("--child", type="int",
help="run as child process, summary to given fd")
parser.add_option("-c", "--cover", action="store_true",
help="print a test coverage report")
Matt Mackall
run-tests: sort options
r11039 parser.add_option("-d", "--debug", action="store_true",
help="debug mode: write output of test scripts to console"
" rather than capturing and diff'ing it (disables timeout)")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("-f", "--first", action="store_true",
help="exit on the first test failure")
Matt Mackall
run-tests: sort options
r11039 parser.add_option("--inotify", action="store_true",
help="enable inotify extension when running tests")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("-i", "--interactive", action="store_true",
help="prompt to accept changed output")
parser.add_option("-j", "--jobs", type="int",
help="number of jobs to run in parallel"
" (default: $%s or %d)" % defaults['jobs'])
parser.add_option("--keep-tmpdir", action="store_true",
Greg Ward
run-tests: make --tmpdir option more useful....
r9706 help="keep temporary directory after running tests")
Matt Mackall
run-tests: sort options
r11039 parser.add_option("-k", "--keywords",
help="run tests matching keywords")
parser.add_option("-l", "--local", action="store_true",
help="shortcut for --with-hg=<testdir>/../hg")
parser.add_option("-n", "--nodiff", action="store_true",
help="skip showing test changes")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("-p", "--port", type="int",
help="port on which servers should listen"
" (default: $%s or %d)" % defaults['port'])
Matt Mackall
run-tests: sort options
r11039 parser.add_option("--pure", action="store_true",
help="use pure Python code instead of C extensions")
parser.add_option("-R", "--restart", action="store_true",
help="restart at last error")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("-r", "--retest", action="store_true",
help="retest failed tests")
Matt Mackall
run-tests: add --noskips option
r9580 parser.add_option("-S", "--noskips", action="store_true",
help="don't report skip tests verbosely")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("-t", "--timeout", type="int",
help="kill errant tests after TIMEOUT seconds"
" (default: $%s or %d)" % defaults['timeout'])
Matt Mackall
run-tests: sort options
r11039 parser.add_option("--tmpdir", type="string",
help="run tests in the given temporary directory"
" (implies --keep-tmpdir)")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("-v", "--verbose", action="store_true",
help="output verbose messages")
Matt Mackall
run-tests: add --view switch to use external diff viewer
r11040 parser.add_option("--view", type="string",
help="external diff viewer")
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 parser.add_option("--with-hg", type="string",
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 metavar="HG",
help="test using specified hg script rather than a "
"temporary installation")
Alejandro Santos
tests: add -3 switch to run-tests.py
r9028 parser.add_option("-3", "--py3k-warnings", action="store_true",
help="enable Py3k warnings on Python 2.6+")
Stephen Darnell
Add a pure python version of run-tests....
r2110
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 for option, default in defaults.items():
defaults[option] = int(os.environ.get(*default))
parser.set_defaults(**defaults)
(options, args) = parser.parse_args()
Ronny Pfannschmidt
tests: adapt the test runner to work with jython
r10758 # jython is always pure
Ronny Pfannschmidt
run-tests: force to test pure on pypy as well
r10766 if 'java' in sys.platform or '__pypy__' in sys.modules:
Ronny Pfannschmidt
Fix run-tests.py -jX after 2ed667a9dfcb
r10765 options.pure = True
Ronny Pfannschmidt
tests: adapt the test runner to work with jython
r10758
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 if options.with_hg:
if not (os.path.isfile(options.with_hg) and
os.access(options.with_hg, os.X_OK)):
parser.error('--with-hg must specify an executable hg script')
if not os.path.basename(options.with_hg) == 'hg':
sys.stderr.write('warning: --with-hg should specify an hg script')
if options.local:
testdir = os.path.dirname(os.path.realpath(sys.argv[0]))
hgbin = os.path.join(os.path.dirname(testdir), 'hg')
if not os.access(hgbin, os.X_OK):
parser.error('--local specified, but %r not found or not executable'
% hgbin)
options.with_hg = hgbin
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 options.anycoverage = options.cover or options.annotate
if options.anycoverage:
try:
import coverage
covver = version.StrictVersion(coverage.__version__).version
if covver < (3, 3):
parser.error('coverage options require coverage 3.3 or later')
except ImportError:
parser.error('coverage options now require the coverage package')
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 if options.anycoverage and options.local:
# this needs some path mangling somewhere, I guess
parser.error("sorry, coverage options do not work when --local "
"is specified")
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674
global vlog
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 if options.verbose:
Greg Ward
run-tests: show PID if running in parallel mode with -v....
r8671 if options.jobs > 1 or options.child is not None:
pid = "[%d]" % os.getpid()
else:
pid = None
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 def vlog(*msg):
Matt Mackall
run-tests: add iolock to vlog
r14018 iolock.acquire()
Greg Ward
run-tests: show PID if running in parallel mode with -v....
r8671 if pid:
print pid,
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 for m in msg:
print m,
print
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 sys.stdout.flush()
Matt Mackall
run-tests: add iolock to vlog
r14018 iolock.release()
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 else:
vlog = lambda *msg: None
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091
Nicolas Dumazet
run-tests: expand --tmpdir and create it if needed
r9394 if options.tmpdir:
options.tmpdir = os.path.expanduser(options.tmpdir)
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 if options.jobs < 1:
Martin Geisler
run-tests: standardize on --foo instead of -f/--foo...
r9408 parser.error('--jobs must be positive')
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 if options.interactive and options.jobs > 1:
print '(--interactive overrides --jobs)'
options.jobs = 1
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 if options.interactive and options.debug:
parser.error("-i/--interactive and -d/--debug are incompatible")
if options.debug:
if options.timeout != defaults['timeout']:
sys.stderr.write(
'warning: --timeout option ignored with --debug\n')
options.timeout = 0
Alejandro Santos
tests: add -3 switch to run-tests.py
r9028 if options.py3k_warnings:
if sys.version_info[:2] < (2, 6) or sys.version_info[:2] >= (3, 0):
Martin Geisler
run-tests: standardize on --foo instead of -f/--foo...
r9408 parser.error('--py3k-warnings can only be used on Python 2.6+')
Nicolas Dumazet
run-tests: add a "--blacklist target" option to skip predefined test lists...
r9959 if options.blacklist:
blacklist = dict()
Nicolas Dumazet
run-tests: split tests/blacklist in tests/blacklists/*...
r10300 for filename in options.blacklist:
try:
path = os.path.expanduser(os.path.expandvars(filename))
f = open(path, "r")
except IOError, err:
if err.errno != errno.ENOENT:
raise
print "warning: no such blacklist file: %s" % filename
continue
for line in f.readlines():
Patrick Mezard
run-tests: handle mixed comment lines in blacklists
r13539 line = line.split('#', 1)[0].strip()
if line:
Nicolas Dumazet
run-tests: split tests/blacklist in tests/blacklists/*...
r10300 blacklist[line] = filename
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 f.close()
Nicolas Dumazet
run-tests: add a "--blacklist target" option to skip predefined test lists...
r9959 options.blacklist = blacklist
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091
return (options, args)
Bryan O'Sullivan
Allow tests to run in parallel.
r5384
Patrick Mezard
Make run-tests.py --interactive work on Windows
r5800 def rename(src, dst):
"""Like os.rename(), trade atomicity and opened files friendliness
for existing destination support.
"""
shutil.copy(src, dst)
os.remove(src)
Vadim Gelfer
run-tests.py: fix handling of newlines....
r2247 def splitnewlines(text):
'''like str.splitlines, but only split on newlines.
keep line endings.'''
i = 0
lines = []
while True:
n = text.find('\n', i)
if n == -1:
last = text[i:]
if last:
lines.append(last)
return lines
Matt Mackall
many, many trivial check-code fixups
r10282 lines.append(text[i:n + 1])
Vadim Gelfer
run-tests.py: fix handling of newlines....
r2247 i = n + 1
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def parsehghaveoutput(lines):
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 '''Parse hghave log lines.
Return tuple of lists (missing, failed):
* the missing/unknown features
* the features for which existence check failed'''
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 missing = []
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 failed = []
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 for line in lines:
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 if line.startswith(SKIPPED_PREFIX):
line = line.splitlines()[0]
missing.append(line[len(SKIPPED_PREFIX):])
elif line.startswith(FAILED_PREFIX):
line = line.splitlines()[0]
failed.append(line[len(FAILED_PREFIX):])
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 return missing, failed
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881
Mads Kiilerich
run-tests.py: Show paths to failing tests, .err and .out...
r10088 def showdiff(expected, output, ref, err):
Idan Kamara
run-tests: print a new line before writing the diff
r14062 print
Mads Kiilerich
run-tests.py: Show paths to failing tests, .err and .out...
r10088 for line in difflib.unified_diff(expected, output, ref, err):
Vadim Gelfer
run-tests.py: fix handling of newlines....
r2247 sys.stdout.write(line)
Stephen Darnell
Add a pure python version of run-tests....
r2110
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def findprogram(program):
Stephen Darnell
Add a pure python version of run-tests....
r2110 """Search PATH for a executable program"""
for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
name = os.path.join(p, program)
if os.access(name, os.X_OK):
return name
return None
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def checktools():
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133 # Before we go any further, check for pre-requisite tools
# stuff from coreutils (cat, rm, etc) are not tested
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 for p in requiredtools:
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133 if os.name == 'nt':
p += '.exe'
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 found = findprogram(p)
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133 if found:
vlog("# Found prerequisite", p, "at", found)
else:
print "WARNING: Did not find prerequisite tool: "+p
Stephen Darnell
Add a pure python version of run-tests....
r2110
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 def killdaemons():
# Kill off any leftover daemon processes
try:
fp = open(DAEMON_PIDS)
for line in fp:
try:
pid = int(line)
except ValueError:
continue
try:
os.kill(pid, 0)
vlog('# Killing daemon process %d' % pid)
os.kill(pid, signal.SIGTERM)
time.sleep(0.25)
os.kill(pid, 0)
vlog('# Daemon process %d is stuck - really killing it' % pid)
os.kill(pid, signal.SIGKILL)
except OSError, err:
if err.errno != errno.ESRCH:
raise
fp.close()
os.unlink(DAEMON_PIDS)
except IOError:
pass
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def cleanup(options):
Peter Arrenbrecht
tests: add --keep-tmp to run-tests.py to debug test environment...
r6208 if not options.keep_tmpdir:
Greg Ward
run-tests: show PID if running in parallel mode with -v....
r8671 vlog("# Cleaning up HGTMP", HGTMP)
Peter Arrenbrecht
tests: add --keep-tmp to run-tests.py to debug test environment...
r6208 shutil.rmtree(HGTMP, True)
Stephen Darnell
Add a pure python version of run-tests....
r2110
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def usecorrectpython():
Vadim Gelfer
run-tests.py: make tests use same python interpreter as test harness....
r2570 # some tests run python interpreter. they must use same
# interpreter we use or bad things will happen.
exedir, exename = os.path.split(sys.executable)
if exename == 'python':
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 path = findprogram('python')
Vadim Gelfer
run-tests.py: make tests use same python interpreter as test harness....
r2570 if os.path.dirname(path) == exedir:
return
vlog('# Making python executable in test path use correct Python')
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 mypython = os.path.join(BINDIR, 'python')
Vadim Gelfer
run-tests.py: make tests use same python interpreter as test harness....
r2570 try:
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 os.symlink(sys.executable, mypython)
Vadim Gelfer
run-tests.py: make tests use same python interpreter as test harness....
r2570 except AttributeError:
# windows fallback
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 shutil.copyfile(sys.executable, mypython)
shutil.copymode(sys.executable, mypython)
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def installhg(options):
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133 vlog("# Performing temporary installation of HG")
installerrs = os.path.join("tests", "install.err")
Martin Geisler
run-tests: add --pure flag for using pure Python modules
r7723 pure = options.pure and "--pure" or ""
Stephen Darnell
Add a pure python version of run-tests....
r2110
Brendan Cully
Make run-tests.py work when invoked outside of tests....
r5267 # Run installer in hg root
Greg Ward
run-tests: use os.path.realpath() to find hg's setup.py....
r8943 script = os.path.realpath(sys.argv[0])
hgroot = os.path.dirname(os.path.dirname(script))
os.chdir(hgroot)
Patrick Mezard
run-tests: work around a distutils bug triggered by 0a8a43b4ca75
r9905 nohome = '--home=""'
if os.name == 'nt':
# The --home="" trick works only on OS where os.sep == '/'
# because of a distutils convert_path() fast-path. Avoid it at
# least on Windows for now, deal with .pydistutils.cfg bugs
# when they happen.
nohome = ''
Martin Geisler
run-tests: add --pure flag for using pure Python modules
r7723 cmd = ('%s setup.py %s clean --all'
Martin Geisler
run-tests: move build/ directory to HGTMP...
r12502 ' build --build-base="%s"'
Benoit Boissinot
run-tests.py: use --prefix instead of --home...
r7139 ' install --force --prefix="%s" --install-lib="%s"'
Martin Geisler
run-tests: backout d7c23f4a14c7...
r10030 ' --install-scripts="%s" %s >%s 2>&1'
Martin Geisler
run-tests: move build/ directory to HGTMP...
r12502 % (sys.executable, pure, os.path.join(HGTMP, "build"),
INST, PYTHONDIR, BINDIR, nohome, installerrs))
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133 vlog("# Running", cmd)
if os.system(cmd) == 0:
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 if not options.verbose:
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133 os.remove(installerrs)
else:
f = open(installerrs)
for line in f:
print line,
f.close()
sys.exit(1)
os.chdir(TESTDIR)
Stephen Darnell
Add a pure python version of run-tests....
r2110
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 usecorrectpython()
Vadim Gelfer
run-tests.py: make tests use same python interpreter as test harness....
r2570
Thomas Arendsen Hein
Use dummy diffstat in tests and remove older diffstat workaround....
r7172 vlog("# Installing dummy diffstat")
f = open(os.path.join(BINDIR, 'diffstat'), 'w')
f.write('#!' + sys.executable + '\n'
'import sys\n'
'files = 0\n'
'for line in sys.stdin:\n'
' if line.startswith("diff "):\n'
' files += 1\n'
'sys.stdout.write("files patched: %d\\n" % files)\n')
f.close()
os.chmod(os.path.join(BINDIR, 'diffstat'), 0700)
Alejandro Santos
tests: add -3 switch to run-tests.py
r9028 if options.py3k_warnings and not options.anycoverage:
vlog("# Updating hg command to enable Py3k Warnings switch")
f = open(os.path.join(BINDIR, 'hg'), 'r')
lines = [line.rstrip() for line in f]
lines[0] += ' -3'
f.close()
f = open(os.path.join(BINDIR, 'hg'), 'w')
for line in lines:
f.write(line + '\n')
f.close()
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 if options.anycoverage:
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 custom = os.path.join(TESTDIR, 'sitecustomize.py')
target = os.path.join(PYTHONDIR, 'sitecustomize.py')
vlog('# Installing coverage trigger to %s' % target)
shutil.copyfile(custom, target)
rc = os.path.join(TESTDIR, '.coveragerc')
vlog('# Installing coverage rc to %s' % rc)
os.environ['COVERAGE_PROCESS_START'] = rc
fn = os.path.join(INST, '..', '.coverage')
os.environ['COVERAGE_FILE'] = fn
Greg Ward
run-tests: move _hgpath() up so it's not in the middle of the main program.
r8092
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 def outputcoverage(options):
Dirkjan Ochtman
tests: make coverage run in parallel mode, clean up coverage code
r8620
vlog('# Producing coverage report')
os.chdir(PYTHONDIR)
def covrun(*args):
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 cmd = 'coverage %s' % ' '.join(args)
Dirkjan Ochtman
tests: make coverage run in parallel mode, clean up coverage code
r8620 vlog('# Running: %s' % cmd)
os.system(cmd)
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 if options.child:
return
Dirkjan Ochtman
tests: make coverage run in parallel mode, clean up coverage code
r8620
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 covrun('-c')
omit = ','.join([BINDIR, TESTDIR])
Dirkjan Ochtman
tests: make coverage run in parallel mode, clean up coverage code
r8620 covrun('-i', '-r', '"--omit=%s"' % omit) # report
Vadim Gelfer
make indentation of coverage code in run-tests.py nicer.
r2145 if options.annotate:
adir = os.path.join(TESTDIR, 'annotated')
if not os.path.isdir(adir):
os.mkdir(adir)
Dirkjan Ochtman
tests: make coverage run in parallel mode, clean up coverage code
r8620 covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
Stephen Darnell
Add code coverage to the python version of run-tests (inc. annotation)...
r2144
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 def pytest(test, wd, options, replacements):
Matt Mackall
tests: move script execution in runner helpers
r11740 py3kswitch = options.py3k_warnings and ' -3' or ''
cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
vlog("# Running", cmd)
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 return run(cmd, wd, options, replacements)
Matt Mackall
tests: move script execution in runner helpers
r11740
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 def shtest(test, wd, options, replacements):
Matt Mackall
tests: move script execution in runner helpers
r11740 cmd = '"%s"' % test
vlog("# Running", cmd)
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 return run(cmd, wd, options, replacements)
Matt Mackall
tests: move script execution in runner helpers
r11740
Mads Kiilerich
tests: use (esc) markup for string-escape...
r12941 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)]
def stringescape(s):
return escapesub(escapef, s)
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 def tsttest(test, wd, options, replacements):
Matt Mackall
tests: basic support for unified tests
r11741 t = open(test)
out = []
script = []
salt = "SALT" + str(time.time())
pos = prepos = -1
after = {}
expected = {}
for n, l in enumerate(t):
Mads Kiilerich
tests: handle .t files without trailing LF...
r12934 if not l.endswith('\n'):
l += '\n'
Matt Mackall
tests: basic support for unified tests
r11741 if l.startswith(' $ '): # commands
after.setdefault(pos, []).append(l)
prepos = pos
pos = n
Matt Mackall
tests: add exit codes to unified tests
r12316 script.append('echo %s %s $?\n' % (salt, n))
Matt Mackall
tests: basic support for unified tests
r11741 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)
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 t.close()
Matt Mackall
tests: add exit codes to unified tests
r12316 script.append('echo %s %s $?\n' % (salt, n + 1))
Matt Mackall
tests: basic support for unified tests
r11741 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)
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 exitcode, output = run(cmd, wd, options, replacements)
Thomas Arendsen Hein
tests: show skip reason instead of "irrelevant" with unified tests, too...
r12573 # do not merge output if skipped, return hghave message instead
Nicolas Dumazet
run-tests: fix --debug for .t tests...
r13002 # similarly, with --debug, output is None
if exitcode == SKIPPED_STATUS or output is None:
Thomas Arendsen Hein
tests: show skip reason instead of "irrelevant" with unified tests, too...
r12573 return exitcode, output
Matt Mackall
tests: basic support for unified tests
r11741 finally:
os.remove(name)
Nicolas Dumazet
tests: catch re.error if test line is not a valid regular expression
r11781 def rematch(el, l):
try:
Brodie Rao
tests: ensure regexes match to the end of the string...
r12374 # ensure that the regex matches to the end of the string
return re.match(el + r'\Z', l)
Nicolas Dumazet
tests: catch re.error if test line is not a valid regular expression
r11781 except re.error:
# el is an invalid regex
return False
Brodie Rao
tests: add glob matching for unified tests...
r12376 def globmatch(el, l):
# The only supported special characters are * and ?. Escaping is
# supported.
i, n = 0, len(el)
res = ''
while i < n:
c = el[i]
i += 1
if c == '\\' and el[i] in '*?\\':
Matt Mackall
tests: various fixes for new unified test pattern format
r12377 res += el[i - 1:i + 1]
Brodie Rao
tests: add glob matching for unified tests...
r12376 i += 1
elif c == '*':
res += '.*'
elif c == '?':
res += '.'
else:
res += re.escape(c)
return rematch(res, l)
Matt Mackall
tests: basic support for unified tests
r11741 pos = -1
postout = []
Matt Mackall
tests: add exit codes to unified tests
r12316 ret = 0
Matt Mackall
tests: basic support for unified tests
r11741 for n, l in enumerate(output):
Mads Kiilerich
tests: (no-eol) markup for command output without trailing LF...
r12940 lout, lcmd = l, None
if salt in l:
lout, lcmd = l.split(salt, 1)
if lout:
if lcmd:
lout += ' (no-eol)\n'
el = None
if pos in expected and expected[pos]:
el = expected[pos].pop(0)
if el == lout: # perfect match (fast)
postout.append(" " + lout)
elif (el and
(el.endswith(" (re)\n") and rematch(el[:-6] + '\n', lout) or
Erik Zielke
run-test: fixed wrong parenthesis...
r12955 el.endswith(" (glob)\n") and globmatch(el[:-8] + '\n', lout)
or el.endswith(" (esc)\n") and
el.decode('string-escape') == l)):
Mads Kiilerich
tests: use (esc) markup for string-escape...
r12941 postout.append(" " + el) # fallback regex/glob/esc match
Mads Kiilerich
tests: (no-eol) markup for command output without trailing LF...
r12940 else:
Mads Kiilerich
tests: use (esc) markup for string-escape...
r12941 if needescape(lout):
lout = stringescape(lout.rstrip('\n')) + " (esc)\n"
Mads Kiilerich
tests: (no-eol) markup for command output without trailing LF...
r12940 postout.append(" " + lout) # let diff deal with it
if lcmd:
Matt Mackall
tests: add exit codes to unified tests
r12316 # add on last return code
Mads Kiilerich
tests: (no-eol) markup for command output without trailing LF...
r12940 ret = int(lcmd.split()[1])
Matt Mackall
tests: add exit codes to unified tests
r12316 if ret != 0:
postout.append(" [%s]\n" % ret)
Matt Mackall
tests: basic support for unified tests
r11741 if pos in after:
postout += after.pop(pos)
Mads Kiilerich
tests: (no-eol) markup for command output without trailing LF...
r12940 pos = int(lcmd.split()[0])
Matt Mackall
tests: basic support for unified tests
r11741
if pos in after:
postout += after.pop(pos)
return exitcode, postout
Simon Heimberg
run-tests: only call WIFEXITED on systems it exists...
r13348 wifexited = getattr(os, "WIFEXITED", lambda x: False)
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 def run(cmd, wd, options, replacements):
Stephen Darnell
Add a pure python version of run-tests....
r2110 """Run command in a sub-process, capturing the output (stdout and stderr).
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 Return a tuple (exitcode, output). output is None in debug mode."""
Stephen Darnell
Add a pure python version of run-tests....
r2110 # TODO: Use subprocess.Popen if we're running on Python 2.4
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 if options.debug:
proc = subprocess.Popen(cmd, shell=True)
ret = proc.wait()
return (ret, None)
Frank Wierzbicki
tests: use same popen strategy for jython as for nt
r7792 if os.name == 'nt' or sys.platform.startswith('java'):
Stephen Darnell
Add a pure python version of run-tests....
r2110 tochild, fromchild = os.popen4(cmd)
tochild.close()
output = fromchild.read()
ret = fromchild.close()
Martin Geisler
code style: prefer 'is' and 'is not' tests with singletons
r13031 if ret is None:
Stephen Darnell
Add a pure python version of run-tests....
r2110 ret = 0
else:
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 proc = Popen4(cmd, wd, options.timeout)
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 def cleanup():
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 try:
proc.terminate()
except OSError:
pass
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 ret = proc.wait()
if ret == 0:
ret = signal.SIGTERM << 8
killdaemons()
return ret
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 output = ''
proc.tochild.close()
Vadim Gelfer
tests: add timeouts, make run-tests.py clean up dead daemon processes...
r2571 try:
output = proc.fromchild.read()
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 except KeyboardInterrupt:
vlog('# Handling keyboard interrupt')
cleanup()
raise
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 ret = proc.wait()
if wifexited(ret):
ret = os.WEXITSTATUS(ret)
if proc.timeout:
ret = 'timeout'
if ret:
killdaemons()
Mads Kiilerich
tests: replace test tmp directory with $TESTTMP in test output...
r12639 for s, r in replacements:
Martin Geisler
run-tests: use regex when searching for $HGPORT in test output...
r12895 output = re.sub(s, r, output)
Vadim Gelfer
run-tests.py: fix handling of newlines....
r2247 return ret, splitnewlines(output)
Stephen Darnell
Add a pure python version of run-tests....
r2110
Matt Mackall
run-tests: add locking on results struct
r14000 def runone(options, test):
Vadim Gelfer
run-tests.py: skip tests that should not run....
r2710 '''tristate output:
None -> skipped
True -> passed
False -> failed'''
Matt Mackall
run-tests: add a lock for console I/O
r14002 global results, resultslock, iolock
Matt Mackall
run-tests: add locking on results struct
r14000
Matt Mackall
run-tests: move existence/name format check into runone
r13989 testpath = os.path.join(TESTDIR, test)
Matt Mackall
run-tests: add locking on results struct
r14000 def result(l, e):
resultslock.acquire()
results[l].append(e)
resultslock.release()
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 def skip(msg):
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 if not options.verbose:
Matt Mackall
run-tests: add locking on results struct
r14000 result('s', (test, msg))
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 else:
Matt Mackall
run-tests: fix some missing i/o locks
r14003 iolock.acquire()
Mads Kiilerich
run-tests.py: Show paths to failing tests, .err and .out...
r10088 print "\nSkipping %s: %s" % (testpath, msg)
Matt Mackall
run-tests: fix some missing i/o locks
r14003 iolock.release()
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 return None
Matt Mackall
run-tests: move interactive handling into runone
r13988 def fail(msg, ret):
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 if not options.nodiff:
Matt Mackall
run-tests: fix some missing i/o locks
r14003 iolock.acquire()
Mads Kiilerich
run-tests.py: Show paths to failing tests, .err and .out...
r10088 print "\nERROR: %s %s" % (testpath, msg)
Matt Mackall
run-tests: fix some missing i/o locks
r14003 iolock.release()
Patrick Mezard
run-tests: fix --interactive (after 994ad067ac6e)...
r13999 if (not ret and options.interactive
and os.path.exists(testpath + ".err")):
Matt Mackall
run-tests: fix some missing i/o locks
r14003 iolock.acquire()
Matt Mackall
run-tests: move interactive handling into runone
r13988 print "Accept this change? [n] ",
answer = sys.stdin.readline().strip()
Matt Mackall
run-tests: fix some missing i/o locks
r14003 iolock.release()
Matt Mackall
run-tests: move interactive handling into runone
r13988 if answer.lower() in "y yes".split():
if test.endswith(".t"):
Patrick Mezard
run-tests: fix --interactive (after 994ad067ac6e)...
r13999 rename(testpath + ".err", testpath)
Matt Mackall
run-tests: move interactive handling into runone
r13988 else:
Patrick Mezard
run-tests: fix --interactive (after 994ad067ac6e)...
r13999 rename(testpath + ".err", testpath + ".out")
Matt Mackall
run-tests: move interactive handling into runone
r13988 return
Matt Mackall
run-tests: add locking on results struct
r14000 result('f', (test, msg))
Matt Mackall
run-tests: use a results dict
r13994
def success():
Matt Mackall
run-tests: add locking on results struct
r14000 result('p', test)
Matt Mackall
run-tests: use a results dict
r13994
def ignore(msg):
Matt Mackall
run-tests: add locking on results struct
r14000 result('i', (test, msg))
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244
Matt Mackall
run-tests: move existence/name format check into runone
r13989 if (test.startswith("test-") and '~' not in test and
('.' not in test or test.endswith('.py') or
test.endswith('.bat') or test.endswith('.t'))):
if not os.path.exists(test):
skip("doesn't exist")
return None
else:
return None # not a supported test, don't record
Matt Mackall
run-tests: move blacklist and retest filtering to runone
r13993 if options.blacklist:
filename = options.blacklist.get(test)
if filename is not None:
Matt Mackall
run-tests: add locking on results struct
r14000 skip("blacklisted")
Matt Mackall
run-tests: move blacklist and retest filtering to runone
r13993 return None
if options.retest and not os.path.exists(test + ".err"):
Matt Mackall
run-tests: use a results dict
r13994 ignore("not retesting")
Matt Mackall
run-tests: move blacklist and retest filtering to runone
r13993 return None
Matt Mackall
run-tests: move keyword checking into runone
r13991 if options.keywords:
fp = open(test)
t = fp.read().lower() + test.lower()
fp.close()
for k in options.keywords.lower().split():
if k in t:
break
else:
Matt Mackall
run-tests: use a results dict
r13994 ignore("doesn't match keyword")
Matt Mackall
run-tests: move keyword checking into runone
r13991 return None
Stephen Darnell
Add a pure python version of run-tests....
r2110 vlog("# Test", test)
Thomas Arendsen Hein
Clear contents of global hgrc for tests before running each test....
r2989 # create a fresh hgrc
Alejandro Santos
compat: use open() instead of file() everywhere
r9031 hgrc = open(HGRCPATH, 'w+')
Alexis S. L. Carvalho
run-tests.py: set ui.slash = True...
r4529 hgrc.write('[ui]\n')
hgrc.write('slash = True\n')
Alexis S. L. Carvalho
run-tests.py: add a default --date "0 0" argument to commit et al...
r5524 hgrc.write('[defaults]\n')
hgrc.write('backout = -d "0 0"\n')
hgrc.write('commit = -d "0 0"\n')
hgrc.write('tag = -d "0 0"\n')
Nicolas Dumazet
run-tests: add --inotify option to test runner...
r9958 if options.inotify:
hgrc.write('[extensions]\n')
hgrc.write('inotify=\n')
hgrc.write('[inotify]\n')
hgrc.write('pidfile=%s\n' % DAEMON_PIDS)
Nicolas Dumazet
run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS...
r10013 hgrc.write('appendpid=True\n')
Thomas Arendsen Hein
Clear contents of global hgrc for tests before running each test....
r2989 hgrc.close()
Stephen Darnell
Add a pure python version of run-tests....
r2110 ref = os.path.join(TESTDIR, test+".out")
Mads Kiilerich
run-tests.py: skipped tests shouldn't change working directory
r10406 err = os.path.join(TESTDIR, test+".err")
Stephen Darnell
Add a pure python version of run-tests....
r2110 if os.path.exists(err):
os.remove(err) # Remove any previous output files
Alexis S. L. Carvalho
run-tests.py: use coverage.py with "#!/usr/bin/env python" tests
r4321 try:
tf = open(testpath)
firstline = tf.readline().rstrip()
tf.close()
except:
firstline = ''
Vadim Gelfer
run-tests.py: skip tests that should not run....
r2710 lctest = test.lower()
Stephen Darnell
Add a pure python version of run-tests....
r2110
Alexis S. L. Carvalho
run-tests.py: use coverage.py with "#!/usr/bin/env python" tests
r4321 if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
Matt Mackall
tests: move script execution in runner helpers
r11740 runner = pytest
Matt Mackall
tests: basic support for unified tests
r11741 elif lctest.endswith('.t'):
runner = tsttest
ref = testpath
Vadim Gelfer
run-tests.py: skip tests that should not run....
r2710 else:
# do not try to run non-executable programs
Benoit Boissinot
run-tests.py: remove support for .bat files
r12678 if not os.access(testpath, os.X_OK):
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 return skip("not executable")
Matt Mackall
tests: move script execution in runner helpers
r11740 runner = shtest
Stephen Darnell
Add a pure python version of run-tests....
r2110
Mads Kiilerich
run-tests.py: skipped tests shouldn't change working directory
r10406 # Make a tmp subdirectory to work in
Idan Kamara
tests: set HOME to the test temp dir (issue2707)
r13764 testtmp = os.environ["TESTTMP"] = os.environ["HOME"] = \
os.path.join(HGTMP, test)
Mads Kiilerich
tests: replace test tmp directory with $TESTTMP in test output...
r12639 os.mkdir(testtmp)
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 ret, out = runner(testpath, testtmp, options, [
Martin Geisler
run-tests: use regex when searching for $HGPORT in test output...
r12895 (re.escape(testtmp), '$TESTTMP'),
(r':%s\b' % options.port, ':$HGPORT'),
(r':%s\b' % (options.port + 1), ':$HGPORT1'),
(r':%s\b' % (options.port + 2), ':$HGPORT2'),
Mads Kiilerich
tests: reintroduce ":$HGPORT" in test output...
r12643 ])
Stephen Darnell
Add a pure python version of run-tests....
r2110 vlog("# Ret was:", ret)
Matt Mackall
run-tests: allow turning off diff display
r7343 mark = '.'
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 skipped = (ret == SKIPPED_STATUS)
Matt Mackall
run-tests: add --view switch to use external diff viewer
r11040
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 # If we're not in --debug mode and reference output file exists,
# check test output against it.
if options.debug:
Martin Geisler
code style: prefer 'is' and 'is not' tests with singletons
r13031 refout = None # to match "out is None"
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 elif os.path.exists(ref):
Vadim Gelfer
run-tests.py must print changed test output no matter what exit code is.
r2213 f = open(ref, "r")
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 refout = splitnewlines(f.read())
Vadim Gelfer
run-tests.py must print changed test output no matter what exit code is.
r2213 f.close()
Vadim Gelfer
run-tests.py: print diff if reference output not existing.
r2246 else:
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 refout = []
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707
Matt Mackall
run-tests: add --view switch to use external diff viewer
r11040 if (ret != 0 or out != refout) and not skipped and not options.debug:
# Save errors to a file for diagnosis
f = open(err, "wb")
for line in out:
f.write(line)
f.close()
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 if skipped:
Matt Mackall
run-tests: allow turning off diff display
r7343 mark = 's'
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 if out is None: # debug mode: nothing to parse
missing = ['unknown']
failed = None
else:
missing, failed = parsehghaveoutput(out)
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 if not missing:
missing = ['irrelevant']
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 if failed:
Matt Mackall
run-tests: move interactive handling into runone
r13988 fail("hghave failed checking for %s" % failed[-1], ret)
Nicolas Dumazet
run-tests: detect when hghave fails to check for a feature and fail test...
r8060 skipped = False
else:
skip(missing[-1])
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 elif ret == 'timeout':
mark = 't'
fail("timed out", ret)
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 elif out != refout:
Matt Mackall
run-tests: allow turning off diff display
r7343 mark = '!'
Patrick Mezard
run-tests: display diff before prompting with --interactive
r14006 if not options.nodiff:
Matt Mackall
run-tests: add a lock for console I/O
r14002 iolock.acquire()
Matt Mackall
run-tests: add --view switch to use external diff viewer
r11040 if options.view:
os.system("%s %s %s" % (options.view, ref, err))
else:
showdiff(refout, out, ref, err)
Matt Mackall
run-tests: add a lock for console I/O
r14002 iolock.release()
Patrick Mezard
run-tests: display diff before prompting with --interactive
r14006 if ret:
fail("output changed and returned error code %d" % ret, ret)
else:
fail("output changed", ret)
Thomas Arendsen Hein
run-tests.py: Only one fail message when output changed and error code....
r6383 ret = 1
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 elif ret:
Matt Mackall
run-tests: allow turning off diff display
r7343 mark = '!'
Matt Mackall
run-tests: move interactive handling into runone
r13988 fail("returned error code %d" % ret, ret)
Idan Kamara
run-tests: don't count test as succeeded if it failed...
r14037 else:
success()
Stephen Darnell
Add a pure python version of run-tests....
r2110
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 if not options.verbose:
Matt Mackall
run-tests: add a lock for console I/O
r14002 iolock.acquire()
Matt Mackall
run-tests: allow turning off diff display
r7343 sys.stdout.write(mark)
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 sys.stdout.flush()
Matt Mackall
run-tests: add a lock for console I/O
r14002 iolock.release()
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 killdaemons()
Vadim Gelfer
tests: add timeouts, make run-tests.py clean up dead daemon processes...
r2571
Peter Arrenbrecht
tests: add --keep-tmp to run-tests.py to debug test environment...
r6208 if not options.keep_tmpdir:
Mads Kiilerich
tests: replace test tmp directory with $TESTTMP in test output...
r12639 shutil.rmtree(testtmp, True)
Patrick Mezard
Add hghave utility and run-tests.py support....
r4881 if skipped:
return None
Stephen Darnell
Add a pure python version of run-tests....
r2110 return ret == 0
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 _hgpath = None
def _gethgpath():
"""Return the path to the mercurial package that is actually found by
the current Python interpreter."""
global _hgpath
if _hgpath is not None:
return _hgpath
cmd = '%s -c "import mercurial; print mercurial.__path__[0]"'
pipe = os.popen(cmd % PYTHON)
try:
_hgpath = pipe.read().strip()
finally:
pipe.close()
return _hgpath
def _checkhglib(verb):
"""Ensure that the 'mercurial' package imported by python is
Greg Ward
run-tests: fix _checkhglib() so it's correct when using --with-hg....
r8673 the one we expect it to be. If not, print a warning to stderr."""
expecthg = os.path.join(PYTHONDIR, 'mercurial')
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 actualhg = _gethgpath()
if actualhg != expecthg:
Greg Ward
run-tests: fix _checkhglib() so it's correct when using --with-hg....
r8673 sys.stderr.write('warning: %s with unexpected mercurial lib: %s\n'
' (expected %s)\n'
% (verb, actualhg, expecthg))
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672
def runchildren(options, tests):
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 if INST:
Benoit Boissinot
run-tests: fix -jN broken by 60a9e3cf0cf4
r8107 installhg(options)
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 _checkhglib("Testing")
Bryan O'Sullivan
Allow tests to run in parallel.
r5384
optcopy = dict(options.__dict__)
optcopy['jobs'] = 1
Ry4an Brase
Fix --blacklist when --jobs > 1 in run_tests.py....
r10904 del optcopy['blacklist']
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 if optcopy['with_hg'] is None:
optcopy['with_hg'] = os.path.join(BINDIR, "hg")
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 optcopy.pop('anycoverage', None)
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 opts = []
for opt, value in optcopy.iteritems():
name = '--' + opt.replace('_', '-')
if value is True:
opts.append(name)
elif value is not None:
opts.append(name + '=' + str(value))
tests.reverse()
jobs = [[] for j in xrange(options.jobs)]
while tests:
Simon Heimberg
run-tests: cosmetics
r8161 for job in jobs:
Matt Mackall
many, many trivial check-code fixups
r10282 if not tests:
break
Simon Heimberg
run-tests: cosmetics
r8161 job.append(tests.pop())
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 fps = {}
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336
Simon Heimberg
run-tests: cosmetics
r8161 for j, job in enumerate(jobs):
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 if not job:
continue
rfd, wfd = os.pipe()
childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
Greg Ward
run-tests: give each child its own tmp dir (issue1911)...
r9899 childtmp = os.path.join(HGTMP, 'child%d' % j)
childopts += ['--tmpdir', childtmp]
Martin Geisler
run-tests: upper-case global PYTHON variable
r8096 cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 vlog(' '.join(cmdline))
fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
os.close(wfd)
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 signal.signal(signal.SIGINT, signal.SIG_IGN)
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 failures = 0
tested, skipped, failed = 0, 0, 0
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 skips = []
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244 fails = []
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 while fps:
pid, status = os.wait()
fp = fps.pop(pid)
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 l = fp.read().splitlines()
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 try:
test, skip, fail = map(int, l[:3])
except ValueError:
test, skip, fail = 0, 0, 0
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244 split = -fail or len(l)
for s in l[3:split]:
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 skips.append(s.split(" ", 1))
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244 for s in l[split:]:
fails.append(s.split(" ", 1))
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 tested += test
skipped += skip
failed += fail
vlog('pid %d exited, status %d' % (pid, status))
failures |= status
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 print
Matt Mackall
run-tests: add --noskips option
r9580 if not options.noskips:
for s in skips:
print "Skipped %s: %s" % (s[0], s[1])
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244 for s in fails:
print "Failed %s: %s" % (s[0], s[1])
Dirkjan Ochtman
imported patch test-check
r6982
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 _checkhglib("Tested")
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 print "# Ran %d tests, %d skipped, %d failed." % (
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 tested, skipped, failed)
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648
if options.anycoverage:
outputcoverage(options)
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 sys.exit(failures != 0)
Matt Mackall
run-tests: add locking on results struct
r14000 results = dict(p=[], f=[], s=[], i=[])
resultslock = threading.Lock()
Matt Mackall
run-tests: add a lock for console I/O
r14002 iolock = threading.Lock()
Matt Mackall
run-tests: add locking on results struct
r14000
Matt Mackall
run-tests: move test loop into a helper function
r13995 def runqueue(options, tests, results):
for test in tests:
Matt Mackall
run-tests: add locking on results struct
r14000 ret = runone(options, test)
Matt Mackall
run-tests: move test loop into a helper function
r13995 if options.first and ret is not None and not ret:
break
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 def runtests(options, tests):
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 global DAEMON_PIDS, HGRCPATH
DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
Benoit Boissinot
catch KeyboardInterrupt in run-tests
r2258 try:
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 if INST:
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 installhg(options)
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 _checkhglib("Testing")
Dirkjan Ochtman
imported patch test-check
r6982
Matt Mackall
tests: add -R switch...
r3625 if options.restart:
orig = list(tests)
while tests:
if os.path.exists(tests[0] + ".err"):
break
tests.pop(0)
if not tests:
print "running all tests"
tests = orig
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133
Matt Mackall
run-tests: move test loop into a helper function
r13995 runqueue(options, tests, results)
Matt Mackall
tests: add -R switch...
r3625
Matt Mackall
run-tests: use a results dict
r13994 failed = len(results['f'])
tested = len(results['p']) + failed
skipped = len(results['s'])
ignored = len(results['i'])
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 if options.child:
fp = os.fdopen(options.child, 'w')
fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
Matt Mackall
run-tests: use a results dict
r13994 for s in results['s']:
Thomas Arendsen Hein
Removed tabs and trailing whitespace in python files
r5760 fp.write("%s %s\n" % s)
Matt Mackall
run-tests: use a results dict
r13994 for s in results['f']:
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244 fp.write("%s %s\n" % s)
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 fp.close()
else:
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 print
Matt Mackall
run-tests: use a results dict
r13994 for s in results['s']:
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 print "Skipped %s: %s" % s
Matt Mackall
run-tests: use a results dict
r13994 for s in results['f']:
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244 print "Failed %s: %s" % s
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 _checkhglib("Tested")
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 print "# Ran %d tests, %d skipped, %d failed." % (
Matt Mackall
run-tests: use a results dict
r13994 tested, skipped + ignored, failed)
Bryan O'Sullivan
Allow tests to run in parallel.
r5384
Greg Ward
run-tests: reduce global variables set by parse_args().
r8095 if options.anycoverage:
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 outputcoverage(options)
Benoit Boissinot
catch KeyboardInterrupt in run-tests
r2258 except KeyboardInterrupt:
failed = True
print "\ninterrupted!"
Bryan O'Sullivan
Allow tests to run in parallel.
r5384
Matt Mackall
run-tests: use a results dict
r13994 if failed:
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 sys.exit(1)
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 def main():
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 (options, args) = parseargs()
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 if not options.child:
os.umask(022)
Greg Ward
run-tests: move bits of main program so it's all at the bottom.
r8093
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 checktools()
Greg Ward
run-tests: move bits of main program so it's all at the bottom.
r8093
Benoit Boissinot
run-tests.py: do not install hg when the tests do no exist
r12677 if len(args) == 0:
args = os.listdir(".")
args.sort()
Matt Mackall
run-tests: move existence/name format check into runone
r13989 tests = args
Benoit Boissinot
run-tests.py: do not install hg when the tests do no exist
r12677
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 # Reset some environment variables to well-known values so that
# the tests produce repeatable output.
Wagner Bruna
run-tests: LANGUAGE may make tests fail
r9931 os.environ['LANG'] = os.environ['LC_ALL'] = os.environ['LANGUAGE'] = 'C'
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 os.environ['TZ'] = 'GMT'
os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
os.environ['CDPATH'] = ''
Benoit Boissinot
run-tests: always set $COLUMNS, fix running tests under emacs shell...
r9913 os.environ['COLUMNS'] = '80'
Brodie Rao
run-tests: make sure GREP_OPTIONS isn't set...
r10750 os.environ['GREP_OPTIONS'] = ''
Wagner Bruna
run-tests.py: clears http_proxy for all tests
r10154 os.environ['http_proxy'] = ''
Greg Ward
run-tests: move bits of main program so it's all at the bottom.
r8093
Benoit Boissinot
run-tests.py: reset env variables set by hooks
r10902 # unset env related to hooks
for k in os.environ.keys():
if k.startswith('HG_'):
Benoit Boissinot
run-tests.py: can't remove from os.environ on solaris
r10923 # can't remove on solaris
os.environ[k] = ''
Benoit Boissinot
run-tests.py: reset env variables set by hooks
r10902 del os.environ[k]
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
TESTDIR = os.environ["TESTDIR"] = os.getcwd()
Greg Ward
run-tests: make --tmpdir option more useful....
r9706 if options.tmpdir:
options.keep_tmpdir = True
tmpdir = options.tmpdir
if os.path.exists(tmpdir):
# Meaning of tmpdir has changed since 1.3: we used to create
# HGTMP inside tmpdir; now HGTMP is tmpdir. So fail if
# tmpdir already exists.
sys.exit("error: temp dir %r already exists" % tmpdir)
# Automatically removing tmpdir sounds convenient, but could
# really annoy anyone in the habit of using "--tmpdir=/tmp"
# or "--tmpdir=$HOME".
#vlog("# Removing temp dir", tmpdir)
#shutil.rmtree(tmpdir)
os.makedirs(tmpdir)
else:
tmpdir = tempfile.mkdtemp('', 'hgtests.')
HGTMP = os.environ['HGTMP'] = os.path.realpath(tmpdir)
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 DAEMON_PIDS = None
HGRCPATH = None
Greg Ward
run-tests: move bits of main program so it's all at the bottom.
r8093
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
os.environ["HGMERGE"] = "internal:merge"
os.environ["HGUSER"] = "test"
os.environ["HGENCODING"] = "ascii"
os.environ["HGENCODINGMODE"] = "strict"
os.environ["HGPORT"] = str(options.port)
os.environ["HGPORT1"] = str(options.port + 1)
os.environ["HGPORT2"] = str(options.port + 2)
Greg Ward
run-tests: move bits of main program so it's all at the bottom.
r8093
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 if options.with_hg:
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 INST = None
BINDIR = os.path.dirname(os.path.realpath(options.with_hg))
# This looks redundant with how Python initializes sys.path from
# the location of the script being executed. Needed because the
# "hg" specified by --with-hg is not the only Python script
# executed in the test suite that needs to import 'mercurial'
# ... which means it's not really redundant at all.
PYTHONDIR = BINDIR
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 else:
INST = os.path.join(HGTMP, "install")
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin")
PYTHONDIR = os.path.join(INST, "lib", "python")
os.environ["BINDIR"] = BINDIR
os.environ["PYTHON"] = PYTHON
if not options.child:
path = [BINDIR] + os.environ["PATH"].split(os.pathsep)
os.environ["PATH"] = os.pathsep.join(path)
Brendan Cully
Unbreak run-tests support for out-of-tree extensions
r8724 # Include TESTDIR in PYTHONPATH so that out-of-tree extensions
# can run .../tests/run-tests.py test-foo where test-foo
# adds an extension to HGRC
pypath = [PYTHONDIR, TESTDIR]
Greg Ward
run-tests: don't replace PYTHONPATH, just augment it....
r8687 # We have to augment PYTHONPATH, rather than simply replacing
# it, in case external libraries are only available via current
# PYTHONPATH. (In particular, the Subversion bindings on OS X
# are in /opt/subversion.)
Ronny Pfannschmidt
tests: adapt the test runner to work with jython
r10758 oldpypath = os.environ.get(IMPL_PATH)
Brendan Cully
Unbreak run-tests support for out-of-tree extensions
r8724 if oldpypath:
pypath.append(oldpypath)
Ronny Pfannschmidt
tests: adapt the test runner to work with jython
r10758 os.environ[IMPL_PATH] = os.pathsep.join(pypath)
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
Greg Ward
run-tests: move bits of main program so it's all at the bottom.
r8093
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 vlog("# Using TESTDIR", TESTDIR)
vlog("# Using HGTMP", HGTMP)
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 vlog("# Using PATH", os.environ["PATH"])
Ronny Pfannschmidt
tests: adapt the test runner to work with jython
r10758 vlog("# Using", IMPL_PATH, os.environ[IMPL_PATH])
Bryan O'Sullivan
Allow tests to run in parallel.
r5384
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 try:
if len(tests) > 1 and options.jobs > 1:
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 runchildren(options, tests)
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 else:
Greg Ward
run-tests: factor out _checkhglib() to check import path of 'mercurial'....
r8672 runtests(options, tests)
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 finally:
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 time.sleep(1)
Martin Geisler
run-tests: removed some underscores (coding style)
r8097 cleanup(options)
Bryan O'Sullivan
Allow tests to run in parallel.
r5384
Simon Heimberg
run-tests: loadable as module
r13347 if __name__ == '__main__':
main()