forked from OSchip/llvm-project
[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.
This commit is contained in:
parent
479ee11061
commit
e22fe98d05
|
@ -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'
|
|
@ -1083,8 +1083,11 @@ class Configuration(object):
|
|||
# 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')
|
||||
|
|
|
@ -108,6 +108,9 @@ class LibcxxTestFormat(object):
|
|||
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 @@ class LibcxxTestFormat(object):
|
|||
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 @@ class LibcxxTestFormat(object):
|
|||
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 @@ class LibcxxTestFormat(object):
|
|||
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 @@ class LibcxxTestFormat(object):
|
|||
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):
|
||||
|
|
|
@ -14,25 +14,41 @@ program's error code.
|
|||
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
|
||||
def main():
|
||||
codesign_ident = sys.argv[1]
|
||||
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:])
|
||||
|
||||
# Ignore 'run.py' and the codesigning identity.
|
||||
argv = sys.argv[2:]
|
||||
|
||||
exec_path = argv[0]
|
||||
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
|
||||
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
|
||||
|
||||
return subprocess.call(argv)
|
||||
# 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())
|
||||
|
|
Loading…
Reference in New Issue