tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

browser_content_shutdown_with_endless_js.js (2719B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const EMPTY_PAGE =
      8  "http://mochi.test:8888/browser/dom/ipc/tests/file_dummy.html";
      9 
     10 const HANG_PAGE =
     11  "http://mochi.test:8888/browser/dom/ipc/tests/file_endless_js.html";
     12 
     13 function pushPref(name, val) {
     14  return SpecialPowers.pushPrefEnv({ set: [[name, val]] });
     15 }
     16 
     17 async function createAndShutdownContentProcess(url) {
     18  info("Create and shutdown a content process for " + url);
     19 
     20  // Launch a new process and load url. Sets up a promise that will resolve
     21  // on shutdown.
     22  let browserDestroyed = Promise.withResolvers();
     23  await BrowserTestUtils.withNewTab(
     24    {
     25      gBrowser,
     26      opening: url,
     27      waitForLoad: true,
     28      forceNewProcess: true,
     29    },
     30    async function (otherBrowser) {
     31      let remoteTab = otherBrowser.frameLoader.remoteTab;
     32 
     33      ok(true, "Content process created.");
     34 
     35      browserDestroyed.resolve(
     36        TestUtils.topicObserved(
     37          "ipc:browser-destroyed",
     38          subject => subject === remoteTab
     39        )
     40      );
     41 
     42      // Trigger onmessage in the content browser
     43      await SpecialPowers.spawn(otherBrowser, [], function () {
     44        content.postMessage("LoadedMessage", "*");
     45      });
     46 
     47      // Give the content process some extra time before we start its shutdown.
     48      // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
     49      await new Promise(resolve => setTimeout(resolve, 50));
     50 
     51      // withNewTab will start the shutdown of the child process for us
     52    }
     53  );
     54 
     55  // Now wait for it to really shut down.
     56  // If the HANG_PAGE JS is not canceled we will hang here.
     57  await browserDestroyed.promise;
     58 
     59  // If we do not hang and get here, we are fine.
     60  ok(true, "Shutdown of content process.");
     61 }
     62 
     63 add_task(async () => {
     64  // This test is only relevant in e10s.
     65  if (!gMultiProcessBrowser) {
     66    ok(true, "We are not in multiprocess mode, skipping test.");
     67    return;
     68  }
     69 
     70  await pushPref("dom.abort_script_on_child_shutdown", true);
     71 
     72  // Ensure the process cache cannot interfere.
     73  pushPref("dom.ipc.processPreload.enabled", false);
     74  // Ensure we have no cached processes from previous tests.
     75  Services.ppmm.releaseCachedProcesses();
     76 
     77  // First let's do a dry run that should always succeed.
     78  await createAndShutdownContentProcess(EMPTY_PAGE);
     79 
     80  // Now we will start a shutdown of our content process while our content
     81  // script is running an endless loop.
     82  //
     83  // If the JS does not get interrupted on shutdown, it will cause this test
     84  // to hang.
     85  await createAndShutdownContentProcess(HANG_PAGE);
     86 });