tor-browser

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

test_remoteworker_launch_new_process.js (3820B)


      1 /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
      2 /* vim: set sts=2 sw=2 et tw=80: */
      3 "use strict";
      4 
      5 // We don't normally allow localhost channels to be proxied, but this
      6 // is easier than updating all the certs and/or domains.
      7 Services.prefs.setBoolPref("network.proxy.allow_hijacking_localhost", true);
      8 registerCleanupFunction(() => {
      9  Services.prefs.clearUserPref("network.proxy.allow_hijacking_localhost");
     10 });
     11 
     12 const { TestUtils } = ChromeUtils.importESModule(
     13  "resource://testing-common/TestUtils.sys.mjs"
     14 );
     15 
     16 const { AddonTestUtils } = ChromeUtils.importESModule(
     17  "resource://testing-common/AddonTestUtils.sys.mjs"
     18 );
     19 const { createHttpServer } = AddonTestUtils;
     20 
     21 // Force ServiceWorkerRegistrar to init by calling do_get_profile.
     22 // (This has to be called before AddonTestUtils.init, because it does
     23 // also call do_get_profile internally but it doesn't notify
     24 // profile-after-change).
     25 do_get_profile(true);
     26 
     27 AddonTestUtils.init(this);
     28 
     29 const server = createHttpServer({ hosts: ["localhost"] });
     30 
     31 server.registerPathHandler("/sw.js", (request, response) => {
     32  info(`/sw.js is being requested: ${JSON.stringify(request)}`);
     33  response.setHeader("Content-Type", "application/javascript");
     34  response.write("");
     35 });
     36 
     37 add_task(async function setup_prefs() {
     38  // Enable nsIServiceWorkerManager.registerForTest.
     39  Services.prefs.setBoolPref("dom.serviceWorkers.testing.enabled", true);
     40 
     41  registerCleanupFunction(() => {
     42    Services.prefs.clearUserPref("dom.serviceWorkers.testing.enabled");
     43  });
     44 });
     45 
     46 /**
     47 * This test installs a ServiceWorker via test API and verify that the install
     48 * process spawns a new process. (Normally ServiceWorker installation won't
     49 * cause a new content process to be spawned because the call to register must
     50 * be coming from within an existing content process, but the registerForTest
     51 * API allows us to bypass this restriction.)
     52 *
     53 * This models the real-world situation of a push notification being received
     54 * from the network which results in a ServiceWorker being spawned without their
     55 * necessarily being an existing content process to host it (especially under Fission).
     56 */
     57 add_task(async function launch_remoteworkers_in_new_processes() {
     58  const swm = Cc["@mozilla.org/serviceworkers/manager;1"].getService(
     59    Ci.nsIServiceWorkerManager
     60  );
     61 
     62  const ssm = Services.scriptSecurityManager;
     63 
     64  const initialChildCount = Services.ppmm.childCount;
     65 
     66  // A test service worker that should spawn a regular web content child process.
     67  const swRegInfoWeb = await swm.registerForTest(
     68    ssm.createContentPrincipal(Services.io.newURI("http://localhost"), {}),
     69    "http://localhost/scope",
     70    "http://localhost/sw.js"
     71  );
     72  swRegInfoWeb.QueryInterface(Ci.nsIServiceWorkerRegistrationInfo);
     73 
     74  info(
     75    `web content service worker registered: ${JSON.stringify({
     76      principal: swRegInfoWeb.principal.spec,
     77      scope: swRegInfoWeb.scope,
     78    })}`
     79  );
     80 
     81  info("Wait new process to be launched");
     82  await TestUtils.waitForCondition(() => {
     83    return Services.ppmm.childCount - initialChildCount >= 1;
     84  }, "wait for a new child processes to be started");
     85 
     86  // Wait both workers to become active to ensure script loading completed
     87  // successfully.  Note that when this test was originally introduced, we had a
     88  // method IsRemoteTypeAllowed which would be run in the content process as an
     89  // additional check that we ended up in the process we expected.  Improvements
     90  // in bug 1901851 and other bugs eliminated that concern, so now all we care
     91  // about is that script loading completes and thereby allows the SW to advance
     92  // to active.
     93  info("Wait for webcontent worker to become active");
     94  await TestUtils.waitForCondition(
     95    () => swRegInfoWeb.activeWorker,
     96    `wait workers for scope ${swRegInfoWeb.scope} to be active`
     97  );
     98 });