tor-browser

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

browser_worker_use_counters.js (5674B)


      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 "use strict";
      5 
      6 const gHttpTestRoot = "https://example.com/browser/dom/workers/test/";
      7 
      8 function unscream(s) {
      9  // Takes SCREAMINGCASE `s` and returns "Screamingcase".
     10  return s.charAt(0) + s.slice(1).toLowerCase();
     11 }
     12 
     13 function screamToCamel(s) {
     14  // Takes SCREAMING_CASE `s` and returns "screamingCase".
     15  const pascal = s.split("_").map(unscream).join("");
     16  return pascal.charAt(0).toLowerCase() + pascal.slice(1);
     17 }
     18 
     19 var check_use_counter_worker = async function (
     20  use_counter_name,
     21  worker_type,
     22  content_task
     23 ) {
     24  info(`checking ${use_counter_name} use counters for ${worker_type} worker`);
     25 
     26  let newTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
     27  gBrowser.selectedTab = newTab;
     28  newTab.linkedBrowser.stop();
     29 
     30  // Hold on to the current values of the instrumentation we're
     31  // interested in.
     32  await Services.fog.testFlushAllChildren();
     33  let glean_before =
     34    Glean[`useCounterWorker${unscream(worker_type)}`][
     35      screamToCamel(use_counter_name)
     36    ].testGetValue();
     37  let glean_destructions_before =
     38    Glean.useCounter[
     39      `${worker_type.toLowerCase()}WorkersDestroyed`
     40    ].testGetValue();
     41 
     42  BrowserTestUtils.startLoadingURIString(
     43    gBrowser.selectedBrowser,
     44    gHttpTestRoot + "file_use_counter_worker.html"
     45  );
     46  await BrowserTestUtils.browserLoaded(gBrowser.selectedBrowser);
     47  await content_task(gBrowser.selectedBrowser);
     48 
     49  // Tear down the page.
     50  let tabClosed = BrowserTestUtils.waitForTabClosing(newTab);
     51  gBrowser.removeTab(newTab);
     52  await tabClosed;
     53 
     54  // Grab data again and compare.
     55  // We'd like for this to be synchronous, but use counters are reported on
     56  // worker destruction which we don't directly observe.
     57  // So we check in a quick loop.
     58  await BrowserTestUtils.waitForCondition(async () => {
     59    await Services.fog.testFlushAllChildren();
     60    return (
     61      glean_before !=
     62      Glean[`useCounterWorker${unscream(worker_type)}`][
     63        screamToCamel(use_counter_name)
     64      ].testGetValue()
     65    );
     66  });
     67  let glean_after =
     68    Glean[`useCounterWorker${unscream(worker_type)}`][
     69      screamToCamel(use_counter_name)
     70    ].testGetValue();
     71  let glean_destructions_after =
     72    Glean.useCounter[
     73      `${worker_type.toLowerCase()}WorkersDestroyed`
     74    ].testGetValue();
     75 
     76  is(
     77    glean_after,
     78    glean_before + 1,
     79    `Glean counter ${use_counter_name} for ${worker_type} worker is correct.`
     80  );
     81  // There might be other workers created by prior tests get destroyed during
     82  // this tests.
     83  Assert.greater(
     84    glean_destructions_after,
     85    glean_destructions_before ?? 0,
     86    `Glean ${worker_type} worker counts are correct`
     87  );
     88 };
     89 
     90 add_task(async function test_dedicated_worker() {
     91  await check_use_counter_worker("CONSOLE_LOG", "DEDICATED", async browser => {
     92    await ContentTask.spawn(browser, {}, function () {
     93      return new Promise(resolve => {
     94        let worker = new content.Worker("file_use_counter_worker.js");
     95        worker.onmessage = function (e) {
     96          if (e.data === "DONE") {
     97            worker.terminate();
     98            resolve();
     99          }
    100        };
    101      });
    102    });
    103  });
    104 });
    105 
    106 add_task(async function test_shared_worker() {
    107  await check_use_counter_worker("CONSOLE_LOG", "SHARED", async browser => {
    108    await ContentTask.spawn(browser, {}, function () {
    109      return new Promise(resolve => {
    110        let worker = new content.SharedWorker(
    111          "file_use_counter_shared_worker.js"
    112        );
    113        worker.port.onmessage = function (e) {
    114          if (e.data === "DONE") {
    115            resolve();
    116          }
    117        };
    118        worker.port.postMessage("RUN");
    119      });
    120    });
    121  });
    122 });
    123 
    124 add_task(async function test_shared_worker_microtask() {
    125  await check_use_counter_worker("CONSOLE_LOG", "SHARED", async browser => {
    126    await ContentTask.spawn(browser, {}, function () {
    127      return new Promise(resolve => {
    128        let worker = new content.SharedWorker(
    129          "file_use_counter_shared_worker_microtask.js"
    130        );
    131        worker.port.onmessage = function (e) {
    132          if (e.data === "DONE") {
    133            resolve();
    134          }
    135        };
    136        worker.port.postMessage("RUN");
    137      });
    138    });
    139  });
    140 });
    141 
    142 add_task(async function test_service_worker() {
    143  await check_use_counter_worker("CONSOLE_LOG", "SERVICE", async browser => {
    144    await ContentTask.spawn(browser, {}, function () {
    145      let waitForActivated = async function (registration) {
    146        return new Promise(resolve => {
    147          let worker =
    148            registration.installing ||
    149            registration.waiting ||
    150            registration.active;
    151          if (worker.state === "activated") {
    152            resolve(worker);
    153            return;
    154          }
    155 
    156          worker.addEventListener("statechange", function onStateChange() {
    157            if (worker.state === "activated") {
    158              worker.removeEventListener("statechange", onStateChange);
    159              resolve(worker);
    160            }
    161          });
    162        });
    163      };
    164 
    165      return new Promise(resolve => {
    166        content.navigator.serviceWorker
    167          .register("file_use_counter_service_worker.js")
    168          .then(async registration => {
    169            content.navigator.serviceWorker.onmessage = function (e) {
    170              if (e.data === "DONE") {
    171                registration.unregister().then(resolve);
    172              }
    173            };
    174            let worker = await waitForActivated(registration);
    175            worker.postMessage("RUN");
    176          });
    177      });
    178    });
    179  });
    180 });