brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.2 KiB · f2a14d1 Raw
362 lines · python
1# -*- Python -*-2 3# Configuration file for the 'lit' test runner.4 5import os6import platform7import shlex8import shutil9import subprocess10import sys11 12import lit.formats13 14# name: The name of this test suite.15config.name = "lldb-api"16 17# suffixes: A list of file extensions to treat as test files.18config.suffixes = [".py"]19 20# test_source_root: The root path where tests are located.21config.test_source_root = os.path.dirname(__file__)22 23# test_exec_root: The root path where tests should be run.24config.test_exec_root = os.path.join(config.lldb_obj_root, "test", "API")25 26 27def mkdir_p(path):28    import errno29 30    try:31        os.makedirs(path)32    except OSError as e:33        if e.errno != errno.EEXIST:34            raise35    if not os.path.isdir(path):36        raise OSError(errno.ENOTDIR, "%s is not a directory" % path)37 38 39def find_sanitizer_runtime(name):40    resource_dir = (41        subprocess.check_output([config.cmake_cxx_compiler, "-print-resource-dir"])42        .decode("utf-8")43        .strip()44    )45    return os.path.join(resource_dir, "lib", "darwin", name)46 47 48def find_shlibpath_var():49    if platform.system() in ["Linux", "FreeBSD", "NetBSD", "OpenBSD", "SunOS"]:50        yield "LD_LIBRARY_PATH"51    elif platform.system() == "Darwin":52        yield "DYLD_LIBRARY_PATH"53    elif platform.system() == "Windows":54        yield "PATH"55 56 57# On macOS, we can't do the DYLD_INSERT_LIBRARIES trick with a shim python58# binary as the ASan interceptors get loaded too late. Also, when SIP is59# enabled, we can't inject libraries into system binaries at all, so we need a60# copy of the "real" python to work with.61def find_python_interpreter():62    # This is only necessary when using DYLD_INSERT_LIBRARIES.63    if "DYLD_INSERT_LIBRARIES" not in config.environment:64        return None65 66    # If we're running in a virtual environment, we have to copy Python into67    # the virtual environment for it to work.68    if sys.prefix != sys.base_prefix:69        copied_python = os.path.join(sys.prefix, "bin", "copied-python")70    else:71        copied_python = os.path.join(config.lldb_build_directory, "copied-python")72 73    # Avoid doing any work if we already copied the binary.74    if os.path.isfile(copied_python):75        return copied_python76 77    # Find the "real" python binary.78    real_python = (79        subprocess.check_output(80            [81                config.python_executable,82                os.path.join(83                    os.path.dirname(os.path.realpath(__file__)),84                    "get_darwin_real_python.py",85                ),86            ]87        )88        .decode("utf-8")89        .strip()90    )91 92    shutil.copy(real_python, copied_python)93    # macOS 15+ restricts injecting the ASAN runtime to only user-compiled code.94    subprocess.check_call(["/usr/bin/codesign", "--remove-signature", copied_python])95 96    # Now make sure the copied Python works. The Python in Xcode has a relative97    # RPATH and cannot be copied.98    try:99        # We don't care about the output, just make sure it runs.100        subprocess.check_call([copied_python, "-V"])101    except subprocess.CalledProcessError:102        # The copied Python didn't work. Assume we're dealing with the Python103        # interpreter in Xcode. Given that this is not a system binary SIP104        # won't prevent us form injecting the interceptors, but when running in105        # a virtual environment, we can't use it directly. Create a symlink106        # instead.107        os.remove(copied_python)108        os.symlink(real_python, copied_python)109 110    # The copied Python works.111    return copied_python112 113 114def is_configured(attr):115    """Return the configuration attribute if it exists and None otherwise.116 117    This allows us to check if the attribute exists before trying to access it."""118    return getattr(config, attr, None)119 120 121def delete_module_cache(path):122    """Clean the module caches in the test build directory.123 124    This is necessary in an incremental build whenever clang changes underneath,125    so doing it once per lit.py invocation is close enough."""126    if os.path.isdir(path):127        lit_config.note("Deleting module cache at %s." % path)128        shutil.rmtree(path)129 130 131if is_configured("llvm_use_sanitizer"):132    config.environment["MallocNanoZone"] = "0"133    if "Address" in config.llvm_use_sanitizer:134        config.environment["ASAN_OPTIONS"] = "detect_stack_use_after_return=1"135        if "Darwin" in config.target_os:136            config.environment["DYLD_INSERT_LIBRARIES"] = find_sanitizer_runtime(137                "libclang_rt.asan_osx_dynamic.dylib"138            )139 140    if "Thread" in config.llvm_use_sanitizer:141        config.environment["TSAN_OPTIONS"] = "halt_on_error=1"142        if "Darwin" in config.target_os:143            config.environment["DYLD_INSERT_LIBRARIES"] = find_sanitizer_runtime(144                "libclang_rt.tsan_osx_dynamic.dylib"145            )146 147if platform.system() == "Darwin":148    python_executable = find_python_interpreter()149    if python_executable:150        lit_config.note(151            "Using {} instead of {}".format(python_executable, config.python_executable)152        )153        config.python_executable = python_executable154 155# Shared library build of LLVM may require LD_LIBRARY_PATH or equivalent.156if is_configured("shared_libs"):157    for shlibpath_var in find_shlibpath_var():158        # In stand-alone build llvm_shlib_dir specifies LLDB's lib directory while159        # llvm_libs_dir specifies LLVM's lib directory.160        shlibpath = os.path.pathsep.join(161            (162                config.llvm_shlib_dir,163                config.llvm_libs_dir,164                config.environment.get(shlibpath_var, ""),165            )166        )167        config.environment[shlibpath_var] = shlibpath168    else:169        lit_config.warning(170            "unable to inject shared library path on '{}'".format(platform.system())171        )172 173lldb_use_simulator = lit_config.params.get("lldb-run-with-simulator", None)174if lldb_use_simulator:175    if lldb_use_simulator == "ios":176        lit_config.note("Running API tests on iOS simulator")177        config.available_features.add("lldb-simulator-ios")178    elif lldb_use_simulator == "watchos":179        lit_config.note("Running API tests on watchOS simulator")180        config.available_features.add("lldb-simulator-watchos")181    elif lldb_use_simulator == "tvos":182        lit_config.note("Running API tests on tvOS simulator")183        config.available_features.add("lldb-simulator-tvos")184    elif lldb_use_simulator == "qemu-user":185        lit_config.note("Running API tests on qemu-user simulator")186        config.available_features.add("lldb-simulator-qemu-user")187    else:188        lit_config.error("Unknown simulator id '{}'".format(lldb_use_simulator))189 190# Set a default per-test timeout of 10 minutes. Setting a timeout per test191# requires that killProcessAndChildren() is supported on the platform and192# lit complains if the value is set but it is not supported.193supported, errormsg = lit_config.maxIndividualTestTimeIsSupported194if supported:195    lit_config.maxIndividualTestTime = 600196else:197    lit_config.warning("Could not set a default per-test timeout. " + errormsg)198 199# Build dotest command.200dotest_cmd = [os.path.join(config.lldb_src_root, "test", "API", "dotest.py")]201 202if is_configured("dotest_common_args_str"):203    dotest_cmd.extend(config.dotest_common_args_str.split(";"))204 205# Library path may be needed to locate just-built clang and libcxx.206if is_configured("llvm_libs_dir"):207    dotest_cmd += ["--env", "LLVM_LIBS_DIR=" + config.llvm_libs_dir]208 209# Include path may be needed to locate just-built libcxx.210if is_configured("llvm_include_dir"):211    dotest_cmd += ["--env", "LLVM_INCLUDE_DIR=" + config.llvm_include_dir]212 213# This path may be needed to locate required llvm tools214if is_configured("llvm_tools_dir"):215    dotest_cmd += ["--env", "LLVM_TOOLS_DIR=" + config.llvm_tools_dir]216 217# If we have a just-built libcxx, prefer it over the system one.218if is_configured("has_libcxx") and config.has_libcxx:219    if platform.system() != "Windows":220        if is_configured("libcxx_include_dir") and is_configured("libcxx_libs_dir"):221            dotest_cmd += ["--libcxx-include-dir", config.libcxx_include_dir]222            if is_configured("libcxx_include_target_dir"):223                dotest_cmd += [224                    "--libcxx-include-target-dir",225                    config.libcxx_include_target_dir,226                ]227            dotest_cmd += ["--libcxx-library-dir", config.libcxx_libs_dir]228 229# Forward ASan-specific environment variables to tests, as a test may load an230# ASan-ified dylib.231for env_var in ("ASAN_OPTIONS", "DYLD_INSERT_LIBRARIES"):232    if env_var in config.environment:233        dotest_cmd += ["--inferior-env", env_var + "=" + config.environment[env_var]]234 235if is_configured("test_arch"):236    dotest_cmd += ["--arch", config.test_arch]237 238if is_configured("lldb_build_directory"):239    dotest_cmd += ["--build-dir", config.lldb_build_directory]240 241if is_configured("lldb_module_cache"):242    delete_module_cache(config.lldb_module_cache)243    dotest_cmd += ["--lldb-module-cache-dir", config.lldb_module_cache]244 245if is_configured("clang_module_cache"):246    delete_module_cache(config.clang_module_cache)247    dotest_cmd += ["--clang-module-cache-dir", config.clang_module_cache]248 249if is_configured("lldb_executable"):250    dotest_cmd += ["--executable", config.lldb_executable]251 252if is_configured("test_compiler"):253    dotest_cmd += ["--compiler", config.test_compiler]254 255if is_configured("dsymutil"):256    dotest_cmd += ["--dsymutil", config.dsymutil]257 258if is_configured("make"):259    dotest_cmd += ["--make", config.make]260 261if is_configured("llvm_tools_dir"):262    dotest_cmd += ["--llvm-tools-dir", config.llvm_tools_dir]263 264if is_configured("server"):265    dotest_cmd += ["--server", config.server]266 267if is_configured("lldb_obj_root"):268    dotest_cmd += ["--lldb-obj-root", config.lldb_obj_root]269 270if is_configured("lldb_libs_dir"):271    dotest_cmd += ["--lldb-libs-dir", config.lldb_libs_dir]272 273if is_configured("lldb_framework_dir"):274    dotest_cmd += ["--framework", config.lldb_framework_dir]275 276if is_configured("cmake_build_type"):277    dotest_cmd += ["--cmake-build-type", config.cmake_build_type]278 279if "lldb-simulator-ios" in config.available_features:280    dotest_cmd += ["--apple-sdk", "iphonesimulator", "--platform-name", "ios-simulator"]281elif "lldb-simulator-watchos" in config.available_features:282    dotest_cmd += [283        "--apple-sdk",284        "watchsimulator",285        "--platform-name",286        "watchos-simulator",287    ]288elif "lldb-simulator-tvos" in config.available_features:289    dotest_cmd += [290        "--apple-sdk",291        "appletvsimulator",292        "--platform-name",293        "tvos-simulator",294    ]295 296if "lldb-simulator-qemu-user" in config.available_features:297    dotest_cmd += ["--platform-name", "qemu-user"]298 299if is_configured("enabled_plugins"):300    for plugin in config.enabled_plugins:301        dotest_cmd += ["--enable-plugin", plugin]302 303# `dotest` args come from three different sources:304# 1. Derived by CMake based on its configs (LLDB_TEST_COMMON_ARGS), which end305# up in `dotest_common_args_str`.306# 2. CMake user parameters (LLDB_TEST_USER_ARGS), which end up in307# `dotest_user_args_str`.308# 3. With `llvm-lit "--param=dotest-args=..."`, which end up in309# `dotest_lit_args_str`.310# Check them in this order, so that more specific overrides are visited last.311# In particular, (1) is visited at the top of the file, since the script312# derives other information from it.313 314if is_configured("lldb_platform_url"):315    dotest_cmd += ["--platform-url", config.lldb_platform_url]316if is_configured("lldb_platform_working_dir"):317    dotest_cmd += ["--platform-working-dir", config.lldb_platform_working_dir]318if is_configured("cmake_sysroot"):319    dotest_cmd += ["--sysroot", config.cmake_sysroot]320 321if is_configured("dotest_user_args_str"):322    dotest_cmd.extend(config.dotest_user_args_str.split(";"))323 324if is_configured("dotest_lit_args_str"):325    # We don't want to force users passing arguments to lit to use `;` as a326    # separator. We use Python's simple lexical analyzer to turn the args into a327    # list. Pass there arguments last so they can override anything that was328    # already configured.329    dotest_cmd.extend(shlex.split(config.dotest_lit_args_str))330 331# Load LLDB test format.332sys.path.append(os.path.join(config.lldb_src_root, "test", "API"))333import lldbtest334 335# testFormat: The test format to use to interpret tests.336config.test_format = lldbtest.LLDBTest(dotest_cmd)337 338# Propagate TERM or default to vt100.339config.environment["TERM"] = os.getenv("TERM", default="vt100")340 341# Propagate FREEBSD_LEGACY_PLUGIN342if "FREEBSD_LEGACY_PLUGIN" in os.environ:343    config.environment["FREEBSD_LEGACY_PLUGIN"] = os.environ["FREEBSD_LEGACY_PLUGIN"]344 345# Propagate XDG_CACHE_HOME346if "XDG_CACHE_HOME" in os.environ:347    config.environment["XDG_CACHE_HOME"] = os.environ["XDG_CACHE_HOME"]348 349# Transfer some environment variables into the tests on Windows build host.350if platform.system() == "Windows":351    for v in ["SystemDrive"]:352        if v in os.environ:353            config.environment[v] = os.environ[v]354 355# Some steps required to initialize the tests dynamically link with python.dll356# and need to know the location of the Python libraries. This ensures that we357# use the same version of Python that was used to build lldb to run our tests.358config.environment["PYTHONHOME"] = config.python_root_dir359config.environment["PATH"] = os.path.pathsep.join(360    (config.python_root_dir, config.environment.get("PATH", ""))361)362