Commit 352663bd authored by Michael Giuffrida's avatar Michael Giuffrida Committed by Commit Bot

Allow Chrome tests to load extensions from //extensions

Allows ExtensionApiTest browser_test tests in Chrome to load test
extensions from //extensions/test/data instead of
//chrome/test/data/extensions/api_test.

This lets us share test extensions between different testing binaries,
like browser_tests (in //chrome) and extensions_browsertests
(in //extensions).

The proof-of-concept moves the "messaging/connect_external" test
extension for MessagingApiTest.ConnectExternal and copies a small part
of a secondary extension used in that test, so that Chrome test loads:
  - //extensions/test/data/messaging/connect_external
  - //extensions/test/data/messaging/receiver

Bug: 388893
Change-Id: Ie111fb5a134597a771c58c90ff974109693ade37
Reviewed-on: https://chromium-review.googlesource.com/588251
Commit-Queue: Michael Giuffrida <michaelpg@chromium.org>
Reviewed-by: default avatarDevlin <rdevlin.cronin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491911}
parent 54906703
......@@ -8,6 +8,8 @@
#include <utility>
#include "base/base_switches.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
......@@ -26,6 +28,7 @@
#include "extensions/browser/extension_system.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_paths.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/switches.h"
#include "extensions/test/result_catcher.h"
......@@ -171,6 +174,12 @@ bool ExtensionApiTest::RunExtensionTest(const std::string& extension_name) {
extension_name, std::string(), NULL, kFlagEnableFileAccess);
}
bool ExtensionApiTest::RunExtensionTestWithFlags(
const std::string& extension_name,
int flags) {
return RunExtensionTestImpl(extension_name, std::string(), nullptr, flags);
}
bool ExtensionApiTest::RunExtensionTestWithArg(
const std::string& extension_name,
const char* custom_arg) {
......@@ -287,6 +296,7 @@ bool ExtensionApiTest::RunExtensionTestImpl(const std::string& extension_name,
bool load_as_component = (flags & kFlagLoadAsComponent) != 0;
bool launch_platform_app = (flags & kFlagLaunchPlatformApp) != 0;
bool use_incognito = (flags & kFlagUseIncognito) != 0;
bool use_root_extensions_dir = (flags & kFlagUseRootExtensionsDir) != 0;
if (custom_arg && custom_arg[0])
test_config_->SetString(kTestCustomArg, custom_arg);
......@@ -297,7 +307,9 @@ bool ExtensionApiTest::RunExtensionTestImpl(const std::string& extension_name,
const extensions::Extension* extension = NULL;
if (!extension_name.empty()) {
base::FilePath extension_path = test_data_dir_.AppendASCII(extension_name);
const base::FilePath& root_path =
use_root_extensions_dir ? shared_test_data_dir_ : test_data_dir_;
base::FilePath extension_path = root_path.AppendASCII(extension_name);
if (load_as_component) {
extension = LoadExtensionAsComponent(extension_path);
} else {
......@@ -445,7 +457,13 @@ bool ExtensionApiTest::StartFTPServer(const base::FilePath& root_directory) {
void ExtensionApiTest::SetUpCommandLine(base::CommandLine* command_line) {
ExtensionBrowserTest::SetUpCommandLine(command_line);
test_data_dir_ = test_data_dir_.AppendASCII("api_test");
extensions::RegisterPathProvider();
PathService::Get(extensions::DIR_TEST_DATA, &shared_test_data_dir_);
shared_test_data_dir_ = shared_test_data_dir_.AppendASCII("api_test");
// Backgrounded renderer processes run at a lower priority, causing the
// tests to take more time to complete. Disable backgrounding so that the
// tests don't time out.
......
......@@ -58,6 +58,10 @@ class ExtensionApiTest : public ExtensionBrowserTest {
// Allow manifest versions older that Extension::kModernManifestVersion.
// Used to test old manifest features.
kFlagAllowOldManifestVersions = 1 << 6,
// Load the extension using //extensions/test/data/ as the root path instead
// of loading from //chrome/test/data/extensions/api_test/.
kFlagUseRootExtensionsDir = 1 << 7,
};
ExtensionApiTest();
......@@ -68,10 +72,14 @@ class ExtensionApiTest : public ExtensionBrowserTest {
void SetUpOnMainThread() override;
void TearDownOnMainThread() override;
// Load |extension_name| and wait for pass / fail notification.
// |extension_name| is a directory in "test/data/extensions/api_test".
// Loads |extension_name| and waits for pass / fail notification.
// |extension_name| is a directory in "chrome/test/data/extensions/api_test".
bool RunExtensionTest(const std::string& extension_name);
// Same as RunExtensionTest, except run with the specific |flags| (as defined
// in the Flags enum).
bool RunExtensionTestWithFlags(const std::string& extension_name, int flags);
// Similar to RunExtensionTest, except sets an additional string argument
// |customArg| to the test config object.
bool RunExtensionTestWithArg(const std::string& extension_name,
......@@ -188,6 +196,10 @@ class ExtensionApiTest : public ExtensionBrowserTest {
// All extensions tested by ExtensionApiTest are in the "api_test" dir.
void SetUpCommandLine(base::CommandLine* command_line) override;
const base::FilePath& shared_test_data_dir() const {
return shared_test_data_dir_;
}
// If it failed, what was the error message?
std::string message_;
......@@ -206,6 +218,9 @@ class ExtensionApiTest : public ExtensionBrowserTest {
// Hold the test FTP server.
std::unique_ptr<net::SpawnedTestServer> ftp_server_;
// Test data directory shared with //extensions.
base::FilePath shared_test_data_dir_;
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_APITEST_H_
......@@ -314,7 +314,8 @@ class ExtensionBrowserTest : virtual public InProcessBrowserTest {
bool set_chromeos_user_;
#endif
// test_data/extensions.
// Set to "chrome/test/data/extensions". Derived classes may override.
// TODO(michaelpg): Don't override protected data members.
base::FilePath test_data_dir_;
std::unique_ptr<extensions::ChromeExtensionTestNotificationObserver>
......
......@@ -164,12 +164,11 @@ IN_PROC_BROWSER_TEST_F(MessagingApiTest, MessagingCrash) {
// Tests that message passing from one extension to another works.
IN_PROC_BROWSER_TEST_F(MessagingApiTest, MessagingExternal) {
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("..").AppendASCII("good")
.AppendASCII("Extensions")
.AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
.AppendASCII("1.0")));
shared_test_data_dir().AppendASCII("messaging").AppendASCII("receiver")));
ASSERT_TRUE(RunExtensionTest("messaging/connect_external")) << message_;
ASSERT_TRUE(RunExtensionTestWithFlags("messaging/connect_external",
kFlagUseRootExtensionsDir))
<< message_;
}
// Tests that a content script can exchange messages with a tab even if there is
......
......@@ -2016,6 +2016,8 @@ test("browser_tests") {
"//extensions:chrome_extensions_browsertests",
"//extensions/common/api",
]
data += [ "//extensions/test/data/" ]
}
if (use_ash) {
......
<!--
* Copyright (c) 2011 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.
-->
<script src="test.js"></script>
......@@ -2,8 +2,8 @@
"name": "connect_external",
"version": "1.0",
"manifest_version": 2,
"description": "Tests connect to an external extension.",
"description": "Tests connecting to an external extension.",
"background": {
"page": "test.html"
"scripts": ["test.js"]
}
}
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Copyright 2017 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.
var testId = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
const TEST_ID = 'bjafgdebaacbbbecmhlhpofkepfkgcpa';
// Call with |api| as either chrome.runtime or chrome.extension, so that both
// get tested (extension is aliased to runtime).
// Call with |api| as either chrome.runtime or chrome.extension.
function connectExternalTest(api) {
var port = api.connect(testId, {name: "extern"});
let port = api.connect(TEST_ID, {name: 'extern'});
port.postMessage({testConnectExternal: true});
port.onMessage.addListener(chrome.test.callbackPass(function(msg) {
chrome.test.assertTrue(msg.success, "Message failed.");
chrome.test.assertTrue(msg.success, 'Message failed.');
chrome.test.assertEq(msg.senderId, location.host,
"Sender ID doesn't match.");
'Sender ID doesn\'t match.');
}));
}
chrome.test.runTests([
function connectExternal_extension() {
connectExternalTest(chrome.extension);
},
function connectExternal_runtime() {
// Generates the list of test functions.
function generateTests() {
let tests = [function connectExternal_runtime() {
connectExternalTest(chrome.runtime);
}];
// In Chrome, also test the same functions on chrome.extension.
if (chrome.extension) {
tests.push(function connectExternal_extension() {
connectExternalTest(chrome.extension);
});
}
]);
return tests;
}
chrome.test.runTests(generateTests());
// Copyright 2017 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.
chrome.runtime.onConnectExternal.addListener((port) => {
port.onMessage.addListener((msg) => {
if (msg.testConnectExternal)
port.postMessage({success: true, senderId: port.sender.id});
});
});
{
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRS2GUBOUAO5VZ2CMRId/eRR8/e9V42nUvY5XG+0sZ+JDHEjIQdq8qQy7HqdqEpCXKPMSPuMiC2t2HE9/hpL89SblNn3mwYPtSJGQdZvAzuv6SB0oA6jZ66V7+h/k0noGD3Tcu+Ko/vfkt5wCx2uHVK29k5JR/vGr0klaoVezGlwIDAQAB",
"version": "1.0",
"manifest_version": 2,
"name": "Test extension to receive extension messages",
"background": {
"scripts": ["background.js"]
}
}
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