changeset 33133:98e2c78e309c

tests: more completely restore the environment in syshgenv Update the syshgenv function to attempt to completely restore the original environment, rather than only updating a few specific variables. run_tests.py now generates a shell script that can be used to restore the original environment, and syshgenv sources it. This is a bit more complicated than the previous code, but should do a better job of running the system hg in the correct environment. I've tested it on Linux using python 2.x, but let me know if it causes issues in other environments. I'm not terribly familiar with how the tests get run on Windows, for instance, and how the environment needs to be updated there.
author Adam Simpkins <simpkins@fb.com>
date Wed, 28 Jun 2017 12:23:22 -0700
parents acfce52518c4
children 0aae80d14fed
files tests/helpers-testrepo.sh tests/run-tests.py
diffstat 2 files changed, 33 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/tests/helpers-testrepo.sh	Wed Jun 28 13:45:51 2017 -0700
+++ b/tests/helpers-testrepo.sh	Wed Jun 28 12:23:22 2017 -0700
@@ -18,10 +18,7 @@
 # Revert the environment so that running "hg" runs the system hg
 # rather than the test hg installation.
 syshgenv () {
-    PATH="$ORIG_PATH"
-    PYTHONPATH="$ORIG_PYTHONPATH"
-    JYTHONPATH="$ORIG_JYTHONPATH"
-    unset HGRCPATH
+    . "$HGTEST_RESTOREENV"
     HGPLAIN=1
     export HGPLAIN
 }
--- a/tests/run-tests.py	Wed Jun 28 13:45:51 2017 -0700
+++ b/tests/run-tests.py	Wed Jun 28 12:23:22 2017 -0700
@@ -70,6 +70,13 @@
 except ImportError:
     import queue
 
+try:
+    import shlex
+    shellquote = shlex.quote
+except (ImportError, AttributeError):
+    import pipes
+    shellquote = pipes.quote
+
 if os.environ.get('RTUNICODEPEDANTRY', False):
     try:
         reload(sys)
@@ -752,6 +759,7 @@
         This will return a tuple describing the result of the test.
         """
         env = self._getenv()
+        self._genrestoreenv(env)
         self._daemonpids.append(env['DAEMON_PIDS'])
         self._createhgrc(env['HGRCPATH'])
 
@@ -888,6 +896,30 @@
         else:
             return b'127.0.0.1'
 
+    def _genrestoreenv(self, testenv):
+        """Generate a script that can be used by tests to restore the original
+        environment."""
+        # Put the restoreenv script inside self._threadtmp
+        scriptpath = os.path.join(self._threadtmp, b'restoreenv.sh')
+        testenv['HGTEST_RESTOREENV'] = scriptpath
+
+        # Only restore environment variable names that the shell allows
+        # us to export.
+        name_regex = re.compile('[a-zA-Z][a-zA-Z0-9_]*')
+
+        with open(scriptpath, 'w') as envf:
+            for name, value in os.environ.items():
+                if not name_regex.match(name):
+                    # Skip environment variables with unusual names not
+                    # allowed by most shells.
+                    continue
+                envf.write('%s=%s\n' % (name, shellquote(value)))
+
+            for name in testenv:
+                if name in os.environ:
+                    continue
+                envf.write('unset %s\n' % (name,))
+
     def _getenv(self):
         """Obtain environment variables to use during test execution."""
         def defineport(i):
@@ -2274,9 +2306,6 @@
             sepb = _bytespath(os.pathsep)
         else:
             sepb = os.pathsep
-        # save the original path, for tests that need to invoke the
-        # system python
-        osenvironb[b"ORIG_PATH"] = osenvironb[b"PATH"]
         path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb)
         if os.path.islink(__file__):
             # test helper will likely be at the end of the symlink
@@ -2302,7 +2331,6 @@
         # are in /opt/subversion.)
         oldpypath = osenvironb.get(IMPL_PATH)
         if oldpypath:
-            osenvironb['ORIG_' + IMPL_PATH] = oldpypath
             pypath.append(oldpypath)
         osenvironb[IMPL_PATH] = sepb.join(pypath)