Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const EMPTY_PAGE =
const HANG_PAGE =
function pushPref(name, val) {
return SpecialPowers.pushPrefEnv({ set: [[name, val]] });
}
async function createAndShutdownContentProcess(url) {
info("Create and shutdown a content process for " + url);
// Launch a new process and load url. Sets up a promise that will resolve
// on shutdown.
let browserDestroyed = Promise.withResolvers();
await BrowserTestUtils.withNewTab(
{
gBrowser,
opening: url,
waitForLoad: true,
forceNewProcess: true,
},
async function (otherBrowser) {
let remoteTab = otherBrowser.frameLoader.remoteTab;
ok(true, "Content process created.");
browserDestroyed.resolve(
TestUtils.topicObserved(
"ipc:browser-destroyed",
subject => subject === remoteTab
)
);
// Trigger onmessage in the content browser
await SpecialPowers.spawn(otherBrowser, [], function () {
content.postMessage("LoadedMessage", "*");
});
// Give the content process some extra time before we start its shutdown.
// eslint-disable-next-line mozilla/no-arbitrary-setTimeout
await new Promise(resolve => setTimeout(resolve, 50));
// withNewTab will start the shutdown of the child process for us
}
);
// Now wait for it to really shut down.
// If the HANG_PAGE JS is not canceled we will hang here.
await browserDestroyed.promise;
// If we do not hang and get here, we are fine.
ok(true, "Shutdown of content process.");
}
add_task(async () => {
// This test is only relevant in e10s.
if (!gMultiProcessBrowser) {
ok(true, "We are not in multiprocess mode, skipping test.");
return;
}
await pushPref("dom.abort_script_on_child_shutdown", true);
// Ensure the process cache cannot interfere.
pushPref("dom.ipc.processPreload.enabled", false);
// Ensure we have no cached processes from previous tests.
Services.ppmm.releaseCachedProcesses();
// First let's do a dry run that should always succeed.
await createAndShutdownContentProcess(EMPTY_PAGE);
// Now we will start a shutdown of our content process while our content
// script is running an endless loop.
//
// If the JS does not get interrupted on shutdown, it will cause this test
// to hang.
await createAndShutdownContentProcess(HANG_PAGE);
});