Skip to content

Commit 0d8aa27

Browse files
committed
[Android] Add testing support
This adds support for running tests for the stdlib built for Android, both on the host machine and on an Android device. The Android variant of Swift may be built and tested using the following `build-script` invocation: ``` $ utils/build-script \ -R \ # Build in ReleaseAssert mode. -T \ # Run all tests. --android \ # Build for Android. --android-deploy-device-path /data/local/tmp \ # Temporary directory on the device where Android tests are run. --android-ndk ~/android-ndk-r10e \ # Path to an Android NDK. --android-ndk-version 21 \ --android-icu-uc ~/libicu-android/armeabi-v7a/libicuuc.so \ --android-icu-uc-include ~/libicu-android/armeabi-v7a/icu/source/common \ --android-icu-i18n ~/libicu-android/armeabi-v7a/libicui18n.so \ --android-icu-i18n-include ~/libicu-android/armeabi-v7a/icu/source/i18n/ ``` See docs/Testing.rst for more details.
1 parent 1c3d998 commit 0d8aa27

24 files changed

+484
-9
lines changed

docs/Testing.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,48 @@ targets mentioned above and modify it as necessary. lit.py also has several
115115
useful features, like timing tests and providing a timeout. Check these features
116116
out with ``lit.py -h``.
117117

118+
Running tests hosted on an Android device
119+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120+
121+
You may run tests targeting android-armv7 by connecting a device to run the
122+
tests on, then pushing the necessary dependencies to that device.
123+
124+
1. Connect your Android device to your computer via USB. Ensure that remote
125+
debugging is enabled for that device by following the official instructions:
126+
https://developer.chrome.com/devtools/docs/remote-debugging.
127+
2. Confirm the device is connected by running ``adb devices``. You should see
128+
your device listed.
129+
3. Push the built products for android-armv7 to your device, using the
130+
``utils/android/adb_push_built_products.py`` script. For example, to push
131+
the built products at a build directory
132+
``~/swift/Ninja-ReleaseAssert/swift-linux-x86_64``, with an Android NDK
133+
placed at ``~/android-ndk-r10e``, run the following:
134+
135+
$ utils/android/adb_push_built_products.py \
136+
~/swift/build/Ninja-ReleaseAssert/swift-linux-x86_64/lib/swift/android/ \
137+
--ndk ~/android-ndk-r10e
138+
4. Run the test suite for the ``android-armv7`` target.
139+
140+
You may run the tests using the build script as well. Specifying a
141+
``--android-deploy-device-path`` pushes the built Android products to your
142+
device as part of the build:
143+
144+
$ utils/build-script \
145+
-R \ # Build in ReleaseAssert mode.
146+
-T \ # Run all tests.
147+
--android \ # Build for Android.
148+
--android-deploy-device-path /data/local/tmp \ # Temporary directory on the device where Android tests are run.
149+
--android-ndk ~/android-ndk-r10e \ # Path to an Android NDK.
150+
--android-ndk-version 21 \
151+
--android-icu-uc ~/libicu-android/armeabi-v7a/libicuuc.so \
152+
--android-icu-uc-include ~/libicu-android/armeabi-v7a/icu/source/common \
153+
--android-icu-i18n ~/libicu-android/armeabi-v7a/libicui18n.so \
154+
--android-icu-i18n-include ~/libicu-android/armeabi-v7a/icu/source/i18n/
155+
156+
You must run the Linux tests once in order to build the Android test suite.
157+
After that, you may run the above command with the ``--skip-test-linux`` option
158+
to only run Android tests.
159+
118160
Writing tests
119161
-------------
120162

test/1_stdlib/InputStream.swift.gyb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
// RUN: %S/../../utils/line-directive %t/InputStream.swift -- %target-run %t/a.out
1717
// REQUIRES: executable_test
1818

19+
// FIXME: This test takes too long to complete on Android.
20+
// UNSUPPORTED: OS=linux-androideabi
21+
1922
import StdlibUnittest
2023

2124

test/1_stdlib/POSIX.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// RUN: %target-run-simple-swift
22
// REQUIRES: executable_test
33

4+
// Android Bionic does not provide a working implementation of
5+
// <semaphore.h>.
6+
// XFAIL: OS=linux-androideabi
7+
48
import StdlibUnittest
59
#if os(Linux)
610
import Glibc

test/ClangModules/autolinking.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// UNSUPPORTED: OS=linux-gnu
1717
// UNSUPPORTED: OS=linux-gnueabihf
1818
// UNSUPPORTED: OS=freebsd
19+
// UNSUPPORTED: OS=linux-androideabi
1920

2021
import LinkMusket
2122
import LinkFramework

test/IRGen/c_layout.sil

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-swift-frontend -I %S/Inputs/abi %s -emit-ir | FileCheck %s --check-prefix=CHECK-%target-cpu
1+
// FIXME: Rather than passing `-fsigned-char`, this should test each platform's expected char
2+
// signedness. For Android, this means implicitly unsigned. See: https://github.com/apple/swift/pull/1103
3+
// RUN: %target-swift-frontend -Xcc -fsigned-char -I %S/Inputs/abi %s -emit-ir | FileCheck %s --check-prefix=CHECK-%target-cpu
24

35
sil_stage canonical
46
import c_layout

test/IRGen/report_dead_method_call.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// RUN: %target-run %t/a.out p1 p2 2> %t/err3.log; FileCheck %s < %t/err3.log
66
// REQUIRES: executable_test
77

8+
// This test correctly outputs "fatal error" on an Android device, but
9+
// the Android test runner interprets the abort as a test failure.
10+
// XFAIL: OS=linux-androideabi
811

912
// The -disable-access-control option let us "call" methods, which are removed
1013
// by dead method elimination.

test/Prototypes/FloatingPoint.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extension UInt32 : FloatingPointRepresentation {
2727
// Ewwww? <rdar://problem/20060017>
2828
#if os(OSX) || os(iOS) || os(watchOS) || os(tvOS)
2929
import Darwin
30-
#elseif os(Linux)
30+
#elseif os(Linux) || os(Android)
3131
import Glibc
3232
#endif
3333

test/Serialization/autolinking.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
// UNSUPPORTED: OS=linux-gnu
2626
// UNSUPPORTED: OS=linux-gnueabihf
2727
// UNSUPPORTED: OS=freebsd
28+
// UNSUPPORTED: OS=linux-androideabi
2829

2930
import someModule
3031

test/lit.cfg

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,65 @@ elif run_os == 'linux-gnu' or run_os == 'linux-gnueabihf' or run_os == 'freebsd'
733733
config.target_ld = (
734734
"ld -L%s" %
735735
(os.path.join(test_resource_dir, config.target_sdk_name)))
736+
elif run_os == 'linux-androideabi':
737+
# Android
738+
lit_config.note("Testing Android " + config.variant_triple)
739+
# FIXME: This value should be read off of config.android_ndk_path,
740+
# but I can't figure out how. The value is set via CMake, and the
741+
# build directory contains a test-android-armv7/lit.site.cfg with
742+
# its @SWIFT_ANDROID_NDK_PATH@ correctly replaced. So what's wrong?
743+
android_ndk_path = "/home/modocache/android-ndk-r10e"
744+
745+
config.target_object_format = "elf"
746+
config.target_runtime = "native"
747+
config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
748+
config.target_sdk_name = "android"
749+
android_linker_opt = "-L {libcxx} -L {libgcc}".format(
750+
libcxx=os.path.join(android_ndk_path,
751+
"sources", "cxx-stl", "llvm-libc++", "libs",
752+
"armeabi-v7a"),
753+
libgcc=os.path.join(android_ndk_path,
754+
"toolchains", "arm-linux-androideabi-4.8",
755+
"prebuilt", "linux-x86_64", "lib", "gcc",
756+
"arm-linux-androideabi", "4.8"))
757+
config.target_build_swift = (
758+
'%s -target %s -sdk %s %s -Xlinker -pie %s %s %s %s'
759+
% (config.swiftc, config.variant_triple, config.variant_sdk,
760+
android_linker_opt, resource_dir_opt, mcp_opt,
761+
config.swift_test_options, swift_execution_tests_extra_flags))
762+
config.target_swift_frontend = (
763+
'%s -frontend -target %s -sdk %s %s %s'
764+
% (config.swift, config.variant_triple, config.variant_sdk,
765+
android_linker_opt, resource_dir_opt))
766+
subst_target_swift_frontend_mock_sdk = config.target_swift_frontend
767+
subst_target_swift_frontend_mock_sdk_after = ""
768+
config.target_run = os.path.join(
769+
config.swift_src_root, 'utils', 'android', 'adb_test_runner.py')
770+
config.target_sil_opt = (
771+
'%s -target %s %s %s' %
772+
(config.sil_opt, config.variant_triple, resource_dir_opt, mcp_opt))
773+
config.target_swift_ide_test = (
774+
'%s -target %s %s %s %s' %
775+
(config.swift_ide_test, config.variant_triple, resource_dir_opt,
776+
mcp_opt, ccp_opt))
777+
subst_target_swift_ide_test_mock_sdk = config.target_swift_ide_test
778+
subst_target_swift_ide_test_mock_sdk_after = ""
779+
config.target_swiftc_driver = (
780+
"%s -target %s -sdk %s %s %s %s" %
781+
(config.swiftc, config.variant_triple, config.variant_sdk,
782+
android_linker_opt, resource_dir_opt, mcp_opt))
783+
config.target_swift_modulewrap = (
784+
'%s -modulewrap -target %s' %
785+
(config.swiftc, config.variant_triple))
786+
config.target_clang = (
787+
"clang++ -target %s %s" %
788+
(config.variant_triple, clang_mcp_opt))
789+
config.target_ld = (
790+
"ld -L%s" %
791+
(os.path.join(test_resource_dir, config.target_sdk_name)))
792+
# config.environment['ANDROID_NDK_HOME'] = os.getenv("ANDROID_NDK_HOME")
793+
# The Swift interpreter is not available when targeting Android.
794+
config.available_features.remove('swift_interpreter')
736795

737796
else:
738797
lit_config.fatal("Don't know how to define target_run and "

test/lit.site.cfg.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ config.variant_sdk = "@VARIANT_SDK@"
1818
config.variant_suffix = "@VARIANT_SUFFIX@"
1919
config.swiftlib_dir = "@LIT_SWIFTLIB_DIR@"
2020
config.darwin_xcrun_toolchain = "@SWIFT_DARWIN_XCRUN_TOOLCHAIN@"
21+
config.android_ndk_path = "@SWIFT_ANDROID_NDK_PATH@"
2122

2223
config.coverage_mode = "@SWIFT_ANALYZE_CODE_COVERAGE@"
2324

0 commit comments

Comments
 (0)