Skip to content

Commit

Permalink
shared worker: Add tests for Chrome extensions.
Browse files Browse the repository at this point in the history
We didn't have specific test coverage for shared worker from Chrome
extensions, just incidental ones via the ExtensionApiTest.Debugger and
ExtensionApiTestWithSwitch.ExtensionDebugger.

Shared workers go through a very different loading path than other
resources, so it's useful to have tests for them especially
including interaction with service workers.

This adds tests that currently fail with NetworkService, a next
patch will have a fix.

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: Ifa6bb3dec8bdea34c3fbefbaeab324fadcb5c929
Bug: 839982
Reviewed-on: https://chromium-review.googlesource.com/1074848
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Reviewed-by: Istiaque Ahmed <lazyboy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#562700}
  • Loading branch information
mfalken authored and Commit Bot committed May 30, 2018
1 parent 8d4aeb8 commit 62628bf
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 1 deletion.
52 changes: 52 additions & 0 deletions chrome/browser/extensions/shared_worker_apitest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright 2018 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 "base/files/file_path.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/process_manager.h"
#include "extensions/test/background_page_watcher.h"
#include "extensions/test/extension_test_message_listener.h"

namespace extensions {

// This tests an extension that starts a shared worker.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, SharedWorker) {
EXPECT_TRUE(RunExtensionTest("shared_worker/basic")) << message_;
}

// This tests an extension that is controlled by a service worker and starts a
// shared worker. The requests for the shared worker scripts and the requests
// initiated by the shared worker should be seen by the service worker.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
SharedWorker_ControlledByServiceWorker) {
// Load the extension. It will register a service worker.
ExtensionTestMessageListener listener("READY", false);
listener.set_failure_message("FAIL");
const Extension* extension = LoadExtension(
test_data_dir_.AppendASCII("shared_worker/service_worker_controlled"));
EXPECT_TRUE(listener.WaitUntilSatisfied());
EXPECT_TRUE(extension);
ProcessManager* process_manager = ProcessManager::Get(profile());
ExtensionHost* background_page =
process_manager->GetBackgroundHostForExtension(extension->id());

// Close the background page and start it again, so it is controlled
// by the service worker.
ExtensionTestMessageListener listener2("CONTROLLED", false);
listener2.set_failure_message("FAIL");
background_page->Close();
BackgroundPageWatcher(process_manager, extension).WaitForClose();
background_page = nullptr;
process_manager->WakeEventPage(extension->id(), base::DoNothing());
BackgroundPageWatcher(process_manager, extension).WaitForOpen();
EXPECT_TRUE(listener2.WaitUntilSatisfied());

// The background page should conduct the tests.
ExtensionTestMessageListener listener3("PASS", false);
listener3.set_failure_message("FAIL");
EXPECT_TRUE(listener3.WaitUntilSatisfied());
}

} // namespace extensions
3 changes: 2 additions & 1 deletion chrome/test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ test("browser_tests") {
"../browser/ui/blocked_content/tab_under_blocker_browsertest.cc",
"../browser/ui/tabs/pinned_tab_service_browsertest.cc",

#If this list is used on Android in the future, these browser / speech/*
# If this list is used on Android in the future, these browser / speech/*
# files will probably not be applicable.
"../browser/speech/extension_api/tts_extension_apitest.cc",
"../browser/speech/speech_recognition_browsertest.cc",
Expand Down Expand Up @@ -1327,6 +1327,7 @@ test("browser_tests") {
"../browser/extensions/sandboxed_pages_apitest.cc",
"../browser/extensions/service_worker_apitest.cc",
"../browser/extensions/shared_module_apitest.cc",
"../browser/extensions/shared_worker_apitest.cc",
"../browser/extensions/startup_helper_browsertest.cc",
"../browser/extensions/stubs_apitest.cc",
"../browser/extensions/subscribe_page_action_browsertest.cc",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2018 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.test.runTests([
function worker() {
const workerPort = new SharedWorker("worker.js").port;
workerPort.onmessage = (evt) => {
if (evt.data != 'hullo there!') {
chrome.test.fail();
} else {
chrome.test.succeed();
}
};
workerPort.start();
},

function workerWithImport() {
const workerPort = new SharedWorker("worker-with-import.js").port;
workerPort.onmessage = (evt) => {
if (evt.data != 'hullo there!') {
chrome.test.fail();
} else {
chrome.test.succeed();
}
};
workerPort.start();
}
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "Shared worker",
"version": "1.0",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2018 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.

importScripts('worker.js');
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2018 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.

self.addEventListener('connect', function(e) {
var port = e.ports[0];
port.start();
port.postMessage('hullo there!');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!--
Copyright 2018 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.
-->

<html><body>
background.html contents for testing.
<script src="background.js"></script>
</body></html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2018 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.

async function setup() {
const reg = await navigator.serviceWorker.register('service_worker.js');
await navigator.serviceWorker.ready;
if (navigator.serviceWorker.controller) {
chrome.test.sendMessage('CONTROLLED');
} else {
chrome.test.sendMessage('READY');
}
}

async function getMessageFromWorker(worker) {
return new Promise(resolve => {
worker.port.onmessage = evt => {
resolve(evt.data);
}
});
}

async function getMessageFromServiceWorker() {
return new Promise(resolve => {
navigator.serviceWorker.onmessage = evt => {
resolve(evt.data);
}
});
}


async function start() {
await setup();
if (!navigator.serviceWorker.controller) {
// The browser will reload this background page so it gets controlled.
return;
}

// Start the shared worker. It should send a message about the resources it
// loaded.
const sharedWorker = new SharedWorker('shared_worker.js');
sharedWorker.port.start();
const kExpectedMessage = [
'CONNECTED',
'SCRIPT_IMPORTED',
'FETCHED'
];
const data = await getMessageFromWorker(sharedWorker);
if (data.length != kExpectedMessage.length) {
throw new Error('bad message length: ' +
`expected ${kExpectedMessage.length}, got ${data.length}`);
}
for (let i = 0; i < data.length; i++) {
if (data[i] != kExpectedMessage[i]) {
throw new Error(
`bad message: expected ${kExpectedMessage[i]}, got ${data[i]}`);
}
}

// Ask the service worker what URLs it intercepted.
navigator.serviceWorker.controller.postMessage('tell me what urls you saw');
const urls = await getMessageFromServiceWorker();
const kExpectedUrls = [
'background.html',
'background.js',
'shared_worker.js',
'shared_worker_import.js',
'data_for_fetch'
];
if (urls.length != kExpectedUrls.length) {
throw new Error(
`bad urls: expected ${kExpectedUrls.length}, got ${urls.length}`);
}
for (let i = 0; i < urls.length; i++) {
const expected = new URL(kExpectedUrls[i], self.location).toString();
if (urls[i] != expected)
throw new Error(`bad url: expected ${expected}, got ${urls[i]}`);
}

chrome.test.sendMessage('PASS');
}

start().catch(err => {
console.error(err.name + ': ' + err.message);
chrome.test.sendMessage('FAIL');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FETCHED
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "Shared worker",
"version": "1.0",
"manifest_version": 2,
"background": {
"page": "background.html",
"persistent": false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2018 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.

let urlsSeen = [];

self.addEventListener('fetch', e => {
urlsSeen.push(e.request.url);
});

self.addEventListener('message', e => {
e.source.postMessage(urlsSeen);
urlsSeen = [];
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2018 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.

let importScriptsGreeting;
let message = [];

self.onconnect = async function(e) {
const port = e.ports[0];
port.start();
message.push('CONNECTED');

// The import scripts writes to |importScriptsGreeting|.
importScripts('shared_worker_import.js');
message.push(importScriptsGreeting);

const resp = await fetch(new URL('data_for_fetch', self.location));
const text = await resp.text();
message.push(text.trim());

port.postMessage(message);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright 2018 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.

importScriptsGreeting = 'SCRIPT_IMPORTED';
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@
# to work with network service.
-ConditionalCacheCountingHelperBrowserTest.Count

# https://crbug.com/839982
-ExtensionApiTest.SharedWorker_ControlledByServiceWorker

# NOTE: if adding an exclusion for an existing failure (e.g. additional test for
# feature X that is already not working), please add it beside the existing
# failures. Otherwise please reach out to network-service-dev@.

0 comments on commit 62628bf

Please sign in to comment.