diff options
author | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-24 03:57:36 +0000 |
---|---|---|
committer | jrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-24 03:57:36 +0000 |
commit | 9713fa838364257affc9e863a4f842f044fa0c20 (patch) | |
tree | 9b80df03f33c22e2fae2eecc7051a7ac1ddffbad | |
parent | 27cc5a09bba00e877f8815d592d0ba955f62002b (diff) | |
download | chromium_src-9713fa838364257affc9e863a4f842f044fa0c20.zip chromium_src-9713fa838364257affc9e863a4f842f044fa0c20.tar.gz chromium_src-9713fa838364257affc9e863a4f842f044fa0c20.tar.bz2 |
apk-based test runner work. Not enabled yet. This CL is a combination of upstreaming, ndk/ant-ification, and other tweaks.
BUG=None
TEST=
Review URL: http://codereview.chromium.org/9834037
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128679 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | base/base.gyp | 3 | ||||
-rw-r--r-- | base/test/android/AndroidManifest.xml | 43 | ||||
-rw-r--r-- | base/test/android/OWNERS | 2 | ||||
-rw-r--r-- | base/test/android/java/org/chromium/ChromeNativeTestActivity.java | 47 | ||||
-rw-r--r-- | base/test/android/native_test.gyp | 40 | ||||
-rw-r--r-- | base/test/android/native_test_apk.xml | 37 | ||||
-rw-r--r-- | base/test/android/native_test_launcher.cc | 190 | ||||
-rw-r--r-- | build/all_android.gyp | 11 | ||||
-rwxr-xr-x | build/android/envsetup.sh | 7 | ||||
-rwxr-xr-x | build/android/run_tests.py | 3 | ||||
-rw-r--r-- | build/android/single_test_runner.py | 11 | ||||
-rw-r--r-- | build/android/test_package.py | 3 | ||||
-rw-r--r-- | build/android/test_package_apk.py | 89 | ||||
-rw-r--r-- | build/common.gypi | 11 | ||||
-rwxr-xr-x | build/install-build-deps-android.sh | 2 | ||||
-rw-r--r-- | ipc/ipc.gyp | 4 |
16 files changed, 489 insertions, 14 deletions
diff --git a/base/base.gyp b/base/base.gyp index 08461d7..ee44677 100644 --- a/base/base.gyp +++ b/base/base.gyp @@ -9,6 +9,7 @@ 'includes': [ '../build/win_precompile.gypi', 'base.gypi', + 'test/android/native_test.gyp' ], 'targets': [ { @@ -153,7 +154,7 @@ }, { 'target_name': 'base_unittests', - 'type': 'executable', + 'type': '<(gtest_target_type)', 'sources': [ # Tests. 'android/jni_android_unittest.cc', diff --git a/base/test/android/AndroidManifest.xml b/base/test/android/AndroidManifest.xml new file mode 100644 index 0000000..5e154a0 --- /dev/null +++ b/base/test/android/AndroidManifest.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.chromium.native_test" + android:versionCode="1" + android:versionName="1.0"> + + <!-- This is the platform API where NativeActivity was introduced. --> + <uses-sdk android:minSdkVersion="14" /> + + <application android:label="ChromeNativeTest"> + <activity android:name=".ChromeNativeTestActivity" + android:label="ChromeNativeTest" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> + + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> + <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> + <uses-permission android:name="android.permission.VIBRATE"/> + <uses-permission android:name="android.permission.GET_ACCOUNTS"/> + <uses-permission android:name="android.permission.USE_CREDENTIALS"/> + <uses-permission android:name="android.permission.READ_CONTACTS"/> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> + <uses-permission android:name="android.permission.READ_LOGS"/> + <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/> + <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"/> + <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_READ"/> + <uses-permission android:name="android.permission.SUBSCRIBED_FEEDS_WRITE" /> + <uses-permission android:name="android.permission.READ_SYNC_STATS"/> + <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/> + <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/> + <uses-permission android:name="android.permission.RECORD_AUDIO"/> + <uses-permission android:name="android.permission.WAKE_LOCK"/> + +</manifest> diff --git a/base/test/android/OWNERS b/base/test/android/OWNERS new file mode 100644 index 0000000..2581007 --- /dev/null +++ b/base/test/android/OWNERS @@ -0,0 +1,2 @@ +jrg@chromium.org +bulach@chromium.org diff --git a/base/test/android/java/org/chromium/ChromeNativeTestActivity.java b/base/test/android/java/org/chromium/ChromeNativeTestActivity.java new file mode 100644 index 0000000..a6290b9 --- /dev/null +++ b/base/test/android/java/org/chromium/ChromeNativeTestActivity.java @@ -0,0 +1,47 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.native_test; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + +// Android's NativeActivity is mostly useful for pure-native code. +// Our tests need to go up to our own java classes, which is not possible using +// the native activity class loader. +// We start a background thread in here to run the tests and avoid an ANR. +// TODO(bulach): watch out for tests that implicitly assume they run on the main +// thread. +public class ChromeNativeTestActivity extends Activity { + private final String TAG = "ChromeNativeTestActivity"; + private final String LIBRARY = "native_tests"; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + loadLibrary(); + new Thread() { + @Override + public void run() { + Log.d(TAG, ">>nativeRunTests"); + nativeRunTests(getFilesDir().getAbsolutePath()); + Log.d(TAG, "<<nativeRunTests"); + } + }.start(); + } catch (UnsatisfiedLinkError e) { + Log.e(TAG, "Unable to load libnative_tests.so: " + e); + throw e; + } + } + + private void loadLibrary() throws UnsatisfiedLinkError { + Log.i(TAG, "loading: " + LIBRARY); + System.loadLibrary(LIBRARY); + Log.i(TAG, "loaded: " + LIBRARY); + } + + private native void nativeRunTests(String filesDir); +} diff --git a/base/test/android/native_test.gyp b/base/test/android/native_test.gyp new file mode 100644 index 0000000..86d3728 --- /dev/null +++ b/base/test/android/native_test.gyp @@ -0,0 +1,40 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'conditions': [ + ['OS=="android"', { + 'targets': [ + { + 'target_name': 'native_test_apk', + 'message': 'building native test package', + 'type': 'none', + 'actions': [ + { + 'action_name': 'native_test_apk', + 'inputs': [ + '<(DEPTH)/base/test/android/native_test_apk.xml', + '<!@(find test/android/java -name "*.java")', + 'native_test_launcher.cc' + ], + 'outputs': [ + # Awkwardly, we build a Debug APK even when gyp is in + # Release mode. I don't think it matters (e.g. we're + # probably happy to not codesign) but naming should be + # fixed. + '<(PRODUCT_DIR)/ChromeNativeTests-debug.apk', + ], + 'action': [ + 'ant', + '-DPRODUCT_DIR=<(PRODUCT_DIR)', + '-buildfile', + '<(DEPTH)/base/test/android/native_test_apk.xml', + ] + } + ], + }, + ], + }] + ] +} diff --git a/base/test/android/native_test_apk.xml b/base/test/android/native_test_apk.xml new file mode 100644 index 0000000..6f39430 --- /dev/null +++ b/base/test/android/native_test_apk.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="ChromeNativeTests" default="debug" basedir="."> + + <description> + Building native test runner ChromeNativeTests.apk + </description> + + <property environment="env"/> + <property name="sdk.dir" location="${env.ANDROID_SDK_ROOT}"/> + <property name="source.dir" location="java"/> + <property name="target" value="android-14"/> + + <!-- We expect PRODUCT_DIR to be set like the gyp var + (e.g. $ROOT/out/Debug) --> + <!-- TODO(jrg): ideally we need this to run before -build-setup, where + directories are made based on this variable. --> + <target name="-pre-build"> + <if> + <condition> + <isset property="PRODUCT_DIR" /> + </condition> + <else> + <fail message="PRODUCT_DIR env var not set?" /> + </else> + </if> + </target> + + <property name="out.dir" location="${PRODUCT_DIR}"/> + + <!-- TODO(jrg): should I make these directories specific to the apk? --> + <property name="resource.absolute.dir" value="${out.dir}/res"/> + <property name="gen.absolute.dir" value="${out.dir}/gen"/> + <property name="jar.libs.dir" value="${out.dir}/java/libs"/> + + <import file="${sdk.dir}/tools/ant/build.xml" /> + +</project> diff --git a/base/test/android/native_test_launcher.cc b/base/test/android/native_test_launcher.cc new file mode 100644 index 0000000..ae702a2 --- /dev/null +++ b/base/test/android/native_test_launcher.cc @@ -0,0 +1,190 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <stdio.h> + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/path_utils.h" +#include "base/at_exit.h" +#include "base/command_line.h" +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/logging.h" +#include "base/stringprintf.h" +#include "base/string_tokenizer.h" +#include "base/string_util.h" +#include "base/test/test_suite.h" +#include "jni/chrome_native_test_activity_jni.h" +#include "gtest/gtest.h" + +// GTest's main function. +extern int main(int argc, char** argv); + +namespace { + +void ParseArgsFromString(const std::string& command_line, + std::vector<std::string>* args) { + StringTokenizer tokenizer(command_line, kWhitespaceASCII); + tokenizer.set_quote_chars("\""); + while (tokenizer.GetNext()) { + std::string token; + RemoveChars(tokenizer.token(), "\"", &token); + args->push_back(token); + } +} + +void ParseArgsFromCommandLineFile(const FilePath& internal_data_path, + std::vector<std::string>* args) { + static const char kCommandLineFile[] = "chrome-native-tests-command-line"; + FilePath command_line(internal_data_path.Append(FilePath(kCommandLineFile))); + std::string command_line_string; + if (file_util::ReadFileToString(command_line, &command_line_string)) { + ParseArgsFromString(command_line_string, args); + } +} + +void ArgsToArgv(const std::vector<std::string>& args, + std::vector<char*>* argv) { + // We need to pass in a non-const char**. + int argc = args.size(); + argv->resize(argc); + for (int i = 0; i < argc; ++i) + (*argv)[i] = const_cast<char*>(args[i].c_str()); +} + +// As we are the native side of an Android app, we don't have any 'console', so +// gtest's standard output goes nowhere. +// Instead, we inject an "EventListener" in gtest and then we print the results +// using LOG, which goes to adb logcat. +class AndroidLogPrinter : public ::testing::EmptyTestEventListener { + public: + void Init(int* argc, char** argv); + + // EmptyTestEventListener + virtual void OnTestProgramStart( + const ::testing::UnitTest& unit_test) OVERRIDE; + virtual void OnTestStart(const ::testing::TestInfo& test_info) OVERRIDE; + virtual void OnTestPartResult( + const ::testing::TestPartResult& test_part_result) OVERRIDE; + virtual void OnTestEnd(const ::testing::TestInfo& test_info) OVERRIDE; + virtual void OnTestProgramEnd(const ::testing::UnitTest& unit_test) OVERRIDE; +}; + +void AndroidLogPrinter::Init(int* argc, char** argv) { + // InitGoogleTest must be called befure we add ourselves as a listener. + ::testing::InitGoogleTest(argc, argv); + ::testing::TestEventListeners& listeners = + ::testing::UnitTest::GetInstance()->listeners(); + // Adds a listener to the end. Google Test takes the ownership. + listeners.Append(this); +} + +void AndroidLogPrinter::OnTestProgramStart( + const ::testing::UnitTest& unit_test) { + std::string msg = StringPrintf("[ START ] %d", + unit_test.test_to_run_count()); + LOG(ERROR) << msg; +} + +void AndroidLogPrinter::OnTestStart(const ::testing::TestInfo& test_info) { + std::string msg = StringPrintf("[ RUN ] %s.%s", + test_info.test_case_name(), test_info.name()); + LOG(ERROR) << msg; +} + +void AndroidLogPrinter::OnTestPartResult( + const ::testing::TestPartResult& test_part_result) { + std::string msg = StringPrintf( + "%s in %s:%d\n%s\n", + test_part_result.failed() ? "*** Failure" : "Success", + test_part_result.file_name(), + test_part_result.line_number(), + test_part_result.summary()); + LOG(ERROR) << msg; +} + +void AndroidLogPrinter::OnTestEnd(const ::testing::TestInfo& test_info) { + std::string msg = StringPrintf("%s %s.%s", + test_info.result()->Failed() ? "[ FAILED ]" : "[ OK ]", + test_info.test_case_name(), test_info.name()); + LOG(ERROR) << msg; +} + +void AndroidLogPrinter::OnTestProgramEnd( + const ::testing::UnitTest& unit_test) { + std::string msg = StringPrintf("[ END ] %d", + unit_test.successful_test_count()); + LOG(ERROR) << msg; +} + +void LibraryLoadedOnMainThread(JNIEnv* env) { + static const char* const kInitialArgv[] = { "ChromeTestActivity" }; + + { + // We need a test suite to be created before we do any tracing or + // logging: it creates a global at_exit_manager and initializes + // internal gtest data structures based on the command line. + // It needs to be scoped as it also resets the CommandLine. + std::vector<std::string> args; + FilePath path("/data/user/0/org.chromium.native_tests/files/"); + ParseArgsFromCommandLineFile(path, &args); + std::vector<char*> argv; + ArgsToArgv(args, &argv); + base::TestSuite test_suite(argv.size(), &argv[0]); + } + + CommandLine::Init(arraysize(kInitialArgv), kInitialArgv); + + logging::InitLogging(NULL, + logging::LOG_ONLY_TO_SYSTEM_DEBUG_LOG, + logging::DONT_LOCK_LOG_FILE, + logging::DELETE_OLD_LOG_FILE, + logging::ENABLE_DCHECK_FOR_NON_OFFICIAL_RELEASE_BUILDS); + // To view log output with IDs and timestamps use "adb logcat -v threadtime". + logging::SetLogItems(false, // Process ID + false, // Thread ID + false, // Timestamp + false); // Tick count + VLOG(0) << "Chromium logging enabled: level = " << logging::GetMinLogLevel() + << ", default verbosity = " << logging::GetVlogVerbosity(); + base::android::RegisterPathUtils(env); +} + +} // namespace + +// This method is called on a separate java thread so that we won't trigger +// an ANR. +static void RunTests(JNIEnv* env, jobject obj, jstring jfiles_dir) { + FilePath files_dir(base::android::ConvertJavaStringToUTF8(env, jfiles_dir)); + // A few options, such "--gtest_list_tests", will just use printf directly + // and won't use the "AndroidLogPrinter". Redirect stdout to a known file. + FilePath stdout_path(files_dir.Append(FilePath("stdout.txt"))); + freopen(stdout_path.value().c_str(), "w", stdout); + + std::vector<std::string> args; + ParseArgsFromCommandLineFile(files_dir, &args); + + // We need to pass in a non-const char**. + std::vector<char*> argv; + ArgsToArgv(args, &argv); + + int argc = argv.size(); + // This object is owned by gtest. + AndroidLogPrinter* log = new AndroidLogPrinter(); + log->Init(&argc, &argv[0]); + + main(argc, &argv[0]); +} + +// This is called by the VM when the shared library is first loaded. +JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { + base::android::InitVM(vm); + JNIEnv* env = base::android::AttachCurrentThread(); + if (!RegisterNativesImpl(env)) { + return -1; + } + LibraryLoadedOnMainThread(env); + return JNI_VERSION_1_4; +} diff --git a/build/all_android.gyp b/build/all_android.gyp index bcfd435..3abca0c 100644 --- a/build/all_android.gyp +++ b/build/all_android.gyp @@ -35,12 +35,19 @@ '../ipc/ipc.gyp:ipc_tests', '../net/net.gyp:net_unittests', '../third_party/WebKit/Source/WebKit/chromium/All.gyp:*', - # From here down: not added to run_tests.py yet. - '../jingle/jingle.gyp:jingle_unittests', '../tools/android/fake_dns/fake_dns.gyp:fake_dns', '../tools/android/forwarder/forwarder.gyp:forwarder', + # From here down: not added to run_tests.py yet. + '../jingle/jingle.gyp:jingle_unittests', '../media/media.gyp:media_unittests', ], + # The Native Test Runner is not on by default. + 'conditions': [ + ['gtest_target_type=="shared_library"', { + 'dependencies': [ + '../base/base.gyp:native_test_apk', + ] + }]], }, { # Experimental / in-progress targets that are expected to fail diff --git a/build/android/envsetup.sh b/build/android/envsetup.sh index 6c4c563..bfb2143 100755 --- a/build/android/envsetup.sh +++ b/build/android/envsetup.sh @@ -49,8 +49,11 @@ export ANDROID_TOOLCHAIN="${ANDROID_NDK_ROOT}/toolchains/arm-linux-androideabi-4 export ANDROID_SDK_VERSION="15" -# Add Android SDK's platform-tools to system path. -export PATH="${PATH}:${ANDROID_SDK_ROOT}/platform-tools/" +# Add Android SDK/NDK tools to system path. +export PATH=$PATH:${ANDROID_NDK_ROOT} +export PATH=$PATH:${ANDROID_SDK_ROOT}/tools +export PATH=$PATH:${ANDROID_SDK_ROOT}/platform-tools + if [ ! -d "${ANDROID_TOOLCHAIN}" ]; then echo "Can not find Android toolchain in ${ANDROID_TOOLCHAIN}." >& 2 diff --git a/build/android/run_tests.py b/build/android/run_tests.py index dc1ec7e..cbe408d 100755 --- a/build/android/run_tests.py +++ b/build/android/run_tests.py @@ -167,7 +167,8 @@ def RunTests(device, test_suite, gtest_filter, test_arguments, rebaseline, if test_suite: global _TEST_SUITES - if not os.path.exists(test_suite): + if (not os.path.exists(test_suite) and + not os.path.splitext(test_suite)[1] == '.apk'): logging.critical('Unrecognized test suite %s, supported: %s' % (test_suite, _TEST_SUITES)) if test_suite in _TEST_SUITES: diff --git a/build/android/single_test_runner.py b/build/android/single_test_runner.py index ef9971a..4a93813 100644 --- a/build/android/single_test_runner.py +++ b/build/android/single_test_runner.py @@ -9,6 +9,7 @@ import sys from base_test_runner import BaseTestRunner import debug_info import run_tests_helper +from test_package_apk import TestPackageApk from test_package_executable import TestPackageExecutable from test_result import TestResults @@ -46,7 +47,15 @@ class SingleTestRunner(BaseTestRunner): self.dump_debug_info = None self.fast_and_loose = fast_and_loose - self.test_package = TestPackageExecutable(self.adb, device, + if os.path.splitext(test_suite)[1] == '.apk': + self.test_package = TestPackageApk(self.adb, device, + test_suite, timeout, rebaseline, performance_test, cleanup_test_files, + tool, self.dump_debug_info) + else: + android_product_out = '.' # os.environ['ANDROID_PRODUCT_OUT'] + symbols_dir = os.path.join(android_product_out, 'symbols', 'data', + 'local') + self.test_package = TestPackageExecutable(self.adb, device, test_suite, timeout, rebaseline, performance_test, cleanup_test_files, tool, self.dump_debug_info) diff --git a/build/android/test_package.py b/build/android/test_package.py index 16b834c..fae869f 100644 --- a/build/android/test_package.py +++ b/build/android/test_package.py @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -35,6 +35,7 @@ class TestPackage(object): performance_test, cleanup_test_files, tool, dump_debug_info): self.adb = adb self.device = device + self.test_suite_full = test_suite self.test_suite = os.path.splitext(test_suite)[0] self.test_suite_basename = os.path.basename(self.test_suite) self.test_suite_dirname = os.path.dirname(self.test_suite) diff --git a/build/android/test_package_apk.py b/build/android/test_package_apk.py new file mode 100644 index 0000000..08e954c --- /dev/null +++ b/build/android/test_package_apk.py @@ -0,0 +1,89 @@ +#!/usr/bin/python +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +import os +import sys + +import cmd_helper +import shutil +import tempfile +from test_package import TestPackage + + +class TestPackageApk(TestPackage): + """A helper class for running APK-based native tests. + + Args: + adb: ADB interface the tests are using. + device: Device to run the tests. + test_suite: A specific test suite to run, empty to run all. + timeout: Timeout for each test. + rebaseline: Whether or not to run tests in isolation and update the filter. + performance_test: Whether or not performance test(s). + cleanup_test_files: Whether or not to cleanup test files on device. + tool: Name of the Valgrind tool. + dump_debug_info: A debug_info object. + """ + + APK_DATA_DIR = '/data/user/0/com.android.chrome.native_tests/files/' + + def __init__(self, adb, device, test_suite, timeout, rebaseline, + performance_test, cleanup_test_files, tool, + dump_debug_info): + TestPackage.__init__(self, adb, device, test_suite, timeout, + rebaseline, performance_test, cleanup_test_files, + tool, dump_debug_info) + + def _CreateTestRunnerScript(self, options): + tool_wrapper = self.tool.GetTestWrapper() + if tool_wrapper: + raise RuntimeError("TestPackageApk does not support custom wrappers.") + command_line_file = tempfile.NamedTemporaryFile() + # GTest expects argv[0] to be the executable path. + command_line_file.write(self.test_suite_basename + ' ' + options) + command_line_file.flush() + self.adb.PushIfNeeded(command_line_file.name, + TestPackageApk.APK_DATA_DIR + + 'chrome-native-tests-command-line') + + def _GetGTestReturnCode(self): + return None + + def GetAllTests(self): + """Returns a list of all tests available in the test suite.""" + self._CreateTestRunnerScript('--gtest_list_tests') + self.adb.RunShellCommand( + 'am start -n ' + 'com.android.chrome.native_tests/' + 'android.app.NativeActivity') + stdout_file = tempfile.NamedTemporaryFile() + ret = [] + self.adb.Adb().Pull(TestPackageApk.APK_DATA_DIR + 'stdout.txt', + stdout_file.name) + ret = self._ParseGTestListTests(stdout_file) + return ret + + def CreateTestRunnerScript(self, gtest_filter, test_arguments): + self._CreateTestRunnerScript('--gtest_filter=%s %s' % (gtest_filter, + test_arguments)) + + def RunTestsAndListResults(self): + self.adb.StartMonitoringLogcat(clear=True, logfile=sys.stdout) + # TODO(jrg): make the activity name a function of the test. + self.adb.RunShellCommand( + 'am start -n ' + 'org.chromium.native_test/' + 'org.chromium.native_test.ChromeNativeTestActivity') + return self._WatchTestOutput(self.adb.GetMonitoredLogCat()) + + def StripAndCopyExecutable(self): + # TODO(jrg): downstream we would package up the .so into the apk + # and rebuild. (Yikes!) We need to do something more kosher, + # such as assembly at build time. E.g. building base_unittests + # will build a libbase_unittests.apk that contains + # libbbase_unittests.so, and avoid a "naked" ChromeNativeTests.apk. + self.adb.Adb().SendCommand('install -r ' + self.test_suite_full, + timeout_time=60*5) diff --git a/build/common.gypi b/build/common.gypi index c90d15b..f3f908a 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -789,9 +789,9 @@ 'notifications%': 0, # Builds the gtest targets as a shared_library. - # TODO(michaelbai): Use the fixed value 'shared_library' once it - # is fully supported. - 'gtest_target_type%': '<(gtest_target_type)', + # TODO(jrg): when 'gtest_target_type'=='shared_libary' and OS==android, + # make all gtest_targets depend on base/base.gyp:native_test_apk. + ### 'gtest_target_type': 'shared_libary', # Uses system APIs for decoding audio and video. 'use_libffmpeg%': '0', @@ -2356,6 +2356,11 @@ 'ldflags': [ '-Wl,-shared,-Bsymbolic', ], + # Use of -nostdlib prevents the compiler from bringing + # in crtbegin_dynamic.o et al, so we get an undefined + # reference to ___dso_handle when building + # gtest_target_type==shared_library. + 'ldflags!': [ '-nostdlib' ], }], ], }], diff --git a/build/install-build-deps-android.sh b/build/install-build-deps-android.sh index 5277a3b..6efaed5 100755 --- a/build/install-build-deps-android.sh +++ b/build/install-build-deps-android.sh @@ -71,6 +71,6 @@ then fi # Install ant -sudo apt-get install ant +sudo apt-get install ant1.8 echo "install-build-deps-android.sh complete." diff --git a/ipc/ipc.gyp b/ipc/ipc.gyp index 9b38f77..8172860 100644 --- a/ipc/ipc.gyp +++ b/ipc/ipc.gyp @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. @@ -32,7 +32,7 @@ 'targets': [ { 'target_name': 'ipc_tests', - 'type': 'executable', + 'type': '<(gtest_target_type)', 'dependencies': [ 'ipc', '../base/base.gyp:base', |