From aec496f48e2c523423cb0b6bf7c7a394a80a8699 Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Tue, 17 Feb 2015 11:46:43 -0800 Subject: [PATCH] Add NDK tests. Bug: 19149083 Change-Id: I2222ee6230ed11e09ee00553e21855290b662da0 --- lit.site.cfg | 42 +++++++++++++++++++++ ndk-test.sh | 19 ++++++++++ test/libcxx/android/test/format.py | 13 +++++-- test/libcxx/ndk/__init__.py | 0 test/libcxx/ndk/test/__init__.py | 0 test/libcxx/ndk/test/config.py | 59 ++++++++++++++++++++++++++++++ 6 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 lit.site.cfg create mode 100755 ndk-test.sh create mode 100644 test/libcxx/ndk/__init__.py create mode 100644 test/libcxx/ndk/test/__init__.py create mode 100644 test/libcxx/ndk/test/config.py diff --git a/lit.site.cfg b/lit.site.cfg new file mode 100644 index 000000000..efc75d01f --- /dev/null +++ b/lit.site.cfg @@ -0,0 +1,42 @@ +import os +import sys + +# Tell pylint that we know config and lit_config exist somewhere. +if 'PYLINT_IMPORT' in os.environ: + config = object() + lit_config = object() + +ndk = os.getenv('NDK') +if ndk is None: + sys.exit('The environment variable NDK must point to an NDK toolchain.') + +top = os.getenv('ANDROID_BUILD_TOP') +out_dir = os.getenv('ANDROID_PRODUCT_OUT') + +if top is None or out_dir is None: + sys.exit('ANDROID_BUILD_TOP or ANDROID_PRODUCT_OUT is not set. Have you ' + 'run lunch?') + +config.cxx_under_test = os.path.join( + top, "prebuilts/clang/linux-x86/host/3.6/bin/clang++") +config.std = "c++11" +config.libcxx_src_root = os.path.join(top, "external/libcxx") +config.libcxx_obj_root = os.path.join(top, "external/libcxx") +config.cxx_library_root = os.path.join(out_dir, 'system/lib') +config.enable_exceptions = "True" +config.enable_rtti = "True" +config.enable_shared = "False" +config.enable_32bit = "False" +config.enable_threads = "True" +config.enable_monotonic_clock = "True" +config.cxx_abi = "libcxxabi" +config.use_sanitizer = "" +config.configuration_variant = "libcxx.ndk" +config.target_triple = "armv7a-linux-androideabi" +config.sysroot = os.path.join(ndk, "platforms/android-21/arch-arm/") +config.gcc_toolchain = os.path.join( + top, "prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9") + +# Let the main config do the real work. +lit_config.load_config( + config, os.path.join(top, "external/libcxx/test/lit.cfg")) diff --git a/ndk-test.sh b/ndk-test.sh new file mode 100755 index 000000000..b98b22d88 --- /dev/null +++ b/ndk-test.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# This file should reside in test/, but it seems that if there is already one +# lit.site.cfg in the test/ directory it is impossible to tell LIT to use +# another. This will need to be fixed upstream before this can get a proper +# home. The downside of this is that there isn't a way to run a subset of the +# libc++ tests against the NDK. +if [ -z "$ANDROID_PRODUCT_OUT" ]; then + >&2 echo "Error: ANDROID_PRODUCT_OUT is not set. Have you run lunch?" + exit 1 +fi + +if [ ! -f $ANDROID_PRODUCT_OUT/system/lib/libc++_ndk.so ]; then + >&2 echo "Error: libc++_ndk.so has not been built for this target." + exit 1 +fi + +adb push $ANDROID_PRODUCT_OUT/system/lib/libc++_ndk.so /data/local/tmp +lit -sv $* . diff --git a/test/libcxx/android/test/format.py b/test/libcxx/android/test/format.py index 7fae5e101..9b56ba7ee 100644 --- a/test/libcxx/android/test/format.py +++ b/test/libcxx/android/test/format.py @@ -57,7 +57,8 @@ class HostTestFormat(libcxx.test.format.LibcxxTestFormat): class TestFormat(HostTestFormat): def __init__(self, cxx_under_test, libcxx_src_root, libcxx_obj_root, - cxx_template, link_template, device_dir, timeout): + cxx_template, link_template, device_dir, timeout, + exec_env=None): HostTestFormat.__init__( self, cxx_under_test, @@ -67,6 +68,7 @@ class TestFormat(HostTestFormat): link_template, timeout) self.device_dir = device_dir + self.exec_env = {} if exec_env is None else exec_env def _working_directory(self, file_name): return os.path.join(self.device_dir, file_name) @@ -111,9 +113,12 @@ class TestFormat(HostTestFormat): def _run(self, exec_path, lit_config, in_dir=None): exec_file = os.path.basename(exec_path) - shell_cmd = 'cd {} && {}; echo $?'.format( - self._working_directory(exec_file), - self._wd_path(exec_file, exec_file)) + env_string = ' '.join(['='.join([k, v]) for k, v in + self.exec_env.items()]) + shell_cmd = 'cd {work_dir} && {env_string} {cmd}; echo $?'.format( + work_dir=self._working_directory(exec_file), + env_string=env_string, + cmd=self._wd_path(exec_file, exec_file)) cmd = ['timeout', self.timeout, 'adb', 'shell', shell_cmd] # Tests will commonly fail with ETXTBSY. Possibly related to this bug: diff --git a/test/libcxx/ndk/__init__.py b/test/libcxx/ndk/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/libcxx/ndk/test/__init__.py b/test/libcxx/ndk/test/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/test/libcxx/ndk/test/config.py b/test/libcxx/ndk/test/config.py new file mode 100644 index 000000000..85ccd8492 --- /dev/null +++ b/test/libcxx/ndk/test/config.py @@ -0,0 +1,59 @@ +import os + +import libcxx.test.config +import libcxx.android.build +import libcxx.android.test.format + + +class Configuration(libcxx.test.config.Configuration): + def __init__(self, lit_config, config): + super(Configuration, self).__init__(lit_config, config) + self.cxx_under_test = None + self.build_cmds_dir = None + self.cxx_template = None + self.link_template = None + + def configure(self): + self.configure_cxx() + self.configure_triple() + self.configure_src_root() + self.configure_obj_root() + self.configure_cxx_library_root() + self.configure_compile_flags() + self.configure_link_flags() + self.configure_features() + + def configure_link_flags(self): + self.link_flags.append('-nodefaultlibs') + + # Configure libc++ library paths. + self.link_flags.append('-L' + self.cxx_library_root) + + # Add libc_ndk's output path to the library search paths. + libdir = '{}/obj/STATIC_LIBRARIES/libc_ndk_intermediates'.format( + os.getenv('ANDROID_PRODUCT_OUT')) + self.link_flags.append('-L' + libdir) + + self.link_flags.append('-lc++_ndk') + self.link_flags.append('-lc_ndk') + self.link_flags.append('-lc') + + def configure_features(self): + self.config.available_features.add('long_tests') + + def get_test_format(self): + cxx_template = ' '.join( + self.compile_flags + ['-c', '-o', '%OUT%', '%SOURCE%']) + link_template = ' '.join( + ['-o', '%OUT%', '%SOURCE%'] + self.compile_flags + self.link_flags) + tmp_dir = getattr(self.config, 'device_dir', '/data/local/tmp/') + + return libcxx.android.test.format.TestFormat( + self.cxx, + self.libcxx_src_root, + self.obj_root, + cxx_template, + link_template, + tmp_dir, + getattr(self.config, 'timeout', '300'), + exec_env={'LD_LIBRARY_PATH': tmp_dir})