tor-browser

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

head.js (5333B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // via xpcshell.toml
      7 /* import-globals-from ../../../shared/test/shared-head.js */
      8 
      9 Services.prefs.setBoolPref("devtools.testing", true);
     10 Services.prefs.setBoolPref("devtools.debugger.log", true);
     11 registerCleanupFunction(() => {
     12  Services.prefs.clearUserPref("devtools.testing");
     13  Services.prefs.clearUserPref("devtools.debugger.log");
     14 });
     15 
     16 var { FileUtils } = ChromeUtils.importESModule(
     17  "resource://gre/modules/FileUtils.sys.mjs"
     18 );
     19 var { expectState } = require("resource://devtools/server/actors/common.js");
     20 var HeapSnapshotFileUtils = require("resource://devtools/shared/heapsnapshot/HeapSnapshotFileUtils.js");
     21 var HeapAnalysesClient = require("resource://devtools/shared/heapsnapshot/HeapAnalysesClient.js");
     22 var { addDebuggerToGlobal } = ChromeUtils.importESModule(
     23  "resource://gre/modules/jsdebugger.sys.mjs"
     24 );
     25 var Store = require("resource://devtools/client/memory/store.js");
     26 var { L10N } = require("resource://devtools/client/memory/utils.js");
     27 var SYSTEM_PRINCIPAL = Cc["@mozilla.org/systemprincipal;1"].createInstance(
     28  Ci.nsIPrincipal
     29 );
     30 
     31 var EXPECTED_DTU_ASSERT_FAILURE_COUNT = 0;
     32 
     33 registerCleanupFunction(function () {
     34  equal(
     35    DevToolsUtils.assertionFailureCount,
     36    EXPECTED_DTU_ASSERT_FAILURE_COUNT,
     37    "Should have had the expected number of DevToolsUtils.assert() failures."
     38  );
     39 });
     40 
     41 function dumpn(msg) {
     42  dump(`MEMORY-TEST: ${msg}\n`);
     43 }
     44 
     45 function initDebugger() {
     46  const global = new Cu.Sandbox(SYSTEM_PRINCIPAL, { freshZone: true });
     47  addDebuggerToGlobal(global);
     48  return new global.Debugger();
     49 }
     50 
     51 function StubbedMemoryFront() {
     52  this.state = "detached";
     53  this.dbg = initDebugger();
     54 }
     55 
     56 StubbedMemoryFront.prototype.attach = async function () {
     57  this.state = "attached";
     58 };
     59 
     60 StubbedMemoryFront.prototype.detach = async function () {
     61  this.state = "detached";
     62 };
     63 
     64 StubbedMemoryFront.prototype.saveHeapSnapshot = expectState(
     65  "attached",
     66  async function () {
     67    return ChromeUtils.saveHeapSnapshot({ runtime: true });
     68  },
     69  "saveHeapSnapshot"
     70 );
     71 
     72 StubbedMemoryFront.prototype.startRecordingAllocations = expectState(
     73  "attached",
     74  async function () {}
     75 );
     76 
     77 StubbedMemoryFront.prototype.stopRecordingAllocations = expectState(
     78  "attached",
     79  async function () {}
     80 );
     81 
     82 function waitUntilSnapshotState(store, expected) {
     83  const predicate = () => {
     84    const snapshots = store.getState().snapshots;
     85    info(snapshots.map(x => x.state));
     86    return (
     87      snapshots.length === expected.length &&
     88      expected.every(
     89        (state, i) => state === "*" || snapshots[i].state === state
     90      )
     91    );
     92  };
     93  info(`Waiting for snapshots to be of state: ${expected}`);
     94  return waitUntilState(store, predicate);
     95 }
     96 
     97 function findReportLeafIndex(node, name = null) {
     98  if (node.reportLeafIndex && (!name || node.name === name)) {
     99    return node.reportLeafIndex;
    100  }
    101 
    102  if (node.children) {
    103    for (const child of node.children) {
    104      const found = findReportLeafIndex(child);
    105      if (found) {
    106        return found;
    107      }
    108    }
    109  }
    110 
    111  return null;
    112 }
    113 
    114 function waitUntilCensusState(store, getCensus, expected) {
    115  const predicate = () => {
    116    const snapshots = store.getState().snapshots;
    117 
    118    info(
    119      "Current census state:" +
    120        snapshots.map(x => (getCensus(x) ? getCensus(x).state : null))
    121    );
    122 
    123    return (
    124      snapshots.length === expected.length &&
    125      expected.every((state, i) => {
    126        const census = getCensus(snapshots[i]);
    127        return (
    128          state === "*" ||
    129          (!census && !state) ||
    130          (census && census.state === state)
    131        );
    132      })
    133    );
    134  };
    135  info(`Waiting for snapshots' censuses to be of state: ${expected}`);
    136  return waitUntilState(store, predicate);
    137 }
    138 
    139 async function createTempFile() {
    140  const file = new FileUtils.File(
    141    PathUtils.join(PathUtils.tempDir, "tmp.fxsnapshot")
    142  );
    143  file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE);
    144  const destPath = file.path;
    145  const stat = await IOUtils.stat(destPath);
    146  Assert.strictEqual(stat.size, 0, "new file is 0 bytes at start");
    147  return destPath;
    148 }
    149 
    150 // This is a copy of the same method from shared-head.js as
    151 // xpcshell test aren't using shared-head.js
    152 /**
    153 * Wait for a specific action type to be dispatched.
    154 *
    155 * If the action is async and defines a `status` property, this helper will wait
    156 * for the status to reach either "error" or "done".
    157 *
    158 * @param {object} store
    159 *        Redux store where the action should be dispatched.
    160 * @param {string} actionType
    161 *        The actionType to wait for.
    162 * @param {number} repeat
    163 *        Optional, number of time the action is expected to be dispatched.
    164 *        Defaults to 1
    165 * @return {Promise}
    166 */
    167 function waitForDispatch(store, actionType, repeat = 1) {
    168  let count = 0;
    169  return new Promise(resolve => {
    170    store.dispatch({
    171      type: "@@service/waitUntil",
    172      predicate: action => {
    173        const isDone =
    174          !action.status ||
    175          action.status === "done" ||
    176          action.status === "error";
    177 
    178        if (action.type === actionType && isDone && ++count == repeat) {
    179          return true;
    180        }
    181 
    182        return false;
    183      },
    184      run: (dispatch, getState, action) => {
    185        resolve(action);
    186      },
    187    });
    188  });
    189 }