зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1662925 - Part 1: Test fetch intercepting spawning a serviceworker process, r=asuth
This is a WIP patch, and currently fails. Differential Revision: https://phabricator.services.mozilla.com/D91173
This commit is contained in:
Родитель
c6c98b8cbc
Коммит
52eb306b64
|
@ -22,3 +22,6 @@ support-files =
|
|||
support-files =
|
||||
file_service_worker.js
|
||||
file_service_worker_container.html
|
||||
[browser_serviceworker_fetch_new_process.js]
|
||||
support-files =
|
||||
file_service_worker_fetch_synthetic.js
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
const DIRPATH = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content/",
|
||||
""
|
||||
);
|
||||
|
||||
add_task(async function setup() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["browser.tabs.remote.separatePrivilegedMozillaWebContentProcess", true],
|
||||
["browser.tabs.remote.separatedMozillaDomains", "example.org"],
|
||||
["dom.ipc.processCount.privilegedmozilla", 1],
|
||||
["dom.ipc.processCount.webIsolated", 1],
|
||||
["dom.ipc.processPrelaunch.enabled", false],
|
||||
["dom.serviceWorkers.enabled", true],
|
||||
["dom.serviceWorkers.testing.enabled", true],
|
||||
["dom.serviceworkers.parent_intercept", true],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
function countRemoteType(remoteType) {
|
||||
return ChromeUtils.getAllDOMProcesses().filter(
|
||||
p => p.remoteType == remoteType
|
||||
).length;
|
||||
}
|
||||
|
||||
async function waitForWorkerIdleShutdown(swRegInfo, remoteType) {
|
||||
info(`waiting for ${remoteType} procs to shut down`);
|
||||
ok(swRegInfo.activeWorker, "worker isn't currently active?");
|
||||
is(
|
||||
countRemoteType(remoteType),
|
||||
1,
|
||||
`should have a single ${remoteType} process`
|
||||
);
|
||||
|
||||
// Let's not wait too long for the process to shutdown.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.serviceWorkers.idle_timeout", 0],
|
||||
["dom.serviceWorkers.idle_extended_timeout", 0],
|
||||
],
|
||||
});
|
||||
|
||||
// We need to cause the worker to re-evaluate its idle timeout. The easiest
|
||||
// way to do this I could think of is to attach and then detach the debugger
|
||||
// from the active worker.
|
||||
swRegInfo.activeWorker.attachDebugger();
|
||||
await new Promise(resolve => Cu.dispatch(resolve));
|
||||
swRegInfo.activeWorker.detachDebugger();
|
||||
|
||||
// Eventually the length will reach 0, meaning we're done!
|
||||
await TestUtils.waitForCondition(
|
||||
() => countRemoteType(remoteType) == 0,
|
||||
"wait for the worker's process to shutdown"
|
||||
);
|
||||
|
||||
is(
|
||||
countRemoteType(remoteType),
|
||||
0,
|
||||
"processes with `remoteType` type should have shut down"
|
||||
);
|
||||
|
||||
// Make sure we never kill workers on idle except when this is called.
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["dom.serviceWorkers.idle_timeout", 299999],
|
||||
["dom.serviceWorkers.idle_extended_timeout", 299999],
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
async function do_test_sw(host, remoteType) {
|
||||
info(`entering test: host=${host}, remoteType=${remoteType}`);
|
||||
|
||||
const prin = Services.scriptSecurityManager.createContentPrincipal(
|
||||
Services.io.newURI(`https://${host}`),
|
||||
{}
|
||||
);
|
||||
const sw = `https://${host}/${DIRPATH}file_service_worker_fetch_synthetic.js`;
|
||||
const scope = `https://${host}/${DIRPATH}scope`;
|
||||
|
||||
const swm = Cc["@mozilla.org/serviceworkers/manager;1"].getService(
|
||||
Ci.nsIServiceWorkerManager
|
||||
);
|
||||
const swRegInfo = await swm.registerForTest(prin, scope, sw);
|
||||
swRegInfo.QueryInterface(Ci.nsIServiceWorkerRegistrationInfo);
|
||||
|
||||
info(
|
||||
`service worker registered: ${JSON.stringify({
|
||||
principal: swRegInfo.principal.spec,
|
||||
scope: swRegInfo.scope,
|
||||
})}`
|
||||
);
|
||||
|
||||
// Wait for the worker to install & shut down.
|
||||
await TestUtils.waitForCondition(
|
||||
() => swRegInfo.activeWorker,
|
||||
"wait for the worker to become active"
|
||||
);
|
||||
await waitForWorkerIdleShutdown(swRegInfo, remoteType);
|
||||
|
||||
await BrowserTestUtils.withNewTab("about:blank", async browser => {
|
||||
// NOTE: We intentionally trigger the navigation from content in order to
|
||||
// make sure frontend doesn't eagerly process-switch for us.
|
||||
SpecialPowers.spawn(browser, [scope], async scope => {
|
||||
content.location.href = `${scope}/intercepted.html`;
|
||||
});
|
||||
await BrowserTestUtils.browserLoaded(browser);
|
||||
|
||||
is(
|
||||
countRemoteType(remoteType),
|
||||
1,
|
||||
"should have spawned a content process with the correct remoteType"
|
||||
);
|
||||
|
||||
// Ensure the worker was loaded in this process.
|
||||
const workerDebuggerURLs = await SpecialPowers.spawn(
|
||||
browser,
|
||||
[sw],
|
||||
async url => {
|
||||
await content.navigator.serviceWorker.ready;
|
||||
const wdm = Cc[
|
||||
"@mozilla.org/dom/workers/workerdebuggermanager;1"
|
||||
].getService(Ci.nsIWorkerDebuggerManager);
|
||||
|
||||
return Array.from(wdm.getWorkerDebuggerEnumerator())
|
||||
.map(wd => {
|
||||
return wd.url;
|
||||
})
|
||||
.filter(swURL => swURL == url);
|
||||
}
|
||||
);
|
||||
Assert.deepEqual(
|
||||
workerDebuggerURLs,
|
||||
[sw],
|
||||
"The worker should be running in the correct child process"
|
||||
);
|
||||
|
||||
// Unregister the worker.
|
||||
await SpecialPowers.spawn(browser, [], async () => {
|
||||
let registration = await content.navigator.serviceWorker.ready;
|
||||
await registration.unregister();
|
||||
});
|
||||
});
|
||||
|
||||
await waitForWorkerIdleShutdown(swRegInfo, remoteType);
|
||||
}
|
||||
|
||||
add_task(async function test() {
|
||||
await do_test_sw("example.org", "privilegedmozilla");
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
addEventListener("install", function(evt) {
|
||||
evt.waitUntil(self.skipWaiting());
|
||||
});
|
||||
|
||||
self.addEventListener("fetch", event => {
|
||||
event.respondWith(
|
||||
new Response(
|
||||
`<!DOCTYPE HTML><body>
|
||||
<h1 id="url">${event.request.url}</h1>
|
||||
<h1 id="location">${self.location.href}</h1>
|
||||
</body>`,
|
||||
{ headers: { "Content-Type": "text/html" } }
|
||||
)
|
||||
);
|
||||
});
|
Загрузка…
Ссылка в новой задаче