toolkit/components/aboutmemory/tests/test_aboutmemory3.xul

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/toolkit/components/aboutmemory/tests/test_aboutmemory3.xul	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,353 @@
     1.4 +<?xml version="1.0"?>
     1.5 +<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
     1.6 +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
     1.7 +<window title="about:memory"
     1.8 +        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
     1.9 +  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
    1.10 +  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
    1.11 +
    1.12 +  <!-- This file tests the saving and loading of memory reports to/from file in
    1.13 +       about:memory. -->
    1.14 +
    1.15 +  <!-- test results are displayed in the html:body -->
    1.16 +  <body xmlns="http://www.w3.org/1999/xhtml"></body>
    1.17 +
    1.18 +  <!-- test code goes here -->
    1.19 +  <script type="application/javascript">
    1.20 +  <![CDATA[
    1.21 +  "use strict";
    1.22 +
    1.23 +  const Cc = Components.classes;
    1.24 +  const Ci = Components.interfaces;
    1.25 +  let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
    1.26 +            getService(Ci.nsIMemoryReporterManager);
    1.27 +
    1.28 +  // Hide all the real reporters;  we'll restore them at the end.
    1.29 +  mgr.blockRegistrationAndHideExistingReporters();
    1.30 +
    1.31 +  // Setup a minimal number of fake reporters.
    1.32 +  const KB = 1024;
    1.33 +  const MB = KB * KB;
    1.34 +  const HEAP  = Ci.nsIMemoryReporter.KIND_HEAP;
    1.35 +  const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
    1.36 +  const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
    1.37 +
    1.38 +  let fakeReporters = [
    1.39 +    { collectReports: function(aCbObj, aClosure) {
    1.40 +        function f(aP, aK, aA, aD) {
    1.41 +          aCbObj.callback("", aP, aK, BYTES, aA, aD, aClosure);
    1.42 +        }
    1.43 +        f("heap-allocated",     OTHER,   250 * MB, "Heap allocated.");
    1.44 +        f("explicit/a/b",       HEAP,     50 * MB, "A b.");
    1.45 +        f("other/a",            OTHER,   0.2 * MB, "Other a.");
    1.46 +        f("other/b",            OTHER,   0.1 * MB, "Other b.");
    1.47 +      }
    1.48 +    }
    1.49 +  ];
    1.50 +
    1.51 +  for (let i = 0; i < fakeReporters.length; i++) {
    1.52 +    mgr.registerStrongReporterEvenIfBlocked(fakeReporters[i]);
    1.53 +  }
    1.54 +
    1.55 +  ]]>
    1.56 +  </script>
    1.57 +
    1.58 +  <iframe id="amFrame"  height="400" src="about:memory"></iframe>
    1.59 +
    1.60 +  <script type="application/javascript">
    1.61 +  <![CDATA[
    1.62 +  function finish()
    1.63 +  {
    1.64 +    mgr.unblockRegistrationAndRestoreOriginalReporters();
    1.65 +    SimpleTest.finish();
    1.66 +  }
    1.67 +
    1.68 +  // Load the given file into the frame, then copy+paste the entire frame and
    1.69 +  // check that the cut text matches what we expect.
    1.70 +  function test(aFilename, aFilename2, aExpected, aDumpFirst, aNext) {
    1.71 +    let frame = document.getElementById("amFrame");
    1.72 +    frame.focus();
    1.73 +
    1.74 +    let doc = frame.contentWindow.document;
    1.75 +    let verbosity = doc.getElementById("verbose");
    1.76 +    verbosity.checked = true;
    1.77 +
    1.78 +    function getFilePath(aFilename) {
    1.79 +      let file = Cc["@mozilla.org/file/directory_service;1"]
    1.80 +                 .getService(Components.interfaces.nsIProperties)
    1.81 +                 .get("CurWorkD", Components.interfaces.nsIFile);
    1.82 +      file.append("chrome");
    1.83 +      file.append("toolkit");
    1.84 +      file.append("components");
    1.85 +      file.append("aboutmemory");
    1.86 +      file.append("tests");
    1.87 +      file.append(aFilename);
    1.88 +      return file.path;
    1.89 +    }
    1.90 +
    1.91 +    let filePath = getFilePath(aFilename);
    1.92 +
    1.93 +    let e = document.createEvent('Event');
    1.94 +    e.initEvent('change', true, true);
    1.95 +
    1.96 +    function check() {
    1.97 +      // Initialize the clipboard contents.
    1.98 +      SpecialPowers.clipboardCopyString("initial clipboard value");
    1.99 +
   1.100 +      let numFailures = 0, maxFailures = 30;
   1.101 +
   1.102 +      // Because the file load is async, we don't know when it will finish and
   1.103 +      // the output will show up.  So we poll.
   1.104 +      function copyPasteAndCheck() {
   1.105 +        // Copy and paste frame contents, and filter out non-deterministic
   1.106 +        // differences.
   1.107 +        synthesizeKey("A", {accelKey: true});
   1.108 +        synthesizeKey("C", {accelKey: true});
   1.109 +        let actual = SpecialPowers.getClipboardData("text/unicode");
   1.110 +        actual = actual.replace(/\(pid \d+\)/g, "(pid NNN)");
   1.111 +
   1.112 +        if (actual === aExpected) {
   1.113 +          SimpleTest.ok(true, "Clipboard has the expected contents");
   1.114 +          aNext();
   1.115 +        } else {
   1.116 +          numFailures++;
   1.117 +          if (numFailures === maxFailures) {
   1.118 +            ok(false, "pasted text doesn't match");
   1.119 +            dump("******EXPECTED******\n");
   1.120 +            dump(aExpected);
   1.121 +            dump("*******ACTUAL*******\n");
   1.122 +            dump(actual);
   1.123 +            dump("********************\n");
   1.124 +            finish();
   1.125 +          } else {
   1.126 +            setTimeout(copyPasteAndCheck, 100);
   1.127 +          }
   1.128 +        }
   1.129 +      }
   1.130 +      copyPasteAndCheck();
   1.131 +    }
   1.132 +
   1.133 +    if (!aFilename2) {
   1.134 +      function loadAndCheck() {
   1.135 +        let fileInput1 =
   1.136 +          frame.contentWindow.document.getElementById("fileInput1");
   1.137 +        fileInput1.value = filePath;    // this works because it's a chrome test
   1.138 +
   1.139 +        fileInput1.dispatchEvent(e);
   1.140 +        check();
   1.141 +      }
   1.142 +
   1.143 +      if (aDumpFirst) {
   1.144 +        let dumper = Cc["@mozilla.org/memory-info-dumper;1"].
   1.145 +                        getService(Ci.nsIMemoryInfoDumper);
   1.146 +        dumper.dumpMemoryReportsToNamedFile(filePath, loadAndCheck, null);
   1.147 +      } else {
   1.148 +        loadAndCheck();
   1.149 +      }
   1.150 +
   1.151 +    } else {
   1.152 +      let fileInput2 =
   1.153 +        frame.contentWindow.document.getElementById("fileInput2");
   1.154 +      fileInput2.value = filePath;    // this works because it's a chrome test
   1.155 +
   1.156 +      // Hack alert:  fileInput2's onchange handler calls fileInput2.click().
   1.157 +      // But we don't want that to happen, because we want to bypass the file
   1.158 +      // picker for the test.  So we set |e.skipClick|, which causes
   1.159 +      // fileInput2.click() to be skipped, and dispatch the second change event
   1.160 +      // directly ourselves.
   1.161 +
   1.162 +      e.skipClick = true;
   1.163 +      fileInput2.dispatchEvent(e);
   1.164 +
   1.165 +      let filePath2 = getFilePath(aFilename2);
   1.166 +      fileInput2.value = filePath2;    // this works because it's a chrome test
   1.167 +
   1.168 +      let e2 = document.createEvent('Event');
   1.169 +      e2.initEvent('change', true, true);
   1.170 +      fileInput2.dispatchEvent(e);
   1.171 +
   1.172 +      check();
   1.173 +    }
   1.174 +  }
   1.175 +
   1.176 +  // Returns a function that chains together multiple test() calls.
   1.177 +  function chain(aPieces) {
   1.178 +    let x = aPieces.shift();
   1.179 +    if (x) {
   1.180 +      return function() { test(x.filename, x.filename2, x.expected, x.dumpFirst, chain(aPieces)); }
   1.181 +    } else {
   1.182 +      return function() { finish(); };
   1.183 +    }
   1.184 +  }
   1.185 +
   1.186 +  let expectedGood =
   1.187 +"\
   1.188 +Explicit-only process\n\
   1.189 +\n\
   1.190 +WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
   1.191 +Explicit Allocations\n\
   1.192 +\n\
   1.193 +100,000 B (100.0%) -- explicit\n\
   1.194 +└──100,000 B (100.0%) ── a/b\n\
   1.195 +\n\
   1.196 +Other Measurements\n\
   1.197 +\n\
   1.198 +End of Explicit-only process\n\
   1.199 +Main Process (pid NNN)\n\
   1.200 +Explicit Allocations\n\
   1.201 +\n\
   1.202 +262,144,000 B (100.0%) -- explicit\n\
   1.203 +├──209,715,200 B (80.00%) ── heap-unclassified\n\
   1.204 +└───52,428,800 B (20.00%) ── a/b\n\
   1.205 +\n\
   1.206 +Other Measurements\n\
   1.207 +\n\
   1.208 +1,024 B (100.0%) -- compartments\n\
   1.209 +└──1,024 B (100.0%) ── system/a\n\
   1.210 +\n\
   1.211 +1,024 B (100.0%) -- ghost-windows\n\
   1.212 +└──1,024 B (100.0%) ── a\n\
   1.213 +\n\
   1.214 +314,572 B (100.0%) -- other\n\
   1.215 +├──209,715 B (66.67%) ── a\n\
   1.216 +└──104,857 B (33.33%) ── b\n\
   1.217 +\n\
   1.218 +1,024 B (100.0%) -- pss\n\
   1.219 +└──1,024 B (100.0%) ── a\n\
   1.220 +\n\
   1.221 +1,024 B (100.0%) -- rss\n\
   1.222 +└──1,024 B (100.0%) ── a\n\
   1.223 +\n\
   1.224 +1,024 B (100.0%) -- size\n\
   1.225 +└──1,024 B (100.0%) ── a\n\
   1.226 +\n\
   1.227 +1,024 B (100.0%) -- swap\n\
   1.228 +└──1,024 B (100.0%) ── a\n\
   1.229 +\n\
   1.230 +262,144,000 B ── heap-allocated\n\
   1.231 +\n\
   1.232 +End of Main Process (pid NNN)\n\
   1.233 +Other-only process\n\
   1.234 +Other Measurements\n\
   1.235 +\n\
   1.236 +200,000 B (100.0%) -- a\n\
   1.237 +├──100,000 B (50.00%) ── b\n\
   1.238 +└──100,000 B (50.00%) ── c\n\
   1.239 +\n\
   1.240 +500,000 B ── heap-allocated\n\
   1.241 +\n\
   1.242 +End of Other-only process\n\
   1.243 +";
   1.244 +
   1.245 +  let expectedGood2 =
   1.246 +"\
   1.247 +Main Process (pid NNN)\n\
   1.248 +Explicit Allocations\n\
   1.249 +\n\
   1.250 +262,144,000 B (100.0%) -- explicit\n\
   1.251 +├──209,715,200 B (80.00%) ── heap-unclassified\n\
   1.252 +└───52,428,800 B (20.00%) ── a/b\n\
   1.253 +\n\
   1.254 +Other Measurements\n\
   1.255 +\n\
   1.256 +314,572 B (100.0%) -- other\n\
   1.257 +├──209,715 B (66.67%) ── a\n\
   1.258 +└──104,857 B (33.33%) ── b\n\
   1.259 +\n\
   1.260 +262,144,000 B ── heap-allocated\n\
   1.261 +\n\
   1.262 +End of Main Process (pid NNN)\n\
   1.263 +";
   1.264 +
   1.265 +  // This is the output for a malformed data file.
   1.266 +  let expectedBad =
   1.267 +"\
   1.268 +Invalid memory report(s): missing 'hasMozMallocUsableSize' property\
   1.269 +";
   1.270 +
   1.271 +  // This is the output for a diff.
   1.272 +  let expectedDiff =
   1.273 +"\
   1.274 +P\n\
   1.275 +\n\
   1.276 +WARNING: the 'heap-allocated' memory reporter does not work for this platform and/or configuration. This means that 'heap-unclassified' is not shown and the 'explicit' tree shows less memory than it should.\n\
   1.277 +Explicit Allocations\n\
   1.278 +\n\
   1.279 +-10,005 B (100.0%) -- explicit\n\
   1.280 +├──-10,000 B (99.95%) ── storage/prefixset/goog-phish-shavar\n\
   1.281 +├───────-6 B (00.06%) ── spell-check [2]\n\
   1.282 +└────────1 B (-0.01%) ── xpcom/category-manager\n\
   1.283 +\n\
   1.284 +Other Measurements\n\
   1.285 +\n\
   1.286 +3,000 B ── canvas-2d-pixel-bytes [2] [+]\n\
   1.287 + -100 B ── foobar [-]\n\
   1.288 +\n\
   1.289 +End of P\n\
   1.290 +P2 (pid NNN)\n\
   1.291 +Other Measurements\n\
   1.292 +\n\
   1.293 +11 B ── z 0xNNN\n\
   1.294 +\n\
   1.295 +End of P2 (pid NNN)\n\
   1.296 +P3\n\
   1.297 +Other Measurements\n\
   1.298 +\n\
   1.299 +-55 B ── p3 [-]\n\
   1.300 +\n\
   1.301 +End of P3\n\
   1.302 +P4\n\
   1.303 +Other Measurements\n\
   1.304 +\n\
   1.305 +66 B ── p4 [+]\n\
   1.306 +\n\
   1.307 +End of P4\n\
   1.308 +P7\n\
   1.309 +Other Measurements\n\
   1.310 +\n\
   1.311 +7 B (100.0%) -- p7\n\
   1.312 +├──4 B (57.14%) ── c [+]\n\
   1.313 +└──3 B (42.86%) ── b [+]\n\
   1.314 +\n\
   1.315 +-5 B ── p7 [-]\n\
   1.316 +\n\
   1.317 +End of P7\n\
   1.318 +P8\n\
   1.319 +Other Measurements\n\
   1.320 +\n\
   1.321 +-22 B (100.0%) -- p8\n\
   1.322 +└──-22 B (100.0%) -- a\n\
   1.323 +   ├──-11 B (50.00%) -- b\n\
   1.324 +   │  ├───-7 B (31.82%) -- c\n\
   1.325 +   │  │   ├──-4 B (18.18%) ── e [-]\n\
   1.326 +   │  │   └──-3 B (13.64%) ── d [-]\n\
   1.327 +   │  ├───-5 B (22.73%) ── f [-]\n\
   1.328 +   │  └────1 B (-4.55%) ── (fake child) [!]\n\
   1.329 +   └──-11 B (50.00%) -- g\n\
   1.330 +      ├───-7 B (31.82%) ── i [-]\n\
   1.331 +      ├───-6 B (27.27%) ── h [-]\n\
   1.332 +      └────2 B (-9.09%) ── (fake child) [!]\n\
   1.333 +\n\
   1.334 +End of P8\n\
   1.335 +";
   1.336 +
   1.337 +  let frames = [
   1.338 +    // This loads a pre-existing file that is valid.
   1.339 +    { filename: "memory-reports-good.json", expected: expectedGood, dumpFirst: false },
   1.340 +
   1.341 +    // This dumps to a file and then reads it back in.
   1.342 +    { filename: "memory-reports-dumped.json.gz", expected: expectedGood2, dumpFirst: true },
   1.343 +
   1.344 +    // This loads a pre-existing file that is invalid.
   1.345 +    { filename: "memory-reports-bad.json",  expected: expectedBad, dumpFirst: false },
   1.346 +
   1.347 +    // This loads a pre-existing diff file.
   1.348 +    { filename: "memory-reports-diff1.json", filename2: "memory-reports-diff2.json",  expected: expectedDiff, dumpFirst: false }
   1.349 +  ];
   1.350 +
   1.351 +  SimpleTest.waitForFocus(chain(frames));
   1.352 +
   1.353 +  SimpleTest.waitForExplicitFinish();
   1.354 +  ]]>
   1.355 +  </script>
   1.356 +</window>

mercurial