@@ -263,6 +263,9 @@
parser.add_option("--with-python3", metavar="PYTHON3",
help="Python 3 interpreter (if running under Python 2)"
" (TEMPORARY)")
+ parser.add_option('--rev', type="string",
+ metavar="rev",
+ help="run tests using the given revision")
parser.add_option('--extra-config-opt', action="append",
help='set the given config opt in the test hgrc')
parser.add_option('--random', action="store_true",
@@ -294,12 +297,16 @@
if options.with_hg:
options.with_hg = canonpath(_bytespath(options.with_hg))
+ if options.rev:
+ parser.error('--with-hg and --rev are incompatible')
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) == b'hg':
sys.stderr.write('warning: --with-hg should specify an hg script\n')
if options.local:
+ if options.rev:
+ parser.error('--local and --rev are incompatible')
testdir = os.path.dirname(_bytespath(canonpath(sys.argv[0])))
hgbin = os.path.join(os.path.dirname(testdir), b'hg')
if os.name != 'nt' and not os.access(hgbin, os.X_OK):
@@ -2334,6 +2341,96 @@
script = _bytespath(script)
exe = _bytespath(exe)
hgroot = os.path.dirname(os.path.dirname(script))
+ if self.options.rev:
+ check = "set:mercurial/*.py and " \
+ 'grep(r"requirements.*%s|%s.*requirements")'
+ procs = []
+ rev = self.options.rev
+ with open(os.path.join(hgroot, '.hg', 'requires'), 'r') as requires:
+ for r in requires:
+ r = r.strip()
+ proc = subprocess.Popen(['hg', 'locate',
+ '--cwd', hgroot,
+ '--rev', rev,
+ check % (r, r),
+ ],
+ stderr=subprocess.STDOUT,
+ stdout=subprocess.PIPE)
+ procs.append((r, proc))
+ badreqs = set()
+ while procs:
+ r, proc = procs.pop(0)
+ ret = proc.wait()
+ if wifexited(ret):
+ ret = os.WEXITSTATUS(ret)
+ if ret:
+ badreqs.add(r)
+ tempsrc = os.path.join(self._hgtmp, b"source")
+ clone = ['hg', 'clone',
+ hgroot,
+ tempsrc,
+ ]
+ if badreqs:
+ tag = rev
+ proc = subprocess.Popen([
+ 'hg', 'log',
+ '--cwd', hgroot,
+ '.hgtags',
+ '-r', 'desc("Added tag %s for changeset")' % rev,
+ '-T', '{node}',
+ ],
+ stderr=subprocess.STDOUT,
+ stdout=subprocess.PIPE)
+ ret = proc.wait()
+ if wifexited(ret):
+ ret = os.WEXITSTATUS(ret)
+ if ret == 0:
+ tag, _err = proc.communicate()
+ clone.extend(['-r', tag,
+ '-u', rev,
+ '--pull',
+ ])
+ for r in badreqs:
+ # There are two common ways to disable a repository format
+ # and there isn't a consistent way to determine which
+ # applies. Thankfully, unlike obsstore, there's no harm in
+ # providing both.
+ clone.extend(['--config', 'format.%s=false' % r,
+ '--config', 'format.use%s=false' % r,
+ ])
+ else:
+ clone.extend(['-u', self.options.rev,
+ ])
+
+ proc = subprocess.Popen(clone,
+ stderr=subprocess.STDOUT,
+ stdout=subprocess.PIPE)
+ ret = proc.wait()
+ if wifexited(ret):
+ ret = os.WEXITSTATUS(ret)
+ if ret:
+ _out, _err = proc.communicate()
+ out = b"hg clone failed (%d):\n" % ret
+ if _out:
+ out += _out
+ if _err:
+ out += _err
+ if PYTHON3:
+ sys.stdout.buffer.write(out)
+ else:
+ sys.stdout.write(out)
+ sys.exit(1)
+ try:
+ # The current obbstore version (1) is horribly incompatible
+ # with certain older versions of hg which are incapable of
+ # being told to ignore the obsstore. And we don't need an
+ # obsstore for our purposes.
+ # We do need a repository to allow setup to calculate the
+ # version correctly.
+ os.remove(os.path.join(tempsrc, '.hg', 'store', 'obsstore'))
+ except OSError:
+ pass
+ hgroot = tempsrc
self._hgroot = hgroot
os.chdir(hgroot)
nohome = b'--home=""'
@@ -824,3 +824,32 @@
# Ran 1 tests, 0 skipped, 0 warned, 1 failed.
python hash seed: * (glob)
[1]
+
+support for running a different version of mercurial
+note that it is typical for ~1/5 tests not to pass when using older
+versions of mercurial...
+
+ $ cat >> test-version.t <<EOF
+ > $ hg version
+ > Mercurial Distributed SCM (version unknown)
+ >
+ > Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others
+ > This is free software; see the source for copying conditions. There is NO
+ > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ > EOF
+ $ run-tests.py --pure --rev 1.2 test-version.t
+ .
+ # Ran 1 tests, 0 skipped, 0 warned, 0 failed.
+
+To run tests at a version from the revision you select from --rev
+you need a test which introspects the source directory
+
+ $ cat > test-old-basic.t <<EOF
+ > $ run-tests.py --pure --local ../../source/tests/test-basic.t
+ > .
+ > # Ran 1 tests, 0 skipped, 0 warned, 0 failed.
+ > EOF
+ $ run-tests.py --pure --rev 1.7 test-old-basic.t
+ .
+ # Ran 1 tests, 0 skipped, 0 warned, 0 failed.
+