Skip to content

Commit

Permalink
[lldb] Make the lit configuration values optional for the API tests
Browse files Browse the repository at this point in the history
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
  • Loading branch information
JDevlieghere committed Aug 29, 2020
1 parent 0231a4e commit 3f2fb01
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 46 deletions.
104 changes: 59 additions & 45 deletions lldb/test/API/lit.cfg.py
Expand Up @@ -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):
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lldb/test/API/lldbtest.py
Expand Up @@ -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:
Expand Down

0 comments on commit 3f2fb01

Please sign in to comment.