# swift/test/lit.cfg - Configuration for the 'lit' test runner -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
#
# -----------------------------------------------------------------------------
#
# This is a configuration file for the 'lit' test runner.
#
# Refer to docs/Testing.rst for documentation.
#
# Update docs/Testing.rst when changing this file.
#
# -----------------------------------------------------------------------------

from __future__ import absolute_import
import os
import platform
import re
import shlex
import shutil
import subprocess
import sys
import socket
import glob
import pipes
from distutils.sysconfig import get_python_lib

import lit
import lit.formats
import lit.util

import site
site.addsitedir(os.path.dirname(__file__))
import swift_test

def make_path(*args):
    return os.path.normpath(os.path.join(*args))

#
# Helper functions.
#

def darwin_get_sdk_version(sdk_path):
    system_version_plist_path = make_path(sdk_path, "System", "Library",
                                          "CoreServices", "SystemVersion.plist")
    name = subprocess.check_output(
        ["defaults", "read", system_version_plist_path,
         "ProductName"]).rstrip()
    vers = subprocess.check_output(
        ["defaults", "read", system_version_plist_path,
         "ProductVersion"]).rstrip()
    build = subprocess.check_output(
        ["defaults", "read", system_version_plist_path,
         "ProductBuildVersion"]).rstrip()
    return (name, vers, build)


def darwin_sdk_build_version_split(version):
    m = re.search("([0-9]+)([A-Z])([0-9]+)", version)
    return (int(m.group(1)), m.group(2), int(m.group(3)))


def darwin_sdk_build_version_cmp(lhs, rhs):
    # The `_cmp` function is provided to port the Python 2 global `cmp`
    # function forward to Python 3. The function implementation is taken
    # directly from the recommendation that announced its removal.
    # See: https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
    def _cmp(a, b):
      return (a > b) - (a < b)
    return _cmp(
        darwin_sdk_build_version_split(lhs),
        darwin_sdk_build_version_split(rhs))


# Run sw_vers on the target to be tested and return the results.
def darwin_get_sw_vers(commandPrefix=[]):
    name = lit.util.executeCommand(
        commandPrefix + ['/usr/bin/sw_vers', '-productName'])[0].rstrip()
    vers = lit.util.executeCommand(
        commandPrefix + ['/usr/bin/sw_vers', '-productVersion'])[0].rstrip()
    build = lit.util.executeCommand(
        commandPrefix + ['/usr/bin/sw_vers', '-buildVersion'])[0].rstrip()
    return (name, vers, build)

def darwin_get_ios_sim_vers():
    sim_output = subprocess.check_output(['xcrun', 'simctl', 'list', 'runtimes'])
    ios_version_str = re.findall(r'iOS \d+\.*\d*',sim_output)
    return [float(v.strip('iOS')) for v in ios_version_str]

# Returns the "prefix" command that should be prepended to the command line to
# run an executable compiled for iOS or AppleTV simulator.
def get_simulator_command(run_os, run_cpu, sdk_path):
    (name, vers, build) = darwin_get_sdk_version(sdk_path)
    if run_os == 'ios':
        # There are two binaries for the iOS simulator: 'sim' and 'simctl'.
        # 'sim' is only supported for iOS <= 8.1 and early versions of 8.2.
        # 'simctl' is supported for iOS >= 8.2.
        # 'simctl' used to have a bug where it failed to propagate the exit
        # code of the child process.  This was fixed only in the middle of 8.2
        # development cycle.
        if ((darwin_sdk_build_version_cmp(build, "12E999") <= 0) or
            (darwin_sdk_build_version_cmp("12F1", build) <= 0 and
             darwin_sdk_build_version_cmp(build, "12F12") <= 0) or
            (darwin_sdk_build_version_cmp("12H1", build) <= 0 and
             darwin_sdk_build_version_cmp(build, "12H11") <= 0)):
            return "sim"
        elif run_cpu == "i386":
            if min(darwin_get_ios_sim_vers()) > 10.3:
                print("ERROR: Install iOS 10.3 or older simulator for 32bit testing")
                print("INFO: Xcode -> Preferences -> Components -> Simulators")
                sys.exit(1)
            else:
                return "simctl spawn 'iPhone 5'"
        else:
            return "simctl spawn 'iPhone 6'"
    elif run_os == 'tvos':
        return "simctl spawn 'Apple TV 4K'"
    elif run_os == 'watchos':
        return "simctl spawn 'Apple Watch Series 3 - 38mm'"
    else:
        lit_config.fatal("Unknown simulator OS %r" % run_os)

assert darwin_sdk_build_version_cmp("11A1", "12A1") < 0
assert darwin_sdk_build_version_cmp("12A1", "11A1") > 0

assert darwin_sdk_build_version_cmp("11A1", "11B1") < 0
assert darwin_sdk_build_version_cmp("11B1", "11A1") > 0

assert darwin_sdk_build_version_cmp("11A22", "11A100") < 0
assert darwin_sdk_build_version_cmp("11A100", "11A22") > 0

###

# Check that the object root is known.
if config.test_exec_root is None:
    # Otherwise, we haven't loaded the site specific configuration (the user is
    # probably trying to run on a test file directly, and either the site
    # configuration hasn't been created by the build system, or we are in an
    # out-of-tree build situation).

    # Check for 'swift_site_config' user parameter, and use that if available.
    site_cfg = lit_config.params.get('swift_site_config', None)
    if site_cfg and os.path.exists(site_cfg):
        lit_config.load_config(config, site_cfg)
        raise SystemExit

    lit_config.fatal("lit must be pointed at a build folder")

###

# name: The name of this test suite.
config.name = 'Swift(%s)' % config.variant_suffix[1:]

# Respect the TOOLCHAINS environment variable when deciding the xcrun
# toolchain for Darwin platforms.
if platform.system() == 'Darwin':
    config.environment['TOOLCHAINS'] = \
        os.environ.get('TOOLCHAINS', config.darwin_xcrun_toolchain)

# NOTE: this mirrors the kIsWindows from lit.lit.TestRunner in LLVM
kIsWindows = platform.system() == 'Windows'

# testFormat: The test format to use to interpret tests.

# Choose between lit's internal shell pipeline runner and a real shell.  If
# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
use_lit_shell = os.environ.get('LIT_USE_INTERNAL_SHELL', not kIsWindows)
config.test_format = swift_test.SwiftTest(coverage_mode=config.coverage_mode,
                                          execute_external=use_lit_shell)

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.swift', '.ll', '.sil', '.gyb', '.m', '.swiftinterface',
                   '.test-sh']

# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ['Inputs']

if lit_config.params.get('disable_unittests', None) is not None:
    config.excludes += ['Unit']

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)

# test_exec_root: The root path where tests should be run.
swift_obj_root = getattr(config, 'swift_obj_root', None)

# Set llvm_{src,obj}_root for use by others.
config.llvm_src_root = getattr(config, 'llvm_src_root', None)
config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)

def append_to_env_path(directory):
    config.environment['PATH'] = \
        os.path.pathsep.join((directory, config.environment['PATH']))

# Tweak the PATH to include the tools dir and the scripts dir.
if swift_obj_root is not None:
    llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
    if not llvm_tools_dir:
        lit_config.fatal('No LLVM tools dir set!')
    append_to_env_path(llvm_tools_dir)

    build_mode = lit_config.params.get('build_mode', '')
    append_to_env_path(make_path(swift_obj_root, build_mode, 'bin'))

native_llvm_tools_path = lit_config.params.get('native_llvm_tools_path')
if native_llvm_tools_path is not None:
    append_to_env_path(native_llvm_tools_path)

native_clang_tools_path = lit_config.params.get('native_clang_tools_path')
if native_clang_tools_path is not None:
    append_to_env_path(native_clang_tools_path)

native_swift_tools_path = lit_config.params.get('native_swift_tools_path')
if native_swift_tools_path is not None:
    append_to_env_path(native_swift_tools_path)

###

# Discover the Swift binaries to use.
def inferSwiftBinary(binaryName):
    # Determine which executable to use.
    envVarName = binaryName.upper().replace("-", "_")
    execPath = os.getenv(envVarName)

    # If the user set the variable in the environment, definitely use that and
    # don't try to validate.
    if execPath:
        return execPath

    # Otherwise look in the path.
    PATH = config.environment['PATH']
    execPath = lit.util.which(binaryName, PATH)

    if execPath:
        if not lit_config.quiet:
            lit_config.note('using %s: %s' % (binaryName, execPath))
    else:
        msg = "couldn't find '%s' program, try setting %s in your environment"
        lit_config.warning(msg % (binaryName, envVarName))

        # Just substitute the plain executable name, so the run line remains
        # reasonable.
        execPath = binaryName

    return execPath

if 'gmalloc' in lit_config.params:
    config.environment['DYLD_INSERT_LIBRARIES'] = '/usr/lib/libgmalloc.dylib'
    config.environment['MALLOC_LOG_FILE'] = '/dev/null'
    config.available_features.add('gmalloc')

config.swift = inferSwiftBinary('swift')
config.swiftc = inferSwiftBinary('swiftc')
config.sil_opt = inferSwiftBinary('sil-opt')
config.sil_func_extractor = inferSwiftBinary('sil-func-extractor')
config.sil_llvm_gen = inferSwiftBinary('sil-llvm-gen')
config.sil_nm = inferSwiftBinary('sil-nm')
config.sil_passpipeline_dumper = inferSwiftBinary('sil-passpipeline-dumper')
config.lldb_moduleimport_test = inferSwiftBinary('lldb-moduleimport-test')
config.swift_ide_test = inferSwiftBinary('swift-ide-test')
config.swift_syntax_test = inferSwiftBinary('swift-syntax-test')
config.swift_reflection_dump = inferSwiftBinary('swift-reflection-dump')
config.swift_remoteast_test = inferSwiftBinary('swift-remoteast-test')
config.swift_format = inferSwiftBinary('swift-format')
config.clang = inferSwiftBinary('clang')
config.llvm_link = inferSwiftBinary('llvm-link')
config.swift_llvm_opt = inferSwiftBinary('swift-llvm-opt')
config.llvm_profdata = inferSwiftBinary('llvm-profdata')
config.llvm_cov = inferSwiftBinary('llvm-cov')
config.llvm_strings = inferSwiftBinary('llvm-strings')
config.filecheck = inferSwiftBinary('FileCheck')
config.llvm_dwarfdump = inferSwiftBinary('llvm-dwarfdump')
config.llvm_dis = inferSwiftBinary('llvm-dis')
config.sourcekitd_test = inferSwiftBinary('sourcekitd-test')
config.complete_test = inferSwiftBinary('complete-test')
config.swift_api_digester = inferSwiftBinary('swift-api-digester')
config.swift_refactor = inferSwiftBinary('swift-refactor')
config.swift_demangle_yamldump = inferSwiftBinary('swift-demangle-yamldump')
config.benchmark_o = inferSwiftBinary('Benchmark_O')
config.benchmark_driver = inferSwiftBinary('Benchmark_Driver')

config.swift_utils = make_path(config.swift_src_root, 'utils')
config.line_directive = make_path(config.swift_utils, 'line-directive')
config.gyb = make_path(config.swift_utils, 'gyb')
config.rth = make_path(config.swift_utils, 'rth') # Resilience test helper
config.scale_test = make_path(config.swift_utils, 'scale-test')
config.PathSanitizingFileCheck = make_path(config.swift_utils, 'PathSanitizingFileCheck')
config.swift_lib_dir = make_path(config.swift, '..', '..', 'lib')
config.round_trip_syntax_test = make_path(config.swift_utils, 'round-trip-syntax-test')

config.link = lit.util.which('link', config.environment.get('PATH', '')) or      \
              lit.util.which('lld-link', config.environment.get('PATH', ''))

# Find the resource directory.  Assume it's near the swift compiler if not set.
test_resource_dir = lit_config.params.get('test_resource_dir')
if test_resource_dir:
    resource_dir_opt = ("-resource-dir %s" % test_resource_dir)
else:
    test_resource_dir = make_path(config.swift_lib_dir, 'swift')
    resource_dir_opt = ""
stdlib_resource_dir_opt = resource_dir_opt
sourcekitd_framework_dir = config.swift_lib_dir
lit_config.note('Using resource dir: ' + test_resource_dir)

# Parse the variant triple.
(run_cpu, run_vendor, run_os, run_vers) = re.match('([^-]+)-([^-]+)-([^0-9]+)(.*)', config.variant_triple).groups()
run_ptrsize = '64' if ('64' in run_cpu or run_cpu == "s390x") else '32'

sdk_overlay_link_path = ""
sdk_overlay_linker_opt = ""
sdk_overlay_dir_opt = ""
test_sdk_overlay_dir = lit_config.params.get('test_sdk_overlay_dir', None)
if test_sdk_overlay_dir is not None:
    config.available_features.add('sdk_overlay')

    sdk_overlay_dir_opt = ("-I %s" % make_path(test_sdk_overlay_dir, run_cpu))
    sdk_overlay_link_path_dir = make_path(test_sdk_overlay_dir, run_cpu)
    sdk_overlay_link_path = ("-L %s" % sdk_overlay_link_path_dir)
    sdk_overlay_linker_opt = (
        "-L %s -Xlinker -rpath -Xlinker %s" %
        (sdk_overlay_link_path_dir, sdk_overlay_link_path_dir))
    lit_config.note('Using SDK overlay dir: ' + test_sdk_overlay_dir)
    resource_dir_opt += (" %s" % sdk_overlay_dir_opt)

# Default to Swift 4 for now.
# Note that this accepts both `--param swift-version` (like the compiler flag)
# and `--param swift_version` (like a lit configuration parameter).
swift_version = lit_config.params.get('swift-version',
    lit_config.params.get('swift_version', '4'))
lit_config.note('Compiling with -swift-version ' + swift_version)
config.swift_test_options = '-swift-version ' + swift_version

if run_os == 'windows-msvc':
  if run_cpu == 'x86_64':
    config.swift_test_options += ' -Xcc -D_AMD64_'

test_options = os.environ.get('SWIFT_TEST_OPTIONS')
if test_options:
    config.swift_test_options += ' '
    config.swift_test_options += test_options

config.swift_frontend_test_options = os.environ.get('SWIFT_FRONTEND_TEST_OPTIONS', '')
config.swift_driver_test_options = os.environ.get('SWIFT_DRIVER_TEST_OPTIONS', '')
config.sil_test_options = os.environ.get('SIL_TEST_OPTIONS', '')

clang_module_cache_path = make_path(config.swift_test_results_dir, "clang-module-cache")
shutil.rmtree(clang_module_cache_path, ignore_errors=True)
mcp_opt = "-module-cache-path %r" % clang_module_cache_path
clang_mcp_opt = "-fmodules-cache-path=%r" % clang_module_cache_path
lit_config.note("Using Clang module cache: " + clang_module_cache_path)
lit_config.note("Using test results dir: " + config.swift_test_results_dir)

completion_cache_path = make_path(config.swift_test_results_dir, "completion-cache")
shutil.rmtree(completion_cache_path, ignore_errors=True)
ccp_opt = "-completion-cache-path %r" % completion_cache_path
lit_config.note("Using code completion cache: " + completion_cache_path)

config.substitutions.append( ('%validate-incrparse', '%{python} %utils/incrparse/validate_parse.py --temp-dir %t --swift-syntax-test %swift-syntax-test') )
config.substitutions.append( ('%incr-transfer-tree', '%{python} %utils/incrparse/incr_transfer_tree.py --temp-dir %t --swift-syntax-test %swift-syntax-test') )
config.substitutions.append( ('%swift_obj_root', config.swift_obj_root) )
config.substitutions.append( ('%swift_src_root', config.swift_src_root) )
config.substitutions.append( ('%{python}', sys.executable) )
config.substitutions.append( ('%mcp_opt', mcp_opt) )
config.substitutions.append( ('%swift_driver_plain', "%r" % config.swift) )
config.substitutions.append( ('%swiftc_driver_plain', "%r" % config.swiftc) )
config.substitutions.append( ('%swift_driver', "env SDKROOT= %r %s %s %s" % (config.swift, mcp_opt, config.swift_test_options, config.swift_driver_test_options)) )
config.substitutions.append( ('%swiftc_driver', "env SDKROOT= %r %s %s %s" % (config.swiftc, mcp_opt, config.swift_test_options, config.swift_driver_test_options)) )
config.substitutions.append( ('%sil-opt', "%r %s %s" % (config.sil_opt, mcp_opt, config.sil_test_options)) )
config.substitutions.append( ('%sil-func-extractor', "%r %s" % (config.sil_func_extractor, mcp_opt)) )
config.substitutions.append( ('%sil-llvm-gen', "%r %s" % (config.sil_llvm_gen, mcp_opt)) )
config.substitutions.append( ('%sil-nm', "%r %s" % (config.sil_nm, mcp_opt)) )
config.substitutions.append( ('%sil-passpipeline-dumper', "%r" % (config.sil_passpipeline_dumper)) )
config.substitutions.append( ('%lldb-moduleimport-test', "%r %s" % (config.lldb_moduleimport_test, mcp_opt)) )
config.substitutions.append( ('%swift-ide-test_plain', config.swift_ide_test) )
config.substitutions.append( ('%swift-ide-test', "%r %s %s -swift-version %s" % (config.swift_ide_test, mcp_opt, ccp_opt, swift_version)) )
config.substitutions.append( ('%swift-syntax-test', config.swift_syntax_test) )
config.substitutions.append( ('%swift-format', config.swift_format) )
config.substitutions.append( ('%llvm-link', config.llvm_link) )
config.substitutions.append( ('%swift-llvm-opt', config.swift_llvm_opt) )
config.substitutions.append( ('%llvm-dwarfdump', config.llvm_dwarfdump) )
config.substitutions.append( ('%llvm-dis', config.llvm_dis) )
config.substitutions.append( ('%swift-demangle-yamldump', config.swift_demangle_yamldump) )
config.substitutions.append( ('%Benchmark_O', config.benchmark_o) )
config.substitutions.append( ('%Benchmark_Driver', config.benchmark_driver) )
config.substitutions.append( ('%llvm-strings', config.llvm_strings) )

# This must come after all substitutions containing "%swift".
config.substitutions.append(
    ('%swift',
     "%r -frontend %s -disable-objc-attr-requires-foundation-module %s %s"
       % (config.swift, mcp_opt, config.swift_test_options, config.swift_frontend_test_options)) )

config.clang_include_dir = make_path(config.swift, '..', '..', 'include')
config.substitutions.append( ('%clang-include-dir', config.clang_include_dir) )

# Use this to build the basic set of Objective-C overlays.
config.substitutions.append(('%build-clang-importer-objc-overlays',
                             '%target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -enable-objc-interop -emit-module -o %t %clang-importer-sdk-path/swift-modules/ObjectiveC.swift -disable-objc-attr-requires-foundation-module && '
                             '%target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -enable-objc-interop -emit-module -o %t %clang-importer-sdk-path/swift-modules/CoreGraphics.swift && '
                             '%target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -enable-objc-interop -emit-module -o %t %clang-importer-sdk-path/swift-modules/Foundation.swift'))

# FIXME: BEGIN -enable-source-import hackaround
config.substitutions.append(('%clang-importer-sdk-path',
                             '%r' % (make_path(config.test_source_root, 'Inputs', 'clang-importer-sdk'))))

config.substitutions.append(('%clang-importer-sdk-nosource',
                             '-sdk %r' % (make_path(config.test_source_root, 'Inputs', 'clang-importer-sdk'))))
# FIXME: END -enable-source-import hackaround

config.substitutions.append(('%clang-importer-sdk',
                             '-enable-source-import -sdk %r -I %r ' % (make_path(config.test_source_root, 'Inputs', 'clang-importer-sdk'),
                                                                       make_path(config.test_source_root, 'Inputs', 'clang-importer-sdk', 'swift-modules'))))

config.substitutions.append( ('%clang_apinotes',
                              "%r -cc1apinotes" %
                                (config.clang)) )

# This must come after all substitutions containing "%clang".
# Note: %clang is the locally-built clang.
# To get Xcode's clang, use %target-clang.
config.substitutions.append( ('%clang',
                              "%r %s" %
                                (config.clang, clang_mcp_opt)) )

###

def disallow(execName):
  warning = '''
    echo '*** Do not use \'{0}\' in tests; use \'%''{0}\'. ***' &&
    exit 1 && echo
  '''
  config.substitutions.append((' {0} '.format(execName),
                               warning.format(execName)))

disallow('swift')
disallow('swiftc')
disallow('swift_driver')
disallow('swiftc_driver')
disallow('sil-opt')
disallow('sil-func-extractor')
disallow('sil-llvm-gen')
disallow('sil-nm')
disallow('sil-passpipeline-dumper')
disallow('lldb-moduleimport-test')
disallow('swift-ide-test')
disallow('clang')
disallow('FileCheck')
disallow('llvm-dwarfdump')
disallow('llvm-dis')

config.substitutions.insert(0,
    ('%p',
     '$(echo "*** Use %""S instead of %""p in the Swift test suite ***" >&2)'))

###

# Set available features we allow tests to conditionalize on.
if platform.system() != 'Windows':
    config.available_features.add('crash-recovery')

# Add each available build target CPU as a feature.
for target in config.llvm_code_generators:
  config.available_features.add("CODEGENERATOR=" + target)

# Add the run target CPU, OS, and pointer size as features.
config.available_features.add("CPU=" + run_cpu)
config.available_features.add("OS=" + run_os)
config.available_features.add("PTRSIZE=" + run_ptrsize)

config.available_features.add("SWIFT_VERSION=" + swift_version)

if "optimized_stdlib" in config.available_features:
  config.available_features.add("optimized_stdlib_" + run_cpu)

swift_test_mode = lit_config.params.get('swift_test_mode', 'optimize_none')
swift_execution_tests_extra_flags = ''
if swift_test_mode == 'optimize_none':
    config.available_features.add("nonexecutable_test")
    config.available_features.add("executable_test")
    config.available_features.add("swift_test_mode_optimize_none")
    # Add the cpu as a feature so we can selectively disable tests in an
    # optimize mode for a cpu.
    config.available_features.add("swift_test_mode_optimize_none_" + run_cpu)
    swift_execution_tests_extra_flags = ''
elif swift_test_mode == 'optimize':
    config.available_features.add("executable_test")
    config.limit_to_features.add("executable_test")
    config.available_features.add("swift_test_mode_optimize")
    # Add the cpu as a feature so we can selectively disable tests in an
    # optimize mode for a cpu.
    config.available_features.add("swift_test_mode_optimize_" + run_cpu)
    swift_execution_tests_extra_flags = '-O'
elif swift_test_mode == 'optimize_size':
    config.available_features.add("executable_test")
    config.limit_to_features.add("executable_test")
    config.available_features.add("swift_test_mode_optimize_size")
    # Add the cpu as a feature so we can selectively disable tests in an
    # optimize mode for a cpu.
    config.available_features.add("swift_test_mode_optimize_" + run_cpu)
    swift_execution_tests_extra_flags = '-Osize'
elif swift_test_mode == 'optimize_unchecked':
    config.available_features.add("executable_test")
    config.limit_to_features.add("executable_test")
    config.available_features.add("swift_test_mode_optimize_unchecked")
    # Add the cpu as a feature so we can selectively disable tests in an
    # optimize mode for a cpu.
    config.available_features.add("swift_test_mode_optimize_unchecked_" + run_cpu)
    swift_execution_tests_extra_flags = '-Ounchecked'
elif swift_test_mode == 'only_executable':
    config.available_features.add("executable_test")
    config.limit_to_features.add("executable_test")
elif swift_test_mode == 'only_non_executable':
    config.available_features.add("nonexecutable_test")
else:
    lit_config.fatal("Unknown test mode %r" % swift_test_mode)

swift_test_subset = lit_config.params.get('swift_test_subset', 'validation')
if swift_test_subset in ['primary', 'validation', 'only_validation']:
    # No extra flags needed.
    pass
elif swift_test_subset == 'all':
    config.available_features.add("long_test")
    config.available_features.add("stress_test")
elif swift_test_subset == 'only_long':
    config.available_features.add("long_test")
    config.limit_to_features.add("long_test")
    config.limit_to_features.discard("executable_test")
elif swift_test_subset == 'only_stress':
    config.available_features.add("stress_test")
    config.limit_to_features.add("stress_test")
    config.limit_to_features.discard("executable_test")
else:
    lit_config.fatal("Unknown test mode %r" % swift_test_subset)

if 'swift_evolve' in lit_config.params:
    config.available_features.add("swift_evolve")

# Enable benchmark testing when the binary is found (has fully qualified path).
if config.benchmark_o != 'Benchmark_O':
    config.available_features.add('benchmark')

# Add substitutions for the run target triple, CPU, OS, and pointer size.
config.substitutions.append(('%target-triple', config.variant_triple))

# Sanitizers are not supported on iOS7, yet all tests are configured to start
# testing with the earliest supported platform, which happens to be iOS7 for
# Swift.
# Setting target manually makes tests less versatile (a separate test is
# then required for each OS), thus instead we define a new environment
# variable which enforces the usage of iOS8+ when iOS is used.
config.substitutions.append(('%sanitizers-target-triple',
    config.variant_triple.replace("ios7", "ios8")))

config.substitutions.append(('%target-cpu', run_cpu))
config.substitutions.append(('%target-os', run_os))
config.substitutions.append(('%target-ptrsize', run_ptrsize))

# Enable Darwin SDK-dependent tests if we have an SDK.
# On Linux, assume that SDK path does not point to the Darwin SDK.
if config.variant_sdk != "":
  config.substitutions.append(('%sdk', '"%s"' % config.variant_sdk))

# Enable interpreter-based tests on platforms where the interpreter is known to
# work.
if platform.system() == 'Darwin' and (run_os == 'macosx' or run_os == 'darwin'):
    # Disable REPL tests if SDK overlay is not in the resource dir.
    # <rdar://problem/16678410> Adding more libraries with -lfoo to REPL is broken
    if swift_test_mode != 'only_non_executable':
      config.available_features.add('swift_repl')
      config.available_features.add('swift_interpreter')
elif platform.system() == 'Linux':
    if swift_test_mode != 'only_non_executable':
      config.available_features.add('swift_interpreter')

# swift-remoteast-test requires the ability to compile and run code
# for the system we compiled the swift-remoteast-test executable on.
# This is potentially a stronger constraint than just "can we interpret",
# but use that as an approximation for now.
if 'swift_interpreter' in config.available_features:
    config.available_features.add('swift-remoteast-test')

config.target_runtime = "unknown"

swift_reflection_test_name = 'swift-reflection-test' + config.variant_suffix

def use_interpreter_for_simple_runs():
    def make_simple_target_run(gyb=False, stdlib=False, parameterized=False):
        result = ''
        if gyb:
            result += ('%empty-directory(%t) && '
                       '%gyb %s -o %t/main.swift && '
                       '%line-directive %t/main.swift -- ')
        # FIXME: SWIFT_INTERPRETER needs to be a set of arguments, not just a
        # path.
        result += (
            'env SWIFT_INTERPRETER=%r %s %r %s -module-name main %s %s %s '
            % (config.swift, xcrun_prefix, config.swift, target_options,
               config.swift_test_options,
               config.swift_driver_test_options,
               swift_execution_tests_extra_flags))
        if stdlib:
            result += '-Xfrontend -disable-access-control '
        if parameterized:
            result += ' \\1 '
        if gyb:
            result += '%t/main.swift'
        else:
            result += '%s'
        return result
    config.target_run_stdlib_swiftgyb = make_simple_target_run(gyb=True)
    config.target_run_simple_swiftgyb = make_simple_target_run(gyb=True)
    config.target_run_stdlib_swift = make_simple_target_run(stdlib=True)
    config.target_run_simple_swift = make_simple_target_run()
    config.target_run_simple_swift_parameterized = make_simple_target_run(parameterized=True)
    config.available_features.add('interpret')

if run_vendor == 'apple':
    config.available_features.add('objc_interop')
    config.target_object_format = "macho"
    config.target_shared_library_prefix = 'lib'
    config.target_shared_library_suffix = ".dylib"
    config.target_codesign = "codesign -f -s -"
    config.target_runtime = "objc"

    xcrun_prefix = (
        "xcrun --toolchain %s --sdk %r" %
        (config.darwin_xcrun_toolchain, config.variant_sdk))
    extra_frameworks_dir = make_path(config.variant_sdk, "..", "..", "..",
                                     "Developer", "Library", "Frameworks")
    target_options = (
        "-target %s %s %s" %
        (config.variant_triple, resource_dir_opt, mcp_opt))
    target_options_for_mock_sdk = (
        "-target %s %s %s" %
        (config.variant_triple, stdlib_resource_dir_opt, mcp_opt))
    target_options_for_mock_sdk_after = sdk_overlay_dir_opt

    if 'arm' in run_cpu and swift_test_mode != 'only_non_executable':
        raise RuntimeError('Device tests are currently only supported when '
        'the swift_test_mode is "only_non_executable". Current '
        'swift_test_mode is {}.'.format(swift_test_mode))

    if 'arm' in run_cpu:
       # iOS/tvOS/watchOS device
       if run_os == 'ios':
           lit_config.note('Testing iOS ' + config.variant_triple)
           xcrun_sdk_name = "iphoneos"
       elif run_os == 'tvos':
           lit_config.note('Testing AppleTV ' + config.variant_triple)
           xcrun_sdk_name = "appletvos"
       elif run_os == 'watchos':
           lit_config.note('Testing watchOS ' + config.variant_triple)
           xcrun_sdk_name = "watchos"

       config.target_cc_options = (
           "-arch %s -m%s-version-min=%s %s" %
           (run_cpu, run_os, run_vers, clang_mcp_opt))

       config.target_build_swift = (
           "%s %s %s -F %r -Xlinker -rpath -Xlinker %r %s %s %s %s" %
           (xcrun_prefix, config.swiftc, target_options,
            extra_frameworks_dir,
            "/tmp/swifttest-device/lib",
            sdk_overlay_linker_opt, config.swift_test_options,
            config.swift_driver_test_options,
            swift_execution_tests_extra_flags))
       config.target_run = "unsupported"

       (sw_vers_name, sw_vers_vers, sw_vers_build) = \
            darwin_get_sdk_version(config.variant_sdk)

    elif run_os == 'ios' or run_os == 'tvos' or run_os == 'watchos':
        # iOS/tvOS/watchOS simulator
        if run_os == 'ios':
            config.available_features.add('DARWIN_SIMULATOR=ios')
            lit_config.note("Testing iOS simulator " + config.variant_triple)
            xcrun_sdk_name = "iphonesimulator"
        elif run_os == 'watchos':
            config.available_features.add('DARWIN_SIMULATOR=watchos')
            lit_config.note("Testing watchOS simulator " + config.variant_triple)
            xcrun_sdk_name = "watchsimulator"
        else:
            config.available_features.add('DARWIN_SIMULATOR=tvos')
            lit_config.note("Testing AppleTV simulator " + config.variant_triple)
            xcrun_sdk_name = "appletvsimulator"

        config.target_cc_options = (
            "-arch %s -m%s-simulator-version-min=%s %s" %
            (run_cpu, run_os, run_vers, clang_mcp_opt))

        config.target_build_swift = (
            "%s %s %s -F %r %s %s %s %s" %
            (xcrun_prefix, config.swiftc, target_options,
             extra_frameworks_dir,
             sdk_overlay_linker_opt, config.swift_test_options,
             config.swift_driver_test_options,
             swift_execution_tests_extra_flags))
        # FIXME: allow specification of simulator and version
        #
        # Note: don't pass '--adopt-pid' to sim.  This can trigger a kernel
        # panic.
        # <rdar://problem/11806093> multithreaded 64-to-32 exec is broken
        # (foundation tool launched with sim --adopt-pid occasionally
        # segmentation faults)
        config.target_run = (
            "%s %s " %
            (xcrun_prefix, get_simulator_command(run_os, run_cpu, config.variant_sdk)))

        (sw_vers_name, sw_vers_vers, sw_vers_build) = \
            darwin_get_sdk_version(config.variant_sdk)

        if (sw_vers_name == '' or sw_vers_vers == '' or sw_vers_build == ''):
            lit_config.fatal('Could not get or decode sw_vers output. ' +
                             'Perhaps the simulator is not working.')

    elif run_os == 'macosx':
        # OS X
        lit_config.note("Testing OS X " + config.variant_triple)

        xcrun_sdk_name = "macosx"
        config.target_cc_options = (
            "-arch %s -m%s-version-min=%s %s" %
            (run_cpu, run_os, run_vers, clang_mcp_opt))

        config.target_build_swift = (
            "%s %s %s -F %r -Xlinker -rpath -Xlinker %r %s %s %s %s -F %r -Xlinker -rpath -Xlinker %r"
            % (xcrun_prefix, config.swiftc, target_options,
               extra_frameworks_dir, extra_frameworks_dir,
               sdk_overlay_linker_opt, config.swift_test_options,
               config.swift_driver_test_options,
               swift_execution_tests_extra_flags, sourcekitd_framework_dir,
               sourcekitd_framework_dir))
        config.target_run = ""

        if 'interpret' in lit_config.params:
            use_interpreter_for_simple_runs()

        (sw_vers_name, sw_vers_vers, sw_vers_build) = \
            darwin_get_sw_vers()

    else:
        lit_config.fatal("Unknown Apple OS '" + run_os + "' " +
                         "(from " + config.variant_triple + ")")

    lit_config.note(
        'Running tests on %s version %s (%s)' %
        (sw_vers_name, sw_vers_vers, sw_vers_build))

    config.target_sdk_name = xcrun_sdk_name
    config.target_ld = "%s ld -L%r" % (xcrun_prefix, make_path(test_resource_dir, config.target_sdk_name))
    config.target_swift_frontend = (
        "%s -frontend %s -sdk %r %s %s" %
        (config.swiftc, target_options, config.variant_sdk,
         config.swift_test_options, config.swift_frontend_test_options))
    subst_target_swift_frontend_mock_sdk = (
        "%s -frontend %s -sdk %r %s %s" %
        (config.swiftc, target_options_for_mock_sdk, config.variant_sdk,
         config.swift_test_options, config.swift_frontend_test_options))
    config.target_swift_modulewrap = (
        '%s -modulewrap -target %s' %
        (config.swiftc, config.variant_triple))
    subst_target_swift_frontend_mock_sdk_after = \
        target_options_for_mock_sdk_after
    config.target_sil_opt = (
        "%s %s %s %s" %
        (xcrun_prefix, config.sil_opt, target_options, config.sil_test_options))
    config.target_swift_ide_test = (
        "%s %s %s %s" %
        (xcrun_prefix, config.swift_ide_test, target_options, ccp_opt))
    subst_target_swift_ide_test_mock_sdk = (
        "%s %s %s %s" %
        (xcrun_prefix, config.swift_ide_test, target_options_for_mock_sdk, ccp_opt))
    subst_target_swift_ide_test_mock_sdk_after = \
        target_options_for_mock_sdk_after
    config.target_swiftc_driver = (
        "%s %s %s" %
        (xcrun_prefix, config.swiftc, target_options))
    config.target_clang = (
        "%s clang++ %s" %
        (xcrun_prefix, config.target_cc_options))

    config.target_build_swift_dylib = (
        "%s -parse-as-library -emit-library -o '\\1' "
        "-Xlinker -install_name -Xlinker @executable_path/$(basename '\\1')"
        % (config.target_build_swift))

elif run_os in ['windows-msvc']:
    lit_config.note('Testing Windows ' + config.variant_triple)
    config.target_object_format = 'coff'
    config.target_shared_library_prefix = ''
    config.target_shared_library_suffix = '.dll'
    config.target_sdk_name = 'windows'
    config.target_runtime = 'native'

    config.target_build_swift =                                                  \
            ('%r -target %s %s %s %s %s %s' % (config.swiftc,                    \
                                               config.variant_triple,            \
                                               resource_dir_opt, mcp_opt,        \
                                               config.swift_test_options,        \
                                               config.swift_driver_test_options, \
                                               swift_execution_tests_extra_flags))

    config.target_run = ''

    config.target_swift_frontend =                                               \
            ('%r -frontend -target %s %s %s %s %s' % (config.swiftc,             \
                                                      config.variant_triple,     \
                                                      resource_dir_opt, mcp_opt, \
                                                      config.swift_test_options, \
                                                      config.swift_frontend_test_options))

    config.target_codesign = ''

    subst_target_swift_frontend_mock_sdk = config.target_swift_frontend
    subst_target_swift_frontend_mock_sdk_after = ''

    config.target_build_swift_dylib =                                            \
            ("%r -parse-as-library -emit-library -o '\\1'" % (config.target_build_swift))
    config.target_clang =                                                        \
            ('clang++ -target %s %s' % (config.variant_triple, clang_mcp_opt))
    config.target_ld =                                                           \
            ('%r -libpath:%s' % (config.link, os.path.join(test_resource_dir,    \
                                                           config.target_sdk_name)))
    config.target_sil_opt =                                                      \
            ('%r -target %s %s %s %s' % (config.sil_opt, config.variant_triple,  \
                                         resource_dir_opt, mcp_opt,              \
                                         config.sil_test_options))
    config.target_swift_ide_test =                                               \
            ('%r -target %s %s %s %s' % (config.swift_ide_test,                  \
                                         config.variant_triple,                  \
                                         resource_dir_opt, mcp_opt, ccp_opt))

    subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test
    subst_target_swift_ide_test_mock_sdk_after = ''

    config.target_swiftc_driver =                                                \
            ('%r -target %s %s %s' % (config.swiftc, config.variant_triple,      \
                                      resource_dir_opt, mcp_opt))
    config.target_swift_modulewrap =                                             \
            ('%r -modulewrap -target %s' % (config.swiftc, config.variant_triple))


elif run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'windows-cygnus', 'windows-gnu']:
    # Linux/FreeBSD/Cygwin
    if run_os == 'windows-cygnus':
      lit_config.note("Testing Cygwin " + config.variant_triple)
      config.target_object_format = "coff"
      config.target_shared_library_prefix = 'lib'
      config.target_shared_library_suffix = ".dll"
      config.target_sdk_name = "cygwin"
    elif run_os == 'windows-gnu':
      lit_config.note("Testing MinGW " + config.variant_triple)
      config.target_object_format = "coff"
      config.target_shared_library_prefix = 'lib'
      config.target_shared_library_suffix = ".dll"
      config.target_sdk_name = "mingw"
    elif run_os == 'freebsd':
      lit_config.note("Testing FreeBSD " + config.variant_triple)
      config.target_object_format = "elf"
      config.target_shared_library_prefix = 'lib'
      config.target_shared_library_suffix = ".so"
      config.target_sdk_name = "freebsd"
    else:
      lit_config.note("Testing Linux " + config.variant_triple)
      config.target_object_format = "elf"
      config.target_shared_library_prefix = 'lib'
      config.target_shared_library_suffix = ".so"
      config.target_sdk_name = "linux"
    config.target_runtime = "native"
    config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
    config.target_build_swift = (
        '%s -target %s %s %s %s %s %s'
        % (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt,
           config.swift_test_options, config.swift_driver_test_options,
           swift_execution_tests_extra_flags))
    config.target_codesign = "echo"
    config.target_build_swift_dylib = (
        "%s -parse-as-library -emit-library -o '\\1'"
        % (config.target_build_swift))
    config.target_swift_frontend = (
        '%s -frontend -target %s %s %s %s %s'
        % (config.swift, config.variant_triple, resource_dir_opt, mcp_opt,
        config.swift_test_options, config.swift_frontend_test_options))
    subst_target_swift_frontend_mock_sdk = config.target_swift_frontend
    subst_target_swift_frontend_mock_sdk_after = ""
    config.target_run = ''
    if 'interpret' in lit_config.params:
        use_interpreter_for_simple_runs()
    config.target_sil_opt = (
        '%s -target %s %s %s %s' %
        (config.sil_opt, config.variant_triple, resource_dir_opt, mcp_opt, config.sil_test_options))
    config.target_swift_ide_test = (
        '%s -target %s %s %s %s' %
        (config.swift_ide_test, config.variant_triple, resource_dir_opt,
         mcp_opt, ccp_opt))
    subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test
    subst_target_swift_ide_test_mock_sdk_after = ""
    config.target_swiftc_driver = (
        "%s -target %s %s %s" %
        (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt))
    config.target_swift_modulewrap = (
        '%s -modulewrap -target %s' %
        (config.swiftc, config.variant_triple))
    config.target_clang = (
        "clang++ -target %s %s" %
        (config.variant_triple, clang_mcp_opt))
    config.target_ld = "ld -L%r" % (make_path(test_resource_dir, config.target_sdk_name))
elif run_os == 'linux-androideabi':
    lit_config.note("Testing Android " + config.variant_triple)
    config.target_object_format = "elf"
    config.target_shared_library_prefix = 'lib'
    config.target_shared_library_suffix = ".so"
    config.target_runtime = "native"
    config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
    config.target_sdk_name = "android"
    android_linker_opt = "-L {libcxx} -L {libgcc}".format(
        libcxx=make_path(config.android_ndk_path,
                         "sources", "cxx-stl", "llvm-libc++", "libs",
                         "armeabi-v7a"),
        libgcc=make_path(config.android_ndk_path,
                         "toolchains",
                         "arm-linux-androideabi-{}".format(config.android_ndk_gcc_version),
                         "prebuilt", "linux-x86_64", "lib", "gcc",
                         "arm-linux-androideabi",
                         "{}.x".format(config.android_ndk_gcc_version)))
    config.target_build_swift = (
        '%s -target %s -sdk %r %s -Xlinker -pie %s %s %s %s %s'
        % (config.swiftc, config.variant_triple, config.variant_sdk,
           android_linker_opt, resource_dir_opt, mcp_opt,
           config.swift_test_options,
           config.swift_driver_test_options, swift_execution_tests_extra_flags))
    config.target_codesign = "echo"
    config.target_build_swift_dylib = (
        "%s -parse-as-library -emit-library -o '\\1'"
        % (config.target_build_swift))
    config.target_swift_frontend = (
        '%s -frontend -target %s -sdk %r %s %s %s %s'
        % (config.swift, config.variant_triple, config.variant_sdk,
           android_linker_opt, resource_dir_opt, mcp_opt,
           config.swift_frontend_test_options))
    subst_target_swift_frontend_mock_sdk = config.target_swift_frontend
    subst_target_swift_frontend_mock_sdk_after = ""
    config.target_run = make_path(config.swift_src_root, 'utils', 'android', 'adb_test_runner.py')
    # FIXME: Include -sdk in this invocation.
    config.target_sil_opt = (
        '%s -target %s %s %s %s' %
        (config.sil_opt, config.variant_triple, resource_dir_opt, mcp_opt, config.sil_test_options))
    config.target_swift_ide_test = (
        '%s -target %s %s %s %s' %
        (config.swift_ide_test, config.variant_triple, resource_dir_opt,
         mcp_opt, ccp_opt))
    subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test
    subst_target_swift_ide_test_mock_sdk_after = ""
    config.target_swiftc_driver = (
        "%s -target %s -sdk %r %s %s %s" %
        (config.swiftc, config.variant_triple, config.variant_sdk,
         android_linker_opt, resource_dir_opt, mcp_opt))
    config.target_swift_modulewrap = (
        '%s -modulewrap -target %s' %
        (config.swiftc, config.variant_triple))
    config.target_clang = (
        "clang++ -target %s %s" %
        (config.variant_triple, clang_mcp_opt))
    config.target_ld = "{} -L{}".format(
        make_path(config.android_ndk_path, 'toolchains',
                  'arm-linux-androideabi-{}'.format(config.android_ndk_gcc_version),
                  'prebuilt', 'linux-x86_64', 'arm-linux-androideabi', 'bin'),
        make_path(test_resource_dir, config.target_sdk_name))
    # The Swift interpreter is not available when targeting Android.
    config.available_features.remove('swift_interpreter')

else:
    lit_config.fatal("Don't know how to define target_run and "
                     "target_build_swift for platform " + config.variant_triple)


# Different OS's require different prefixes for the environment variables to be
# propagated to the calling contexts.
# In order to make tests OS-agnostic, names of environment variables should be
# prefixed with `%env-`, which is then expanded to the appropriate prefix.
SIMULATOR_ENV_PREFIX = 'SIMCTL_CHILD_'
ENV_VAR_PREFIXES = {
    'iphonesimulator': SIMULATOR_ENV_PREFIX,
    'watchsimulator': SIMULATOR_ENV_PREFIX,
    'appletvsimulator': SIMULATOR_ENV_PREFIX,
    'android': 'ANDROID_CHILD_'
}
TARGET_ENV_PREFIX = ENV_VAR_PREFIXES.get(config.target_sdk_name, "")

if (not getattr(config, 'target_run', None) and
    'remote_run_host' in lit_config.params):
    if 'remote_run_tmpdir' not in lit_config.params:
        lit_config.fatal("'remote_run_host' provided, but no "
                         "'remote_run_tmpdir'")

    remote_run_host = lit_config.params['remote_run_host']
    remote_tmp_dir = lit_config.params['remote_run_tmpdir']
    remote_lib_dir = os.path.join(remote_tmp_dir, 'stdlib')

    remote_run_extra_args_param = lit_config.params.get('remote_run_extra_args')
    remote_run_extra_args = shlex.split(remote_run_extra_args_param or '')
    if 'remote_run_identity' in lit_config.params:
        remote_run_identity = lit_config.params['remote_run_identity']
        remote_run_extra_args += ['-i', remote_run_identity]

    if 'remote_run_skip_upload_stdlib' not in lit_config.params:
        lit_config.note(
            "Uploading resources to {0} on {1}".format(remote_lib_dir,
                                                       remote_run_host))

        def upload_files(files, input_prefix, remote_input_prefix):
            subprocess.check_call(
                [
                    os.path.join(config.swift_utils, 'remote-run'),
                    '--remote-dir', remote_tmp_dir,
                    '--input-prefix', input_prefix,
                    '--remote-input-prefix', remote_input_prefix
                ] + remote_run_extra_args + [
                    remote_run_host,
                    '--',
                    'true' # A dummy command that ignores its arguments.
                ] + files)

        def upload_dylibs(dylib_dir):
            glob_pattern = os.path.join(dylib_dir,
                                        '*' + config.target_shared_library_suffix)
            libs = glob.glob(glob_pattern)
            upload_files(libs, dylib_dir, 'stdlib/')

        upload_dylibs(os.path.join(test_resource_dir, config.target_sdk_name))
        # FIXME: This could be more principled.
        upload_dylibs(os.path.join(test_resource_dir, "clang", "lib", "darwin"))
        upload_dylibs(os.path.join(test_resource_dir, "clang", "lib", "linux"))

        # FIXME: Uploading specific files in bin/ is not very scalable.
        local_swift_reflection_test = lit.util.which(
            swift_reflection_test_name, config.environment['PATH'])
        upload_files([local_swift_reflection_test],
                     os.path.dirname(local_swift_reflection_test),
                     'bin/')

    config.target_run = (
        "/usr/bin/env "
        "REMOTE_RUN_CHILD_DYLD_LIBRARY_PATH='{0}' " # Apple option
        "REMOTE_RUN_CHILD_LD_LIBRARY_PATH='{0}' " # Linux option
        "'{1}'/remote-run --input-prefix '{2}' --output-prefix %t "
        "--remote-dir '{3}'%t {4} {5}".format(remote_lib_dir,
                                              config.swift_utils,
                                              config.swift_src_root,
                                              remote_tmp_dir,
                                              ' '.join(remote_run_extra_args),
                                              remote_run_host))
    config.target_swift_reflection_test = os.path.join(
        remote_tmp_dir, 'bin', swift_reflection_test_name)
    TARGET_ENV_PREFIX = 'REMOTE_RUN_CHILD_'
    config.available_features.add('remote_run')

config.substitutions.append(('%env-', TARGET_ENV_PREFIX))
config.substitutions.append(("%target-sdk-name", config.target_sdk_name))

simulator_sdks = [
    'iphonesimulator',
    'watchsimulator',
    'appletvsimulator'
]
if config.target_sdk_name in simulator_sdks:
    config.substitutions.append(('%target-is-simulator', 'true'))
else:
    config.substitutions.append(('%target-is-simulator', 'false'))


config.compiler_rt_libs = []
config.compiler_rt_platform = {
    'iphoneos': 'ios',
    'appletvos': 'tvos',
    'watchos': 'watchos',
    'iphonesimulator': 'iossim',
    'watchsimulator': 'watchossim',
    'appletvsimulator': 'tvossim',
    'macosx': 'osx'
}.get(config.target_sdk_name, run_cpu)

def source_compiler_rt_libs(path):
    if os.path.exists(path):
        config.compiler_rt_libs.extend([lib for lib in
                                        os.listdir(path)
                                        if lib.startswith('libclang_rt.')
                                        and config.compiler_rt_platform in lib])

compiler_rt_dir = make_path(test_resource_dir, 'clang', 'lib',
                            platform.system().lower())
source_compiler_rt_libs(compiler_rt_dir)

def check_runtime_libs(features_to_check):
    for lib in config.compiler_rt_libs:
        for (libname, feature) in features_to_check.iteritems():
            if lib.startswith("libclang_rt." + libname + "_"):
                config.available_features.add(feature)

runtime_libs = {
    'profile': 'profile_runtime',
    'asan': 'asan_runtime',
    'ubsan': 'ubsan_runtime',
    'safestack': 'safestack_runtime',
    'fuzzer': 'fuzzer_runtime'
}

if run_ptrsize != "32":
    runtime_libs['tsan'] = 'tsan_runtime'

check_runtime_libs(runtime_libs)

# From https://stackoverflow.com/a/2393022
def strip_right(text, suffix):
    if not text.endswith(suffix):
        return text
    return text[:len(text)-len(suffix)]

base_runtime_lib_name = (
    'libclang_rt.' + strip_right(config.compiler_rt_platform, 'sim') + '.a')
if os.path.exists(make_path(compiler_rt_dir, base_runtime_lib_name)):
    config.available_features.add('c_runtime')

# For testing the remote-run utility itself, see if we can find an sftp-server
# binary.
def find_sftp_server():
    paths_to_try = ['/usr/libexec/sftp-server', '/usr/lib/sftp-server',
                    '/usr/libexec/openssh/sftp-server',
                    '/usr/lib/openssh/sftp-server']
    return next((path for path in paths_to_try if os.path.isfile(path)), None)

sftp_server_path = find_sftp_server()
if sftp_server_path:
    config.available_features.add('sftp_server')
config.substitutions.append(('%sftp-server',
                             sftp_server_path or 'no-sftp-server'))


if not getattr(config, 'target_run_simple_swift', None):
    config.target_run_simple_swift_parameterized = (
        '%%empty-directory(%%t) && '
        '%s %s %%s \\1 -o %%t/a.out -module-name main && '
        '%s %%t/a.out &&'
        '%s %%t/a.out'
        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
    config.target_run_simple_swift = (
        '%%empty-directory(%%t) && '
        '%s %s %%s -o %%t/a.out -module-name main && '
        '%s %%t/a.out &&'
        '%s %%t/a.out'
        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
    config.target_run_stdlib_swift = (
        '%%empty-directory(%%t) && '
        '%s %s %%s -o %%t/a.out -module-name main '
        '-Xfrontend -disable-access-control && '
        '%s %%t/a.out &&'
        '%s %%t/a.out'
        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
    config.target_run_simple_swiftgyb = (
        '%%empty-directory(%%t) && '
        '%%gyb %%s -o %%t/main.swift && '
        '%%line-directive %%t/main.swift -- '
        '%s %s %%t/main.swift -o %%t/a.out -module-name main && '
        '%s %%t/a.out &&'
        '%%line-directive %%t/main.swift -- '
        '%s %%t/a.out'
        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))
    config.target_run_stdlib_swiftgyb = (
        '%%empty-directory(%%t) && '
        '%%gyb %%s -o %%t/main.swift && '
        '%%line-directive %%t/main.swift -- '
        '%s %s %%t/main.swift -o %%t/a.out -module-name main '
        '-Xfrontend -disable-access-control && '
        '%s %%t/a.out &&'
        '%%line-directive %%t/main.swift -- '
        '%s %%t/a.out'
        % (config.target_build_swift, mcp_opt, config.target_codesign, config.target_run))

subst_target_jit_run = ""
if 'swift_interpreter' in config.available_features:
    subst_target_jit_run = (
        "%s -interpret %s" %
        (config.target_swift_frontend, sdk_overlay_link_path))

subst_target_repl_run_simple_swift = ""
if 'swift_repl' in config.available_features:
    subst_target_repl_run_simple_swift = (
        "%s -repl %s < %%s 2>&1" %
        (config.target_swift_frontend, sdk_overlay_link_path))

config.target_parse_verify_swift = (
    '%s -typecheck -verify -disable-objc-attr-requires-foundation-module %%s'
    % (config.target_swift_frontend, ))

config.target_sil_func_extractor = (
    '%s -target %s %s'
    % (config.sil_func_extractor, config.variant_triple, mcp_opt))

config.target_sil_llvm_gen = (
    '%s -target %s %s'
    % (config.sil_llvm_gen, config.variant_triple, mcp_opt))

config.target_sil_nm = (
    '%s -target %s %s'
    % (config.sil_nm, config.variant_triple, mcp_opt))

rth_flags = ''
if swift_execution_tests_extra_flags:
    rth_flags = swift_execution_tests_extra_flags + ' -wmo'

config.target_resilience_test = (
     '%s --target-build-swift "%s" --target-run "%s" --t %%t --S %%S --s %%s '
     '--lib-prefix "%s" --lib-suffix "%s" --target-codesign "%s" '
     '--additional-compile-flags "%s"'
     % (config.rth, config.target_build_swift, config.target_run,
        config.target_shared_library_prefix,
        config.target_shared_library_suffix, config.target_codesign,
        rth_flags))

# FIXME: Get symbol diffing working with binutils nm as well. The flags are slightly
# different.
if platform.system() != 'Darwin':
    config.target_resilience_test = ('%s --no-symbol-diff' %
                                     config.target_resilience_test)

#
# When changing substitutions, update docs/Testing.rst.
#

config.substitutions.append(('%target-runtime', config.target_runtime))

config.substitutions.append(('%target-typecheck-verify-swift', config.target_parse_verify_swift))

config.substitutions.append(('%target-swift-emit-silgen\(mock-sdk:([^)]+)\)',
                             SubstituteCaptures(r'%target-swift-frontend(mock-sdk:\1) -emit-silgen -verify-syntax-tree -enable-sil-ownership')))
config.substitutions.append(('%target-swift-emit-silgen', '%target-swift-frontend -emit-silgen -verify-syntax-tree -enable-sil-ownership'))
config.substitutions.append(('%target-swift-emit-sil\(mock-sdk:([^)]+)\)',
                             SubstituteCaptures(r'%target-swift-frontend(mock-sdk:\1) -emit-sil -verify-syntax-tree')))
config.substitutions.append(('%target-swift-emit-sil', '%target-swift-frontend -emit-sil -verify-syntax-tree'))
config.substitutions.append(('%target-swift-emit-ir\(mock-sdk:([^)]+)\)',
                             SubstituteCaptures(r'%target-swift-frontend(mock-sdk:\1) -emit-ir -verify-syntax-tree')))
config.substitutions.append(('%target-swift-emit-ir', '%target-swift-frontend -emit-ir -verify-syntax-tree'))
config.substitutions.append(('%target-swift-frontend\(mock-sdk:([^)]+)\)',
                             SubstituteCaptures(r'%s \1 %s' % (subst_target_swift_frontend_mock_sdk,
                                                               subst_target_swift_frontend_mock_sdk_after))))
config.substitutions.append(('%target-swift-frontend', config.target_swift_frontend))


config.substitutions.append(('%target-run-simple-swiftgyb', config.target_run_simple_swiftgyb))
config.substitutions.append(('%target-run-simple-swift\(([^)]+)\)', config.target_run_simple_swift_parameterized))
config.substitutions.append(('%target-run-simple-swift', config.target_run_simple_swift))
config.substitutions.append(('%target-run-stdlib-swiftgyb', config.target_run_stdlib_swiftgyb))
config.substitutions.append(('%target-run-stdlib-swift', config.target_run_stdlib_swift))
config.substitutions.append(('%target-repl-run-simple-swift', subst_target_repl_run_simple_swift))
config.substitutions.append(('%target-run', config.target_run))
config.substitutions.append(('%target-jit-run', subst_target_jit_run))
config.substitutions.append(('%target-build-swift-dylib\(([^)]+)\)', config.target_build_swift_dylib))
config.substitutions.append(('%target-codesign', config.target_codesign))
config.substitutions.append(('%target-build-swift', config.target_build_swift))
config.substitutions.append(('%target-clang', config.target_clang))
config.substitutions.append(('%target-ld', config.target_ld))
if hasattr(config, 'target_cc_options'):
    config.substitutions.append(('%target-cc-options', config.target_cc_options))

config.substitutions.append(
    (r'%hardlink-or-copy\(from: *(.*), *to: *(.*)\)',
     r'ln \1 \2 || cp \1 \2'))

config.substitutions.append(('%utils', config.swift_utils))
config.substitutions.append(('%line-directive', '%r %s' % (sys.executable, config.line_directive)))
config.substitutions.append(('%gyb', '%r %s' % (sys.executable, config.gyb)))
config.substitutions.append(('%round-trip-syntax-test', config.round_trip_syntax_test))
config.substitutions.append(('%rth', config.rth))
config.substitutions.append(('%scale-test',
                             '{} --swiftc-binary={} --tmpdir=%t'.format(
                                 config.scale_test, config.swiftc)))
config.substitutions.append(('%empty-directory\(([^)]+)\)',
                             SubstituteCaptures(r'rm -rf "\1" && mkdir -p "\1"')))

config.substitutions.append(('%target-sil-opt', config.target_sil_opt))
config.substitutions.append(('%target-sil-func-extractor', config.target_sil_func_extractor))
config.substitutions.append(('%target-sil-llvm-gen', config.target_sil_llvm_gen))
config.substitutions.append(('%target-sil-nm', config.target_sil_nm))

config.substitutions.append(('%target-swift-ide-test\(mock-sdk:([^)]+)\)',
                             SubstituteCaptures(r'%s \1 %s -swift-version %s' % (subst_target_swift_ide_test_mock_sdk,
                                                                                 subst_target_swift_ide_test_mock_sdk_after,
                                                                                 swift_version))))
config.substitutions.append(('%target-swift-ide-test', "%s -swift-version %s" % (config.target_swift_ide_test, swift_version)))

if not hasattr(config, 'target_swift_reflection_test'):
    config.target_swift_reflection_test = lit.util.which(
        swift_reflection_test_name, config.environment['PATH'])

config.substitutions.append(('%target-swift-reflection-test', config.target_swift_reflection_test))

config.substitutions.append(('%target-swift-reflection-dump', '{} {} {}'.format(config.swift_reflection_dump, '-arch', run_cpu)))
config.substitutions.append(('%target-swiftc_driver', config.target_swiftc_driver))
config.substitutions.append(('%target-swift-remoteast-test-with-sdk',
                             '%s -sdk %r' %
                               (config.swift_remoteast_test, config.variant_sdk)))
config.substitutions.append(('%target-swift-remoteast-test', config.swift_remoteast_test))

if hasattr(config, 'target_swift_autolink_extract'):
    config.available_features.add('autolink-extract')
    config.substitutions.append(('%target-swift-autolink-extract',
                                 config.target_swift_autolink_extract))

config.substitutions.append(('%target-swift-modulewrap',
                             config.target_swift_modulewrap))

platform_module_dir = make_path(test_resource_dir, '%target-sdk-name', run_cpu)
lit_config.note('Using platform module dir: ' + platform_module_dir)
if test_sdk_overlay_dir is not None:
    platform_sdk_overlay_dir = make_path(test_sdk_overlay_dir, run_cpu)
else:
    platform_sdk_overlay_dir = platform_module_dir

config.substitutions.insert(0, ('%platform-module-dir', platform_module_dir))
config.substitutions.insert(0, ('%platform-sdk-overlay-dir', platform_sdk_overlay_dir))

config.substitutions.append(('%target-swiftmodule-name', run_cpu + '.swiftmodule'))
config.substitutions.append(('%target-swiftdoc-name', run_cpu + '.swiftdoc'))

config.substitutions.append(('%target-object-format', config.target_object_format))
config.substitutions.append(('%{target-shared-library-prefix}', config.target_shared_library_prefix))
config.substitutions.append(('%{target-shared-library-suffix}', config.target_shared_library_suffix))
config.substitutions.insert(0, ('%target-library-name\(([^)]+)\)',
                                SubstituteCaptures(r'%s\1%s' % (config.target_shared_library_prefix,
                                                                config.target_shared_library_suffix))))

config.substitutions.append(('%target-resilience-test', config.target_resilience_test))

config.substitutions.append(('%llvm-profdata', config.llvm_profdata))
config.substitutions.append(('%llvm-cov', config.llvm_cov))

config.substitutions.append(('%FileCheck',
                             '%r %r --sanitize BUILD_DIR=%r --sanitize SOURCE_DIR=%r --use-filecheck %r' % (sys.executable,
                                                                                                            config.PathSanitizingFileCheck,
                                                                                                            swift_obj_root,
                                                                                                            config.swift_src_root,
                                                                                                            config.filecheck)))
config.substitutions.append(('%raw-FileCheck', pipes.quote(config.filecheck)))

# If static stdlib is present, enable static stdlib tests
static_stdlib_path = make_path(config.swift_lib_dir, "swift_static", config.target_sdk_name)
libswiftCore_path = make_path(static_stdlib_path, "libswiftCore.a")
if os.path.exists(libswiftCore_path):
    config.available_features.add("static_stdlib")
    config.substitutions.append(('%target-static-stdlib-path', static_stdlib_path))
    lit_config.note('using static stdlib path: %s' % static_stdlib_path)

if config.lldb_build_root != "":
    config.available_features.add('lldb')
    # Note: using the same approach to locating the lib dir as in
    # finishSwigPythonLLDB.py in the lldb repo
    python_lib_dir = get_python_lib(True, False, config.lldb_build_root)
    config.substitutions.append(('%lldb-python-path', python_lib_dir))

# Disable randomized hash seeding by default. Tests need to manually opt in to
# random seeds by unsetting the SWIFT_DETERMINISTIC_HASHING environment
# variable.
config.environment[TARGET_ENV_PREFIX + 'SWIFT_DETERMINISTIC_HASHING'] = '1'

# Run lsb_release on the target to be tested and return the results.
def linux_get_lsb_release():
    lsb_release_path = '/usr/bin/lsb_release'
    if os.path.isfile(lsb_release_path) and os.access(lsb_release_path, os.X_OK):
        distributor = lit.util.executeCommand([lsb_release_path, '-is'])[0].rstrip()
        release = lit.util.executeCommand([lsb_release_path, '-rs'])[0].rstrip()
        return (distributor, release)
    return ('', '')

if platform.system() == 'Linux':
    (distributor, release) = linux_get_lsb_release()
    if distributor != '' and release != '':
        config.available_features.add("LinuxDistribution=" + distributor + '-' + release)
        lit_config.note('Running tests on %s-%s' % (distributor, release))

lit_config.note("Available features: " + ", ".join(sorted(config.available_features)))
