"""
A simple testing framework for lldb using python's unit testing framework.

Tests for lldb are written as python scripts which take advantage of the script
bridging provided by LLDB.framework to interact with lldb core.

A specific naming pattern is followed by the .py script to be recognized as
a module which implements a test scenario, namely, Test*.py.

To specify the directories where "Test*.py" python test scripts are located,
you need to pass in a list of directory names.  By default, the current
working directory is searched if nothing is specified on the command line.

Type:

./dotest.py -h

for available options.
"""

# System modules
import atexit
import datetime
import errno
import logging
import os
import platform
import re
import shutil
import signal
import subprocess
import sys
import tempfile

# Third-party modules
import unittest

# LLDB Modules
import lldbsuite
from . import configuration
from . import dotest_args
from . import lldbtest_config
from . import test_categories
from . import test_result
from ..support import seven
from ..support import temp_file


def is_exe(fpath):
    """Returns true if fpath is an executable."""
    if fpath is None:
        return False
    if sys.platform == "win32":
        if not fpath.endswith(".exe"):
            fpath += ".exe"
    return os.path.isfile(fpath) and os.access(fpath, os.X_OK)


def which(program):
    """Returns the full path to a program; None otherwise."""
    fpath, _ = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file
    return None


def usage(parser):
    parser.print_help()
    if configuration.verbose > 0:
        print(
            """
Examples:

This is an example of using the -f option to pinpoint to a specific test class
and test method to be run:

$ ./dotest.py -f ClassTypesTestCase.test_with_dsym_and_run_command
----------------------------------------------------------------------
Collected 1 test

test_with_dsym_and_run_command (TestClassTypes.ClassTypesTestCase)
Test 'frame variable this' when stopped on a class constructor. ... ok

----------------------------------------------------------------------
Ran 1 test in 1.396s

OK

And this is an example of using the -p option to run a single file (the filename
matches the pattern 'ObjC' and it happens to be 'TestObjCMethods.py'):

$ ./dotest.py -v -p ObjC
----------------------------------------------------------------------
Collected 4 tests

test_break_with_dsym (TestObjCMethods.FoundationTestCase)
Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
test_break_with_dwarf (TestObjCMethods.FoundationTestCase)
Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'. ... ok
test_data_type_and_expr_with_dsym (TestObjCMethods.FoundationTestCase)
Lookup objective-c data types and evaluate expressions. ... ok
test_data_type_and_expr_with_dwarf (TestObjCMethods.FoundationTestCase)
Lookup objective-c data types and evaluate expressions. ... ok

----------------------------------------------------------------------
Ran 4 tests in 16.661s

OK

Running of this script also sets up the LLDB_TEST environment variable so that
individual test cases can locate their supporting files correctly.  The script
tries to set up Python's search paths for modules by looking at the build tree
relative to this script.  See also the '-i' option in the following example.

Finally, this is an example of using the lldb.py module distributed/installed by
Xcode4 to run against the tests under the 'forward' directory, and with the '-w'
option to add some delay between two tests.  It uses ARCH=x86_64 to specify that
as the architecture and CC=clang to specify the compiler used for the test run:

$ PYTHONPATH=/Xcode4/Library/PrivateFrameworks/LLDB.framework/Versions/A/Resources/Python ARCH=x86_64 CC=clang ./dotest.py -v -w -i forward

Session logs for test failures/errors will go into directory '2010-11-11-13_56_16'
----------------------------------------------------------------------
Collected 2 tests

test_with_dsym_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok
test_with_dwarf_and_run_command (TestForwardDeclaration.ForwardDeclarationTestCase)
Display *bar_ptr when stopped on a function with forward declaration of struct bar. ... ok

----------------------------------------------------------------------
Ran 2 tests in 5.659s

OK

The 'Session ...' verbiage is recently introduced (see also the '-s' option) to
notify the directory containing the session logs for test failures or errors.
In case there is any test failure/error, a similar message is appended at the
end of the stderr output for your convenience.

ENABLING LOGS FROM TESTS

Option 1:

Writing logs into different files per test case::

$ ./dotest.py --channel "lldb all"

$ ./dotest.py --channel "lldb all" --channel "gdb-remote packets"

These log files are written to:

<session-dir>/<test-id>-host.log (logs from lldb host process)
<session-dir>/<test-id>-server.log (logs from debugserver/lldb-server)
<session-dir>/<test-id>-<test-result>.log (console logs)

By default, logs from successful runs are deleted.  Use the --log-success flag
to create reference logs for debugging.

$ ./dotest.py --log-success

"""
        )
    sys.exit(0)


def parseExclusion(exclusion_file):
    """Parse an exclusion file, of the following format, where
    'skip files', 'skip methods', 'xfail files', and 'xfail methods'
    are the possible list heading values:

    skip files
    <file name>
    <file name>

    xfail methods
    <method name>
    """
    excl_type = None

    with open(exclusion_file) as f:
        for line in f:
            line = line.strip()
            if not excl_type:
                excl_type = line
                continue

            if not line:
                excl_type = None
            elif excl_type == "skip":
                if not configuration.skip_tests:
                    configuration.skip_tests = []
                configuration.skip_tests.append(line)
            elif excl_type == "xfail":
                if not configuration.xfail_tests:
                    configuration.xfail_tests = []
                configuration.xfail_tests.append(line)


def parseOptionsAndInitTestdirs():
    """Initialize the list of directories containing our unittest scripts.

    '-h/--help as the first option prints out usage info and exit the program.
    """

    do_help = False

    platform_system = platform.system()
    platform_machine = platform.machine()

    try:
        parser = dotest_args.create_parser()
        args = parser.parse_args()
    except:
        raise

    if args.unset_env_varnames:
        for env_var in args.unset_env_varnames:
            if env_var in os.environ:
                # From Python Doc: When unsetenv() is supported, deletion of items in os.environ
                # is automatically translated into a corresponding call to
                # unsetenv().
                del os.environ[env_var]
                # os.unsetenv(env_var)

    if args.set_env_vars:
        for env_var in args.set_env_vars:
            parts = env_var.split("=", 1)
            if len(parts) == 1:
                os.environ[parts[0]] = ""
            else:
                os.environ[parts[0]] = parts[1]

    if args.set_inferior_env_vars:
        lldbtest_config.inferior_env = " ".join(args.set_inferior_env_vars)

    if args.h:
        do_help = True

    if args.compiler:
        configuration.compiler = os.path.abspath(args.compiler)
        if not is_exe(configuration.compiler):
            configuration.compiler = which(args.compiler)
        if not is_exe(configuration.compiler):
            logging.error(
                '"%s" is not a valid compiler executable; aborting...', args.compiler
            )
            sys.exit(-1)
    else:
        # Use a compiler appropriate appropriate for the Apple SDK if one was
        # specified
        if platform_system == "Darwin" and args.apple_sdk:
            configuration.compiler = seven.get_command_output(
                'xcrun -sdk "%s" -find clang 2> /dev/null' % (args.apple_sdk)
            )
        else:
            # 'clang' on ubuntu 14.04 is 3.4 so we try clang-3.5 first
            candidateCompilers = ["clang-3.5", "clang", "gcc"]
            for candidate in candidateCompilers:
                if which(candidate):
                    configuration.compiler = candidate
                    break

    if args.make:
        configuration.make_path = args.make

    if args.dsymutil:
        configuration.dsymutil = args.dsymutil
    elif platform_system == "Darwin":
        configuration.dsymutil = seven.get_command_output(
            "xcrun -find -toolchain default dsymutil"
        )
    if args.llvm_tools_dir:
        configuration.llvm_tools_dir = args.llvm_tools_dir
        configuration.filecheck = shutil.which("FileCheck", path=args.llvm_tools_dir)
        configuration.yaml2obj = shutil.which("yaml2obj", path=args.llvm_tools_dir)
        configuration.yaml2macho_core = shutil.which(
            "yaml2macho-core", path=args.llvm_tools_dir
        )

    if not configuration.get_filecheck_path():
        logging.warning("No valid FileCheck executable; some tests may fail...")
        logging.warning("(Double-check the --llvm-tools-dir argument to dotest.py)")

    if args.libcxx_include_dir or args.libcxx_library_dir:
        if args.lldb_platform_name:
            logging.warning(
                "Custom libc++ is not supported for remote runs: ignoring --libcxx arguments"
            )
        elif not (args.libcxx_include_dir and args.libcxx_library_dir):
            logging.error(
                "Custom libc++ requires both --libcxx-include-dir and --libcxx-library-dir"
            )
            sys.exit(-1)
        else:
            configuration.libcxx_include_dir = args.libcxx_include_dir
            configuration.libcxx_include_target_dir = args.libcxx_include_target_dir
            configuration.libcxx_library_dir = args.libcxx_library_dir

    configuration.cmake_build_type = args.cmake_build_type.lower()

    if args.channels:
        lldbtest_config.channels = args.channels

    if args.log_success:
        lldbtest_config.log_success = args.log_success

    if args.out_of_tree_debugserver:
        lldbtest_config.out_of_tree_debugserver = args.out_of_tree_debugserver

    # Set SDKROOT if we are using an Apple SDK
    if args.sysroot is not None:
        configuration.sdkroot = args.sysroot
    elif platform_system == "Darwin" and args.apple_sdk:
        configuration.sdkroot = seven.get_command_output(
            'xcrun --sdk "%s" --show-sdk-path 2> /dev/null' % (args.apple_sdk)
        )
        if not configuration.sdkroot:
            logging.error("No SDK found with the name %s; aborting...", args.apple_sdk)
            sys.exit(-1)

    if args.triple:
        configuration.triple = args.triple

    if args.arch:
        configuration.arch = args.arch
    elif args.triple:
        configuration.arch = args.triple.split("-")[0]
    else:
        configuration.arch = platform_machine

    if args.categories_list:
        configuration.categories_list = set(
            test_categories.validate(args.categories_list, False)
        )
        configuration.use_categories = True
    else:
        configuration.categories_list = []

    if args.skip_categories:
        configuration.skip_categories += test_categories.validate(
            args.skip_categories, False
        )

    if args.xfail_categories:
        configuration.xfail_categories += test_categories.validate(
            args.xfail_categories, False
        )

    if args.E:
        os.environ["CFLAGS_EXTRAS"] = args.E

    if args.dwarf_version:
        configuration.dwarf_version = args.dwarf_version
        # We cannot modify CFLAGS_EXTRAS because they're used in test cases
        # that explicitly require no debug info.
        os.environ["CFLAGS"] = "-gdwarf-{}".format(configuration.dwarf_version)

    if args.settings:
        for setting in args.settings:
            if not len(setting) == 1 or not setting[0].count("="):
                logging.error(
                    '"%s" is not a setting in the form "key=value"', setting[0]
                )
                sys.exit(-1)
            setting_list = setting[0].split("=", 1)
            configuration.settings.append((setting_list[0], setting_list[1]))

    if args.d:
        sys.stdout.write(
            "Suspending the process %d to wait for debugger to attach...\n"
            % os.getpid()
        )
        sys.stdout.flush()
        os.kill(os.getpid(), signal.SIGSTOP)

    if args.f:
        if any([x.startswith("-") for x in args.f]):
            usage(parser)
        configuration.filters.extend(args.f)

    if args.framework:
        configuration.lldb_framework_path = args.framework

    if args.executable:
        # lldb executable is passed explicitly
        lldbtest_config.lldbExec = os.path.abspath(args.executable)
        if not is_exe(lldbtest_config.lldbExec):
            lldbtest_config.lldbExec = which(args.executable)
        if not is_exe(lldbtest_config.lldbExec):
            logging.error(
                "%s is not a valid executable to test; aborting...", args.executable
            )
            sys.exit(-1)

    if args.excluded:
        for excl_file in args.excluded:
            parseExclusion(excl_file)

    if args.p:
        if args.p.startswith("-"):
            usage(parser)
        configuration.regexp = args.p

    if args.t:
        os.environ["LLDB_COMMAND_TRACE"] = "YES"

    if args.v:
        configuration.verbose = 2

    # argparse makes sure we have a number
    if args.sharp:
        configuration.count = args.sharp

    if sys.platform.startswith("win32"):
        os.environ["LLDB_DISABLE_CRASH_DIALOG"] = str(args.disable_crash_dialog)
        os.environ["LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE"] = str(True)

    if do_help:
        usage(parser)

    if args.lldb_platform_name:
        configuration.lldb_platform_name = args.lldb_platform_name
    if args.lldb_platform_url:
        configuration.lldb_platform_url = args.lldb_platform_url
    if args.lldb_platform_working_dir:
        configuration.lldb_platform_working_dir = args.lldb_platform_working_dir
    if args.lldb_platform_available_ports:
        configuration.lldb_platform_available_ports = args.lldb_platform_available_ports
    if platform_system == "Darwin" and args.apple_sdk:
        configuration.apple_sdk = args.apple_sdk
    if args.test_build_dir:
        configuration.test_build_dir = args.test_build_dir
    if args.lldb_module_cache_dir:
        configuration.lldb_module_cache_dir = args.lldb_module_cache_dir
    else:
        configuration.lldb_module_cache_dir = os.path.join(
            configuration.test_build_dir, "module-cache-lldb"
        )

    if args.clang_module_cache_dir:
        configuration.clang_module_cache_dir = args.clang_module_cache_dir
    else:
        configuration.clang_module_cache_dir = os.path.join(
            configuration.test_build_dir, "module-cache-clang"
        )

    if args.lldb_libs_dir:
        configuration.lldb_libs_dir = args.lldb_libs_dir
    if args.lldb_obj_root:
        configuration.lldb_obj_root = args.lldb_obj_root

    if args.enabled_plugins:
        configuration.enabled_plugins = args.enabled_plugins

    # Gather all the dirs passed on the command line.
    if len(args.args) > 0:
        configuration.testdirs = [
            os.path.realpath(os.path.abspath(x)) for x in args.args
        ]


def registerFaulthandler():
    try:
        import faulthandler
    except ImportError:
        # faulthandler is not available until python3
        return

    faulthandler.enable()
    # faulthandler.register is not available on Windows.
    if getattr(faulthandler, "register", None):
        faulthandler.register(signal.SIGTERM, chain=True)


def setupSysPath():
    """
    Add LLDB.framework/Resources/Python to the search paths for modules.
    As a side effect, we also discover the 'lldb' executable and export it here.
    """

    # Get the directory containing the current script.
    if "DOTEST_PROFILE" in os.environ and "DOTEST_SCRIPT_DIR" in os.environ:
        scriptPath = os.environ["DOTEST_SCRIPT_DIR"]
    else:
        scriptPath = os.path.dirname(os.path.abspath(__file__))
    if not scriptPath.endswith("test"):
        print("This script expects to reside in lldb's test directory.")
        sys.exit(-1)

    os.environ["LLDB_TEST"] = scriptPath

    # Set up the root build directory.
    if not configuration.test_build_dir:
        raise Exception("test_build_dir is not set")
    configuration.test_build_dir = os.path.abspath(configuration.test_build_dir)

    # Set up the LLDB_SRC environment variable, so that the tests can locate
    # the LLDB source code.
    os.environ["LLDB_SRC"] = lldbsuite.lldb_root

    pluginPath = os.path.join(scriptPath, "plugins")
    toolsLLDBDAP = os.path.join(scriptPath, "tools", "lldb-dap")
    toolsLLDBServerPath = os.path.join(scriptPath, "tools", "lldb-server")
    intelpt = os.path.join(scriptPath, "tools", "intelpt")

    # Insert script dir, plugin dir and lldb-server dir to the sys.path.
    sys.path.insert(0, pluginPath)
    # Adding test/tools/lldb-dap to the path makes it easy to
    # "import lldb_dap_testcase" from the DAP tests
    sys.path.insert(0, toolsLLDBDAP)
    # Adding test/tools/lldb-server to the path makes it easy
    # to "import lldbgdbserverutils" from the lldb-server tests
    sys.path.insert(0, toolsLLDBServerPath)
    # Adding test/tools/intelpt to the path makes it easy
    # to "import intelpt_testcase" from the lldb-server tests
    sys.path.insert(0, intelpt)

    # This is the root of the lldb git/svn checkout
    # When this changes over to a package instead of a standalone script, this
    # will be `lldbsuite.lldb_root`
    lldbRootDirectory = lldbsuite.lldb_root

    # Some of the tests can invoke the 'lldb' command directly.
    # We'll try to locate the appropriate executable right here.

    # The lldb executable can be set from the command line
    # if it's not set, we try to find it now
    # first, we try the environment
    if not lldbtest_config.lldbExec:
        # First, you can define an environment variable LLDB_EXEC specifying the
        # full pathname of the lldb executable.
        if "LLDB_EXEC" in os.environ:
            lldbtest_config.lldbExec = os.environ["LLDB_EXEC"]

    if not lldbtest_config.lldbExec:
        # Last, check the path
        lldbtest_config.lldbExec = which("lldb")

    if lldbtest_config.lldbExec and not is_exe(lldbtest_config.lldbExec):
        print(
            "'{}' is not a path to a valid executable".format(lldbtest_config.lldbExec)
        )
        lldbtest_config.lldbExec = None

    if not lldbtest_config.lldbExec:
        print(
            "The 'lldb' executable cannot be located.  Some of the tests may not be run as a result."
        )
        sys.exit(-1)

    os.system("%s -v" % lldbtest_config.lldbExec)

    lldbDir = os.path.dirname(lldbtest_config.lldbExec)

    lldbDAPExec = os.path.join(lldbDir, "lldb-dap")
    if is_exe(lldbDAPExec):
        os.environ["LLDBDAP_EXEC"] = lldbDAPExec

    lldbPythonDir = None  # The directory that contains 'lldb/__init__.py'

    # If our lldb supports the -P option, use it to find the python path:
    lldb_dash_p_result = subprocess.check_output(
        [lldbtest_config.lldbExec, "-P"], universal_newlines=True
    )
    if lldb_dash_p_result:
        for line in lldb_dash_p_result.splitlines():
            if os.path.isdir(line) and os.path.exists(
                os.path.join(line, "lldb", "__init__.py")
            ):
                lldbPythonDir = line
                break

    if not lldbPythonDir:
        print(
            "Unable to load lldb extension module.  Possible reasons for this include:"
        )
        print("  1) LLDB was built with LLDB_ENABLE_PYTHON=0")
        print(
            "  2) PYTHONPATH and PYTHONHOME are not set correctly.  PYTHONHOME should refer to"
        )
        print(
            "     the version of Python that LLDB built and linked against, and PYTHONPATH"
        )
        print(
            "     should contain the Lib directory for the same python distro, as well as the"
        )
        print("     location of LLDB's site-packages folder.")
        print(
            "  3) A different version of Python than that which was built against is exported in"
        )
        print("     the system's PATH environment variable, causing conflicts.")
        print(
            "  4) The executable '%s' could not be found.  Please check "
            % lldbtest_config.lldbExec
        )
        print("     that it exists and is executable.")

    if lldbPythonDir:
        lldbPythonDir = os.path.normpath(lldbPythonDir)
        # Some of the code that uses this path assumes it hasn't resolved the Versions... link.
        # If the path we've constructed looks like that, then we'll strip out
        # the Versions/A part.
        (before, frameWithVersion, after) = lldbPythonDir.rpartition(
            "LLDB.framework/Versions/A"
        )
        if frameWithVersion != "":
            lldbPythonDir = before + "LLDB.framework" + after

        lldbPythonDir = os.path.abspath(lldbPythonDir)

        if "freebsd" in sys.platform or "linux" in sys.platform:
            os.environ["LLDB_LIB_DIR"] = os.path.join(lldbPythonDir, "..", "..")

        # If tests need to find LLDB_FRAMEWORK, now they can do it
        os.environ["LLDB_FRAMEWORK"] = os.path.dirname(os.path.dirname(lldbPythonDir))

        # This is to locate the lldb.py module.  Insert it right after
        # sys.path[0].
        sys.path[1:1] = [lldbPythonDir]


def visit_file(dir, name):
    # Try to match the regexp pattern, if specified.
    if configuration.regexp:
        if not re.search(configuration.regexp, name):
            # We didn't match the regex, we're done.
            return

    if configuration.skip_tests:
        for file_regexp in configuration.skip_tests:
            if re.search(file_regexp, name):
                return

    # We found a match for our test.  Add it to the suite.

    # Update the sys.path first.
    if not sys.path.count(dir):
        sys.path.insert(0, dir)
    base = os.path.splitext(name)[0]

    # Thoroughly check the filterspec against the base module and admit
    # the (base, filterspec) combination only when it makes sense.

    def check(obj, parts):
        for part in parts:
            try:
                parent, obj = obj, getattr(obj, part)
            except AttributeError:
                # The filterspec has failed.
                return False
        return True

    module = __import__(base)

    def iter_filters():
        for filterspec in configuration.filters:
            parts = filterspec.split(".")
            if check(module, parts):
                yield filterspec
            elif parts[0] == base and len(parts) > 1 and check(module, parts[1:]):
                yield ".".join(parts[1:])
            else:
                for key, value in module.__dict__.items():
                    if check(value, parts):
                        yield key + "." + filterspec

    filtered = False
    for filterspec in iter_filters():
        filtered = True
        print("adding filter spec %s to module %s" % (filterspec, repr(module)))
        tests = unittest.defaultTestLoader.loadTestsFromName(filterspec, module)
        configuration.suite.addTests(tests)

    # Forgo this module if the (base, filterspec) combo is invalid
    if configuration.filters and not filtered:
        return

    if not filtered:
        # Add the entire file's worth of tests since we're not filtered.
        # Also the fail-over case when the filterspec branch
        # (base, filterspec) combo doesn't make sense.
        configuration.suite.addTests(unittest.defaultTestLoader.loadTestsFromName(base))


def visit(prefix, dir, names):
    """Visitor function for os.path.walk(path, visit, arg)."""

    dir_components = set(dir.split(os.sep))
    excluded_components = set([".svn", ".git"])
    if dir_components.intersection(excluded_components):
        return

    # Gather all the Python test file names that follow the Test*.py pattern.
    python_test_files = [
        name for name in names if name.endswith(".py") and name.startswith(prefix)
    ]

    # Visit all the python test files.
    for name in python_test_files:
        # Ensure we error out if we have multiple tests with the same
        # base name.
        # Future improvement: find all the places where we work with base
        # names and convert to full paths.  We have directory structure
        # to disambiguate these, so we shouldn't need this constraint.
        if name in configuration.all_tests:
            raise Exception("Found multiple tests with the name %s" % name)
        configuration.all_tests.add(name)

        # Run the relevant tests in the python file.
        visit_file(dir, name)


# ======================================== #
#                                          #
# Execution of the test driver starts here #
#                                          #
# ======================================== #


def checkDsymForUUIDIsNotOn():
    cmd = ["defaults", "read", "com.apple.DebugSymbols"]
    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    cmd_output = process.stdout.read()
    output_str = cmd_output.decode("utf-8")
    if "DBGFileMappedPaths = " in output_str:
        print("%s =>" % " ".join(cmd))
        print(output_str)
        print(
            "Disable automatic lookup and caching of dSYMs before running the test suite!"
        )
        print("Exiting...")
        sys.exit(0)


def exitTestSuite(exitCode=None):
    # lldb.py does SBDebugger.Initialize().
    # Call SBDebugger.Terminate() on exit.
    import lldb

    lldb.SBDebugger.Terminate()
    if exitCode:
        sys.exit(exitCode)


def getVersionForSDK(sdk):
    sdk = str.lower(sdk)
    full_path = seven.get_command_output("xcrun -sdk %s --show-sdk-path" % sdk)
    basename = os.path.basename(full_path)
    basename = os.path.splitext(basename)[0]
    basename = str.lower(basename)
    ver = basename.replace(sdk, "")
    return ver


def checkCompiler():
    # Add some intervention here to sanity check that the compiler requested is sane.
    # If found not to be an executable program, we abort.
    c = configuration.compiler
    if which(c):
        return

    if not sys.platform.startswith("darwin"):
        raise Exception(c + " is not a valid compiler")

    pipe = subprocess.Popen(
        ["xcrun", "-find", c], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
    )
    cmd_output = pipe.stdout.read()
    if not cmd_output or "not found" in cmd_output:
        raise Exception(c + " is not a valid compiler")

    configuration.compiler = cmd_output.split("\n")[0]
    print("'xcrun -find %s' returning %s" % (c, configuration.compiler))


def canRunLibcxxTests():
    from lldbsuite.test import lldbplatformutil

    platform = lldbplatformutil.getPlatform()

    if lldbplatformutil.target_is_android() or lldbplatformutil.platformIsDarwin():
        return True, "libc++ always present"

    if platform == "linux":
        with temp_file.OnDiskTempFile() as f:
            cmd = [configuration.compiler, "-xc++", "-stdlib=libc++", "-o", f.path, "-"]
            p = subprocess.Popen(
                cmd,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                universal_newlines=True,
            )
            _, stderr = p.communicate("#include <cassert>\nint main() {}")
            if not p.returncode:
                return True, "Compiling with -stdlib=libc++ works"
            return (
                False,
                "Compiling with -stdlib=libc++ fails with the error: %s" % stderr,
            )

    return False, "Don't know how to build with libc++ on %s" % platform


def checkLibcxxSupport():
    result, reason = canRunLibcxxTests()
    if result:
        return  # libc++ supported
    if "libc++" in configuration.categories_list:
        return  # libc++ category explicitly requested, let it run.
    if configuration.verbose:
        print("libc++ tests will not be run because: " + reason)
    configuration.skip_categories.append("libc++")


def canRunLibstdcxxTests():
    from lldbsuite.test import lldbplatformutil

    platform = lldbplatformutil.getPlatform()
    if lldbplatformutil.target_is_android():
        platform = "android"
    if platform == "linux":
        return True, "libstdcxx always present"
    return False, "Don't know how to build with libstdcxx on %s" % platform


def checkLibstdcxxSupport():
    result, reason = canRunLibstdcxxTests()
    if result:
        return  # libstdcxx supported
    if "libstdcxx" in configuration.categories_list:
        return  # libstdcxx category explicitly requested, let it run.
    if configuration.verbose:
        print("libstdcxx tests will not be run because: " + reason)
    configuration.skip_categories.append("libstdcxx")


def canRunMsvcStlTests():
    from lldbsuite.test import lldbplatformutil

    platform = lldbplatformutil.getPlatform()
    if platform != "windows":
        return False, f"Don't know how to build with MSVC's STL on {platform}"

    with temp_file.OnDiskTempFile() as f:
        cmd = [configuration.compiler, "-xc++", "-o", f.path, "-E", "-"]
        p = subprocess.Popen(
            cmd,
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            universal_newlines=True,
        )
        _, stderr = p.communicate(
            """
            #include <yvals_core.h>
            #ifndef _MSVC_STL_VERSION
            #error _MSVC_STL_VERSION not defined
            #endif
            """
        )
        if not p.returncode:
            return True, "Compiling with MSVC STL"
        return (False, f"Not compiling with MSVC STL: {stderr}")


def checkMsvcStlSupport():
    result, reason = canRunMsvcStlTests()
    if result:
        return  # msvcstl supported
    if "msvcstl" in configuration.categories_list:
        return  # msvcstl category explicitly requested, let it run.
    if configuration.verbose:
        print(f"msvcstl tests will not be run because: {reason}")
    configuration.skip_categories.append("msvcstl")


def canRunWatchpointTests():
    from lldbsuite.test import lldbplatformutil

    platform = lldbplatformutil.getPlatform()
    if platform == "netbsd":
        if os.geteuid() == 0:
            return True, "root can always write dbregs"
        try:
            output = (
                subprocess.check_output(
                    ["/sbin/sysctl", "-n", "security.models.extensions.user_set_dbregs"]
                )
                .decode()
                .strip()
            )
            if output == "1":
                return True, "security.models.extensions.user_set_dbregs enabled"
        except subprocess.CalledProcessError:
            pass
        return False, "security.models.extensions.user_set_dbregs disabled"
    elif platform == "freebsd" and configuration.arch == "aarch64":
        import lldb

        if lldb.SBPlatform.GetHostPlatform().GetOSMajorVersion() < 13:
            return False, "Watchpoint support on arm64 requires FreeBSD 13.0"
    return True, "watchpoint support available"


def checkWatchpointSupport():
    result, reason = canRunWatchpointTests()
    if result:
        return  # watchpoints supported
    if "watchpoint" in configuration.categories_list:
        return  # watchpoint category explicitly requested, let it run.
    if configuration.verbose:
        print("watchpoint tests will not be run because: " + reason)
    configuration.skip_categories.append("watchpoint")


def checkObjcSupport():
    from lldbsuite.test import lldbplatformutil

    if not lldbplatformutil.platformIsDarwin():
        if configuration.verbose:
            print("objc tests will be skipped because of unsupported platform")
        configuration.skip_categories.append("objc")


def checkDebugInfoSupport():
    from lldbsuite.test import lldbplatformutil

    platform = lldbplatformutil.getPlatform()
    compiler = configuration.compiler
    for cat in test_categories.debug_info_categories:
        if cat in configuration.categories_list:
            continue  # Category explicitly requested, let it run.
        if test_categories.is_supported_on_platform(cat, platform, compiler):
            continue
        configuration.skip_categories.append(cat)


def checkDebugServerSupport():
    from lldbsuite.test import lldbplatformutil
    import lldb

    skip_msg = "Skipping %s tests, as they are not compatible with remote testing on this platform"
    if lldbplatformutil.platformIsDarwin():
        configuration.skip_categories.append("llgs")
        if lldb.remote_platform:
            # <rdar://problem/34539270>
            configuration.skip_categories.append("debugserver")
            if configuration.verbose:
                print(skip_msg % "debugserver")
    else:
        configuration.skip_categories.append("debugserver")
        if lldb.remote_platform and lldbplatformutil.getPlatform() == "windows":
            configuration.skip_categories.append("llgs")
            if configuration.verbose:
                print(skip_msg % "lldb-server")


def checkForkVForkSupport():
    from lldbsuite.test import lldbplatformutil

    platform = lldbplatformutil.getPlatform()
    if platform not in ["freebsd", "linux", "netbsd"]:
        configuration.skip_categories.append("fork")


def checkPexpectSupport():
    from lldbsuite.test import lldbplatformutil

    platform = lldbplatformutil.getPlatform()

    # llvm.org/pr22274: need a pexpect replacement for windows
    if platform in ["windows"]:
        if configuration.verbose:
            print("pexpect tests will be skipped because of unsupported platform")
        configuration.skip_categories.append("pexpect")


def checkDAPSupport():
    import lldb

    if "LLDBDAP_EXEC" not in os.environ:
        msg = (
            "The 'lldb-dap' executable cannot be located and its tests will not be run."
        )
    elif lldb.remote_platform:
        msg = "lldb-dap tests are not compatible with remote platforms and will not be run."
    else:
        msg = None

    if msg:
        if configuration.verbose:
            print(msg)
        configuration.skip_categories.append("lldb-dap")


def run_suite():
    # On MacOS X, check to make sure that domain for com.apple.DebugSymbols defaults
    # does not exist before proceeding to running the test suite.
    if sys.platform.startswith("darwin"):
        checkDsymForUUIDIsNotOn()

    # Start the actions by first parsing the options while setting up the test
    # directories, followed by setting up the search paths for lldb utilities;
    # then, we walk the directory trees and collect the tests into our test suite.
    #
    parseOptionsAndInitTestdirs()

    # Print a stack trace if the test hangs or is passed SIGTERM.
    registerFaulthandler()

    setupSysPath()

    import lldb

    lldb.SBDebugger.Initialize()
    lldb.SBDebugger.PrintStackTraceOnError()

    # Use host platform by default.
    lldb.remote_platform = None
    lldb.selected_platform = lldb.SBPlatform.GetHostPlatform()

    # Now we can also import lldbutil
    from lldbsuite.test import lldbutil

    if configuration.lldb_platform_name:
        print("Setting up remote platform '%s'" % (configuration.lldb_platform_name))
        lldb.remote_platform = lldb.SBPlatform(configuration.lldb_platform_name)
        lldb.selected_platform = lldb.remote_platform
        if not lldb.remote_platform.IsValid():
            print(
                "error: unable to create the LLDB platform named '%s'."
                % (configuration.lldb_platform_name)
            )
            exitTestSuite(1)
        if configuration.lldb_platform_url:
            # We must connect to a remote platform if a LLDB platform URL was
            # specified
            print(
                "Connecting to remote platform '%s' at '%s'..."
                % (configuration.lldb_platform_name, configuration.lldb_platform_url)
            )
            platform_connect_options = lldb.SBPlatformConnectOptions(
                configuration.lldb_platform_url
            )
            err = lldb.remote_platform.ConnectRemote(platform_connect_options)
            if err.Success():
                print("Connected.")
            else:
                print(
                    "error: failed to connect to remote platform using URL '%s': %s"
                    % (configuration.lldb_platform_url, err)
                )
                exitTestSuite(1)
        else:
            configuration.lldb_platform_url = None

    if configuration.lldb_platform_working_dir:
        print(
            "Setting remote platform working directory to '%s'..."
            % (configuration.lldb_platform_working_dir)
        )
        error = lldb.remote_platform.MakeDirectory(
            configuration.lldb_platform_working_dir, 448
        )  # 448 = 0o700
        if error.Fail():
            raise Exception(
                "making remote directory '%s': %s"
                % (configuration.lldb_platform_working_dir, error)
            )

        if not lldb.remote_platform.SetWorkingDirectory(
            configuration.lldb_platform_working_dir
        ):
            raise Exception(
                "failed to set working directory '%s'"
                % configuration.lldb_platform_working_dir
            )
        lldb.selected_platform = lldb.remote_platform
    else:
        lldb.remote_platform = None
        configuration.lldb_platform_working_dir = None
        configuration.lldb_platform_url = None

    # Set up the working directory.
    # Note that it's not dotest's job to clean this directory.
    lldbutil.mkdir_p(configuration.test_build_dir)

    checkLibcxxSupport()
    checkLibstdcxxSupport()
    checkMsvcStlSupport()
    checkWatchpointSupport()
    checkDebugInfoSupport()
    checkDebugServerSupport()
    checkObjcSupport()
    checkForkVForkSupport()
    checkPexpectSupport()
    checkDAPSupport()

    skipped_categories_list = ", ".join(configuration.skip_categories)
    print(
        "Skipping the following test categories: {}".format(
            configuration.skip_categories
        )
    )

    for testdir in configuration.testdirs:
        for dirpath, dirnames, filenames in os.walk(testdir):
            visit("Test", dirpath, filenames)

    #
    # Now that we have loaded all the test cases, run the whole test suite.
    #

    # Install the control-c handler.
    unittest.signals.installHandler()

    #
    # Invoke the default TextTestRunner to run the test suite
    #
    checkCompiler()

    if configuration.verbose:
        print("compiler=%s" % configuration.compiler)

    # Iterating over all possible architecture and compiler combinations.
    configString = "arch=%s compiler=%s" % (configuration.arch, configuration.compiler)

    # Output the configuration.
    if configuration.verbose:
        sys.stderr.write("\nConfiguration: " + configString + "\n")

    # First, write out the number of collected test cases.
    if configuration.verbose:
        sys.stderr.write(configuration.separator + "\n")
        sys.stderr.write(
            "Collected %d test%s\n\n"
            % (
                configuration.suite.countTestCases(),
                configuration.suite.countTestCases() != 1 and "s" or "",
            )
        )

    if configuration.suite.countTestCases() == 0:
        logging.error("did not discover any matching tests")
        exitTestSuite(1)

    # Invoke the test runner.
    if configuration.count == 1:
        result = unittest.TextTestRunner(
            stream=sys.stderr,
            verbosity=configuration.verbose,
            resultclass=test_result.LLDBTestResult,
        ).run(configuration.suite)
    else:
        # We are invoking the same test suite more than once.  In this case,
        # mark __ignore_singleton__ flag as True so the signleton pattern is
        # not enforced.
        test_result.LLDBTestResult.__ignore_singleton__ = True
        for i in range(configuration.count):
            result = unittest.TextTestRunner(
                stream=sys.stderr,
                verbosity=configuration.verbose,
                resultclass=test_result.LLDBTestResult,
            ).run(configuration.suite)

    configuration.failed = not result.wasSuccessful()

    if configuration.sdir_has_content and configuration.verbose:
        sys.stderr.write(
            "Session logs for test failures/errors/unexpected successes"
            " can be found in the test build directory\n"
        )

    if configuration.use_categories and len(configuration.failures_per_category) > 0:
        sys.stderr.write("Failures per category:\n")
        for category in configuration.failures_per_category:
            sys.stderr.write(
                "%s - %d\n" % (category, configuration.failures_per_category[category])
            )

    # Exiting.
    exitTestSuite(configuration.failed)


if __name__ == "__main__":
    print(
        __file__
        + " is for use as a module only.  It should not be run as a standalone script."
    )
    sys.exit(-1)
