toolkit/components/aboutmemory/tests/test_aboutmemory3.xul

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:8395bc5c2e65
1 <?xml version="1.0"?>
2 <?xml-stylesheet type="text/css" href="chrome://global/skin"?>
3 <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
4 <window title="about:memory"
5 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
6 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
7 <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
8
9 <!-- This file tests the saving and loading of memory reports to/from file in
10 about:memory. -->
11
12 <!-- test results are displayed in the html:body -->
13 <body xmlns="http://www.w3.org/1999/xhtml"></body>
14
15 <!-- test code goes here -->
16 <script type="application/javascript">
17 <![CDATA[
18 "use strict";
19
20 const Cc = Components.classes;
21 const Ci = Components.interfaces;
22 let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
23 getService(Ci.nsIMemoryReporterManager);
24
25 // Hide all the real reporters; we'll restore them at the end.
26 mgr.blockRegistrationAndHideExistingReporters();
27
28 // Setup a minimal number of fake reporters.
29 const KB = 1024;
30 const MB = KB * KB;
31 const HEAP = Ci.nsIMemoryReporter.KIND_HEAP;
32 const OTHER = Ci.nsIMemoryReporter.KIND_OTHER;
33 const BYTES = Ci.nsIMemoryReporter.UNITS_BYTES;
34
35 let fakeReporters = [
36 { collectReports: function(aCbObj, aClosure) {
37 function f(aP, aK, aA, aD) {
38 aCbObj.callback("", aP, aK, BYTES, aA, aD, aClosure);
39 }
40 f("heap-allocated", OTHER, 250 * MB, "Heap allocated.");
41 f("explicit/a/b", HEAP, 50 * MB, "A b.");
42 f("other/a", OTHER, 0.2 * MB, "Other a.");
43 f("other/b", OTHER, 0.1 * MB, "Other b.");
44 }
45 }
46 ];
47
48 for (let i = 0; i < fakeReporters.length; i++) {
49 mgr.registerStrongReporterEvenIfBlocked(fakeReporters[i]);
50 }
51
52 ]]>
53 </script>
54
55 <iframe id="amFrame" height="400" src="about:memory"></iframe>
56
57 <script type="application/javascript">
58 <![CDATA[
59 function finish()
60 {
61 mgr.unblockRegistrationAndRestoreOriginalReporters();
62 SimpleTest.finish();
63 }
64
65 // Load the given file into the frame, then copy+paste the entire frame and
66 // check that the cut text matches what we expect.
67 function test(aFilename, aFilename2, aExpected, aDumpFirst, aNext) {
68 let frame = document.getElementById("amFrame");
69 frame.focus();
70
71 let doc = frame.contentWindow.document;
72 let verbosity = doc.getElementById("verbose");
73 verbosity.checked = true;
74
75 function getFilePath(aFilename) {
76 let file = Cc["@mozilla.org/file/directory_service;1"]
77 .getService(Components.interfaces.nsIProperties)
78 .get("CurWorkD", Components.interfaces.nsIFile);
79 file.append("chrome");
80 file.append("toolkit");
81 file.append("components");
82 file.append("aboutmemory");
83 file.append("tests");
84 file.append(aFilename);
85 return file.path;
86 }
87
88 let filePath = getFilePath(aFilename);
89
90 let e = document.createEvent('Event');
91 e.initEvent('change', true, true);
92
93 function check() {
94 // Initialize the clipboard contents.
95 SpecialPowers.clipboardCopyString("initial clipboard value");
96
97 let numFailures = 0, maxFailures = 30;
98
99 // Because the file load is async, we don't know when it will finish and
100 // the output will show up. So we poll.
101 function copyPasteAndCheck() {
102 // Copy and paste frame contents, and filter out non-deterministic
103 // differences.
104 synthesizeKey("A", {accelKey: true});
105 synthesizeKey("C", {accelKey: true});
106 let actual = SpecialPowers.getClipboardData("text/unicode");
107 actual = actual.replace(/\(pid \d+\)/g, "(pid NNN)");
108
109 if (actual === aExpected) {
110 SimpleTest.ok(true, "Clipboard has the expected contents");
111 aNext();
112 } else {
113 numFailures++;
114 if (numFailures === maxFailures) {
115 ok(false, "pasted text doesn't match");
116 dump("******EXPECTED******\n");
117 dump(aExpected);
118 dump("*******ACTUAL*******\n");
119 dump(actual);
120 dump("********************\n");
121 finish();
122 } else {
123 setTimeout(copyPasteAndCheck, 100);
124 }
125 }
126 }
127 copyPasteAndCheck();
128 }
129
130 if (!aFilename2) {
131 function loadAndCheck() {
132 let fileInput1 =
133 frame.contentWindow.document.getElementById("fileInput1");
134 fileInput1.value = filePath; // this works because it's a chrome test
135
136 fileInput1.dispatchEvent(e);
137 check();
138 }
139
140 if (aDumpFirst) {
141 let dumper = Cc["@mozilla.org/memory-info-dumper;1"].
142 getService(Ci.nsIMemoryInfoDumper);
143 dumper.dumpMemoryReportsToNamedFile(filePath, loadAndCheck, null);
144 } else {
145 loadAndCheck();
146 }
147
148 } else {
149 let fileInput2 =
150 frame.contentWindow.document.getElementById("fileInput2");
151 fileInput2.value = filePath; // this works because it's a chrome test
152
153 // Hack alert: fileInput2's onchange handler calls fileInput2.click().
154 // But we don't want that to happen, because we want to bypass the file
155 // picker for the test. So we set |e.skipClick|, which causes
156 // fileInput2.click() to be skipped, and dispatch the second change event
157 // directly ourselves.
158
159 e.skipClick = true;
160 fileInput2.dispatchEvent(e);
161
162 let filePath2 = getFilePath(aFilename2);
163 fileInput2.value = filePath2; // this works because it's a chrome test
164
165 let e2 = document.createEvent('Event');
166 e2.initEvent('change', true, true);
167 fileInput2.dispatchEvent(e);
168
169 check();
170 }
171 }
172
173 // Returns a function that chains together multiple test() calls.
174 function chain(aPieces) {
175 let x = aPieces.shift();
176 if (x) {
177 return function() { test(x.filename, x.filename2, x.expected, x.dumpFirst, chain(aPieces)); }
178 } else {
179 return function() { finish(); };
180 }
181 }
182
183 let expectedGood =
184 "\
185 Explicit-only process\n\
186 \n\
187 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\
188 Explicit Allocations\n\
189 \n\
190 100,000 B (100.0%) -- explicit\n\
191 └──100,000 B (100.0%) ── a/b\n\
192 \n\
193 Other Measurements\n\
194 \n\
195 End of Explicit-only process\n\
196 Main Process (pid NNN)\n\
197 Explicit Allocations\n\
198 \n\
199 262,144,000 B (100.0%) -- explicit\n\
200 ├──209,715,200 B (80.00%) ── heap-unclassified\n\
201 └───52,428,800 B (20.00%) ── a/b\n\
202 \n\
203 Other Measurements\n\
204 \n\
205 1,024 B (100.0%) -- compartments\n\
206 └──1,024 B (100.0%) ── system/a\n\
207 \n\
208 1,024 B (100.0%) -- ghost-windows\n\
209 └──1,024 B (100.0%) ── a\n\
210 \n\
211 314,572 B (100.0%) -- other\n\
212 ├──209,715 B (66.67%) ── a\n\
213 └──104,857 B (33.33%) ── b\n\
214 \n\
215 1,024 B (100.0%) -- pss\n\
216 └──1,024 B (100.0%) ── a\n\
217 \n\
218 1,024 B (100.0%) -- rss\n\
219 └──1,024 B (100.0%) ── a\n\
220 \n\
221 1,024 B (100.0%) -- size\n\
222 └──1,024 B (100.0%) ── a\n\
223 \n\
224 1,024 B (100.0%) -- swap\n\
225 └──1,024 B (100.0%) ── a\n\
226 \n\
227 262,144,000 B ── heap-allocated\n\
228 \n\
229 End of Main Process (pid NNN)\n\
230 Other-only process\n\
231 Other Measurements\n\
232 \n\
233 200,000 B (100.0%) -- a\n\
234 ├──100,000 B (50.00%) ── b\n\
235 └──100,000 B (50.00%) ── c\n\
236 \n\
237 500,000 B ── heap-allocated\n\
238 \n\
239 End of Other-only process\n\
240 ";
241
242 let expectedGood2 =
243 "\
244 Main Process (pid NNN)\n\
245 Explicit Allocations\n\
246 \n\
247 262,144,000 B (100.0%) -- explicit\n\
248 ├──209,715,200 B (80.00%) ── heap-unclassified\n\
249 └───52,428,800 B (20.00%) ── a/b\n\
250 \n\
251 Other Measurements\n\
252 \n\
253 314,572 B (100.0%) -- other\n\
254 ├──209,715 B (66.67%) ── a\n\
255 └──104,857 B (33.33%) ── b\n\
256 \n\
257 262,144,000 B ── heap-allocated\n\
258 \n\
259 End of Main Process (pid NNN)\n\
260 ";
261
262 // This is the output for a malformed data file.
263 let expectedBad =
264 "\
265 Invalid memory report(s): missing 'hasMozMallocUsableSize' property\
266 ";
267
268 // This is the output for a diff.
269 let expectedDiff =
270 "\
271 P\n\
272 \n\
273 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\
274 Explicit Allocations\n\
275 \n\
276 -10,005 B (100.0%) -- explicit\n\
277 ├──-10,000 B (99.95%) ── storage/prefixset/goog-phish-shavar\n\
278 ├───────-6 B (00.06%) ── spell-check [2]\n\
279 └────────1 B (-0.01%) ── xpcom/category-manager\n\
280 \n\
281 Other Measurements\n\
282 \n\
283 3,000 B ── canvas-2d-pixel-bytes [2] [+]\n\
284 -100 B ── foobar [-]\n\
285 \n\
286 End of P\n\
287 P2 (pid NNN)\n\
288 Other Measurements\n\
289 \n\
290 11 B ── z 0xNNN\n\
291 \n\
292 End of P2 (pid NNN)\n\
293 P3\n\
294 Other Measurements\n\
295 \n\
296 -55 B ── p3 [-]\n\
297 \n\
298 End of P3\n\
299 P4\n\
300 Other Measurements\n\
301 \n\
302 66 B ── p4 [+]\n\
303 \n\
304 End of P4\n\
305 P7\n\
306 Other Measurements\n\
307 \n\
308 7 B (100.0%) -- p7\n\
309 ├──4 B (57.14%) ── c [+]\n\
310 └──3 B (42.86%) ── b [+]\n\
311 \n\
312 -5 B ── p7 [-]\n\
313 \n\
314 End of P7\n\
315 P8\n\
316 Other Measurements\n\
317 \n\
318 -22 B (100.0%) -- p8\n\
319 └──-22 B (100.0%) -- a\n\
320 ├──-11 B (50.00%) -- b\n\
321 │ ├───-7 B (31.82%) -- c\n\
322 │ │ ├──-4 B (18.18%) ── e [-]\n\
323 │ │ └──-3 B (13.64%) ── d [-]\n\
324 │ ├───-5 B (22.73%) ── f [-]\n\
325 │ └────1 B (-4.55%) ── (fake child) [!]\n\
326 └──-11 B (50.00%) -- g\n\
327 ├───-7 B (31.82%) ── i [-]\n\
328 ├───-6 B (27.27%) ── h [-]\n\
329 └────2 B (-9.09%) ── (fake child) [!]\n\
330 \n\
331 End of P8\n\
332 ";
333
334 let frames = [
335 // This loads a pre-existing file that is valid.
336 { filename: "memory-reports-good.json", expected: expectedGood, dumpFirst: false },
337
338 // This dumps to a file and then reads it back in.
339 { filename: "memory-reports-dumped.json.gz", expected: expectedGood2, dumpFirst: true },
340
341 // This loads a pre-existing file that is invalid.
342 { filename: "memory-reports-bad.json", expected: expectedBad, dumpFirst: false },
343
344 // This loads a pre-existing diff file.
345 { filename: "memory-reports-diff1.json", filename2: "memory-reports-diff2.json", expected: expectedDiff, dumpFirst: false }
346 ];
347
348 SimpleTest.waitForFocus(chain(frames));
349
350 SimpleTest.waitForExplicitFinish();
351 ]]>
352 </script>
353 </window>

mercurial