From 3f2fb0132f7b09e1309e8f7e0b5ba8ea471b17e7 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 28 Aug 2020 18:05:01 -0700 Subject: [PATCH] [lldb] Make the lit configuration values optional for the API tests LIT uses a model where the test suite is configurable trough a lit.site.cfg file. Most of the time we use the lit.site.cfg with values that match the current build configuration, generated by CMake. Nothing prevents you from running the test suite with a different configuration, either by overriding some of these values from the command line, or by passing a different lit.site.cfg. The latter is currently tedious. Many configuration values are optional but they still need to be set because lit.cfg.py is accessing them directly. This patch changes the code to use getattr to return the attribute if it exists. This makes it possible to specify a minimal lit.site.cfg with only the mandatory/desired configuration values. Differential revision: https://reviews.llvm.org/D86821 --- lldb/test/API/lit.cfg.py | 104 +++++++++++++++++++++----------------- lldb/test/API/lldbtest.py | 2 +- 2 files changed, 60 insertions(+), 46 deletions(-) diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index 238df53b69a50..5da12eea4504f 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -23,14 +23,14 @@ def mkdir_p(path): - import errno - try: - os.makedirs(path) - except OSError as e: - if e.errno != errno.EEXIST: - raise - if not os.path.isdir(path): - raise OSError(errno.ENOTDIR, "%s is not a directory"%path) + import errno + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + if not os.path.isdir(path): + raise OSError(errno.ENOTDIR, "%s is not a directory"%path) def find_sanitizer_runtime(name): @@ -85,22 +85,39 @@ def find_python_interpreter(): return copied_python -if 'Address' in config.llvm_use_sanitizer: - config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1' - if 'Darwin' in config.host_os and 'x86' in config.host_triple: - config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( - 'libclang_rt.asan_osx_dynamic.dylib') +def is_configured(attr): + """Return the configuration attribute if it exists and None otherwise. + + This allows us to check if the attribute exists before trying to access it.""" + return getattr(config, attr, None) + + +def delete_module_cache(path): + """Clean the module caches in the test build directory. + + This is necessary in an incremental build whenever clang changes underneath, + so doing it once per lit.py invocation is close enough. """ + if os.path.isdir(path): + print("Deleting module cache at %s." % path) + shutil.rmtree(path) -if 'Thread' in config.llvm_use_sanitizer: - if 'Darwin' in config.host_os and 'x86' in config.host_triple: - config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( - 'libclang_rt.tsan_osx_dynamic.dylib') +if is_configured('llvm_use_sanitizer'): + if 'Address' in config.llvm_use_sanitizer: + config.environment['ASAN_OPTIONS'] = 'detect_stack_use_after_return=1' + if 'Darwin' in config.host_os and 'x86' in config.host_triple: + config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( + 'libclang_rt.asan_osx_dynamic.dylib') + + if 'Thread' in config.llvm_use_sanitizer: + if 'Darwin' in config.host_os and 'x86' in config.host_triple: + config.environment['DYLD_INSERT_LIBRARIES'] = find_sanitizer_runtime( + 'libclang_rt.tsan_osx_dynamic.dylib') if 'DYLD_INSERT_LIBRARIES' in config.environment and platform.system() == 'Darwin': config.python_executable = find_python_interpreter() # Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent. -if config.shared_libs: +if is_configured('shared_libs'): for shlibpath_var in find_shlibpath_var(): # In stand-alone build llvm_shlib_dir specifies LLDB's lib directory while # llvm_libs_dir specifies LLVM's lib directory. @@ -129,14 +146,6 @@ def find_python_interpreter(): elif lldb_repro_mode == 'replay': config.available_features.add('lldb-repro-replay') -# Clean the module caches in the test build directory. This is necessary in an -# incremental build whenever clang changes underneath, so doing it once per -# lit.py invocation is close enough. -for cachedir in [config.clang_module_cache, config.lldb_module_cache]: - if os.path.isdir(cachedir): - print("Deleting module cache at %s." % cachedir) - shutil.rmtree(cachedir) - # Set a default per-test timeout of 10 minutes. Setting a timeout per test # requires that killProcessAndChildren() is supported on the platform and # lit complains if the value is set but it is not supported. @@ -148,11 +157,12 @@ def find_python_interpreter(): # Build dotest command. dotest_cmd = [os.path.join(config.lldb_src_root, 'test', 'API', 'dotest.py')] -dotest_cmd += ['--arch', config.test_arch] -dotest_cmd.extend(config.dotest_args_str.split(';')) + +if is_configured('dotest_args_str'): + dotest_cmd.extend(config.dotest_args_str.split(';')) # Library path may be needed to locate just-built clang. -if config.llvm_libs_dir: +if is_configured('llvm_libs_dir'): dotest_cmd += ['--env', 'LLVM_LIBS_DIR=' + config.llvm_libs_dir] # Forward ASan-specific environment variables to tests, as a test may load an @@ -161,49 +171,53 @@ def find_python_interpreter(): if env_var in config.environment: dotest_cmd += ['--inferior-env', env_var + '=' + config.environment[env_var]] -if config.lldb_build_directory: +if is_configured('test_arch'): + dotest_cmd += ['--arch', config.test_arch] + +if is_configured('lldb_build_directory'): dotest_cmd += ['--build-dir', config.lldb_build_directory] -if config.lldb_module_cache: +if is_configured('lldb_module_cache'): + delete_module_cache(config.lldb_module_cache) dotest_cmd += ['--lldb-module-cache-dir', config.lldb_module_cache] -if config.clang_module_cache: +if is_configured('clang_module_cache'): + delete_module_cache(config.clang_module_cache) dotest_cmd += ['--clang-module-cache-dir', config.clang_module_cache] -if config.lldb_executable: +if is_configured('lldb_executable'): dotest_cmd += ['--executable', config.lldb_executable] -if config.test_compiler: +if is_configured('test_compiler'): dotest_cmd += ['--compiler', config.test_compiler] -if config.dsymutil: +if is_configured('dsymutil'): dotest_cmd += ['--dsymutil', config.dsymutil] -if config.filecheck: +if is_configured('filecheck'): dotest_cmd += ['--filecheck', config.filecheck] -if config.yaml2obj: +if is_configured('yaml2obj'): dotest_cmd += ['--yaml2obj', config.yaml2obj] -if config.lldb_libs_dir: +if is_configured('lldb_libs_dir'): dotest_cmd += ['--lldb-libs-dir', config.lldb_libs_dir] if 'lldb-repro-capture' in config.available_features or \ 'lldb-repro-replay' in config.available_features: dotest_cmd += ['--skip-category=lldb-vscode', '--skip-category=std-module'] -if config.enabled_plugins: +if is_configured('enabled_plugins'): for plugin in config.enabled_plugins: dotest_cmd += ['--enable-plugin', plugin] -# We don't want to force users passing arguments to lit to use `;` as a -# separator. We use Python's simple lexical analyzer to turn the args into a -# list. Pass there arguments last so they can override anything that was -# already configured. -if config.dotest_lit_args_str: +if is_configured('dotest_lit_args_str'): + # We don't want to force users passing arguments to lit to use `;` as a + # separator. We use Python's simple lexical analyzer to turn the args into a + # list. Pass there arguments last so they can override anything that was + # already configured. dotest_cmd.extend(shlex.split(config.dotest_lit_args_str)) - # Load LLDB test format. sys.path.append(os.path.join(config.lldb_src_root, "test", "API")) import lldbtest diff --git a/lldb/test/API/lldbtest.py b/lldb/test/API/lldbtest.py index 94eb8ebd054aa..a03390ee38787 100644 --- a/lldb/test/API/lldbtest.py +++ b/lldb/test/API/lldbtest.py @@ -38,7 +38,7 @@ def execute(self, test, litConfig): if litConfig.noExecute: return lit.Test.PASS, '' - if not test.config.lldb_enable_python: + if not getattr(test.config, 'lldb_enable_python', False): return (lit.Test.UNSUPPORTED, 'Python module disabled') if test.config.unsupported: