##// END OF EJS Templates
rebase: properly handle unrebased revision between rebased one...
rebase: properly handle unrebased revision between rebased one With rebase taking multiple roots it is possible to have revision in the "rebase domain" not rebased themself. We do not want rebased revision above them to be detached. We want such revision to be rebased on the nearest rebased ancestors. This allows to preserve the topology of the rebase set as much a possible To achieve this we introduce a new state `revignored` which informs `defineparents` of the situation. The test in `test-rebase-obsolete.t` was actually wrote and his now fixed.

File last commit:

r18384:e389a25e default
r18447:7159426c default
Show More
run-tests.py
1357 lines | 45.3 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
Patrick Mezard
run-tests: do not duplicate killdaemons() code
r17464 import killdaemons as killmod
Siddharth Agarwal
run-tests: use pickle to send results from children to parent...
r17919 import cPickle as pickle
Bryan O'Sullivan
run-tests: support running tests in parallel on windows...
r18057 import Queue as queue
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()
Patrick Mezard
run-tests: replace chdir() with Popen cwd option
r14340 p = subprocess.Popen(cmd, shell=True, bufsize=-1, cwd=wd,
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 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
Patrick Mezard
run-tests: ignore timeout when Popen.terminate is unavailable...
r14337 p.timeout = False
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 if timeout:
def t():
start = time.time()
while time.time() - start < timeout and p.returncode is None:
Matt Mackall
tests: shorten post-test sleeps...
r16346 time.sleep(.1)
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 p.timeout = True
if p.returncode is None:
Thomas Arendsen Hein
run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
r14821 terminate(p)
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001 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: '
Mads Kiilerich
run-tests: convert windows paths to unix
r15448 PYTHON = sys.executable.replace('\\', '/')
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
Bryan O'Sullivan
run-tests: check for the correct python when starting
r18049 requiredtools = [os.path.basename(sys.executable), "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),
Mads Kiilerich
tests: let run-tests.py default to use 'sh' in $PATH instead of '/bin/sh'...
r15941 'shell': ('HGTEST_SHELL', 'sh'),
Thomas Arendsen Hein
run-tests.py: Allow environment variables to set jobs/timeout/port.
r6366 }
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 def parselistfiles(files, listtype, warn=True):
entries = dict()
for filename in files:
try:
path = os.path.expanduser(os.path.expandvars(filename))
f = open(path, "r")
except IOError, err:
if err.errno != errno.ENOENT:
raise
if warn:
print "warning: no such %s file: %s" % (listtype, filename)
continue
for line in f.readlines():
line = line.split('#', 1)[0].strip()
if line:
entries[line] = filename
f.close()
return entries
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")
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 parser.add_option("--whitelist", action="append",
help="always run tests listed in the specified whitelist 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")
Markus Zapke-Gründemann
tests: add htmlcov option
r15859 parser.add_option("-H", "--htmlcov", action="store_true",
help="create an HTML report of the coverage of the files")
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'])
Bryan O'Sullivan
run-tests: add a --compiler option...
r17966 parser.add_option("--compiler", type="string",
help="compiler to build with")
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")
Martin Geisler
run-tests: add --shell command line flag...
r14202 parser.add_option("--shell", type="string",
help="shell to use (default: $%s or %s)" % defaults['shell'])
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'])
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 parser.add_option("--time", action="store_true",
help="time how long each test takes")
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+")
Augie Fackler
run-tests: add flag to provide extra hgrc options for test runs
r14134 parser.add_option('--extra-config-opt', action="append",
help='set the given config opt in the test hgrc')
Stephen Darnell
Add a pure python version of run-tests....
r2110
Martin Geisler
run-tests: use type of default to convert environment variable...
r14201 for option, (envvar, default) in defaults.items():
defaults[option] = type(default)(os.environ.get(envvar, default))
Greg Ward
run-tests: factor out parse_args(). Clarify use of globals a bit.
r8091 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:
Mads Kiilerich
run-tests: expand user in --with-hg...
r15942 options.with_hg = os.path.expanduser(options.with_hg)
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 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':
Thomas Arendsen Hein
run-tests: print a newline after all warnings
r14359 sys.stderr.write('warning: --with-hg should specify an hg script\n')
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 if options.local:
testdir = os.path.dirname(os.path.realpath(sys.argv[0]))
hgbin = os.path.join(os.path.dirname(testdir), 'hg')
Mads Kiilerich
tests: don't require 'hg' without extension on windows...
r16538 if os.name != 'nt' and not os.access(hgbin, os.X_OK):
Greg Ward
run-tests: redefine --with-hg so it takes the 'hg' script to run....
r8674 parser.error('--local specified, but %r not found or not executable'
% hgbin)
options.with_hg = hgbin
Markus Zapke-Gründemann
tests: add htmlcov option
r15859 options.anycoverage = options.cover or options.annotate or options.htmlcov
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648 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
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 if options.time:
sys.stderr.write(
'warning: --time option ignored with --debug\n')
options.time = False
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:
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 options.blacklist = parselistfiles(options.blacklist, 'blacklist')
if options.whitelist:
options.whitelisted = parselistfiles(options.whitelist, 'whitelist',
warn=options.child is None)
else:
options.whitelisted = {}
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)
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)
Patrick Mezard
run-tests: fix python executable detection and copy on Windows
r14335 if os.name == 'nt' or os.access(name, os.X_OK):
Stephen Darnell
Add a pure python version of run-tests....
r2110 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:
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 if os.name == 'nt' and not p.endswith('.exe'):
Stephen Darnell
Tidyups for run-tests.py inc. try/finally cleanup and allow tests to be specified on command line
r2133 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
Thomas Arendsen Hein
run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
r14821 def terminate(proc):
"""Terminate subprocess (with fallback for Python versions < 2.6)"""
vlog('# Terminating process %d' % proc.pid)
try:
Augie Fackler
tests: use getattr instead of hasattr
r14971 getattr(proc, 'terminate', lambda : os.kill(proc.pid, signal.SIGTERM))()
Thomas Arendsen Hein
run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
r14821 except OSError:
pass
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 def killdaemons():
Patrick Mezard
run-tests: do not duplicate killdaemons() code
r17464 return killmod.killdaemons(DAEMON_PIDS, tryhard=False, remove=True,
logfn=vlog)
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336
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.
Mads Kiilerich
run-tests.py: fix handling of symlink to the right python...
r18244 pyexename = sys.platform == 'win32' and 'python.exe' or 'python'
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 if getattr(os, 'symlink', None):
Bryan O'Sullivan
run-tests: fix whitespace nonsense
r18061 vlog("# Making python executable in test path a symlink to '%s'" %
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 sys.executable)
Mads Kiilerich
run-tests.py: fix handling of symlink to the right python...
r18244 mypython = os.path.join(BINDIR, pyexename)
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 try:
Mads Kiilerich
run-tests.py: fix handling of symlink to the right python...
r18244 if os.readlink(mypython) == sys.executable:
return
os.unlink(mypython)
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 except OSError, err:
Mads Kiilerich
run-tests.py: fix handling of symlink to the right python...
r18244 if err.errno != errno.ENOENT:
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 raise
Mads Kiilerich
run-tests.py: fix handling of symlink to the right python...
r18244 if findprogram(pyexename) != sys.executable:
try:
os.symlink(sys.executable, mypython)
except OSError, err:
# child processes may race, which is harmless
if err.errno != errno.EEXIST:
raise
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 else:
Mads Kiilerich
run-tests.py: fix handling of symlink to the right python...
r18244 exedir, exename = os.path.split(sys.executable)
vlog("# Modifying search path to find %s as %s in '%s'" %
(exename, pyexename, exedir))
Bryan O'Sullivan
run-tests: on windows, put correct python at front of PATH...
r18059 path = os.environ['PATH'].split(os.pathsep)
while exedir in path:
path.remove(exedir)
os.environ['PATH'] = os.pathsep.join([exedir] + path)
Mads Kiilerich
run-tests.py: fix handling of symlink to the right python...
r18244 if not findprogram(pyexename):
print "WARNING: Cannot find %s in search path" % pyexename
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")
Bryan O'Sullivan
run-tests: add a --compiler option...
r17966 compiler = ''
if options.compiler:
compiler = '--compiler ' + options.compiler
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 = ''
Bryan O'Sullivan
run-tests: make build command line less intimidating...
r17965 cmd = ('%(exe)s setup.py %(pure)s clean --all'
Bryan O'Sullivan
run-tests: add a --compiler option...
r17966 ' build %(compiler)s --build-base="%(base)s"'
Bryan O'Sullivan
run-tests: make build command line less intimidating...
r17965 ' install --force --prefix="%(prefix)s" --install-lib="%(libdir)s"'
' --install-scripts="%(bindir)s" %(nohome)s >%(logfile)s 2>&1'
Bryan O'Sullivan
run-tests: add a --compiler option...
r17966 % dict(exe=sys.executable, pure=pure, compiler=compiler,
Bryan O'Sullivan
run-tests: make build command line less intimidating...
r17965 base=os.path.join(HGTMP, "build"),
Bryan O'Sullivan
run-tests: fix an unnoticed check-code violation
r17967 prefix=INST, libdir=PYTHONDIR, bindir=BINDIR,
Bryan O'Sullivan
run-tests: make build command line less intimidating...
r17965 nohome=nohome, logfile=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()
Patrick Mezard
run-tests: fix hg.bat python reference...
r14336 hgbat = os.path.join(BINDIR, 'hg.bat')
if os.path.isfile(hgbat):
# hg.bat expects to be put in bin/scripts while run-tests.py
# installation layout put it in bin/ directly. Fix it
f = open(hgbat, 'rb')
data = f.read()
f.close()
if '"%~dp0..\python" "%~dp0hg" %*' in data:
data = data.replace('"%~dp0..\python" "%~dp0hg" %*',
'"%~dp0python" "%~dp0hg" %*')
f = open(hgbat, 'wb')
f.write(data)
f.close()
else:
print 'WARNING: cannot fix hg.bat reference to python.exe'
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
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 def outputtimes(options):
vlog('# Producing time report')
times.sort(key=lambda t: (t[1], t[0]), reverse=True)
cols = '%7.3f %s'
print '\n%-7s %s' % ('Time', 'Test')
for test, timetaken in times:
print cols % (timetaken, test)
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')
Matt Mackall
run-tests: use a list comprehension instead of map
r15858 omit = ','.join(os.path.join(x, '*') for x in [BINDIR, TESTDIR])
Dirkjan Ochtman
tests: make coverage run in parallel mode, clean up coverage code
r8620 covrun('-i', '-r', '"--omit=%s"' % omit) # report
Markus Zapke-Gründemann
tests: add htmlcov option
r15859 if options.htmlcov:
htmldir = os.path.join(TESTDIR, 'htmlcov')
covrun('-i', '-b', '"--directory=%s"' % htmldir, '"--omit=%s"' % omit)
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)
Mads Kiilerich
run-tests: handle windows crlf in .py tests again...
r17800 if os.name == 'nt':
replacements.append((r'\r\n', '\n'))
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: pull out unified matching funcs
r15414 def rematch(el, l):
try:
Mads Kiilerich
run-tests: alternative way of handling \r on Windows...
r17777 # use \Z to ensure that the regex matches to the end of the string
if os.name == 'nt':
return re.match(el + r'\r?\n\Z', l)
return re.match(el + r'\n\Z', l)
Matt Mackall
run-tests: pull out unified matching funcs
r15414 except re.error:
# el is an invalid regex
return False
def globmatch(el, l):
Mads Kiilerich
tests: make (glob) on windows accept \ instead of /...
r15447 # The only supported special characters are * and ? plus / which also
# matches \ on windows. Escaping of these caracters is supported.
Matt Mackall
run-tests: pull out unified matching funcs
r15414 i, n = 0, len(el)
res = ''
while i < n:
c = el[i]
i += 1
Mads Kiilerich
tests: make (glob) on windows accept \ instead of /...
r15447 if c == '\\' and el[i] in '*?\\/':
Matt Mackall
run-tests: pull out unified matching funcs
r15414 res += el[i - 1:i + 1]
i += 1
elif c == '*':
res += '.*'
elif c == '?':
res += '.'
Mads Kiilerich
tests: make (glob) on windows accept \ instead of /...
r15447 elif c == '/' and os.name == 'nt':
res += '[/\\\\]'
Matt Mackall
run-tests: pull out unified matching funcs
r15414 else:
res += re.escape(c)
return rematch(res, l)
Matt Mackall
run-tests: pull out line matching function
r15415 def linematch(el, l):
if el == l: # perfect match (fast)
return True
Mads Kiilerich
run-tests: make it possible to combine (esc) with (glob) and (re)...
r17778 if el:
if el.endswith(" (esc)\n"):
el = el[:-7].decode('string-escape') + '\n'
if el == l or os.name == 'nt' and el[:-1] + '\r\n' == l:
return True
if (el.endswith(" (re)\n") and rematch(el[:-6], l) or
el.endswith(" (glob)\n") and globmatch(el[:-8], l)):
return True
Matt Mackall
run-tests: pull out line matching function
r15415 return False
Matt Mackall
run-tests: do chdir for tests under a lock for thread safety
r14019 def tsttest(test, wd, options, replacements):
Matt Mackall
tests: add some comments to the unified test code
r15413 # We generate a shell script which outputs unique markers to line
# up script results with our source. These markers include input
# line number and the last return code
Matt Mackall
tests: basic support for unified tests
r11741 salt = "SALT" + str(time.time())
Matt Mackall
run-tests: replace inline python handling with more native scheme...
r15434 def addsalt(line, inpython):
if inpython:
script.append('%s %d 0\n' % (salt, line))
else:
script.append('echo %s %s $?\n' % (salt, line))
Matt Mackall
tests: basic support for unified tests
r11741
Matt Mackall
tests: add some comments to the unified test code
r15413 # After we run the shell script, we re-unify the script output
# with non-active parts of the source, with synchronization by our
# SALT line number markers. The after table contains the
# non-active components, ordered by line number
after = {}
Matt Mackall
tests: basic support for unified tests
r11741 pos = prepos = -1
Matt Mackall
tests: add some comments to the unified test code
r15413
# Expected shellscript output
Matt Mackall
tests: basic support for unified tests
r11741 expected = {}
Matt Mackall
tests: add some comments to the unified test code
r15413
# We keep track of whether or not we're in a Python block so we
# can generate the surrounding doctest magic
Matt Mackall
tests: rewrite inline Python support...
r15412 inpython = False
Matt Mackall
tests: add some comments to the unified test code
r15413
Mads Kiilerich
tests: introduce c-style conditional sections in .t tests...
r16842 # True or False when in a true or false conditional section
skipping = None
def hghave(reqs):
# TODO: do something smarter when all other uses of hghave is gone
Adrian Buehlmann
tests/run-tests: avoid C:/ in arguments...
r16897 tdir = TESTDIR.replace('\\', '/')
Mads Kiilerich
tests: introduce c-style conditional sections in .t tests...
r16842 proc = Popen4('%s -c "%s/hghave %s"' %
Mads Kiilerich
tests: use the right directory for running hghave from run-tests.py
r16906 (options.shell, tdir, ' '.join(reqs)), wd, 0)
Mads Kiilerich
tests: make hghave and run-tests exit on unknown feature requirements
r18229 stdout, stderr = proc.communicate()
Mads Kiilerich
tests: introduce c-style conditional sections in .t tests...
r16842 ret = proc.wait()
if wifexited(ret):
ret = os.WEXITSTATUS(ret)
Mads Kiilerich
tests: make hghave and run-tests exit on unknown feature requirements
r18229 if ret == 2:
print stdout
sys.exit(1)
Mads Kiilerich
tests: introduce c-style conditional sections in .t tests...
r16842 return ret == 0
Matt Mackall
run-tests: minor cleanups
r15416 f = open(test)
t = f.readlines()
f.close()
script = []
Mads Kiilerich
tests: add 'set -x' to the .t sh scripts in run-tests.py debug mode...
r15940 if options.debug:
script.append('set -x\n')
Mads Kiilerich
tests: use an alias to make msys 'pwd' return paths with forward slashes
r15569 if os.getenv('MSYSTEM'):
script.append('alias pwd="pwd -W"\n')
Matt Mackall
tests: rewrite inline Python support...
r15412 for n, l in enumerate(t):
Mads Kiilerich
tests: handle .t files without trailing LF...
r12934 if not l.endswith('\n'):
l += '\n'
Mads Kiilerich
tests: introduce c-style conditional sections in .t tests...
r16842 if l.startswith('#if'):
if skipping is not None:
after.setdefault(pos, []).append(' !!! nested #if\n')
skipping = not hghave(l.split()[1:])
after.setdefault(pos, []).append(l)
elif l.startswith('#else'):
if skipping is None:
after.setdefault(pos, []).append(' !!! missing #if\n')
skipping = not skipping
after.setdefault(pos, []).append(l)
elif l.startswith('#endif'):
if skipping is None:
after.setdefault(pos, []).append(' !!! missing #if\n')
skipping = None
after.setdefault(pos, []).append(l)
elif skipping:
after.setdefault(pos, []).append(l)
elif l.startswith(' >>> '): # python inlines
Matt Mackall
run-tests: replace inline python handling with more native scheme...
r15434 after.setdefault(pos, []).append(l)
prepos = pos
pos = n
Matt Mackall
tests: rewrite inline Python support...
r15412 if not inpython:
# we've just entered a Python block, add the header
inpython = True
Matt Mackall
run-tests: replace inline python handling with more native scheme...
r15434 addsalt(prepos, False) # make sure we report the exit code
Matt Mackall
tests: rewrite inline Python support...
r15412 script.append('%s -m heredoctest <<EOF\n' % PYTHON)
Matt Mackall
run-tests: replace inline python handling with more native scheme...
r15434 addsalt(n, True)
script.append(l[2:])
Adrian Buehlmann
run-tests: don't add python lines to expected dict...
r16841 elif l.startswith(' ... '): # python inlines
Matt Mackall
tests: rewrite inline Python support...
r15412 after.setdefault(prepos, []).append(l)
script.append(l[2:])
elif l.startswith(' $ '): # commands
if inpython:
script.append("EOF\n")
inpython = False
Matt Mackall
tests: basic support for unified tests
r11741 after.setdefault(pos, []).append(l)
prepos = pos
pos = n
Matt Mackall
run-tests: replace inline python handling with more native scheme...
r15434 addsalt(n, False)
Mads Kiilerich
tests: make .t tests stop immediately if a cd fails...
r16905 cmd = l[4:].split()
if len(cmd) == 2 and cmd[0] == 'cd':
l = ' $ cd %s || exit 1\n' % cmd[1]
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
Matt Mackall
run-tests: replace inline python handling with more native scheme...
r15434 # queue up a list of expected results
expected.setdefault(pos, []).append(l[2:])
Matt Mackall
tests: basic support for unified tests
r11741 else:
Matt Mackall
tests: rewrite inline Python support...
r15412 if inpython:
script.append("EOF\n")
inpython = False
Matt Mackall
tests: basic support for unified tests
r11741 # non-command/result - queue up for merged output
after.setdefault(pos, []).append(l)
Matt Mackall
tests: add some comments to the unified test code
r15413 if inpython:
script.append("EOF\n")
Mads Kiilerich
tests: introduce c-style conditional sections in .t tests...
r16842 if skipping is not None:
after.setdefault(pos, []).append(' !!! missing #endif\n')
Matt Mackall
run-tests: replace inline python handling with more native scheme...
r15434 addsalt(n + 1, False)
Matt Mackall
tests: add exit codes to unified tests
r12316
Matt Mackall
run-tests: minor cleanups
r15416 # Write out the script and execute it
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)
Mads Kiilerich
run-tests: don't quote command names - that do apparently not work with msys
r15450 cmd = '%s "%s"' % (options.shell, name)
Matt Mackall
tests: basic support for unified tests
r11741 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)
Matt Mackall
tests: add some comments to the unified test code
r15413 # Merge the script output back into a unified test
Matt Mackall
tests: basic support for unified tests
r11741 pos = -1
postout = []
Matt Mackall
tests: add exit codes to unified tests
r12316 ret = 0
Mads Kiilerich
run-tests: drop unused enumerate
r17739 for l in 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:
Mads Kiilerich
run-tests: use more explicit criteria for detecting no-eol...
r17741 if not lout.endswith('\n'):
Mads Kiilerich
tests: (no-eol) markup for command output without trailing LF...
r12940 lout += ' (no-eol)\n'
Matt Mackall
tests: add some comments to the unified test code
r15413 # find the expected output at the current position
Mads Kiilerich
tests: (no-eol) markup for command output without trailing LF...
r12940 el = None
if pos in expected and expected[pos]:
el = expected[pos].pop(0)
Matt Mackall
run-tests: pull out line matching function
r15415 if linematch(el, lout):
postout.append(" " + el)
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:
Matt Mackall
tests: add some comments to the unified test code
r15413 # merge in non-active test bits
Matt Mackall
tests: basic support for unified tests
r11741 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:
Mads Kiilerich
run-tests.py: don't use console for stdin when running in debug mode...
r18230 proc = subprocess.Popen(cmd, shell=True, cwd=wd, stdin=subprocess.PIPE)
proc.stdin.close()
Greg Ward
run-tests: add "debug" mode: don't capture child output, just show it....
r9707 ret = proc.wait()
return (ret, None)
Patrick Mezard
run-tests: use the common test path on Windows and Java...
r14338 proc = Popen4(cmd, wd, options.timeout)
def cleanup():
Thomas Arendsen Hein
run-tests: fallback to SIGTERM if subprocess.Popen does not have terminate()
r14821 terminate(proc)
Patrick Mezard
run-tests: use the common test path on Windows and Java...
r14338 ret = proc.wait()
if ret == 0:
ret = signal.SIGTERM << 8
killdaemons()
return ret
output = ''
proc.tochild.close()
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336
Patrick Mezard
run-tests: use the common test path on Windows and Java...
r14338 try:
output = proc.fromchild.read()
except KeyboardInterrupt:
vlog('# Handling keyboard interrupt')
cleanup()
raise
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336
Patrick Mezard
run-tests: use the common test path on Windows and Java...
r14338 ret = proc.wait()
if wifexited(ret):
ret = os.WEXITSTATUS(ret)
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001
Patrick Mezard
run-tests: use the common test path on Windows and Java...
r14338 if proc.timeout:
ret = 'timeout'
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001
Patrick Mezard
run-tests: use the common test path on Windows and Java...
r14338 if ret:
killdaemons()
Matt Mackall
run-tests: switch timeout handling from alarm to helper thread...
r14001
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)
Mads Kiilerich
run-tests: allow test output lines to be terminated with \r in addition to \n...
r17742 return ret, output.splitlines(True)
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: backout 4a4173519b63...
r17936 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: backout 4a4173519b63...
r17936 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: backout 4a4173519b63...
r17936 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: backout 4a4173519b63...
r17936 result('p', test)
Matt Mackall
run-tests: move interactive handling into runone
r13988 return
Matt Mackall
run-tests: backout 4a4173519b63...
r17936 result('f', (test, msg))
Matt Mackall
run-tests: use a results dict
r13994
def success():
Matt Mackall
run-tests: backout 4a4173519b63...
r17936 result('p', test)
Matt Mackall
run-tests: use a results dict
r13994
def ignore(msg):
Matt Mackall
run-tests: backout 4a4173519b63...
r17936 result('i', (test, msg))
Benoit Boissinot
run-tests.py: add a summary of failed tests at the end
r6244
Idan Kamara
run-tests: take the basepath when constructing the test temp dir...
r14264 if (os.path.basename(test).startswith("test-") and '~' not in test and
Matt Mackall
run-tests: move existence/name format check into runone
r13989 ('.' 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:
Idan Kamara
run-tests: verbose log ignored test
r14598 vlog('# Test file', test, 'not supported, ignoring')
Matt Mackall
run-tests: move existence/name format check into runone
r13989 return None # not a supported test, don't record
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 if not (options.whitelisted and test in options.whitelisted):
if options.blacklist and test in options.blacklist:
skip("blacklisted")
return None
Matt Mackall
run-tests: move blacklist and retest filtering to runone
r13993
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 if options.retest and not os.path.exists(test + ".err"):
ignore("not retesting")
return None
Matt Mackall
run-tests: move blacklist and retest filtering to runone
r13993
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 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:
ignore("doesn't match keyword")
return None
Matt Mackall
run-tests: move keyword checking into runone
r13991
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')
Augie Fackler
run-tests: add flag to provide extra hgrc options for test runs
r14134 if options.extra_config_opt:
for opt in options.extra_config_opt:
section, key = opt.split('.', 1)
assert '=' in key, ('extra config opt %s must '
'have an = for assignment' % opt)
hgrc.write('[%s]\n%s\n' % (section, key))
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()
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except IOError:
Alexis S. L. Carvalho
run-tests.py: use coverage.py with "#!/usr/bin/env python" tests
r4321 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:
Mads Kiilerich
run-tests: remove dead code for supporting old test scripts
r17801 return skip("unknown test type")
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"] = \
Adrian Buehlmann
tests/run-tests: avoid C:/ in arguments...
r16897 os.path.join(HGTMP, os.path.basename(test))
Idan Kamara
tests: set HOME to the test temp dir (issue2707)
r13764
Mads Kiilerich
tests: ignore \r on windows
r15449 replacements = [
Martin Geisler
run-tests: use regex when searching for $HGPORT in test output...
r12895 (r':%s\b' % options.port, ':$HGPORT'),
(r':%s\b' % (options.port + 1), ':$HGPORT1'),
(r':%s\b' % (options.port + 2), ':$HGPORT2'),
Mads Kiilerich
tests: ignore \r on windows
r15449 ]
if os.name == 'nt':
Mads Kiilerich
run-tests: make $TESTTMP matching case-insensitive on windows
r15451 replacements.append(
(''.join(c.isalpha() and '[%s%s]' % (c.lower(), c.upper()) or
c in '/\\' and r'[/\\]' or
c.isdigit() and c or
'\\' + c
for c in testtmp), '$TESTTMP'))
else:
replacements.append((re.escape(testtmp), '$TESTTMP'))
Mads Kiilerich
tests: ignore \r on windows
r15449
os.mkdir(testtmp)
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 if options.time:
starttime = time.time()
Mads Kiilerich
tests: ignore \r on windows
r15449 ret, out = runner(testpath, testtmp, options, replacements)
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 if options.time:
endtime = time.time()
times.append((test, endtime - starttime))
Stephen Darnell
Add a pure python version of run-tests....
r2110 vlog("# Ret was:", ret)
Mads Kiilerich
tests: kill daemons early, making breaking at "Accept" prompt safe
r18051 killdaemons()
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")
Mads Kiilerich
run-tests: allow test output lines to be terminated with \r in addition to \n...
r17742 refout = f.read().splitlines(True)
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()
Bryan O'Sullivan
tests: correctly report a test killed by a signal
r17751 def describe(ret):
if ret < 0:
return 'killed by signal %d' % -ret
return 'returned error code %d' % ret
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:
Bryan O'Sullivan
tests: correctly report a test killed by a signal
r17751 fail("output changed and " + describe(ret), ret)
Patrick Mezard
run-tests: display diff before prompting with --interactive
r14006 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 = '!'
Bryan O'Sullivan
tests: correctly report a test killed by a signal
r17751 fail(describe(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
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()
Idan Kamara
run-tests: compare absolute paths in _checkhglib
r14263 if os.path.abspath(actualhg) != os.path.abspath(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
run-tests: use correct python when run with --local
r18048 else:
usecorrectpython()
Bryan O'Sullivan
Allow tests to run in parallel.
r5384
optcopy = dict(options.__dict__)
optcopy['jobs'] = 1
Idan Kamara
run-tests: fix --blacklist with jobs > 1...
r14447
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 # Because whitelist has to override keyword matches, we have to
# actually load the whitelist in the children as well, so we allow
# the list of whitelist files to pass through and be parsed in the
# children, but not the dict of whitelisted tests resulting from
# the parse, used here to override blacklisted tests.
whitelist = optcopy['whitelisted'] or []
del optcopy['whitelisted']
Idan Kamara
run-tests: fix --blacklist with jobs > 1...
r14447 blacklist = optcopy['blacklist'] or []
Ry4an Brase
Fix --blacklist when --jobs > 1 in run_tests.py....
r10904 del optcopy['blacklist']
Idan Kamara
run-tests: fix --blacklist with jobs > 1...
r14447 blacklisted = []
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)
Augie Fackler
run-tests.py: correctly handle list options with parallel tasks
r14192 elif isinstance(value, list):
for v in value:
opts.append(name + '=' + str(v))
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 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
Idan Kamara
run-tests: fix --blacklist with jobs > 1...
r14447 test = tests.pop()
Augie Fackler
run-tests: allow whitelisting tests that should always run...
r14493 if test not in whitelist and test in blacklist:
Idan Kamara
run-tests: fix --blacklist with jobs > 1...
r14447 blacklisted.append(test)
else:
job.append(test)
Bryan O'Sullivan
run-tests: support running tests in parallel on windows...
r18057
waitq = queue.Queue()
# windows lacks os.wait, so we must emulate it
def waitfor(proc, rfd):
fp = os.fdopen(rfd, 'rb')
return lambda: waitq.put((proc.pid, proc.wait(), fp))
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))
Bryan O'Sullivan
run-tests: support running tests in parallel on windows...
r18057 proc = subprocess.Popen(cmdline, executable=cmdline[0])
threading.Thread(target=waitfor(proc, rfd)).start()
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 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
Siddharth Agarwal
run-tests: use pickle to send results from children to parent...
r17919 passed, 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
run-tests: support running tests in parallel on windows...
r18057 for job in jobs:
if not job:
continue
pid, status, fp = waitq.get()
Brendan Cully
run-tests: kill daemons on ^C with -j....
r10336 try:
Siddharth Agarwal
run-tests: use pickle to send results from children to parent...
r17919 childresults = pickle.load(fp)
Bryan O'Sullivan
run-tests: exit cleanly if parallel run is interrupted...
r18383 except (pickle.UnpicklingError, EOFError):
sys.exit(255)
Siddharth Agarwal
run-tests: use pickle to send results from children to parent...
r17919 else:
passed += len(childresults['p'])
skipped += len(childresults['s'])
failed += len(childresults['f'])
skips.extend(childresults['s'])
fails.extend(childresults['f'])
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 if options.time:
childtimes = pickle.load(fp)
times.extend(childtimes)
Siddharth Agarwal
run-tests: use pickle to send results from children to parent...
r17919
Bryan O'Sullivan
Allow tests to run in parallel.
r5384 vlog('pid %d exited, status %d' % (pid, status))
failures |= status
Matt Mackall
tests: tidy up reporting of skipped tests...
r5470 print
Idan Kamara
run-tests: fix --blacklist with jobs > 1...
r14447 skipped += len(blacklisted)
Matt Mackall
run-tests: add --noskips option
r9580 if not options.noskips:
for s in skips:
print "Skipped %s: %s" % (s[0], s[1])
Idan Kamara
run-tests: fix --blacklist with jobs > 1...
r14447 for s in blacklisted:
print "Skipped %s: blacklisted" % s
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." % (
Siddharth Agarwal
run-tests: use pickle to send results from children to parent...
r17919 passed + failed, skipped, failed)
Dirkjan Ochtman
tests: use external coverage, mandate newer version...
r10648
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 if options.time:
outputtimes(options)
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=[])
Matt Mackall
run-tests: backout 4a4173519b63...
r17936 resultslock = threading.Lock()
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 times = []
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
Siddharth Agarwal
run-tests.py: remove runqueue's results parameter since it is now a global
r17928 def runqueue(options, tests):
Matt Mackall
run-tests: move test loop into a helper function
r13995 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")
Bryan O'Sullivan
run-tests: use correct python when run with --local
r18048 else:
usecorrectpython()
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
Siddharth Agarwal
run-tests.py: remove runqueue's results parameter since it is now a global
r17928 runqueue(options, tests)
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:
Siddharth Agarwal
run-tests: open child-parent pipes in binary mode...
r17925 fp = os.fdopen(options.child, 'wb')
Siddharth Agarwal
run-tests: use pickle to send results from children to parent...
r17919 pickle.dump(results, fp, pickle.HIGHEST_PROTOCOL)
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 if options.time:
pickle.dump(times, fp, pickle.HIGHEST_PROTOCOL)
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)
Siddharth Agarwal
run-tests: add --time option to log times for each test...
r17921 if options.time:
outputtimes(options)
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
Bryan O'Sullivan
run-tests: exit cleanly if parallel run is interrupted...
r18383 if not options.child:
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
Simon Heimberg
run-tests: skip unnecessary operations on the args in the child proces...
r17908 if len(args) == 0:
args = os.listdir(".")
args.sort()
Benoit Boissinot
run-tests.py: do not install hg when the tests do no exist
r12677
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'] = ''
Thomas Arendsen Hein
run-tests: make sure no_proxy/NO_PROXY are empty to fix test-http-proxy.t...
r15344 os.environ['no_proxy'] = ''
os.environ['NO_PROXY'] = ''
Matt Mackall
tests: set a standard terminal type...
r16613 os.environ['TERM'] = 'xterm'
Mads Kiilerich
tests: run with PYTHONHASHSEED=random...
r18384 os.environ['PYTHONHASHSEED'] = 'random'
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]
Simon Heimberg
tests: unset variable HG if it is set...
r17541 if 'HG' in os.environ:
# can't remove on solaris
os.environ['HG'] = ''
del os.environ['HG']
Benoit Boissinot
run-tests.py: reset env variables set by hooks
r10902
Greg Ward
run-tests: factor out main(); reduce use of globals a bit.
r8094 global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
Adrian Buehlmann
tests/run-tests: avoid C:/ in arguments...
r16897 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:
Adrian Buehlmann
tests/run-tests: use $TMP on Windows (issue3490)...
r16890 d = None
if os.name == 'nt':
# without this, we get the default temp dir location, but
# in all lowercase, which causes troubles with paths (issue3490)
d = os.getenv('TMP')
tmpdir = tempfile.mkdtemp('', 'hgtests.', d)
Greg Ward
run-tests: make --tmpdir option more useful....
r9706 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:
Matt Mackall
tests: shorten post-test sleeps...
r16346 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()