tor-browser

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

test_dominator_trees_06.js (4179B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test that we can incrementally fetch a subtree of a dominator tree.
      7 
      8 const {
      9  dominatorTreeState,
     10  viewState,
     11 } = require("resource://devtools/client/memory/constants.js");
     12 const {
     13  takeSnapshotAndCensus,
     14  fetchImmediatelyDominated,
     15 } = require("resource://devtools/client/memory/actions/snapshot.js");
     16 const DominatorTreeLazyChildren = require("resource://devtools/client/memory/dominator-tree-lazy-children.js");
     17 
     18 const {
     19  changeView,
     20 } = require("resource://devtools/client/memory/actions/view.js");
     21 
     22 add_task(async function () {
     23  const front = new StubbedMemoryFront();
     24  const heapWorker = new HeapAnalysesClient();
     25  await front.attach();
     26  const store = Store();
     27  const { getState, dispatch } = store;
     28 
     29  dispatch(changeView(viewState.DOMINATOR_TREE));
     30  dispatch(takeSnapshotAndCensus(front, heapWorker));
     31 
     32  // Wait for the dominator tree to finish being fetched.
     33  await waitUntilState(
     34    store,
     35    state =>
     36      state.snapshots[0] &&
     37      state.snapshots[0].dominatorTree &&
     38      state.snapshots[0].dominatorTree.state === dominatorTreeState.LOADED
     39  );
     40  ok(
     41    getState().snapshots[0].dominatorTree.root,
     42    "The dominator tree was fetched"
     43  );
     44 
     45  // Find a node that has children, but none of them are loaded.
     46 
     47  function findNode(node) {
     48    if (node.moreChildrenAvailable && !node.children) {
     49      return node;
     50    }
     51 
     52    if (node.children) {
     53      for (const child of node.children) {
     54        const found = findNode(child);
     55        if (found) {
     56          return found;
     57        }
     58      }
     59    }
     60 
     61    return null;
     62  }
     63 
     64  const oldRoot = getState().snapshots[0].dominatorTree.root;
     65  const oldNode = findNode(oldRoot);
     66  ok(
     67    oldNode,
     68    "Should have found a node with children that are not loaded since we " +
     69      "only send partial dominator trees across initially and load the rest " +
     70      "on demand"
     71  );
     72  Assert.notStrictEqual(
     73    oldNode,
     74    oldRoot,
     75    "But the node should not be the root"
     76  );
     77 
     78  const lazyChildren = new DominatorTreeLazyChildren(oldNode.nodeId, 0);
     79  dispatch(
     80    fetchImmediatelyDominated(
     81      heapWorker,
     82      getState().snapshots[0].id,
     83      lazyChildren
     84    )
     85  );
     86 
     87  equal(
     88    getState().snapshots[0].dominatorTree.state,
     89    dominatorTreeState.INCREMENTAL_FETCHING,
     90    "Fetching immediately dominated children should put us in the " +
     91      "INCREMENTAL_FETCHING state"
     92  );
     93 
     94  await waitUntilState(
     95    store,
     96    state =>
     97      state.snapshots[0].dominatorTree.state === dominatorTreeState.LOADED
     98  );
     99  ok(
    100    true,
    101    "The dominator tree should go back to LOADED after the incremental " +
    102      "fetching is done."
    103  );
    104 
    105  const newRoot = getState().snapshots[0].dominatorTree.root;
    106  Assert.notStrictEqual(
    107    oldRoot,
    108    newRoot,
    109    "When we insert new nodes, we get a new tree"
    110  );
    111  equal(
    112    oldRoot.children.length,
    113    newRoot.children.length,
    114    "The new tree's root should have the same number of children as the " +
    115      "old root's"
    116  );
    117 
    118  let differentChildrenCount = 0;
    119  for (let i = 0; i < oldRoot.children.length; i++) {
    120    if (oldRoot.children[i] !== newRoot.children[i]) {
    121      differentChildrenCount++;
    122    }
    123  }
    124  equal(
    125    differentChildrenCount,
    126    1,
    127    "All subtrees except the subtree we inserted incrementally fetched " +
    128      "children into should be the same because we use persistent updates"
    129  );
    130 
    131  // Find the new node which has the children inserted.
    132 
    133  function findNewNode(node) {
    134    if (node.nodeId === oldNode.nodeId) {
    135      return node;
    136    }
    137 
    138    if (node.children) {
    139      for (const child of node.children) {
    140        const found = findNewNode(child);
    141        if (found) {
    142          return found;
    143        }
    144      }
    145    }
    146 
    147    return null;
    148  }
    149 
    150  const newNode = findNewNode(newRoot);
    151  ok(newNode, "Should find the node in the new tree again");
    152  Assert.notStrictEqual(
    153    newNode,
    154    oldNode,
    155    "We did not mutate the old node in place, instead created a new node"
    156  );
    157  ok(newNode.children, "And the new node should have the children attached");
    158 
    159  heapWorker.destroy();
    160  await front.detach();
    161 });