Patchwork [1,of,2] run-tests: expose hghave to .py tests by wrapping test file

mail settings
Submitter Gregory Szorc
Date March 14, 2016, 12:50 a.m.
Message ID <7e524606e308bf43eb3e.1457916655@ubuntu-vm-main>
Download mbox | patch
Permalink /patch/13858/
State Superseded
Headers show


Gregory Szorc - March 14, 2016, 12:50 a.m.
# HG changeset patch
# User Gregory Szorc <>
# Date 1457916452 25200
#      Sun Mar 13 17:47:32 2016 -0700
# Node ID 7e524606e308bf43eb3e1385ed8f03fa42b6b67a
# Parent  70c2f8a982766b512e9d7f41f2d93fdb92f5481f
run-tests: expose hghave to .py tests by wrapping test file

This patch adds a "wrapper" script to invoke Python tests. Instead
of executing .py tests directly, we invoke the wrapper which installs
some code and then executes the original .py file.

The wrapper script imports hghave and makes the "require" function
from it available in the global namespace. This will enable .py tests
to call hghave natively (instead of invoking it as a process).

The end goal is to consume hghave as a native Python module everywhere
instead of invoking a Python script to run hghave.


diff --git a/tests/ b/tests/
--- a/tests/
+++ b/tests/
@@ -879,17 +879,33 @@  class PythonTest(Test):
     """A Python-based test."""
     def refpath(self):
         return os.path.join(self._testdir, b'%s.out' % self.bname)
     def _run(self, env):
         py3kswitch = self._py3kwarnings and b' -3' or b''
-        cmd = b'%s%s "%s"' % (PYTHON, py3kswitch, self.path)
+        # We don't write the test path directly to the file in order to
+        # avoid quoting concerns.
+        testlines = [
+            b'import sys',
+            b'from hghave import require',
+            b'with open(sys.argv[1], "rb") as fh:',
+            b'    code = compile(, sys.argv[1], "exec")',
+            b'exec(code)',
+        ]
+        testpath = os.path.join(self._testtmp, b'')
+        with open(testpath, 'wb') as fh:
+            fh.write(b'\n'.join(testlines))
+        cmd = b'%s%s "%s" "%s"' % (PYTHON, py3kswitch, testpath, self.path)
         vlog("# Running", cmd)
         normalizenewlines = == 'nt'
         result = self._runcommand(cmd, env,
         if self._aborted:
             raise KeyboardInterrupt()
         return result