<div dir="ltr">Did you check if this slows down test execution at all? Creating a temp dir per test sounds potentially slow.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Apr 1, 2020 at 10:17 PM Louis Dionne via libcxx-commits <<a href="mailto:libcxx-commits@lists.llvm.org">libcxx-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
Author: Louis Dionne<br>
Date: 2020-04-01T22:17:03-04:00<br>
New Revision: ff09135fc2b7a9696f87a8a8e89be2ef777895d3<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/ff09135fc2b7a9696f87a8a8e89be2ef777895d3" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/ff09135fc2b7a9696f87a8a8e89be2ef777895d3</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/ff09135fc2b7a9696f87a8a8e89be2ef777895d3.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/ff09135fc2b7a9696f87a8a8e89be2ef777895d3.diff</a><br>
<br>
LOG: [libc++] Execute tests from the Lit execution root instead of the test tree<br>
<br>
Instead of executing tests from within the libc++ test suite, we execute<br>
them from the Lit execution directory. However, since some tests have<br>
file dependencies, we must copy those dependencies to the execution<br>
directory where they are executed.<br>
<br>
This has the major benefit that if a test modifies a file (whether it<br>
is wanted or not), other tests will not see those modifications. This<br>
is good because current tests assume that input data is never modified,<br>
however this could be an incorrect assumption if some test does not<br>
behave properly.<br>
<br>
Added: <br>
<br>
<br>
Modified: <br>
    libcxx/utils/libcxx/test/config.py<br>
    libcxx/utils/libcxx/test/executor.py<br>
    libcxx/utils/libcxx/test/format.py<br>
    libcxx/utils/run.py<br>
<br>
Removed: <br>
<br>
<br>
<br>
################################################################################<br>
diff  --git a/libcxx/utils/libcxx/test/config.py b/libcxx/utils/libcxx/test/config.py<br>
index 3e983e1b4d4a..20d0a796a3af 100644<br>
--- a/libcxx/utils/libcxx/test/config.py<br>
+++ b/libcxx/utils/libcxx/test/config.py<br>
@@ -1050,7 +1050,6 @@ def configure_substitutions(self):<br>
             exec_args.append('--host {}'.format(self.executor.user_prefix + self.executor.host))<br>
             executor = os.path.join(self.libcxx_src_root, 'utils', 'ssh.py')<br>
         else:<br>
-            exec_args.append('--working_directory "%S"')<br>
             executor = os.path.join(self.libcxx_src_root, 'utils', 'run.py')<br>
         sub.append(('%{exec}', '{} {} {} -- '.format(pipes.quote(sys.executable),<br>
                                                      pipes.quote(executor),<br>
<br>
diff  --git a/libcxx/utils/libcxx/test/executor.py b/libcxx/utils/libcxx/test/executor.py<br>
index b555b1f03df9..c34310cdd2e2 100644<br>
--- a/libcxx/utils/libcxx/test/executor.py<br>
+++ b/libcxx/utils/libcxx/test/executor.py<br>
@@ -10,6 +10,7 @@<br>
 import os<br>
 import posixpath<br>
 import ntpath<br>
+import shutil<br>
<br>
 from libcxx.test import tracing<br>
 from libcxx.util import executeCommand<br>
@@ -61,6 +62,12 @@ def run(self, exe_path, cmd=None, work_dir='.', file_deps=None, env=None):<br>
         if env:<br>
             env = self.merge_environments(os.environ, env)<br>
<br>
+        for dep in file_deps:<br>
+            if os.path.isdir(dep):<br>
+                shutil.copytree(dep, os.path.join(work_dir, os.path.basename(dep)), symlinks=True)<br>
+            else:<br>
+                shutil.copy2(dep, work_dir)<br>
+<br>
         out, err, rc = executeCommand(cmd, cwd=work_dir, env=env)<br>
         return (cmd, out, err, rc)<br>
<br>
<br>
diff  --git a/libcxx/utils/libcxx/test/format.py b/libcxx/utils/libcxx/test/format.py<br>
index a026c4f1ba02..1bc85f24976a 100644<br>
--- a/libcxx/utils/libcxx/test/format.py<br>
+++ b/libcxx/utils/libcxx/test/format.py<br>
@@ -9,6 +9,8 @@<br>
 import copy<br>
 import errno<br>
 import os<br>
+import shutil<br>
+import tempfile<br>
 import time<br>
 import random<br>
<br>
@@ -209,16 +211,21 @@ def _evaluate_pass_test(self, test, tmpBase, lit_config,<br>
                 report += "Compilation failed unexpectedly!"<br>
                 return lit.Test.Result(lit.Test.FAIL, report)<br>
             # Run the test<br>
-            local_cwd = os.path.dirname(source_path)<br>
             env = None<br>
             if self.exec_env:<br>
                 env = self.exec_env<br>
<br>
             max_retry = test.allowed_retries + 1<br>
             for retry_count in range(max_retry):<br>
-                cmd, out, err, rc = self.executor.run(exec_path, [exec_path],<br>
-                                                      local_cwd, data_files,<br>
-                                                      env)<br>
+                # Create a temporary directory just for that test and run the<br>
+                # test in that directory<br>
+                try:<br>
+                    execDirTmp = tempfile.mkdtemp(dir=execDir)<br>
+                    cmd, out, err, rc = self.executor.run(exec_path, [exec_path],<br>
+                                                          execDirTmp, data_files,<br>
+                                                          env)<br>
+                finally:<br>
+                    shutil.rmtree(execDirTmp)<br>
                 report = "Compiled With: '%s'\n" % ' '.join(compile_cmd)<br>
                 report += libcxx.util.makeReport(cmd, out, err, rc)<br>
                 if rc == 0:<br>
<br>
diff  --git a/libcxx/utils/run.py b/libcxx/utils/run.py<br>
index 6a89a2b9388a..7de82c78dbfa 100644<br>
--- a/libcxx/utils/run.py<br>
+++ b/libcxx/utils/run.py<br>
@@ -14,14 +14,15 @@<br>
<br>
 import argparse<br>
 import os<br>
+import shutil<br>
 import subprocess<br>
 import sys<br>
+import tempfile<br>
<br>
<br>
 def main():<br>
     parser = argparse.ArgumentParser()<br>
     parser.add_argument('--codesign_identity', type=str, required=False)<br>
-    parser.add_argument('--working_directory', type=str, required=True)<br>
     parser.add_argument('--dependencies', type=str, nargs='*', required=True)<br>
     parser.add_argument('--env', type=str, nargs='*', required=True)<br>
     (args, remaining) = parser.parse_known_args(sys.argv[1:])<br>
@@ -42,14 +43,23 @@ def main():<br>
     # Extract environment variables into a dictionary<br>
     env = {k : v  for (k, v) in map(lambda s: s.split('=', 1), args.env)}<br>
<br>
-    # Ensure the file dependencies exist<br>
-    for file in args.dependencies:<br>
-        if not os.path.exists(file):<br>
-            sys.stderr.write('Missing file {} marked as a dependency of a test'.format(file))<br>
-            exit(1)<br>
+    try:<br>
+        tmpDir = tempfile.mkdtemp()<br>
<br>
-    # Run the executable with the given environment in the given working directory<br>
-    return subprocess.call(' '.join(remaining), cwd=args.working_directory, env=env, shell=True)<br>
+        # Ensure the file dependencies exist and copy them to a temporary directory.<br>
+        for dep in args.dependencies:<br>
+            if not os.path.exists(dep):<br>
+                sys.stderr.write('Missing file or directory "{}" marked as a dependency of a test'.format(dep))<br>
+                exit(1)<br>
+            if os.path.isdir(dep):<br>
+                shutil.copytree(dep, os.path.join(tmpDir, os.path.basename(dep)), symlinks=True)<br>
+            else:<br>
+                shutil.copy2(dep, tmpDir)<br>
+<br>
+        # Run the executable with the given environment in the temporary directory.<br>
+        return subprocess.call(' '.join(remaining), cwd=tmpDir, env=env, shell=True)<br>
+    finally:<br>
+        shutil.rmtree(tmpDir)<br>
<br>
 if __name__ == '__main__':<br>
     exit(main())<br>
<br>
<br>
<br>
_______________________________________________<br>
libcxx-commits mailing list<br>
<a href="mailto:libcxx-commits@lists.llvm.org" target="_blank">libcxx-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/libcxx-commits</a><br>
</blockquote></div>