3 <script src="../../http/tests/inspector/inspector-test.js"></script>
4 <script src="heap-snapshot-test.js"></script>
9 WebInspector.inspectorView.showPanel("profiles");
11 function createTestEnvironmentInWorker()
13 if (!this.InspectorTest)
16 InspectorTest.assertEquals = function(expected, found, message)
18 if (expected === found)
23 error = "Failure (" + message + "):";
26 throw new Error(error + " expected <" + expected + "> found <" + found + ">");
30 function runTestSuiteInWorker()
33 function postOrderIndexBug()
35 var builder = new InspectorTest.HeapSnapshotBuilder();
36 var node1 = new InspectorTest.HeapNode("Node1");
37 var node2 = new InspectorTest.HeapNode("Node2");
38 builder.rootNode.linkNode(node1, InspectorTest.HeapEdge.Type.internal);
39 builder.rootNode.linkNode(node2, InspectorTest.HeapEdge.Type.internal);
40 node2.linkNode(node1, InspectorTest.HeapEdge.Type.internal);
41 var snapshot = builder.createJSHeapSnapshot();
42 var postOrderIndexes = snapshot._buildPostOrderIndex().nodeOrdinal2PostOrderIndex;
43 var nodeOrdinals = snapshot._buildPostOrderIndex().postOrderIndex2NodeOrdinal;
44 InspectorTest.assertEquals(JSON.stringify(new Uint32Array([2, 0, 1])), JSON.stringify(postOrderIndexes), "postOrderIndexes");
45 InspectorTest.assertEquals(JSON.stringify(new Uint32Array([1, 2, 0])), JSON.stringify(nodeOrdinals), "nodeOrdinals");
48 function heapSnapshotNodeSimpleTest()
50 var snapshot = InspectorTest.createJSHeapSnapshotMockObject();
51 var nodeRoot = snapshot.createNode(snapshot._rootNodeIndex);
52 InspectorTest.assertEquals("", nodeRoot.name(), "root name");
53 InspectorTest.assertEquals("hidden", nodeRoot.type(), "root type");
54 InspectorTest.assertEquals(2, nodeRoot.edgesCount(), "root edges");
55 var nodeE = snapshot.createNode(15);
56 InspectorTest.assertEquals("E", nodeE.name(), "E name");
57 InspectorTest.assertEquals("object", nodeE.type(), "E type");
58 InspectorTest.assertEquals(0, nodeE.edgesCount(), "E edges");
61 function heapSnapshotNodeIteratorTest()
63 var snapshot = InspectorTest.createJSHeapSnapshotMockObject();
64 var nodeRoot = snapshot.createNode(snapshot._rootNodeIndex);
65 var iterator = new WebInspector.HeapSnapshotNodeIterator(nodeRoot);
67 for (; iterator.hasNext(); iterator.next())
68 names.push(iterator.item().name());
69 InspectorTest.assertEquals(",A,B,C,D,E", names.join(","), "node iterator");
72 function heapSnapshotEdgeSimpleTest()
74 var snapshot = InspectorTest.createJSHeapSnapshotMockObject();
75 var nodeRoot = snapshot.createNode(snapshot._rootNodeIndex);
76 var edgeIterator = new WebInspector.HeapSnapshotEdgeIterator(nodeRoot);
77 InspectorTest.assertEquals(true, edgeIterator.hasNext(), "has edges");
78 var edge = edgeIterator.item();
79 InspectorTest.assertEquals("shortcut", edge.type(), "edge type");
80 InspectorTest.assertEquals("a", edge.name(), "edge name");
81 InspectorTest.assertEquals("A", edge.node().name(), "edge node name");
84 for (; edgeIterator.hasNext(); edgeIterator.next())
86 InspectorTest.assertEquals(nodeRoot.edgesCount(), edgesCount, "edges count");
89 function heapSnapshotEdgeIteratorTest()
91 var snapshot = InspectorTest.createJSHeapSnapshotMockObject();
92 var nodeRoot = snapshot.createNode(snapshot._rootNodeIndex);
94 for (var iterator = nodeRoot.edges(); iterator.hasNext(); iterator.next())
95 names.push(iterator.item().name());
96 InspectorTest.assertEquals("a,b", names.join(","), "edge iterator");
97 var nodeE = snapshot.createNode(15);
98 InspectorTest.assertEquals(false, nodeE.edges().hasNext(), "empty edge iterator");
101 function heapSnapshotNodeAndEdgeTest()
103 var snapshotMock = InspectorTest.createJSHeapSnapshotMockObject();
104 var nodeRoot = snapshotMock.createNode(snapshotMock._rootNodeIndex);
107 function depthFirstTraversal(node)
109 names.push(node.name());
110 for (var edges = node.edges(); edges.hasNext(); edges.next()) {
111 names.push(edges.item().name());
112 depthFirstTraversal(edges.item().node());
116 depthFirstTraversal(nodeRoot);
117 var reference = ",a,A,1,B,bc,C,ce,E,bd,D,ac,C,ce,E,b,B,bc,C,ce,E,bd,D";
118 InspectorTest.assertEquals(reference, names.join(","), "mock traversal");
120 // Now check against a real HeapSnapshot instance.
122 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
123 depthFirstTraversal(snapshot.rootNode());
124 InspectorTest.assertEquals(reference, names.join(","), "snapshot traversal");
127 function heapSnapshotSimpleTest()
129 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
130 InspectorTest.assertEquals(6, snapshot.nodeCount, "node count");
131 InspectorTest.assertEquals(20, snapshot.totalSize, "total size");
134 function heapSnapshotContainmentEdgeIndexesTest()
136 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
137 var actual = snapshot._firstEdgeIndexes;
138 var expected = [0, 6, 12, 18, 21, 21, 21];
139 InspectorTest.assertEquals(expected.length, actual.length, "Edge indexes size");
140 for (var i = 0; i < expected.length; ++i)
141 InspectorTest.assertEquals(expected[i], actual[i], "Edge indexes");
144 function heapSnapshotPostOrderIndexTest()
146 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
147 var postOrderIndex2NodeOrdinal = snapshot._buildPostOrderIndex().postOrderIndex2NodeOrdinal;
148 var expected = [5,3,4,2,1,0];
149 for (var i = 0; i < expected.length; ++i)
150 InspectorTest.assertEquals(expected[i], postOrderIndex2NodeOrdinal[i], "Post ordered indexes");
153 function heapSnapshotDominatorsTreeTest()
155 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
156 var result = snapshot._buildPostOrderIndex();
157 var dominatorsTree = snapshot._buildDominatorTree(result.postOrderIndex2NodeOrdinal, result.nodeOrdinal2PostOrderIndex);
158 var expected = [0, 0, 0, 0, 2, 3];
159 for (var i = 0; i < expected.length; ++i)
160 InspectorTest.assertEquals(expected[i], dominatorsTree[i], "Dominators Tree");
163 function heapSnapshotRetainedSizeTest()
165 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
166 var actualRetainedSizes = new Array(snapshot.nodeCount);
167 for (var nodeOrdinal = 0; nodeOrdinal < snapshot.nodeCount; ++nodeOrdinal)
168 actualRetainedSizes[nodeOrdinal] = snapshot._retainedSizes[nodeOrdinal];
169 var expectedRetainedSizes = [20, 2, 8, 10, 5, 6];
170 InspectorTest.assertEquals(JSON.stringify(expectedRetainedSizes), JSON.stringify(actualRetainedSizes), "Retained sizes");
173 function heapSnapshotLargeRetainedSize(next)
175 var builder = new InspectorTest.HeapSnapshotBuilder();
176 var node = builder.rootNode;
179 var nodeSize = 1000 * 1000 * 1000;
180 for (var i = 0; i < 6; i++) {
181 var newNode = new InspectorTest.HeapNode("Node" + i, nodeSize);
182 node.linkNode(newNode, InspectorTest.HeapEdge.Type.element);
186 var snapshot = builder.createJSHeapSnapshot();
187 InspectorTest.assertEquals(
188 iterations * nodeSize, snapshot.rootNode().retainedSize(),
189 "Ensure that root node retained size supports values exceeding 2^32 bytes.");
192 function heapSnapshotDominatedNodesTest()
194 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
196 var expectedDominatedNodes = [21, 14, 7, 28, 35];
197 var actualDominatedNodes = snapshot._dominatedNodes;
198 InspectorTest.assertEquals(expectedDominatedNodes.length, actualDominatedNodes.length, "Dominated Nodes length");
199 for (var i = 0; i < expectedDominatedNodes.length; ++i)
200 InspectorTest.assertEquals(expectedDominatedNodes[i], actualDominatedNodes[i], "Dominated Nodes");
202 var expectedDominatedNodeIndex = [0, 3, 3, 4, 5, 5, 5];
203 var actualDominatedNodeIndex = snapshot._firstDominatedNodeIndex;
204 InspectorTest.assertEquals(expectedDominatedNodeIndex.length, actualDominatedNodeIndex.length, "Dominated Nodes Index length");
205 for (var i = 0; i < expectedDominatedNodeIndex.length; ++i)
206 InspectorTest.assertEquals(expectedDominatedNodeIndex[i], actualDominatedNodeIndex[i], "Dominated Nodes Index");
209 function heapSnapshotPageOwnedTest(next)
211 var builder = new InspectorTest.HeapSnapshotBuilder();
212 var rootNode = builder.rootNode;
214 var debuggerNode = new InspectorTest.HeapNode("Debugger");
215 rootNode.linkNode(debuggerNode, InspectorTest.HeapEdge.Type.element);
217 var windowNode = new InspectorTest.HeapNode("Window");
218 rootNode.linkNode(windowNode, InspectorTest.HeapEdge.Type.shortcut);
220 var pageOwnedNode = new InspectorTest.HeapNode("PageOwnedNode");
221 windowNode.linkNode(pageOwnedNode, InspectorTest.HeapEdge.Type.element);
222 debuggerNode.linkNode(pageOwnedNode, InspectorTest.HeapEdge.Type.property, "debugger2pageOwnedNode");
224 var debuggerOwnedNode = new InspectorTest.HeapNode("debuggerOwnedNode");
225 debuggerNode.linkNode(debuggerOwnedNode, InspectorTest.HeapEdge.Type.element);
227 var snapshot = builder.createJSHeapSnapshot();
228 snapshot._flags = new Array(snapshot.nodeCount);
229 for (var i = 0; i < snapshot.nodeCount; ++i)
230 snapshot._flags[i] = 0;
231 snapshot._markPageOwnedNodes();
233 var expectedFlags = [0, 0, 4, 4, 0];
234 InspectorTest.assertEquals(
235 JSON.stringify(expectedFlags),
236 JSON.stringify(snapshot._flags),
237 "We are expecting that only window(third element) and PageOwnedNode(forth element) have flag === 4.");
240 function heapSnapshotRetainersTest()
242 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
243 var expectedRetainers = {
250 for (var nodes = snapshot._allNodes(); nodes.hasNext(); nodes.next()) {
252 for (var retainers = nodes.item().retainers(); retainers.hasNext(); retainers.next())
253 names.push(retainers.item().node().name());
255 InspectorTest.assertEquals(expectedRetainers[nodes.item().name()].join(","), names.join(","), "retainers of \"" + nodes.item().name() + "\"");
259 function heapSnapshotAggregatesTest()
261 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
262 var expectedAggregates = {
263 "A": { count: 1, self: 2, maxRet: 2, type: "object", name: "A" },
264 "B": { count: 1, self: 3, maxRet: 8, type: "object", name: "B" },
265 "C": { count: 1, self: 4, maxRet: 10, type: "object", name: "C" },
266 "D": { count: 1, self: 5, maxRet: 5, type: "object", name: "D" },
267 "E": { count: 1, self: 6, maxRet: 6, type: "object", name: "E" }
269 var aggregates = snapshot.aggregates(false);
270 for (var name in aggregates) {
271 var aggregate = aggregates[name];
272 var expectedAggregate = expectedAggregates[name];
273 for (var parameter in expectedAggregate)
274 InspectorTest.assertEquals(expectedAggregate[parameter], aggregate[parameter], "parameter " + parameter + " of \"" + name + "\"");
276 var expectedIndexes = {
277 // Index of corresponding node in the raw snapshot:
284 var indexes = snapshot.aggregates(true);
285 for (var name in aggregates) {
286 var aggregate = aggregates[name];
287 var expectedIndex = expectedIndexes[name];
288 InspectorTest.assertEquals(expectedIndex.join(","), aggregate.idxs.join(","), "indexes of \"" + name + "\"");
292 function heapSnapshotFlagsTest()
294 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMockWithDOM(), new WebInspector.HeapSnapshotProgress());
295 var expectedCanBeQueried = {
309 for (var nodes = snapshot._allNodes(); nodes.hasNext(); nodes.next()) {
310 var node = nodes.item();
311 InspectorTest.assertEquals(expectedCanBeQueried[node.name()], node.canBeQueried(), "canBeQueried of \"" + node.name() + "\"");
315 function heapSnapshotNodesProviderTest()
317 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
319 function nodeFilter(node)
321 return node.type() === "object" && node.name() !== "B" && node.name() !== "D";
324 var allNodeIndexes = [];
325 for (var i = 0; i < snapshot._nodes.length; i += snapshot._nodeFieldCount)
326 allNodeIndexes.push(i);
327 var provider = new WebInspector.HeapSnapshotNodesProvider(snapshot, nodeFilter, allNodeIndexes);
328 // Sort by names in reverse order.
329 provider.sortAndRewind({fieldName1: "name", ascending1: false, fieldName2: "id", ascending2: false});
330 var range = provider.serializeItemsRange(0, 3);
331 InspectorTest.assertEquals(3, range.totalLength, "Node range total length");
332 InspectorTest.assertEquals(0, range.startPosition, "Node range start position");
333 InspectorTest.assertEquals(3, range.endPosition, "Node range end position");
334 var names = range.items.map(function(item)
338 InspectorTest.assertEquals("E,C,A", names.join(","), "nodes provider names");
341 function heapSnapshotEdgesProviderTest()
343 var snapshot = new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress());
345 function edgeFilter(edge)
347 return edge.name() === "b";
350 var provider = snapshot.createEdgesProviderForTest(snapshot.rootNodeIndex, edgeFilter);
351 provider.sortAndRewind({fieldName1: "!edgeName", ascending1: false, fieldName2: "id", ascending2: false});
352 var range = provider.serializeItemsRange(0, 10);
353 InspectorTest.assertEquals(1, range.totalLength, "Edge range total length");
354 InspectorTest.assertEquals(0, range.startPosition, "Edge range start position");
355 InspectorTest.assertEquals(1, range.endPosition, "Edge range end position");
356 var names = range.items.map(function(item)
360 InspectorTest.assertEquals("b", names.join(","), "edges provider names");
363 function heapSnapshotLoaderTest()
365 var source = InspectorTest.createHeapSnapshotMockRaw();
366 var sourceStringified = JSON.stringify(source);
367 var partSize = sourceStringified.length >> 3;
369 var loader = new WebInspector.HeapSnapshotLoader();
370 for (var i = 0, l = sourceStringified.length; i < l; i += partSize)
371 loader.write(sourceStringified.slice(i, i + partSize));
373 var result = loader.buildSnapshot(false);
374 result._nodes = new Uint32Array(result._nodes);
375 result._containmentEdges = new Uint32Array(result._containmentEdges);
376 function assertSnapshotEquals(reference, actual)
378 InspectorTest.assertEquals(JSON.stringify(reference), JSON.stringify(actual));
380 assertSnapshotEquals(new WebInspector.JSHeapSnapshot(InspectorTest.createHeapSnapshotMock(), new WebInspector.HeapSnapshotProgress(), false), result);
385 for (var i = 0; i < testSuite.length; i++) {
386 var test = testSuite[i];
388 result.push("Running: " + test.name);
392 result.push("FAIL: " + e);
395 return result.join("\n");
398 var proxy = new WebInspector.HeapSnapshotWorkerProxy(function(eventName, arg)
400 InspectorTest.addResult("Unexpected event from worker: " + eventName);
402 var source = "(" + createTestEnvironmentInWorker + ")();" +
403 "(" + InspectorTest.createHeapSnapshotMockFactories + ")();" +
404 "(" + runTestSuiteInWorker + ")();";
405 proxy.evaluateForTest(source, function(result)
407 InspectorTest.addResult(result);
408 InspectorTest.completeTest();
415 <body onload="runTest()">
417 This test checks HeapSnapshots module.