[libcxx-commits] [libcxx] e22fe98 - [libc++] Make the %run substitution closer to how .pass.cpp tests are executed

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Mar 20 15:52:31 PDT 2020


Author: Louis Dionne
Date: 2020-03-20T18:52:14-04:00
New Revision: e22fe98d059c37a605b85641f4ff8e285164ac3b

URL: https://github.com/llvm/llvm-project/commit/e22fe98d059c37a605b85641f4ff8e285164ac3b
DIFF: https://github.com/llvm/llvm-project/commit/e22fe98d059c37a605b85641f4ff8e285164ac3b.diff

LOG: [libc++] Make the %run substitution closer to how .pass.cpp tests are executed

Before this patch, the %run substitution did not contain the same
environment variables as normal `pass.cpp` tests. It also didn't
have the right working directory and the script wasn't aware of
potential file dependencies.

With this change, the combination of %build and %run in a .sh.cpp script
should match how pass.cpp tests are actually executed much more closely.

Added: 
    libcxx/test/libcxx/selftest/test.file_dependencies.sh.cpp

Modified: 
    libcxx/utils/libcxx/test/config.py
    libcxx/utils/libcxx/test/format.py
    libcxx/utils/run.py

Removed: 
    


################################################################################
diff  --git a/libcxx/test/libcxx/selftest/test.file_dependencies.sh.cpp b/libcxx/test/libcxx/selftest/test.file_dependencies.sh.cpp
new file mode 100644
index 000000000000..b850b44b2bfe
--- /dev/null
+++ b/libcxx/test/libcxx/selftest/test.file_dependencies.sh.cpp
@@ -0,0 +1,12 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// FILE_DEPENDENCIES: test.pass.cpp
+
+// RUN: echo %file_dependencies | grep 'test.pass.cpp'

diff  --git a/libcxx/utils/libcxx/test/config.py b/libcxx/utils/libcxx/test/config.py
index 459a5ccdf225..cc7691402f2a 100644
--- a/libcxx/utils/libcxx/test/config.py
+++ b/libcxx/utils/libcxx/test/config.py
@@ -1083,8 +1083,11 @@ def configure_substitutions(self):
         # Configure run env substitution.
         codesign_ident = self.get_lit_conf('llvm_codesign_identity', '')
         run_py = os.path.join(self.libcxx_src_root, 'utils', 'run.py')
-        run_str = '%s %s "%s" %%t.exe' % (pipes.quote(sys.executable), \
-                                          pipes.quote(run_py), codesign_ident)
+        env_vars = ' '.join('%s=%s' % (k, pipes.quote(v)) for (k, v) in self.exec_env.items())
+        run_str = '%s %s --codesign_identity "%s" --working_directory "%%S" ' \
+                  '--dependencies %%file_dependencies --env %s -- %%t.exe' %  \
+            (pipes.quote(sys.executable), pipes.quote(run_py),
+             codesign_ident, env_vars)
         sub.append(('%run', run_str))
         # Configure not program substitutions
         not_py = os.path.join(self.libcxx_src_root, 'utils', 'not.py')

diff  --git a/libcxx/utils/libcxx/test/format.py b/libcxx/utils/libcxx/test/format.py
index 4f7283d04f3a..bf526d3618d1 100644
--- a/libcxx/utils/libcxx/test/format.py
+++ b/libcxx/utils/libcxx/test/format.py
@@ -108,6 +108,9 @@ def _execute(self, test, lit_config):
         parsers = self._make_custom_parsers(test)
         script = lit.TestRunner.parseIntegratedTestScript(
             test, additional_parsers=parsers, require_script=is_sh_test)
+
+        local_cwd = os.path.dirname(test.getSourcePath())
+        data_files = [os.path.join(local_cwd, f) for f in test.file_dependencies]
         # Check if a result for the test was returned. If so return that
         # result.
         if isinstance(script, lit.Test.Result):
@@ -122,6 +125,7 @@ def _execute(self, test, lit_config):
         tmpDir, tmpBase = lit.TestRunner.getTempPaths(test)
         substitutions = lit.TestRunner.getDefaultSubstitutions(test, tmpDir,
                                                                tmpBase)
+        substitutions.append(('%file_dependencies', ' '.join(data_files)))
         script = lit.TestRunner.applySubstitutions(script, substitutions)
 
         test_cxx = copy.deepcopy(self.cxx)
@@ -165,7 +169,7 @@ def _execute(self, test, lit_config):
             return self._evaluate_fail_test(test, test_cxx, parsers)
         elif is_pass_test:
             return self._evaluate_pass_test(test, tmpBase, lit_config,
-                                            test_cxx, parsers)
+                                            test_cxx, parsers, data_files)
         else:
             # No other test type is supported
             assert False
@@ -174,7 +178,7 @@ def _clean(self, exec_path):  # pylint: disable=no-self-use
         libcxx.util.cleanFile(exec_path)
 
     def _evaluate_pass_test(self, test, tmpBase, lit_config,
-                            test_cxx, parsers):
+                            test_cxx, parsers, data_files):
         execDir = os.path.dirname(test.getExecPath())
         source_path = test.getSourcePath()
         exec_path = tmpBase + '.exe'
@@ -196,7 +200,6 @@ def _evaluate_pass_test(self, test, tmpBase, lit_config,
             env = None
             if self.exec_env:
                 env = self.exec_env
-            data_files = [os.path.join(local_cwd, f) for f in test.file_dependencies]
             is_flaky = self._get_parser('FLAKY_TEST.', parsers).getValue()
             max_retry = 3 if is_flaky else 1
             for retry_count in range(max_retry):

diff  --git a/libcxx/utils/run.py b/libcxx/utils/run.py
index fcfee96c69eb..33d0095a17ea 100644
--- a/libcxx/utils/run.py
+++ b/libcxx/utils/run.py
@@ -14,25 +14,41 @@
 
 import subprocess
 import sys
+import argparse
 
 
 def main():
-    codesign_ident = sys.argv[1]
-
-    # Ignore 'run.py' and the codesigning identity.
-    argv = sys.argv[2:]
-
-    exec_path = argv[0]
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--codesign_identity', type=str, required=False)
+    parser.add_argument('--working_directory', type=str, required=True)
+    parser.add_argument('--dependencies', type=str, nargs='*', required=True)
+    parser.add_argument('--env', type=str, nargs='*', required=True)
+    (args, remaining) = parser.parse_known_args(sys.argv[1:])
+
+    if len(remaining) < 2:
+        sys.stderr.write('Missing actual commands to run')
+        exit(1)
+    remaining = remaining[1:] # Skip the '--'
 
     # Do any necessary codesigning.
-    if codesign_ident:
-        sign_cmd = ['xcrun', 'codesign', '-f', '-s', codesign_ident, exec_path]
-        cs_rc = subprocess.call(sign_cmd, env={})
-        if cs_rc != 0:
-            sys.stderr.write('Failed to codesign: ' + exec_path)
-            return cs_rc
-
-    return subprocess.call(argv)
+    if args.codesign_identity:
+        exe = remaining[0]
+        rc = subprocess.call(['xcrun', 'codesign', '-f', '-s', args.codesign_identity, exe], env={})
+        if rc != 0:
+            sys.stderr.write('Failed to codesign: ' + exe)
+            return rc
+
+    # Extract environment variables into a dictionary
+    env = {k : v  for (k, v) in map(lambda s: s.split('='), args.env)}
+
+    # Ensure the file dependencies exist
+    for file in args.dependencies:
+        if not os.path.exists(file):
+            sys.stderr.write('Missing file {} marked as a dependency of a test'.format(file))
+            exit(1)
+
+    # Run the executable with the given environment in the given working directory
+    return subprocess.call(remaining, cwd=args.working_directory, env=env)
 
 if __name__ == '__main__':
     exit(main())


        


More information about the libcxx-commits mailing list