Patchwork [5,of,6,chg-test] run-tests: add --with-chg option to run tests using chg

login
register
mail settings
Submitter Yuya Nishihara
Date Feb. 12, 2016, 4:12 p.m.
Message ID <5b4ae8da2b4264b0f61d.1455293558@mimosa>
Download mbox | patch
Permalink /patch/13142/
State Accepted
Headers show

Comments

Yuya Nishihara - Feb. 12, 2016, 4:12 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1454830452 -32400
#      Sun Feb 07 16:34:12 2016 +0900
# Node ID 5b4ae8da2b4264b0f61db70f0ea37ad3464dc976
# Parent  07088be4fbe16adfa2efdd9d5dba799909823acc
run-tests: add --with-chg option to run tests using chg

Unlike --with-hg=/path/to/chg, this option allows us to start and clean up
command servers in isolated environment. And we can specify the hg command
as well as the chg command.

Patch

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -257,6 +257,8 @@  def getparser():
         metavar="HG",
         help="test using specified hg script rather than a "
              "temporary installation")
+    parser.add_option("--with-chg", metavar="CHG",
+                      help="use specified chg wrapper in place of hg")
     parser.add_option("-3", "--py3k-warnings", action="store_true",
         help="enable Py3k warnings on Python 2.6+")
     parser.add_option('--extra-config-opt', action="append",
@@ -300,6 +302,15 @@  def parseargs(args, parser):
                          % hgbin)
         options.with_hg = hgbin
 
+    if options.with_chg:
+        if os.name == 'nt':
+            parser.error('chg does not work on %s' % os.name)
+        options.with_chg = os.path.realpath(
+            os.path.expanduser(_bytespath(options.with_chg)))
+        if not (os.path.isfile(options.with_chg) and
+                os.access(options.with_chg, os.X_OK)):
+            parser.error('--with-chg must specify a chg executable')
+
     options.anycoverage = options.cover or options.annotate or options.htmlcov
     if options.anycoverage:
         try:
@@ -1825,6 +1836,7 @@  class TestRunner(object):
         self._createdfiles = []
         self._hgcommand = None
         self._hgpath = None
+        self._chgsockdir = None
         self._portoffset = 0
         self._ports = {}
 
@@ -1949,6 +1961,16 @@  class TestRunner(object):
             self._tmpbindir = self._bindir
             self._pythondir = os.path.join(self._installdir, b"lib", b"python")
 
+        # set up crafted chg environment, then replace "hg" command by "chg"
+        chgbindir = self._bindir
+        if self.options.with_chg:
+            self._chgsockdir = d = os.path.join(self._hgtmp, b'chgsock')
+            os.mkdir(d)
+            osenvironb[b'CHGSOCKNAME'] = os.path.join(d, b"server")
+            osenvironb[b'CHGHG'] = os.path.join(self._bindir, self._hgcommand)
+            chgbindir = os.path.dirname(os.path.realpath(self.options.with_chg))
+            self._hgcommand = os.path.basename(self.options.with_chg)
+
         osenvironb[b"BINDIR"] = self._bindir
         osenvironb[b"PYTHON"] = PYTHON
 
@@ -1965,6 +1987,8 @@  class TestRunner(object):
             realfile = os.path.realpath(fileb)
             realdir = os.path.abspath(os.path.dirname(realfile))
             path.insert(2, realdir)
+        if chgbindir != self._bindir:
+            path.insert(1, chgbindir)
         if self._testdir != runtestdir:
             path = [self._testdir] + path
         if self._tmpbindir != self._bindir:
@@ -2134,6 +2158,8 @@  class TestRunner(object):
 
     def _cleanup(self):
         """Clean up state from this test invocation."""
+        if self._chgsockdir:
+            self._killchgdaemons()
 
         if self.options.keep_tmpdir:
             return
@@ -2333,6 +2359,13 @@  class TestRunner(object):
 
         return self._hgpath
 
+    def _killchgdaemons(self):
+        """Kill all background chg command servers spawned by tests"""
+        for f in os.listdir(self._chgsockdir):
+            if not f.endswith(b'.pid'):
+                continue
+            killdaemons(os.path.join(self._chgsockdir, f))
+
     def _outputcoverage(self):
         """Produce code coverage output."""
         from coverage import coverage