Patchwork [002,of,179,tests-refactor] run-tests: move testtmp into Test class

login
register
mail settings
Submitter Gregory Szorc
Date May 2, 2014, 6:37 p.m.
Message ID <b81c28c2cb25a35e899f.1399055839@vm-ubuntu-main.gateway.sonic.net>
Download mbox | patch
Permalink /patch/4497/
State Accepted
Commit dd8e946014178cc4b55305949a33f297331df729
Headers show

Comments

Gregory Szorc - May 2, 2014, 6:37 p.m.
# HG changeset patch
# User Gregory Szorc <gregory.szorc@gmail.com>
# Date 1397937249 25200
#      Sat Apr 19 12:54:09 2014 -0700
# Branch stable
# Node ID b81c28c2cb25a35e899faf379b3f139dc12cbd66
# Parent  7dd9be16585bd36596a2f65358d36c5b039a7092
run-tests: move testtmp into Test class

This patch starts the process of moving test-specific variables into the
Test class. The ultimate goal is to be able to instantiate a Test with
minimal arguments and to call run() on it without too much thinking.
This will make it much easier to run tests from other contexts. It will
also enable things like running a test multiple times.

Patch

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -575,38 +575,42 @@  def outputcoverage(options):
         adir = os.path.join(TESTDIR, 'annotated')
         if not os.path.isdir(adir):
             os.mkdir(adir)
         covrun('-i', '-a', '"--directory=%s"' % adir, '"--omit=%s"' % omit)
 
 class Test(object):
     """Encapsulates a single, runnable test."""
 
-    def __init__(self, path, options):
+    def __init__(self, path, options, threadtmp):
         self._path = path
         self._options = options
 
-    def run(self, testtmp, replacements, env):
-        return self._run(testtmp, replacements, env)
+        self.testtmp = os.path.join(threadtmp, os.path.basename(path))
+        os.mkdir(self.testtmp)
 
-    def _run(self, testtmp, replacements, env):
+    def run(self, replacements, env):
+        return self._run(replacements, env)
+
+    def _run(self, replacements, env):
         raise NotImplemented('Subclasses must implement Test.run()')
 
 def pytest(test, wd, options, replacements, env):
     py3kswitch = options.py3k_warnings and ' -3' or ''
     cmd = '%s%s "%s"' % (PYTHON, py3kswitch, test)
     vlog("# Running", cmd)
     if os.name == 'nt':
         replacements.append((r'\r\n', '\n'))
     return run(cmd, wd, options, replacements, env)
 
 class PythonTest(Test):
     """A Python-based test."""
-    def _run(self, testtmp, replacements, env):
-        return pytest(self._path, testtmp, self._options, replacements, env)
+    def _run(self, replacements, env):
+        return pytest(self._path, self.testtmp, self._options, replacements,
+                      env)
 
 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):
@@ -857,18 +861,19 @@  def tsttest(test, wd, options, replaceme
 
     if warnonly == 2:
         exitcode = False # set exitcode to warned
     return exitcode, postout
 
 class TTest(Test):
     """A "t test" is a test backed by a .t file."""
 
-    def _run(self, testtmp, replacements, env):
-        return tsttest(self._path, testtmp, self._options, replacements, env)
+    def _run(self, replacements, env):
+        return tsttest(self._path, self.testtmp, self._options, replacements,
+                       env)
 
 wifexited = getattr(os, "WIFEXITED", lambda x: False)
 def run(cmd, wd, options, replacements, env):
     """Run command in a sub-process, capturing the output (stdout and stderr).
     Return a tuple (exitcode, output).  output is None in debug mode."""
     # TODO: Use subprocess.Popen if we're running on Python 2.4
     if options.debug:
         proc = subprocess.Popen(cmd, shell=True, cwd=wd, env=env)
@@ -982,46 +987,44 @@  def runone(options, test, count):
     else:
         return skip("unknown test type")
 
     vlog("# Test", test)
 
     if os.path.exists(err):
         os.remove(err)       # Remove any previous output files
 
-    t = runner(testpath, options)
-
     # Make a tmp subdirectory to work in
     threadtmp = os.path.join(HGTMP, "child%d" % count)
-    testtmp = os.path.join(threadtmp, os.path.basename(test))
     os.mkdir(threadtmp)
-    os.mkdir(testtmp)
+
+    t = runner(testpath, options, threadtmp)
 
     port = options.port + count * 3
     replacements = [
         (r':%s\b' % port, ':$HGPORT'),
         (r':%s\b' % (port + 1), ':$HGPORT1'),
         (r':%s\b' % (port + 2), ':$HGPORT2'),
         ]
     if os.name == 'nt':
         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'))
+                     for c in t.testtmp), '$TESTTMP'))
     else:
-        replacements.append((re.escape(testtmp), '$TESTTMP'))
+        replacements.append((re.escape(t.testtmp), '$TESTTMP'))
 
-    env = createenv(options, testtmp, threadtmp, port)
+    env = createenv(options, t.testtmp, threadtmp, port)
     createhgrc(env['HGRCPATH'], options)
 
     starttime = time.time()
     try:
-        ret, out = t.run(testtmp, replacements, env)
+        ret, out = t.run(replacements, env)
     except KeyboardInterrupt:
         endtime = time.time()
         log('INTERRUPTED: %s (after %d seconds)' % (test, endtime - starttime))
         raise
     endtime = time.time()
     times.append((test, endtime - starttime))
     vlog("# Ret was:", ret)