Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -46,6 +46,8 @@ pythonize_bool(LIBCXX_ENABLE_MONOTONIC_CLOCK) set(LIBCXX_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING "TargetInfo to use when setting up test environment.") + set(LIBCXX_EXECUTOR "None" CACHE STRING + "Executor to use when running tests.") set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!") Index: libcxx/test/config.py =================================================================== --- libcxx/test/config.py +++ libcxx/test/config.py @@ -12,7 +12,8 @@ from libcxx.test.format import LibcxxTestFormat from libcxx.compiler import CXXCompiler - +from libcxx.test.executor import * +from libcxx.test.tracing import * def loadSiteConfig(lit_config, config, param_name, env_name): # We haven't loaded the site specific configuration (the user is @@ -78,6 +79,7 @@ "parameter '{}' should be true or false".format(name)) def configure(self): + self.configure_executor() self.configure_target_info() self.configure_cxx() self.configure_triple() @@ -108,6 +110,32 @@ list(self.config.available_features)) self.lit_config.note('Using environment: %r' % self.env) + def get_test_format(self): + return LibcxxTestFormat( + self.cxx, + self.use_clang_verify, + self.execute_external, + self.executor, + exec_env=self.env) + + def configure_executor(self): + exec_str = self.get_lit_conf('executor', "None") + te = eval(exec_str) + if te: + self.lit_config.note("inferred executor as: %r" % exec_str) + if self.lit_config.useValgrind: + # We have no way of knowing where in the chain the + # ValgrindExecutor is supposed to go. It is likely + # that the user wants it at the end, but we have no + # way of getting at that easily. + selt.lit_config.fatal("Cannot infer how to create a Valgrind " + " executor.") + else: + te = LocalExecutor() + if self.lit_config.useValgrind: + te = ValgrindExecutor(self.lit_config.valgrindArgs, te) + self.executor = te + def configure_target_info(self): default = "libcxx.test.target_info.LocalTI" info_str = self.get_lit_conf('target_info', default) @@ -117,13 +145,6 @@ if info_str != default: self.lit_config.note("inferred target_info as: %r" % info_str) - def get_test_format(self): - return LibcxxTestFormat( - self.cxx, - self.use_clang_verify, - self.execute_external, - exec_env=self.env) - def configure_cxx(self): # Gather various compiler parameters. cxx = self.get_lit_conf('cxx_under_test') @@ -317,7 +338,7 @@ # Configure include paths self.cxx.compile_flags += ['-nostdinc++'] self.configure_compile_flags_header_includes() - if sys.platform.startswith('linux'): + if self.target_info.platform() == 'linux': self.cxx.compile_flags += ['-D__STDC_FORMAT_MACROS', '-D__STDC_LIMIT_MACROS', '-D__STDC_CONSTANT_MACROS'] @@ -576,15 +597,16 @@ # linux-gnu is needed in the triple to properly identify linuxes # that use GLIBC. Handle redhat and opensuse triples as special # cases and append the missing `-gnu` portion. - if target_triple.endswith('redhat-linux') or \ - target_triple.endswith('suse-linux'): + if (target_triple.endswith('redhat-linux') or + target_triple.endswith('suse-linux')): target_triple += '-gnu' self.config.target_triple = target_triple self.lit_config.note( "inferred target_triple as: %r" % self.config.target_triple) def configure_env(self): - if sys.platform == 'darwin' and not self.use_system_cxx_lib: + if (self.target_info.platform() == 'darwin' and + not self.use_system_cxx_lib): libcxx_library = self.get_lit_conf('libcxx_library') if libcxx_library: cxx_library_root = os.path.dirname(libcxx_library) Index: libcxx/test/format.py =================================================================== --- libcxx/test/format.py +++ libcxx/test/format.py @@ -20,10 +20,12 @@ FOO.sh.cpp - A test that uses LIT's ShTest format. """ - def __init__(self, cxx, use_verify_for_fail, execute_external, exec_env): + def __init__(self, cxx, use_verify_for_fail, execute_external, + executor, exec_env): self.cxx = cxx self.use_verify_for_fail = use_verify_for_fail self.execute_external = execute_external + self.executor = executor self.exec_env = dict(exec_env) # TODO: Move this into lit's FileBasedTest @@ -73,6 +75,10 @@ # Dispatch the test based on its suffix. if is_sh_test: + if self.executor: + # We can't run ShTest tests with a executor yet. + # For now, bail on trying to run them + return lit.Test.UNSUPPORTED, 'ShTest format not yet supported' return lit.TestRunner._runShTest(test, lit_config, self.execute_external, script, tmpBase, execDir) @@ -104,15 +110,12 @@ report += "Compilation failed unexpectedly!" return lit.Test.FAIL, report # Run the test - cmd = [] + local_cwd = os.path.dirname(source_path) + env = None if self.exec_env: - cmd += ['env'] - cmd += ['%s=%s' % (k, v) for k, v in self.exec_env.items()] - if lit_config.useValgrind: - cmd = lit_config.valgrindArgs + cmd - cmd += [exec_path] - out, err, rc = lit.util.executeCommand( - cmd, cwd=os.path.dirname(source_path)) + env = self.exec_env + out, err, rc = self.executor.run(exec_path, [exec_path], + local_cwd, env) if rc != 0: report = libcxx.util.makeReport(cmd, out, err, rc) report = "Compiled With: %s\n%s" % (compile_cmd, report) Index: lit.site.cfg.in =================================================================== --- lit.site.cfg.in +++ lit.site.cfg.in @@ -18,6 +18,7 @@ config.sysroot = "@LIBCXX_SYSROOT@" config.gcc_toolchain = "@LIBCXX_GCC_TOOLCHAIN@" config.target_info = "@LIBCXX_TARGET_INFO@" +config.executor = "@LIBCXX_EXECUTOR@" # Let the main config do the real work. lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg")