<?xml version="1.0"?> <?xml-stylesheet type="text/css" href="chrome://global/skin"?> <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> <window title="about:memory" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> <!-- This file tests the collapsing and expanding of sub-trees in about:memory. --> <!-- test results are displayed in the html:body --> <body xmlns="http://www.w3.org/1999/xhtml"></body> <!-- test code goes here --> <script type="application/javascript"> <![CDATA[ "use strict"; const Cc = Components.classes; const Ci = Components.interfaces; let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. getService(Ci.nsIMemoryReporterManager); // Hide all the real reporters; we'll restore them at the end. mgr.blockRegistrationAndHideExistingReporters(); // Setup various fake-but-deterministic reporters. const KB = 1024; const MB = KB * KB; const HEAP = Ci.nsIMemoryReporter.KIND_HEAP; const OTHER = Ci.nsIMemoryReporter.KIND_OTHER; const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES; let hiPath = "explicit/h/i"; let hi2Path = "explicit/h/i2"; let jkPath = "explicit/j/k"; let jk2Path = "explicit/j/k2"; let fakeReporters = [ { collectReports: function(aCbObj, aClosure, aAnonymize) { function f(aP, aK, aA) { aCbObj.callback("", aP, aK, BYTES, aA, "Desc.", aClosure); } f("heap-allocated", OTHER, 250 * MB); f("explicit/a/b", HEAP, 50 * MB); f("explicit/a/c/d", HEAP, 25 * MB); f("explicit/a/c/e", HEAP, 15 * MB); f("explicit/a/f", HEAP, 30 * MB); f("explicit/g", HEAP, 100 * MB); f(hiPath, HEAP, 10 * MB); f(hi2Path, HEAP, 9 * MB); f(jkPath, HEAP, 0.5 * MB); f(jk2Path, HEAP, 0.3 * MB); f("explicit/a/l/m", HEAP, 0.1 * MB); f("explicit/a/l/n", HEAP, 0.1 * MB); } } ]; for (let i = 0; i < fakeReporters.length; i++) { mgr.registerStrongReporterEvenIfBlocked(fakeReporters[i]); } ]]> </script> <iframe id="amFrame" height="500" src="about:memory"></iframe> <script type="application/javascript"> <![CDATA[ function finish() { mgr.unblockRegistrationAndRestoreOriginalReporters(); SimpleTest.finish(); } // Click on the identified element, then cut+paste the entire page and // check that the cut text matches what we expect. function test(aId, aSwap, aExpected, aNext) { let win = document.getElementById("amFrame").contentWindow; if (aId) { let node = win.document.getElementById(aId); // Yuk: clicking a button is easy; but for tree entries we need to // click on a child of the span identified via |id|. if (node.nodeName === "button") { if (aSwap) { // We swap hipath/hi2Path and jkPath/jk2Path just before updating, to // test what happens when significant nodes become insignificant and // vice versa. hiPath = "explicit/j/k"; hi2Path = "explicit/j/k2"; jkPath = "explicit/h/i"; jk2Path = "explicit/h/i2"; } node.click(); } else { node.childNodes[0].click(); } } SimpleTest.executeSoon(function() { let mostRecentActual; document.getElementById("amFrame").focus(); SimpleTest.waitForClipboard( function(aActual) { mostRecentActual = aActual; let rslt = aActual.trim() === aExpected.trim(); if (!rslt) { // Try copying again. synthesizeKey("A", {accelKey: true}); synthesizeKey("C", {accelKey: true}); } return rslt; }, function() { synthesizeKey("A", {accelKey: true}); synthesizeKey("C", {accelKey: true}); }, aNext, function() { ok(false, "pasted text doesn't match"); dump("******EXPECTED******\n"); dump(aExpected); dump("*******ACTUAL*******\n"); dump(mostRecentActual); dump("********************\n"); finish(); } ); }); } // Returns a function that chains together one test() call per id. function chain(aIds) { let x = aIds.shift(); if (x) { return function() { test(x.id, x.swap, x.expected, chain(aIds)); } } else { return function() { finish(); }; } } let startExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) -- a\n\ │ ├───50.00 MB (20.00%) ── b\n\ │ ├───40.00 MB (16.00%) -- c\n\ │ │ ├──25.00 MB (10.00%) ── d\n\ │ │ └──15.00 MB (06.00%) ── e\n\ │ ├───30.00 MB (12.00%) ── f\n\ │ └────0.20 MB (00.08%) ++ l\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- h\n\ │ ├──10.00 MB (04.00%) ── i\n\ │ └───9.00 MB (03.60%) ── i2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ j\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let acCollapsedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) -- a\n\ │ ├───50.00 MB (20.00%) ── b\n\ │ ├───40.00 MB (16.00%) ++ c\n\ │ ├───30.00 MB (12.00%) ── f\n\ │ └────0.20 MB (00.08%) ++ l\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- h\n\ │ ├──10.00 MB (04.00%) ── i\n\ │ └───9.00 MB (03.60%) ── i2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ j\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let alExpandedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) -- a\n\ │ ├───50.00 MB (20.00%) ── b\n\ │ ├───40.00 MB (16.00%) ++ c\n\ │ ├───30.00 MB (12.00%) ── f\n\ │ └────0.20 MB (00.08%) -- l\n\ │ ├──0.10 MB (00.04%) ── m\n\ │ └──0.10 MB (00.04%) ── n\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- h\n\ │ ├──10.00 MB (04.00%) ── i\n\ │ └───9.00 MB (03.60%) ── i2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ j\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let aCollapsedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) ++ a\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- h\n\ │ ├──10.00 MB (04.00%) ── i\n\ │ └───9.00 MB (03.60%) ── i2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ j\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let hCollapsedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) ++ a\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) ++ h\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ j\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let jExpandedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) ++ a\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) ++ h\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) -- j\n\ ├──0.50 MB (00.20%) ── k\n\ └──0.30 MB (00.12%) ── k2\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; // The important thing here is that two values have been swapped. // explicit/h/i should remain collapsed, and explicit/j/k should remain // expanded. See bug 724863. let updatedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) ++ a\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- j\n\ │ ├──10.00 MB (04.00%) ── k\n\ │ └───9.00 MB (03.60%) ── k2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ h\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let aExpandedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) -- a\n\ │ ├───50.00 MB (20.00%) ── b\n\ │ ├───40.00 MB (16.00%) ++ c\n\ │ ├───30.00 MB (12.00%) ── f\n\ │ └────0.20 MB (00.08%) -- l\n\ │ ├──0.10 MB (00.04%) ── m\n\ │ └──0.10 MB (00.04%) ── n\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- j\n\ │ ├──10.00 MB (04.00%) ── k\n\ │ └───9.00 MB (03.60%) ── k2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ h\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let acExpandedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) -- a\n\ │ ├───50.00 MB (20.00%) ── b\n\ │ ├───40.00 MB (16.00%) -- c\n\ │ │ ├──25.00 MB (10.00%) ── d\n\ │ │ └──15.00 MB (06.00%) ── e\n\ │ ├───30.00 MB (12.00%) ── f\n\ │ └────0.20 MB (00.08%) -- l\n\ │ ├──0.10 MB (00.04%) ── m\n\ │ └──0.10 MB (00.04%) ── n\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- j\n\ │ ├──10.00 MB (04.00%) ── k\n\ │ └───9.00 MB (03.60%) ── k2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ h\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; let alCollapsedExpected = "\ Main Process\n\ Explicit Allocations\n\ \n\ 250.00 MB (100.0%) -- explicit\n\ ├──120.20 MB (48.08%) -- a\n\ │ ├───50.00 MB (20.00%) ── b\n\ │ ├───40.00 MB (16.00%) -- c\n\ │ │ ├──25.00 MB (10.00%) ── d\n\ │ │ └──15.00 MB (06.00%) ── e\n\ │ ├───30.00 MB (12.00%) ── f\n\ │ └────0.20 MB (00.08%) ++ l\n\ ├──100.00 MB (40.00%) ── g\n\ ├───19.00 MB (07.60%) -- j\n\ │ ├──10.00 MB (04.00%) ── k\n\ │ └───9.00 MB (03.60%) ── k2\n\ ├───10.00 MB (04.00%) ── heap-unclassified\n\ └────0.80 MB (00.32%) ++ h\n\ \n\ Other Measurements\n\ \n\ 250.00 MB ── heap-allocated\n\ \n\ End of Main Process\n\ "; // Test the following cases: // - explicit/a/c is significant, we collapse it, it's unchanged upon // update, we re-expand it // - explicit/a/l is insignificant, we expand it, it's unchanged upon // update, we re-collapse it // - explicit/a is significant, we collapse it (which hides its // sub-trees), it's unchanged upon update, we re-expand it // - explicit/h is significant, we collapse it, it becomes insignificant // upon update (and should remain collapsed) // - explicit/j is insignificant, we expand it, it becomes significant // upon update (and should remain expanded) // let idsToClick = [ { id: "measureButton", swap: 0, expected: startExpected }, { id: "Main Process:explicit/a/c", swap: 0, expected: acCollapsedExpected }, { id: "Main Process:explicit/a/l", swap: 0, expected: alExpandedExpected }, { id: "Main Process:explicit/a", swap: 0, expected: aCollapsedExpected }, { id: "Main Process:explicit/h", swap: 0, expected: hCollapsedExpected }, { id: "Main Process:explicit/j", swap: 0, expected: jExpandedExpected }, { id: "measureButton", swap: 1, expected: updatedExpected }, { id: "Main Process:explicit/a", swap: 0, expected: aExpandedExpected }, { id: "Main Process:explicit/a/c", swap: 0, expected: acExpandedExpected }, { id: "Main Process:explicit/a/l", swap: 0, expected: alCollapsedExpected } ]; SimpleTest.waitForFocus(chain(idsToClick)); SimpleTest.waitForExplicitFinish(); ]]> </script> </window>