summaryrefslogtreecommitdiffstats
path: root/devtools/client/memory/test/xpcshell/test_dominator_trees_06.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/memory/test/xpcshell/test_dominator_trees_06.js')
-rw-r--r--devtools/client/memory/test/xpcshell/test_dominator_trees_06.js161
1 files changed, 161 insertions, 0 deletions
diff --git a/devtools/client/memory/test/xpcshell/test_dominator_trees_06.js b/devtools/client/memory/test/xpcshell/test_dominator_trees_06.js
new file mode 100644
index 0000000000..7caffb972e
--- /dev/null
+++ b/devtools/client/memory/test/xpcshell/test_dominator_trees_06.js
@@ -0,0 +1,161 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Test that we can incrementally fetch a subtree of a dominator tree.
+
+const {
+ dominatorTreeState,
+ viewState,
+} = require("resource://devtools/client/memory/constants.js");
+const {
+ takeSnapshotAndCensus,
+ fetchImmediatelyDominated,
+} = require("resource://devtools/client/memory/actions/snapshot.js");
+const DominatorTreeLazyChildren = require("resource://devtools/client/memory/dominator-tree-lazy-children.js");
+
+const {
+ changeView,
+} = require("resource://devtools/client/memory/actions/view.js");
+
+add_task(async function () {
+ const front = new StubbedMemoryFront();
+ const heapWorker = new HeapAnalysesClient();
+ await front.attach();
+ const store = Store();
+ const { getState, dispatch } = store;
+
+ dispatch(changeView(viewState.DOMINATOR_TREE));
+ dispatch(takeSnapshotAndCensus(front, heapWorker));
+
+ // Wait for the dominator tree to finish being fetched.
+ await waitUntilState(
+ store,
+ state =>
+ state.snapshots[0] &&
+ state.snapshots[0].dominatorTree &&
+ state.snapshots[0].dominatorTree.state === dominatorTreeState.LOADED
+ );
+ ok(
+ getState().snapshots[0].dominatorTree.root,
+ "The dominator tree was fetched"
+ );
+
+ // Find a node that has children, but none of them are loaded.
+
+ function findNode(node) {
+ if (node.moreChildrenAvailable && !node.children) {
+ return node;
+ }
+
+ if (node.children) {
+ for (const child of node.children) {
+ const found = findNode(child);
+ if (found) {
+ return found;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ const oldRoot = getState().snapshots[0].dominatorTree.root;
+ const oldNode = findNode(oldRoot);
+ ok(
+ oldNode,
+ "Should have found a node with children that are not loaded since we " +
+ "only send partial dominator trees across initially and load the rest " +
+ "on demand"
+ );
+ Assert.notStrictEqual(
+ oldNode,
+ oldRoot,
+ "But the node should not be the root"
+ );
+
+ const lazyChildren = new DominatorTreeLazyChildren(oldNode.nodeId, 0);
+ dispatch(
+ fetchImmediatelyDominated(
+ heapWorker,
+ getState().snapshots[0].id,
+ lazyChildren
+ )
+ );
+
+ equal(
+ getState().snapshots[0].dominatorTree.state,
+ dominatorTreeState.INCREMENTAL_FETCHING,
+ "Fetching immediately dominated children should put us in the " +
+ "INCREMENTAL_FETCHING state"
+ );
+
+ await waitUntilState(
+ store,
+ state =>
+ state.snapshots[0].dominatorTree.state === dominatorTreeState.LOADED
+ );
+ ok(
+ true,
+ "The dominator tree should go back to LOADED after the incremental " +
+ "fetching is done."
+ );
+
+ const newRoot = getState().snapshots[0].dominatorTree.root;
+ Assert.notStrictEqual(
+ oldRoot,
+ newRoot,
+ "When we insert new nodes, we get a new tree"
+ );
+ equal(
+ oldRoot.children.length,
+ newRoot.children.length,
+ "The new tree's root should have the same number of children as the " +
+ "old root's"
+ );
+
+ let differentChildrenCount = 0;
+ for (let i = 0; i < oldRoot.children.length; i++) {
+ if (oldRoot.children[i] !== newRoot.children[i]) {
+ differentChildrenCount++;
+ }
+ }
+ equal(
+ differentChildrenCount,
+ 1,
+ "All subtrees except the subtree we inserted incrementally fetched " +
+ "children into should be the same because we use persistent updates"
+ );
+
+ // Find the new node which has the children inserted.
+
+ function findNewNode(node) {
+ if (node.nodeId === oldNode.nodeId) {
+ return node;
+ }
+
+ if (node.children) {
+ for (const child of node.children) {
+ const found = findNewNode(child);
+ if (found) {
+ return found;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ const newNode = findNewNode(newRoot);
+ ok(newNode, "Should find the node in the new tree again");
+ Assert.notStrictEqual(
+ newNode,
+ oldNode,
+ "We did not mutate the old node in place, instead created a new node"
+ );
+ ok(newNode.children, "And the new node should have the children attached");
+
+ heapWorker.destroy();
+ await front.detach();
+});