Commit 6cdb6927 authored by jbudorick's avatar jbudorick Committed by Commit bot

Revert of [Android] Refactor the native test wrappers. (patchset #7 id:120001...

Revert of [Android] Refactor the native test wrappers. (patchset #7 id:120001 of https://codereview.chromium.org/1126543009/)

Reason for revert:
broke http://build.chromium.org/p/chromium.mojo/builders/Chromium%20Mojo%20Android

e.g. http://build.chromium.org/p/chromium.mojo/builders/Chromium%20Mojo%20Android/builds/1922

Original issue's description:
> [Android] Refactor the native test wrappers.
>
> BUG=476410
>
> Committed: https://crrev.com/581d25e509e4a2b1e8927c6d8accc0c90ea86090
> Cr-Commit-Position: refs/heads/master@{#330531}

TBR=jochen@chromium.org,cjhopman@chromium.org,jaekyun@chromium.org,perezju@chromium.org,tedchoc@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=476410

Review URL: https://codereview.chromium.org/1138993009

Cr-Commit-Position: refs/heads/master@{#330591}
parent 08051efe
......@@ -102,7 +102,7 @@ PACKAGE_INFO = {
'org.chromium.android_webview.test'),
'gtest': PackageInfo(
'org.chromium.native_test',
'org.chromium.native_test.NativeUnitTestActivity',
'org.chromium.native_test.NativeTestActivity',
'/data/local/tmp/chrome-native-tests-command-line',
None,
None),
......@@ -110,13 +110,13 @@ PACKAGE_INFO = {
'org.chromium.components_browsertests_apk',
('org.chromium.components_browsertests_apk' +
'.ComponentsBrowserTestsActivity'),
'/data/local/tmp/chrome-native-tests-command-line',
'/data/local/tmp/components-browser-tests-command-line',
None,
None),
'content_browsertests': PackageInfo(
'org.chromium.content_browsertests_apk',
'org.chromium.content_browsertests_apk.ContentBrowserTestsActivity',
'/data/local/tmp/chrome-native-tests-command-line',
'/data/local/tmp/content-browser-tests-command-line',
None,
None),
'chromedriver_webview_shell': PackageInfo(
......
......@@ -17,12 +17,6 @@ sys.path.append(os.path.join(
import unittest_util
BROWSER_TEST_SUITES = [
'components_browsertests',
'content_browsertests',
]
# Used for filtering large data deps at a finer grain than what's allowed in
# isolate files since pushing deps to devices is expensive.
# Wildcards are allowed.
......@@ -98,9 +92,16 @@ class GtestTestInstance(test_instance.TestInstance):
raise ValueError('Platform mode currently supports only 1 gtest suite')
self._suite = args.suite_name[0]
self._apk_path = os.path.join(
constants.GetOutDirectory(), '%s_apk' % self._suite,
'%s-debug.apk' % self._suite)
if (self._suite == 'content_browsertests' or
self._suite == 'components_browsertests'):
error_func('%s are not currently supported '
'in platform mode.' % self._suite)
self._apk_path = os.path.join(
constants.GetOutDirectory(), 'apks', '%s.apk' % self._suite)
else:
self._apk_path = os.path.join(
constants.GetOutDirectory(), '%s_apk' % self._suite,
'%s-debug.apk' % self._suite)
self._exe_path = os.path.join(constants.GetOutDirectory(),
self._suite)
if not os.path.exists(self._apk_path):
......
......@@ -24,9 +24,6 @@ _EXTRA_COMMAND_LINE_FILE = (
'org.chromium.native_test.NativeTestActivity.CommandLineFile')
_EXTRA_COMMAND_LINE_FLAGS = (
'org.chromium.native_test.NativeTestActivity.CommandLineFlags')
_EXTRA_NATIVE_TEST_ACTIVITY = (
'org.chromium.native_test.NativeTestInstrumentationTestRunner'
'.NativeTestActivity')
_MAX_SHARD_SIZE = 256
......@@ -40,11 +37,8 @@ _SUITE_REQUIRES_TEST_SERVER_SPAWNER = [
class _ApkDelegate(object):
def __init__(self, apk):
self._apk = apk
helper = apk_helper.ApkHelper(self._apk)
self._activity = helper.GetActivityName()
self._package = helper.GetPackageName()
self._runner = helper.GetInstrumentationName()
self._package = apk_helper.GetPackageName(self._apk)
self._runner = apk_helper.GetInstrumentationName(self._apk)
self._component = '%s/%s' % (self._package, self._runner)
self._enable_test_server_spawner = False
......@@ -57,7 +51,6 @@ class _ApkDelegate(object):
extras = {
_EXTRA_COMMAND_LINE_FILE: command_line_file.name,
_EXTRA_NATIVE_TEST_ACTIVITY: self._activity,
}
return device.StartInstrumentation(
......@@ -139,7 +132,7 @@ class LocalDeviceGtestRun(local_device_test_run.LocalDeviceTestRun):
#override
def TestPackage(self):
return self._test_instance.suite
return self._test_instance._suite
#override
def SetUp(self):
......@@ -173,16 +166,13 @@ class LocalDeviceGtestRun(local_device_test_run.LocalDeviceTestRun):
#override
def _CreateShards(self, tests):
if self._test_instance.suite in gtest_test_instance.BROWSER_TEST_SUITES:
return tests
else:
device_count = len(self._env.devices)
shards = []
for i in xrange(0, device_count):
unbounded_shard = tests[i::device_count]
shards += [unbounded_shard[j:j+_MAX_SHARD_SIZE]
for j in xrange(0, len(unbounded_shard), _MAX_SHARD_SIZE)]
return [':'.join(s) for s in shards]
device_count = len(self._env.devices)
shards = []
for i in xrange(0, device_count):
unbounded_shard = tests[i::device_count]
shards += [unbounded_shard[j:j+_MAX_SHARD_SIZE]
for j in xrange(0, len(unbounded_shard), _MAX_SHARD_SIZE)]
return [':'.join(s) for s in shards]
#override
def _GetTests(self):
......@@ -195,8 +185,8 @@ class LocalDeviceGtestRun(local_device_test_run.LocalDeviceTestRun):
#override
def _RunTest(self, device, test):
# Run the test.
output = self._delegate.RunWithFlags(
device, '--gtest_filter=%s' % test, timeout=900, retries=0)
output = self._delegate.RunWithFlags(device, '--gtest_filter=%s' % test,
timeout=900, retries=0)
for s in self._servers[str(device)]:
s.Reset()
self._delegate.Clear(device)
......
......@@ -15,7 +15,6 @@ from pylib.base import base_setup
from pylib.base import base_test_result
from pylib.base import test_dispatcher
from pylib.device import device_utils
from pylib.gtest import gtest_test_instance
from pylib.gtest import test_package_apk
from pylib.gtest import test_package_exe
from pylib.gtest import test_runner
......@@ -241,7 +240,8 @@ def Setup(test_options, devices):
tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter)
# Coalesce unit tests into a single test per device
if test_options.suite_name not in gtest_test_instance.BROWSER_TEST_SUITES:
if (test_options.suite_name != 'content_browsertests' and
test_options.suite_name != 'components_browsertests'):
num_devices = len(devices)
tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)]
tests = [t for t in tests if t]
......
......@@ -30,14 +30,18 @@ class TestPackageApk(TestPackage):
suite_name: Name of the test suite (e.g. base_unittests).
"""
TestPackage.__init__(self, suite_name)
self.suite_path = os.path.join(
constants.GetOutDirectory(), '%s_apk' % suite_name,
'%s-debug.apk' % suite_name)
if suite_name == 'content_browsertests':
self.suite_path = os.path.join(
constants.GetOutDirectory(), 'apks', '%s.apk' % suite_name)
self._package_info = constants.PACKAGE_INFO['content_browsertests']
elif suite_name == 'components_browsertests':
self.suite_path = os.path.join(
constants.GetOutDirectory(), 'apks', '%s.apk' % suite_name)
self._package_info = constants.PACKAGE_INFO['components_browsertests']
else:
self.suite_path = os.path.join(
constants.GetOutDirectory(), '%s_apk' % suite_name,
'%s-debug.apk' % suite_name)
self._package_info = constants.PACKAGE_INFO['gtest']
def _CreateCommandLineFileOnDevice(self, device, options):
......
......@@ -11,7 +11,6 @@ from pylib import ports
from pylib.base import base_test_result
from pylib.base import base_test_runner
from pylib.device import device_errors
from pylib.gtest import gtest_test_instance
from pylib.local import local_test_server_spawner
from pylib.perf import perf_control
......
......@@ -201,9 +201,8 @@ class InstrumentationTestInstance(test_instance.TestInstance):
if not os.path.exists(self._test_jar):
error_func('Unable to find test JAR: %s' % self._test_jar)
apk = apk_helper.ApkHelper(self.test_apk)
self._test_package = apk.GetPackageName()
self._test_runner = apk.GetInstrumentationName()
self._test_package = apk_helper.GetPackageName(self.test_apk)
self._test_runner = apk_helper.GetInstrumentationName(self.test_apk)
self._package_info = None
for package_info in constants.PACKAGE_INFO.itervalues():
......@@ -275,9 +274,10 @@ class InstrumentationTestInstance(test_instance.TestInstance):
constants.GetOutDirectory(), constants.SDK_BUILD_APKS_DIR,
'OnDeviceInstrumentationDriver.apk')
if os.path.exists(self._driver_apk):
driver_apk = apk_helper.ApkHelper(self._driver_apk)
self._driver_package = driver_apk.GetPackageName()
self._driver_name = driver_apk.GetInstrumentationName()
self._driver_package = apk_helper.GetPackageName(
self._driver_apk)
self._driver_name = apk_helper.GetInstrumentationName(
self._driver_apk)
else:
self._driver_apk = None
......
......@@ -19,14 +19,14 @@ _MANIFEST_ELEMENT_RE = re.compile(r'\s*(?:E|N): (\S*) .*$')
def GetPackageName(apk_path):
"""Returns the package name of the apk."""
return ApkHelper(apk_path).GetPackageName()
# TODO(jbudorick): Deprecate and remove this function once callers have been
# converted to ApkHelper.GetInstrumentationName
def GetInstrumentationName(apk_path):
"""Returns the name of the Instrumentation in the apk."""
return ApkHelper(apk_path).GetInstrumentationName()
aapt_cmd = [_AAPT_PATH, 'dump', 'badging', apk_path]
aapt_output = cmd_helper.GetCmdOutput(aapt_cmd).split('\n')
package_name_re = re.compile(r'package: .*name=\'(\S*)\'')
for line in aapt_output:
m = package_name_re.match(line)
if m:
return m.group(1)
raise Exception('Failed to determine package name of %s' % apk_path)
def _ParseManifestFromApk(apk_path):
......@@ -65,53 +65,12 @@ def _ParseManifestFromApk(apk_path):
return parsed_manifest
class ApkHelper(object):
def __init__(self, apk_path):
self._apk_path = apk_path
self._manifest = None
self._package_name = None
def GetActivityName(self):
"""Returns the name of the Activity in the apk."""
manifest_info = self._GetManifest()
try:
activity = (
manifest_info['manifest']['application']['activity']
['android:name'][0])
except KeyError:
return None
if '.' not in activity:
activity = '%s.%s' % (self.GetPackageName(), activity)
elif activity.startswith('.'):
activity = '%s%s' % (self.GetPackageName(), activity)
return activity
def GetInstrumentationName(
self, default='android.test.InstrumentationTestRunner'):
"""Returns the name of the Instrumentation in the apk."""
manifest_info = self._GetManifest()
try:
return manifest_info['manifest']['instrumentation']['android:name'][0]
except KeyError:
return default
def GetPackageName(self):
"""Returns the package name of the apk."""
if self._package_name:
return self._package_name
aapt_cmd = [_AAPT_PATH, 'dump', 'badging', self._apk_path]
aapt_output = cmd_helper.GetCmdOutput(aapt_cmd).split('\n')
package_name_re = re.compile(r'package: .*name=\'(\S*)\'')
for line in aapt_output:
m = package_name_re.match(line)
if m:
self._package_name = m.group(1)
return self._package_name
raise Exception('Failed to determine package name of %s' % self._apk_path)
def _GetManifest(self):
if not self._manifest:
self._manifest = _ParseManifestFromApk(self._apk_path)
return self._manifest
def GetInstrumentationName(
apk_path, default='android.test.InstrumentationTestRunner'):
"""Returns the name of the Instrumentation in the apk."""
try:
manifest_info = _ParseManifestFromApk(apk_path)
return manifest_info['manifest']['instrumentation']['android:name'][0]
except KeyError:
return default
# Copyright 2015 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.
# This file is meant to be included into a target to provide a rule
# to build APK-based browser test suites.
#
# To use this, create a gyp target with the following form:
# {
# 'target_name': 'test_suite_name_apk',
# 'type': 'none',
# 'variables': {
# 'test_suite_name': 'test_suite_name', # string
# 'java_in_dir': 'path/to/java/dir',
# },
# 'includes': ['path/to/this/gypi/file'],
# }
#
{
'dependencies': [
'<(DEPTH)/base/base.gyp:base_java',
'<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
'<(DEPTH)/build/android/pylib/remote/device/dummy/dummy.gyp:remote_device_dummy_apk',
'<(DEPTH)/testing/android/appurify_support.gyp:appurify_support_java',
'<(DEPTH)/testing/android/native_test.gyp:native_test_java',
'<(DEPTH)/tools/android/android_tools.gyp:android_tools',
],
'conditions': [
['OS == "android"', {
'variables': {
# These are used to configure java_apk.gypi included below.
'apk_name': '<(test_suite_name)',
'intermediate_dir': '<(PRODUCT_DIR)/<(test_suite_name)_apk',
'final_apk_path': '<(intermediate_dir)/<(test_suite_name)-debug.apk',
'native_lib_target': 'lib<(test_suite_name)',
# TODO(yfriedman, cjhopman): Support managed installs for gtests.
'gyp_managed_install': 0,
},
'includes': [ 'java_apk.gypi' ],
}], # 'OS == "android"
], # conditions
}
......@@ -14,7 +14,7 @@ found in the LICENSE file.
<application android:label="NativeTests"
android:name="org.chromium.chrome.unit_tests_apk.ChromeNativeTestApplication">
<activity android:name="org.chromium.native_test.NativeUnitTestActivity"
<activity android:name="org.chromium.native_test.NativeTestActivity"
android:label="NativeTest"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
......
......@@ -342,6 +342,17 @@ repack("components_tests_pak") {
]
}
if (is_android) {
import("//build/config/android/rules.gni")
generate_jni("components_browsertests_jni_headers") {
jni_package = "components_browsertests/shell"
sources = [
"test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsActivity.java",
]
}
}
test("components_browsertests") {
sources = [
"autofill/content/browser/risk/fingerprint_browsertest.cc",
......@@ -383,7 +394,10 @@ test("components_browsertests") {
"test/android/browsertests_apk/components_browser_tests_jni_onload.cc",
]
sources -= [ "autofill/content/browser/risk/fingerprint_browsertest.cc" ]
deps += [ "//testing/android/native_test:native_test_support" ]
deps += [
":components_browsertests_jni_headers",
"//testing/android/native_test:native_test_util",
]
use_launcher = false
}
......
......@@ -1205,6 +1205,17 @@
},
'includes': [ '../build/android/jinja_template.gypi' ],
},
{
'target_name': 'components_browsertests_jni_headers',
'type': 'none',
'sources': [
'test/android/browsertests_apk/src/org/chromium/components_browsertests_apk/ComponentsBrowserTestsActivity.java',
],
'variables': {
'jni_gen_package': 'content/shell',
},
'includes': [ '../build/jni_generator.gypi' ],
},
{
# TODO(GN)
'target_name': 'components_browsertests_apk',
......@@ -1219,13 +1230,14 @@
'components_browsertests',
],
'variables': {
'test_suite_name': 'components_browsertests',
'apk_name': 'components_browsertests',
'java_in_dir': 'test/android/browsertests_apk',
'android_manifest_path': '<(SHARED_INTERMEDIATE_DIR)/components_browsertests_manifest/AndroidManifest.xml',
'resource_dir': 'test/android/browsertests_apk/res',
'native_lib_target': 'libcomponents_browsertests',
'asset_location': '<(PRODUCT_DIR)/components_browsertests_apk_shell/assets',
},
'includes': [ '../build/apk_browsertest.gypi' ],
'includes': [ '../build/java_apk.gypi' ],
},
],
}],
......@@ -1311,13 +1323,16 @@
'conditions': [
['OS == "android"', {
'sources' : [
'test/android/browsertests_apk/components_browser_tests_android.cc',
'test/android/browsertests_apk/components_browser_tests_android.h',
'test/android/browsertests_apk/components_browser_tests_jni_onload.cc',
],
'sources!': [
'autofill/content/browser/risk/fingerprint_browsertest.cc',
],
'dependencies': [
'../testing/android/native_test.gyp:native_test_support',
'../testing/android/native_test.gyp:native_test_util',
'components_browsertests_jni_headers',
],
}],
['OS == "linux"', {
......
......@@ -47,10 +47,6 @@
{% endfor %}
</application>
<instrumentation android:name="org.chromium.native_test.NativeTestInstrumentationTestRunner"
android:label="ComponentsBrowserTests"
android:targetPackage="org.chromium.components_browsertests_apk"/>
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
......
// Copyright 2015 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.
// This class sets up the environment for running the content browser tests
// inside an android application.
#include <android/log.h>
#include <unistd.h>
#include "base/android/base_jni_registrar.h"
#include "base/android/fifo_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/android/scoped_java_ref.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_launcher.h"
#include "jni/ComponentsBrowserTestsActivity_jni.h"
#include "media/base/media_switches.h"
#include "testing/android/native_test/native_test_util.h"
using testing::native_test_util::ArgsToArgv;
using testing::native_test_util::ParseArgsFromCommandLineFile;
using testing::native_test_util::ScopedMainEntryLogger;
// The main function of the program to be wrapped as an apk.
extern int main(int argc, char** argv);
namespace {
// The test runner script writes the command line file in
// "/data/local/tmp".
static const char kCommandLineFilePath[] =
"/data/local/tmp/components-browser-tests-command-line";
} // namespace
namespace components {
// TODO(jaekyun): Refactor and deduplicate with
// testing/android/native_test/native_test_launcher.cc (http://crbug.com/476410)
static void RunTests(JNIEnv* env,
jobject obj,
jstring jfiles_dir,
jobject app_context) {
// Command line basic initialization, will be fully initialized later.
static const char* const kInitialArgv[] = {"ComponentsBrowserTestsActivity"};
base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
// Set the application context in base.
base::android::ScopedJavaLocalRef<jobject> scoped_context(
env, env->NewLocalRef(app_context));
base::android::InitApplicationContext(env, scoped_context);
base::android::RegisterJni(env);
std::vector<std::string> args;
ParseArgsFromCommandLineFile(kCommandLineFilePath, &args);
std::vector<char*> argv;
int argc = ArgsToArgv(args, &argv);
// Fully initialize command line with arguments.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
command_line->AppendArguments(base::CommandLine(argc, &argv[0]), false);
// Append required switches.
command_line->AppendSwitch(content::kSingleProcessTestsFlag);
command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
// Specify a socket name to not conflict with the default one used
// in content_shell.
command_line->AppendSwitchASCII(switches::kRemoteDebuggingSocketName,
"components_browsertests_devtools_remote");
// Create fifo and redirect stdout and stderr to it.
base::FilePath files_dir(
base::android::ConvertJavaStringToUTF8(env, jfiles_dir));
base::FilePath fifo_path(files_dir.Append(base::FilePath("test.fifo")));
base::android::CreateFIFO(fifo_path, 0666);
base::android::RedirectStream(stdout, fifo_path, "w+");
dup2(STDOUT_FILENO, STDERR_FILENO);
ScopedMainEntryLogger scoped_main_entry_logger;
main(argc, &argv[0]);
}
bool RegisterComponentsBrowserTestsAndroid(JNIEnv* env) {
return RegisterNativesImpl(env);
}
} // namespace components
// Copyright 2015 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.
#ifndef COMPONENTS_TEST_ANDROID_BROWSERTESTS_APK_COMPONENTS_BROWSER_TESTS_ANDROID_H_
#define COMPONENTS_TEST_ANDROID_BROWSERTESTS_APK_COMPONENTS_BROWSER_TESTS_ANDROID_H_
#include <jni.h>
namespace components {
bool RegisterComponentsBrowserTestsAndroid(JNIEnv* env);
} // namespace components
#endif // COMPONENTS_TEST_ANDROID_BROWSERTESTS_APK_COMPONENTS_BROWSER_TESTS_ANDROID_H_
......@@ -2,23 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/base_jni_registrar.h"
#include "base/android/jni_android.h"
#include "base/bind.h"
#include "components/test/android/browsertests_apk/components_browser_tests_android.h"
#include "content/public/app/content_jni_onload.h"
#include "content/public/app/content_main.h"
#include "content/public/test/nested_message_pump_android.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
#include "testing/android/native_test/native_test_launcher.h"
namespace {
bool RegisterJNI(JNIEnv* env) {
return base::android::RegisterJni(env) &&
content::android::RegisterShellJni(env) &&
content::NestedMessagePumpAndroid::RegisterJni(env) &&
testing::android::RegisterNativeTestJNI(env);
return content::android::RegisterShellJni(env) &&
content::NestedMessagePumpAndroid::RegisterJni(env) &&
components::RegisterComponentsBrowserTestsAndroid(env);
}
bool Init() {
......
......@@ -4,44 +4,43 @@
package org.chromium.components_browsertests_apk;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import org.chromium.base.Log;
import org.chromium.base.JNINamespace;
import org.chromium.base.annotations.SuppressFBWarnings;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.content.browser.BrowserStartupController;
import org.chromium.content_shell.ShellManager;
import org.chromium.native_test.NativeBrowserTestActivity;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.WindowAndroid;
/**
* Android activity for running components browser tests
*/
public class ComponentsBrowserTestsActivity extends NativeBrowserTestActivity {
private static final String TAG = Log.makeTag("native_test");
@JNINamespace("components")
public class ComponentsBrowserTestsActivity extends Activity {
private static final String TAG = "ComponentsBrowserTestsActivity";
private ShellManager mShellManager;
private WindowAndroid mWindowAndroid;
@Override
@SuppressFBWarnings("DM_EXIT")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appendCommandLineFlags(
"--remote-debugging-socket-name components_browsertests_devtools_remote");
}
@Override
@SuppressFBWarnings("DM_EXIT")
protected void initializeBrowserProcess() {
try {
LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized();
} catch (ProcessInitException e) {
Log.e(TAG, "Cannot load components_browsertests.", e);
Log.i(TAG, "Cannot load components_browsertests:" + e);
System.exit(-1);
}
BrowserStartupController.get(getApplicationContext(), LibraryProcessType.PROCESS_BROWSER)
......@@ -56,5 +55,21 @@ public class ComponentsBrowserTestsActivity extends NativeBrowserTestActivity {
wind.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
wind.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
wind.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
new Handler().post(new Runnable() {
@Override
public void run() {
Log.i(TAG, "Running tests");
runTests();
Log.i(TAG, "Tests finished.");
finish();
}
});
}
private void runTests() {
nativeRunTests(getFilesDir().getAbsolutePath(), getApplicationContext());
}
private native void nativeRunTests(String filesDir, Context appContext);
}
......@@ -1005,6 +1005,7 @@
'target_name': 'content_shell_jni_headers',
'type': 'none',
'sources': [
'shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsActivity.java',
'shell/android/java/src/org/chromium/content_shell/ShellLayoutTestUtils.java',
'shell/android/java/src/org/chromium/content_shell/ShellMojoTestUtils.java',
'shell/android/java/src/org/chromium/content_shell/ShellManager.java',
......
......@@ -268,6 +268,8 @@
'content_browsertests_android_sources': [
'browser/accessibility/android_granularity_movement_browsertest.cc',
'browser/accessibility/android_hit_testing_browsertest.cc',
'shell/android/browsertests_apk/content_browser_tests_android.cc',
'shell/android/browsertests_apk/content_browser_tests_android.h',
'shell/android/browsertests_apk/content_browser_tests_jni_onload.cc',
],
'content_browsertests_webrtc_sources': [
......@@ -1439,7 +1441,7 @@
'dependencies': [
'content_shell_jni_headers',
'content_shell_lib',
'../testing/android/native_test.gyp:native_test_support',
'../testing/android/native_test.gyp:native_test_util',
],
}],
['OS=="mac"', {
......@@ -1801,10 +1803,11 @@
'content_shell_java',
],
'variables': {
'test_suite_name': 'content_browsertests',
'apk_name': 'content_browsertests',
'java_in_dir': 'shell/android/browsertests_apk',
'android_manifest_path': '<(SHARED_INTERMEDIATE_DIR)/content_browsertests_manifest/AndroidManifest.xml',
'resource_dir': 'shell/android/browsertests_apk/res',
'native_lib_target': 'libcontent_browsertests',
'additional_input_paths': ['<(PRODUCT_DIR)/content_shell/assets/content_shell.pak'],
'asset_location': '<(PRODUCT_DIR)/content_shell/assets',
'conditions': [
......@@ -1821,7 +1824,7 @@
}],
],
},
'includes': [ '../build/apk_browsertest.gypi' ],
'includes': [ '../build/java_apk.gypi' ],
},
{
# TODO(GN)
......
......@@ -10,6 +10,7 @@ import("//third_party/icu/config.gni")
generate_jni("content_shell_jni_headers") {
jni_package = "content/shell"
sources = [
"browsertests_apk/src/org/chromium/content_browsertests_apk/ContentBrowserTestsActivity.java",
"java/src/org/chromium/content_shell/Shell.java",
"java/src/org/chromium/content_shell/ShellLayoutTestUtils.java",
"java/src/org/chromium/content_shell/ShellManager.java",
......
......@@ -47,10 +47,6 @@
{% endfor %}
</application>
<instrumentation android:name="org.chromium.native_test.NativeTestInstrumentationTestRunner"
android:label="ContentBrowserTests"
android:targetPackage="org.chromium.content_browsertests_apk"/>
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
......
// 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.
// This class sets up the environment for running the content browser tests
// inside an android application.
#include <android/log.h>
#include <unistd.h>
#include "base/android/base_jni_registrar.h"
#include "base/android/fifo_utils.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/android/scoped_java_ref.h"
#include "base/base_switches.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_launcher.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
#include "jni/ContentBrowserTestsActivity_jni.h"
#include "media/base/media_switches.h"
#include "testing/android/native_test/native_test_util.h"
using testing::native_test_util::ArgsToArgv;
using testing::native_test_util::ParseArgsFromCommandLineFile;
using testing::native_test_util::ScopedMainEntryLogger;
// The main function of the program to be wrapped as an apk.
extern int main(int argc, char** argv);
namespace {
// The test runner script writes the command line file in
// "/data/local/tmp".
static const char kCommandLineFilePath[] =
"/data/local/tmp/content-browser-tests-command-line";
} // namespace
namespace content {
// TODO(nileshagrawal): Refactor and deduplicate with
// testing/android/native_test_launcher.cc
static void RunTests(JNIEnv* env,
jobject obj,
jstring jfiles_dir,
jobject app_context) {
// Command line basic initialization, will be fully initialized later.
static const char* const kInitialArgv[] = { "ContentBrowserTestsActivity" };
base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
// Set the application context in base.
base::android::ScopedJavaLocalRef<jobject> scoped_context(
env, env->NewLocalRef(app_context));
base::android::InitApplicationContext(env, scoped_context);
base::android::RegisterJni(env);
std::vector<std::string> args;
ParseArgsFromCommandLineFile(kCommandLineFilePath, &args);
std::vector<char*> argv;
int argc = ArgsToArgv(args, &argv);
// Fully initialize command line with arguments.
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
command_line->AppendArguments(base::CommandLine(argc, &argv[0]), false);
// Append required switches.
command_line->AppendSwitch(content::kSingleProcessTestsFlag);
command_line->AppendSwitch(switches::kUseFakeDeviceForMediaStream);
command_line->AppendSwitch(switches::kUseFakeUIForMediaStream);
// Specify a socket name to not conflict with the default one used
// in content_shell.
command_line->AppendSwitchASCII(switches::kRemoteDebuggingSocketName,
"content_browsertests_devtools_remote");
// Create fifo and redirect stdout and stderr to it.
base::FilePath files_dir(
base::android::ConvertJavaStringToUTF8(env, jfiles_dir));
base::FilePath fifo_path(files_dir.Append(base::FilePath("test.fifo")));
base::android::CreateFIFO(fifo_path, 0666);
base::android::RedirectStream(stdout, fifo_path, "w+");
dup2(STDOUT_FILENO, STDERR_FILENO);
ScopedMainEntryLogger scoped_main_entry_logger;
main(argc, &argv[0]);
}
bool RegisterContentBrowserTestsAndroid(JNIEnv* env) {
return RegisterNativesImpl(env);
}
} // namespace content
// Copyright 2015 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.
#ifndef CONTENT_SHELL_ANDROID_BROWSERTESTS_APK_CONTENT_BROWSER_TESTS_ANDROID_H_
#define CONTENT_SHELL_ANDROID_BROWSERTESTS_APK_CONTENT_BROWSER_TESTS_ANDROID_H_
#include <jni.h>
namespace content {
bool RegisterContentBrowserTestsAndroid(JNIEnv* env);
} // namespace content
#endif // CONTENT_SHELL_ANDROID_BROWSERTESTS_APK_CONTENT_BROWSER_TESTS_ANDROID_H_
......@@ -2,23 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/base_jni_registrar.h"
#include "base/android/jni_android.h"
#include "base/bind.h"
#include "content/public/app/content_jni_onload.h"
#include "content/public/app/content_main.h"
#include "content/public/test/nested_message_pump_android.h"
#include "content/shell/android/browsertests_apk/content_browser_tests_android.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
#include "testing/android/native_test/native_test_launcher.h"
namespace {
bool RegisterJNI(JNIEnv* env) {
return base::android::RegisterJni(env) &&
content::android::RegisterShellJni(env) &&
return content::android::RegisterShellJni(env) &&
content::NestedMessagePumpAndroid::RegisterJni(env) &&
testing::android::RegisterNativeTestJNI(env);
content::RegisterContentBrowserTestsAndroid(env);
}
bool Init() {
......
......@@ -4,44 +4,43 @@
package org.chromium.content_browsertests_apk;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import org.chromium.base.Log;
import org.chromium.base.JNINamespace;
import org.chromium.base.annotations.SuppressFBWarnings;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
import org.chromium.base.library_loader.ProcessInitException;
import org.chromium.content.browser.BrowserStartupController;
import org.chromium.content_shell.ShellManager;
import org.chromium.native_test.NativeBrowserTestActivity;
import org.chromium.ui.base.ActivityWindowAndroid;
import org.chromium.ui.base.WindowAndroid;
/**
* Android activity for running content browser tests
*/
public class ContentBrowserTestsActivity extends NativeBrowserTestActivity {
private static final String TAG = Log.makeTag("native_test");
@JNINamespace("content")
public class ContentBrowserTestsActivity extends Activity {
private static final String TAG = "ChromeBrowserTestsActivity";
private ShellManager mShellManager;
private WindowAndroid mWindowAndroid;
@Override
@SuppressFBWarnings("DM_EXIT")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appendCommandLineFlags(
"--remote-debugging-socket-name content_browsertests_devtools_remote");
}
@Override
@SuppressFBWarnings("DM_EXIT")
protected void initializeBrowserProcess() {
try {
LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized();
} catch (ProcessInitException e) {
Log.e(TAG, "Cannot load content_browsertests.", e);
Log.i(TAG, "Cannot load content_browsertests:" + e);
System.exit(-1);
}
BrowserStartupController.get(getApplicationContext(), LibraryProcessType.PROCESS_BROWSER)
......@@ -56,5 +55,21 @@ public class ContentBrowserTestsActivity extends NativeBrowserTestActivity {
wind.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
wind.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
wind.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
new Handler().post(new Runnable() {
@Override
public void run() {
Log.i(TAG, "Running tests");
runTests();
Log.i(TAG, "Tests finished.");
finish();
}
});
}
private void runTests() {
nativeRunTests(getFilesDir().getAbsolutePath(), getApplicationContext());
}
private native void nativeRunTests(String filesDir, Context appContext);
}
......@@ -350,7 +350,7 @@ if (!is_mac) {
deps += [
"//content/shell/android:content_shell_jni_headers",
"//content/shell:content_shell_lib",
"//testing/android/native_test:native_test_support",
"//testing/android/native_test:native_test_util",
]
use_launcher = false
......
......@@ -7,27 +7,14 @@
['OS=="android"', {
'targets': [
{
# GN: //testing/android:native_test_jni_headers
'target_name': 'native_test_jni_headers',
'type': 'none',
'sources': [
'native_test/java/src/org/chromium/native_test/NativeTestActivity.java'
],
'variables': {
'jni_gen_package': 'testing',
},
'includes': [ '../../build/jni_generator.gypi' ],
},
{
# GN: //testing/android:native_test_support
'target_name': 'native_test_support',
# GN: //testing/android:native_test_native_code
'target_name': 'native_test_native_code',
'message': 'building native pieces of native test package',
'type': 'static_library',
'sources': [
'native_test/native_test_jni_onload.cc',
'native_test/native_test_launcher.cc',
'native_test/native_test_launcher.h',
'native_test/native_test_util.cc',
'native_test/native_test_util.h',
],
'dependencies': [
'../../base/base.gyp:base',
......@@ -35,35 +22,32 @@
'../../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations',
'../gtest.gyp:gtest',
'native_test_jni_headers',
'native_test_util',
],
},
{
# GN: //testing/android:native_test_native_code
'target_name': 'native_test_native_code',
'message': 'building JNI onload for native test package',
'type': 'static_library',
# GN: //testing/android:native_test_jni_headers
'target_name': 'native_test_jni_headers',
'type': 'none',
'sources': [
'native_test/native_test_jni_onload.cc',
],
'dependencies': [
'native_test_support',
'../../base/base.gyp:base',
'native_test/java/src/org/chromium/native_test/NativeTestActivity.java'
],
'variables': {
'jni_gen_package': 'testing',
},
'includes': [ '../../build/jni_generator.gypi' ],
},
{
'target_name': 'native_test_java',
'type': 'none',
# GN: //testing/android:native_test_util
'target_name': 'native_test_util',
'type': 'static_library',
'sources': [
'native_test/native_test_util.cc',
'native_test/native_test_util.h',
],
'dependencies': [
'appurify_support.gyp:appurify_support_java',
'../../base/base.gyp:base_native_libraries_gen',
'../../base/base.gyp:base_java',
'../../base/base.gyp:base',
],
'variables': {
'chromium_code': '1',
'jar_excluded_classes': [ '*/NativeLibraries.class' ],
'java_in_dir': 'native_test/java',
},
'includes': [ '../../build/java.gypi' ],
},
],
}]
......
......@@ -4,17 +4,18 @@
import("//build/config/android/rules.gni")
# GYP: //testing/android/native_test.gyp:native_test_support
source_set("native_test_support") {
# GYP: //testing/android/native_test.gyp:native_test_native_code
source_set("native_test_native_code") {
testonly = true
sources = [
"native_test_jni_onload.cc",
"native_test_launcher.cc",
"native_test_launcher.h",
"native_test_util.cc",
"native_test_util.h",
]
libs = [ "log" ]
deps = [
":native_test_jni_headers",
":native_test_util",
"//base",
"//base/test:test_support",
"//base/third_party/dynamic_annotations",
......@@ -22,19 +23,6 @@ source_set("native_test_support") {
]
}
# GYP: //testing/android/native_test.gyp:native_test_native_code
source_set("native_test_native_code") {
testonly = true
sources = [
"native_test_jni_onload.cc",
]
libs = [ "log" ]
deps = [
":native_test_support",
"//base",
]
}
# GYP: //testing/android/native_test.gyp:native_test_jni_headers
generate_jni("native_test_jni_headers") {
sources = [
......@@ -42,3 +30,14 @@ generate_jni("native_test_jni_headers") {
]
jni_package = "testing"
}
# GYP: //testing/android/native_test.gyp:native_test_util
source_set("native_test_util") {
sources = [
"native_test_util.cc",
"native_test_util.h",
]
deps = [
"//base",
]
}
......@@ -22,7 +22,7 @@ found in the LICENSE file.
<application android:label="NativeTests"
android:name="org.chromium.base.BaseChromiumApplication">
<activity android:name=".NativeUnitTestActivity"
<activity android:name=".NativeTestActivity"
android:label="NativeTest"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
......
// Copyright 2015 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.os.Bundle;
/**
* An {@link android.app.Activity} for running native browser tests.
*/
public abstract class NativeBrowserTestActivity extends NativeTestActivity {
private static final String BROWSER_TESTS_FLAGS[] = {
// content::kSingleProcessTestsFlag
"--single_process",
// switches::kUseFakeDeviceForMediaStream
"--use-fake-device-for-media-stream",
// switches::kUseFakeUIForMediaStream
"--use-fake-ui-for-media-stream"
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
for (String flag : BROWSER_TESTS_FLAGS) {
appendCommandLineFlags(flag);
}
}
@Override
public void onStart() {
initializeBrowserProcess();
super.onStart();
}
/** Initializes the browser process.
*
* This generally includes loading native libraries and switching to the native command line,
* among other things.
*/
protected abstract void initializeBrowserProcess();
}
......@@ -6,14 +6,16 @@ package org.chromium.native_test;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import org.chromium.base.CommandLine;
import org.chromium.base.JNINamespace;
import org.chromium.base.Log;
import org.chromium.base.PathUtils;
import org.chromium.base.PowerMonitor;
import org.chromium.base.ResourceExtractor;
import org.chromium.base.library_loader.NativeLibraries;
import java.io.File;
......@@ -22,7 +24,6 @@ import java.io.File;
* Our tests need to go up to our own java classes, which is not possible using
* the native activity class loader.
*/
@JNINamespace("testing::android")
public class NativeTestActivity extends Activity {
public static final String EXTRA_COMMAND_LINE_FILE =
"org.chromium.native_test.NativeTestActivity.CommandLineFile";
......@@ -36,54 +37,25 @@ public class NativeTestActivity extends Activity {
// We post a delayed task to run tests so that we do not block onCreate().
private static final long RUN_TESTS_DELAY_IN_MS = 300;
private String mCommandLineFilePath;
private StringBuilder mCommandLineFlags = new StringBuilder();
private boolean mRunInSubThread = false;
private boolean mStdoutFifo = false;
private String mStdoutFilePath;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CommandLine.init(new String[]{});
parseArgumentsFromIntent(getIntent());
}
private void parseArgumentsFromIntent(Intent intent) {
mCommandLineFilePath = intent.getStringExtra(EXTRA_COMMAND_LINE_FILE);
if (mCommandLineFilePath == null) {
mCommandLineFilePath = "";
} else {
File commandLineFile = new File(mCommandLineFilePath);
if (!commandLineFile.isAbsolute()) {
mCommandLineFilePath = Environment.getExternalStorageDirectory() + "/"
+ mCommandLineFilePath;
}
Log.i(TAG, "command line file path: %s", mCommandLineFilePath);
}
// Needed by path_utils_unittest.cc
PathUtils.setPrivateDataDirectorySuffix("chrome", getApplicationContext());
String commandLineFlags = intent.getStringExtra(EXTRA_COMMAND_LINE_FLAGS);
if (commandLineFlags != null) mCommandLineFlags.append(commandLineFlags);
ResourceExtractor resourceExtractor = ResourceExtractor.get(getApplicationContext());
resourceExtractor.setExtractAllPaksAndV8SnapshotForTesting();
resourceExtractor.startExtractingResources();
resourceExtractor.waitForCompletion();
mRunInSubThread = intent.hasExtra(EXTRA_RUN_IN_SUB_THREAD);
// Needed by system_monitor_unittest.cc
PowerMonitor.createForTests(this);
mStdoutFilePath = intent.getStringExtra(EXTRA_STDOUT_FILE);
if (mStdoutFilePath == null) {
mStdoutFilePath = new File(getFilesDir(), "test.fifo").getAbsolutePath();
mStdoutFifo = true;
}
}
protected void appendCommandLineFlags(String flags) {
mCommandLineFlags.append(" ").append(flags);
}
@Override
public void onStart() {
super.onStart();
if (mRunInSubThread) {
loadLibraries();
Bundle extras = this.getIntent().getExtras();
if (extras != null && extras.containsKey(EXTRA_RUN_IN_SUB_THREAD)) {
// Create a new thread and run tests on it.
new Thread() {
@Override
......@@ -104,8 +76,31 @@ public class NativeTestActivity extends Activity {
}
private void runTests() {
nativeRunTests(mCommandLineFlags.toString(), mCommandLineFilePath, mStdoutFilePath,
mStdoutFifo, getApplicationContext());
String commandLineFlags = getIntent().getStringExtra(EXTRA_COMMAND_LINE_FLAGS);
if (commandLineFlags == null) commandLineFlags = "";
String commandLineFilePath = getIntent().getStringExtra(EXTRA_COMMAND_LINE_FILE);
if (commandLineFilePath == null) {
commandLineFilePath = "";
} else {
File commandLineFile = new File(commandLineFilePath);
if (!commandLineFile.isAbsolute()) {
commandLineFilePath = Environment.getExternalStorageDirectory() + "/"
+ commandLineFilePath;
}
Log.i(TAG, "command line file path: %s", commandLineFilePath);
}
String stdoutFilePath = getIntent().getStringExtra(EXTRA_STDOUT_FILE);
boolean stdoutFifo = false;
if (stdoutFilePath == null) {
stdoutFilePath = new File(getFilesDir(), "test.fifo").getAbsolutePath();
stdoutFifo = true;
}
// This directory is used by build/android/pylib/test_package_apk.py.
nativeRunTests(commandLineFlags, commandLineFilePath, stdoutFilePath, stdoutFifo,
getApplicationContext());
finish();
}
......@@ -116,6 +111,14 @@ public class NativeTestActivity extends Activity {
Log.e(TAG, "[ RUNNER_FAILED ] could not load native library");
}
private void loadLibraries() {
for (String library : NativeLibraries.LIBRARIES) {
Log.i(TAG, "loading: %s", library);
System.loadLibrary(library);
Log.i(TAG, "loaded: %s", library);
}
}
private native void nativeRunTests(String commandLineFlags, String commandLineFilePath,
String stdoutFilePath, boolean stdoutFifo, Context appContext);
}
......@@ -31,9 +31,6 @@ import java.util.regex.Pattern;
* An Instrumentation that runs tests based on NativeTestActivity.
*/
public class NativeTestInstrumentationTestRunner extends Instrumentation {
public static final String EXTRA_NATIVE_TEST_ACTIVITY =
"org.chromium.native_test.NativeTestInstrumentationTestRunner."
+ "NativeTestActivity";
// TODO(jbudorick): Remove this extra when b/18981674 is fixed.
public static final String EXTRA_ONLY_OUTPUT_FAILURES =
"org.chromium.native_test.NativeTestInstrumentationTestRunner."
......@@ -42,25 +39,19 @@ public class NativeTestInstrumentationTestRunner extends Instrumentation {
private static final String TAG = Log.makeTag("native_test");
private static final int ACCEPT_TIMEOUT_MS = 5000;
private static final String DEFAULT_NATIVE_TEST_ACTIVITY =
"org.chromium.native_test.NativeUnitTestActivity";
private static final Pattern RE_TEST_OUTPUT = Pattern.compile("\\[ *([^ ]*) *\\] ?([^ ]+) .*");
private ResultsBundleGenerator mBundleGenerator = new RobotiumBundleGenerator();
private String mCommandLineFile;
private String mCommandLineFlags;
private String mNativeTestActivity;
private Bundle mLogBundle = new Bundle();
private boolean mOnlyOutputFailures;
private File mStdoutFile;
private Bundle mLogBundle;
private ResultsBundleGenerator mBundleGenerator;
private boolean mOnlyOutputFailures;
@Override
public void onCreate(Bundle arguments) {
mCommandLineFile = arguments.getString(NativeTestActivity.EXTRA_COMMAND_LINE_FILE);
mCommandLineFlags = arguments.getString(NativeTestActivity.EXTRA_COMMAND_LINE_FLAGS);
mNativeTestActivity = arguments.getString(EXTRA_NATIVE_TEST_ACTIVITY);
if (mNativeTestActivity == null) mNativeTestActivity = DEFAULT_NATIVE_TEST_ACTIVITY;
try {
mStdoutFile = File.createTempFile(
".temp_stdout_", ".txt", Environment.getExternalStorageDirectory());
......@@ -70,7 +61,8 @@ public class NativeTestInstrumentationTestRunner extends Instrumentation {
finish(Activity.RESULT_CANCELED, new Bundle());
return;
}
mLogBundle = new Bundle();
mBundleGenerator = new RobotiumBundleGenerator();
mOnlyOutputFailures = arguments.containsKey(EXTRA_ONLY_OUTPUT_FAILURES);
start();
}
......@@ -108,7 +100,9 @@ public class NativeTestInstrumentationTestRunner extends Instrumentation {
*/
private Activity startNativeTestActivity() {
Intent i = new Intent(Intent.ACTION_MAIN);
i.setComponent(new ComponentName(getContext().getPackageName(), mNativeTestActivity));
i.setComponent(new ComponentName(
"org.chromium.native_test",
"org.chromium.native_test.NativeTestActivity"));
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (mCommandLineFile != null) {
Log.i(TAG, "Passing command line file extra: %s", mCommandLineFile);
......
// Copyright 2015 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.os.Bundle;
import org.chromium.base.Log;
import org.chromium.base.PathUtils;
import org.chromium.base.PowerMonitor;
import org.chromium.base.ResourceExtractor;
import org.chromium.base.library_loader.NativeLibraries;
/**
* An {@link android.app.Activity} for running native unit tests.
* (i.e., not browser tests)
*/
public class NativeUnitTestActivity extends NativeTestActivity {
private static final String TAG = Log.makeTag("native_test");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Needed by path_utils_unittest.cc
PathUtils.setPrivateDataDirectorySuffix("chrome", getApplicationContext());
ResourceExtractor resourceExtractor = ResourceExtractor.get(getApplicationContext());
resourceExtractor.setExtractAllPaksAndV8SnapshotForTesting();
resourceExtractor.startExtractingResources();
resourceExtractor.waitForCompletion();
// Needed by system_monitor_unittest.cc
PowerMonitor.createForTests(this);
loadLibraries();
}
private void loadLibraries() {
for (String library : NativeLibraries.LIBRARIES) {
Log.i(TAG, "loading: %s", library);
System.loadLibrary(library);
Log.i(TAG, "loaded: %s", library);
}
}
}
......@@ -10,11 +10,11 @@
namespace {
bool RegisterJNI(JNIEnv* env) {
return testing::android::RegisterNativeTestJNI(env);
return RegisterNativeTestJNI(env);
}
bool Init() {
testing::android::InstallHandlers();
InstallHandlers();
return true;
}
......
......@@ -28,12 +28,14 @@
#include "jni/NativeTestActivity_jni.h"
#include "testing/android/native_test/native_test_util.h"
using testing::native_test_util::ArgsToArgv;
using testing::native_test_util::ParseArgsFromCommandLineFile;
using testing::native_test_util::ParseArgsFromString;
using testing::native_test_util::ScopedMainEntryLogger;
// The main function of the program to be wrapped as a test apk.
extern int main(int argc, char** argv);
namespace testing {
namespace android {
namespace {
// The test runner script writes the command line file in
......@@ -121,7 +123,7 @@ static void RunTests(JNIEnv* env,
exit(EXIT_FAILURE);
}
}
if (!base::android::RedirectStream(stdout, stdout_file_path, "w+")) {
if (!base::android::RedirectStream(stdout, stdout_file_path, "w")) {
AndroidLog(ANDROID_LOG_ERROR, "Failed to redirect stream to file: %s: %s\n",
stdout_file_path.value().c_str(), strerror(errno));
exit(EXIT_FAILURE);
......@@ -143,6 +145,7 @@ bool RegisterNativeTestJNI(JNIEnv* env) {
return RegisterNativesImpl(env);
}
// TODO(nileshagrawal): now that we're using FIFO, test scripts can detect EOF.
// Remove the signal handlers.
void InstallHandlers() {
......@@ -156,6 +159,3 @@ void InstallHandlers() {
sigaction(kExceptionSignals[i], &sa, &g_old_sa[kExceptionSignals[i]]);
}
}
} // namespace android
} // namespace testing
......@@ -7,13 +7,7 @@
#include <jni.h>
namespace testing {
namespace android {
void InstallHandlers();
bool RegisterNativeTestJNI(JNIEnv* env);
} // namespace android
} // namespace testing
#endif // TESTING_ANDROID_NATIVE_TEST_LAUNCHER_H_
......@@ -10,7 +10,7 @@
#include "base/strings/string_util.h"
namespace testing {
namespace android {
namespace native_test_util {
void ParseArgsFromString(const std::string& command_line,
std::vector<std::string>* args) {
......@@ -46,5 +46,5 @@ int ArgsToArgv(const std::vector<std::string>& args,
return argc;
}
} // namespace android
} // namespace native_test_util
} // namespace testing
......@@ -12,7 +12,7 @@
// Helper methods for setting up environment for running gtest tests
// inside an APK.
namespace testing {
namespace android {
namespace native_test_util {
class ScopedMainEntryLogger {
public:
......@@ -33,7 +33,7 @@ void ParseArgsFromCommandLineFile(
const char* path, std::vector<std::string>* args);
int ArgsToArgv(const std::vector<std::string>& args, std::vector<char*>* argv);
} // namespace android
} // namespace native_test_util
} // namespace testing
#endif // TESTING_ANDROID_NATIVE_TEST_UTIL_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment