# Tests/Functional/lit.cfg - Functional test suite lit config -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See http://swift.org/LICENSE.txt for license information
# See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors

import os
import platform
import tempfile
import sys
import lit

# Set up lit config.
config.name = 'SwiftXCTestFunctionalTests'
config.test_format = lit.formats.ShTest(execute_external=False)
config.suffixes = ['.swift']

# Set up the substitutions used by the functional test suite.

# First, our tests need a way to compile source files into
# executables that are linked against swift-corelibs-xctest.
# We'll provide one via the %swiftc substitution.
#
# Linux tests are run after swift-corelibs-xctest is installed
# in the Swift library path, so we only need the path to `swiftc`
# in order to compile.
def _getenv(name):
    value = os.getenv(name, None)
    if value is None:
        lit_config.fatal(
            'Environment variable ${} is required to run tests on this '
            'platform, but it is not set.'.format(name))
    return value

built_products_dir = _getenv('BUILT_PRODUCTS_DIR')
# Force tests to build with -swift-version 4 for now.
swift_exec = [
    _getenv('SWIFT_EXEC'),
    '-swift-version', '4',
    '-Xlinker', '-rpath',
    '-Xlinker', built_products_dir,
    '-L', built_products_dir,
    '-I', built_products_dir,
]

if platform.system() == 'Darwin':
    # On Darwin, we need to make sure swiftc references the
    # proper SDK, has a deployment target set, and more...
    # Here we rely on environment variables, produced by xcodebuild.
    sdk_root = _getenv('SDKROOT')
    platform_name = _getenv('PLATFORM_NAME')
    deployment_target = _getenv('MACOSX_DEPLOYMENT_TARGET')

    target = '{}-apple-{}{}'.format(
        platform.machine(), platform_name, deployment_target)
    swift_exec.extend([
        '-sdk', sdk_root,
        '-target', target,
        '-F', built_products_dir,
        # FIXME: We must include the C header dependencies of any module we wish
        #        to use, due to a limitation in the Swift compiler. See SR-655
        #        for details. Here, we include the headers from CoreFoundation.
        '-I', os.path.join(built_products_dir, 'usr', 'local', 'include'),
    ])
else:
    # On Linux, we need to jump through extra hoops to link
    # swift-corelibs-foundation.
    foundation_dir = _getenv('FOUNDATION_BUILT_PRODUCTS_DIR')
    core_foundation_dir = _getenv('CORE_FOUNDATION_BUILT_PRODUCTS_DIR')
    swift_exec.extend([
        '-Xlinker', '-rpath',
        '-Xlinker', foundation_dir,
        '-L', foundation_dir,
        '-I', foundation_dir,
        '-I', core_foundation_dir,
    ])
    config.environment['LD_LIBRARY_PATH'] = foundation_dir
    # We also need to link swift-corelibs-libdispatch, if
    # swift-corelibs-foundation is using it.
    libdispatch_src_dir = os.getenv('LIBDISPATCH_SRC_DIR')
    libdispatch_build_dir = os.getenv('LIBDISPATCH_BUILD_DIR')
    libdispatch_overlay_dir = os.getenv('LIBDISPATCH_OVERLAY_DIR')
    if ((libdispatch_src_dir is not None) 
        and (libdispatch_build_dir is not None)
        and (libdispatch_overlay_dir is not None)):
            swift_exec.extend([
                '-Xcc', '-fblocks',
                '-I', libdispatch_src_dir,
                '-I', libdispatch_overlay_dir,
                '-L', libdispatch_build_dir,
            ])

# Having prepared the swiftc command, we set the substitution.
config.substitutions.append(('%{swiftc}', ' '.join(swift_exec)))

# Add the %{xctest_checker} substitution, which is a Python script that
# can be used to compare the actual XCTest output to the expected
# output.
xctest_checker = os.path.join(
    os.path.dirname(os.path.abspath(__file__)),
    'xctest_checker',
    'xctest_checker.py')
config.substitutions.append(('%{xctest_checker}', xctest_checker))

# Add Python to run xctest_checker.py tests as part of XCTest tests
config.substitutions.append( ('%{python}', sys.executable) )
