Files
swift-mirror/utils/run-test
Daniel Rodríguez Troitiño 9cec482ef3 [android] Allow executing only Android compiler tests.
The manipulation of host-test and skip-android-host was a little
different than the equivalent skip-ios-host and similar variables. These
changes make them closer and allows executing only the compiler tests,
but skip the test that need an Android device to run.

- Disables the upload command of the tests if the subset is the
  non-executable tests. The non-executable test do not need to be
  uploaded, and in the case of Android, a device doesn't need to be
  connected, so trying to connect to one will fail.
- Fix a problem where the swift_interpreter feature was removed without
  first checking if it was really added.
- Only enable the host tests (the compiler tests) in the Android CI
  preset (there's no device attached to that server, but currently only
  the Linux tests were being executed, which doesn't make a lot of
  sense).
- Move the decision about which platform support device/host tests into
  the platform themselves, which allows Android to have device/host
  tests. Also modify a little bit the logic around enabling/disabling
  the test suite to allow running only the host tests of a platform.
- Fix the suffix name for the target of non-executable tests in a couple
  of places.
2019-03-22 14:43:00 -07:00

256 lines
9.0 KiB
Python
Executable File

#!/usr/bin/env python
# utils/run-test - test runner for Swift -*- 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
from __future__ import print_function
import argparse
import multiprocessing
import os
import shutil
import sys
from swift_build_support.swift_build_support import (
arguments,
shell
)
from swift_build_support.swift_build_support.SwiftBuildSupport import \
SWIFT_SOURCE_ROOT
from swift_build_support.swift_build_support.targets import \
StdlibDeploymentTarget
TEST_MODES = [
'optimize_none',
'optimize',
'optimize_unchecked',
'only_executable',
'only_non_executable',
]
TEST_SUBSETS = [
'primary',
'validation',
'all',
'only_validation',
'only_long',
'only_stress',
]
SWIFT_SOURCE_DIR = os.path.join(SWIFT_SOURCE_ROOT, 'swift')
TEST_SOURCE_DIR = os.path.join(SWIFT_SOURCE_DIR, 'test')
VALIDATION_TEST_SOURCE_DIR = os.path.join(SWIFT_SOURCE_DIR, 'validation-test')
LIT_BIN_DEFAULT = os.path.join(SWIFT_SOURCE_ROOT, 'llvm',
'utils', 'lit', 'lit.py')
host_target = StdlibDeploymentTarget.host_target().name
def error_exit(msg):
print("%s: %s" % (os.path.basename(sys.argv[0]), msg), file=sys.stderr)
sys.exit(1)
# Return true if the path looks like swift build directory.
def is_swift_build_dir(path):
return (os.path.exists(os.path.join(path, "CMakeCache.txt")) and
os.path.isdir(os.path.join(path, "test-%s" % host_target)))
# Return true if the swift build directory is configured with `Xcode`
# generator.
def is_build_dir_xcode(path):
return os.path.exists(os.path.join(path, 'Swift.xcodeproj'))
# Return true if 'path' is sub path of 'd'
def is_subpath(path, d):
path, d = os.path.abspath(path), os.path.abspath(d)
if os.path.isdir(path):
path = os.path.join(path, '')
d = os.path.join(d, '')
return path.startswith(d)
# Convert test path in source directory to corresponding path in build
# directory. If the path is not sub path of test directories in source,
# return the path as is.
def normalize_test_path(path, build_dir, variant):
for d, prefix in [(TEST_SOURCE_DIR, 'test-%s'),
(VALIDATION_TEST_SOURCE_DIR, 'validation-test-%s')]:
if is_subpath(path, d):
return os.path.normpath(os.path.join(
build_dir,
prefix % variant,
os.path.relpath(path, d)))
return path
def main():
parser = argparse.ArgumentParser()
parser.add_argument("paths", type=os.path.realpath,
nargs="*", metavar="PATH",
help="paths to test. Accept multiple. "
"If --build-dir is not specified, these paths "
"must be test paths in the Swift build "
"directory. (default: primary test suite if "
"--build-dir is specified, none otherwise)")
parser.add_argument("-v", "--verbose", action="store_true",
help="run test with verbose output")
parser.add_argument("--build-dir", type=os.path.realpath, metavar="PATH",
help="Swift build directory")
parser.add_argument("--build",
choices=["true", "verbose", "skip"], default='true',
help="build test dependencies before running tests "
"(default: true)")
parser.add_argument("--target",
type=arguments.type.shell_split,
action=arguments.action.concat,
dest="targets",
help="stdlib deployment targets to test. Accept "
"multiple (default: " + host_target + ")")
parser.add_argument("--mode",
choices=TEST_MODES, default='optimize_none',
help="test mode (default: optimize_none)")
parser.add_argument("--subset",
choices=TEST_SUBSETS, default='primary',
help="test subset (default: primary)")
parser.add_argument("--param",
type=arguments.type.shell_split,
action=arguments.action.concat,
default=[],
help="key=value parameters they are directly passed "
"to lit command in addition to `mode` and "
"`subset`. Accept multiple.")
parser.add_argument("--result-dir", type=os.path.realpath, metavar="PATH",
help="directory to store test results (default: none)")
parser.add_argument("--lit", default=LIT_BIN_DEFAULT, metavar="PATH",
help="lit.py executable path "
"(default: ${LLVM_SOURCE_DIR}/utils/lit/lit.py)")
args = parser.parse_args()
targets = args.targets
if targets is None:
targets = [host_target]
paths = []
build_dir = args.build_dir
if build_dir is not None:
# Fixup build directory.
# build_dir can be:
# build-root/ # assuming we are to test host deployment target.
# build-root/swift-{tool-deployment_target}/
for d in [
build_dir,
os.path.join(build_dir, 'swift-%s' % host_target)]:
if is_swift_build_dir(d):
build_dir = d
break
else:
error_exit("'%s' is not a swift build directory" % args.build_dir)
# If no path given, run primary test suite.
if not args.paths:
args.paths = [TEST_SOURCE_DIR]
# $ run-test --build-dir=<swift-build-dir> <test-dir-in-source> ... \
# --target macosx-x86_64 --target iphonesimulator-i386
for target in targets:
paths += map(
lambda p: normalize_test_path(p, build_dir, target),
args.paths)
else:
# Otherwise, we assume all given paths are valid test paths in the
# build_dir.
paths = args.paths
if not paths:
parser.print_usage()
error_exit("error: too few arguments")
if args.build != 'skip':
# Building dependencies requires `build_dir` set.
# Traverse the first test path to find the `build_dir`
d = os.path.dirname(paths[0])
while d not in ['', os.sep]:
if is_swift_build_dir(d):
build_dir = d
break
d = os.path.dirname(d)
else:
error_exit("Can't infer swift build directory")
# Ensure we have up to date test dependency
if args.build != 'skip' and is_build_dir_xcode(build_dir):
# We don't support Xcode Generator build yet.
print("warning: Building Xcode project is not supported yet. "
"Skipping...")
sys.stdout.flush()
elif args.build != 'skip':
dependency_targets = ["all", "SwiftUnitTests"]
upload_stdlib_targets = []
need_validation = any('/validation-test-' in path for path in paths)
for target in targets:
if args.mode != 'only_non_executable':
upload_stdlib_targets += ["upload-stdlib-%s" % target]
if need_validation:
dependency_targets += ["swift-stdlib-%s" % target]
else:
dependency_targets += ["swift-test-stdlib-%s" % target]
cmake_build = ['cmake', '--build', build_dir, '--']
if args.build == 'verbose':
cmake_build += ['-v']
cmake_build += ['-j%d' % multiprocessing.cpu_count()]
print("--- Building test dependencies %s ---" %
', '.join(dependency_targets))
sys.stdout.flush()
shell.call(cmake_build + dependency_targets)
shell.call(cmake_build + upload_stdlib_targets)
print("--- Build finished ---")
sys.stdout.flush()
if args.result_dir is not None:
# Clear result directory
if os.path.exists(args.result_dir):
shutil.rmtree(args.result_dir)
os.makedirs(args.result_dir)
if args.verbose:
test_args = ["-a"]
else:
test_args = ["-sv"]
# Test parameters.
test_args += ['--param', 'swift_test_mode=%s' % args.mode,
'--param', 'swift_test_subset=%s' % args.subset]
for param in args.param:
test_args += ['--param', param]
if args.result_dir:
test_args += ['--param', 'swift_test_results_dir=%s' % args.result_dir,
'--xunit-xml-output=%s' % os.path.join(args.result_dir,
'lit-tests.xml')]
test_cmd = [sys.executable, args.lit] + test_args + paths
# Do execute test
shell.call(test_cmd)
if __name__ == "__main__":
main()