|
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 in the presence of child processes. It is also notable |
|
11 for being an about:memory test that uses the real reporters, rather |
|
12 than fake deterministic ones, and so tends to show up problems in the |
|
13 real reporters (like bogus negative values). --> |
|
14 |
|
15 <!-- test results are displayed in the html:body --> |
|
16 <body xmlns="http://www.w3.org/1999/xhtml"></body> |
|
17 |
|
18 <iframe id="amFrame" height="400" src="about:memory"></iframe> |
|
19 |
|
20 <script type="application/javascript"> |
|
21 <![CDATA[ |
|
22 "use strict"; |
|
23 |
|
24 const Cc = Components.classes; |
|
25 const Ci = Components.interfaces; |
|
26 let mgr = Cc["@mozilla.org/memory-reporter-manager;1"]. |
|
27 getService(Ci.nsIMemoryReporterManager); |
|
28 |
|
29 let numRemotes = 3; |
|
30 let numReady = 0; |
|
31 |
|
32 // Create some remote processes, and set up message-passing so that |
|
33 // we know when each child is fully initialized. |
|
34 let remotes = []; |
|
35 |
|
36 let prefs = [ |
|
37 ["dom.ipc.processCount", 3], // Allow up to 3 child processes |
|
38 ["memory.system_memory_reporter", true] // Test SystemMemoryReporter |
|
39 ]; |
|
40 |
|
41 SpecialPowers.pushPrefEnv({"set": prefs}, function() { |
|
42 for (let i = 0; i < numRemotes; i++) { |
|
43 let w = remotes[i] = window.open("remote.xul", "", "chrome"); |
|
44 |
|
45 w.addEventListener("load", function loadHandler() { |
|
46 w.removeEventListener("load", loadHandler); |
|
47 let remoteBrowser = w.document.getElementById("remote"); |
|
48 let mm = remoteBrowser.messageManager; |
|
49 mm.addMessageListener("test:ready", function readyHandler() { |
|
50 mm.removeMessageListener("test:ready", readyHandler); |
|
51 numReady++; |
|
52 if (numReady == numRemotes) { |
|
53 // All the remote processes are ready. |
|
54 SimpleTest.waitForFocus(onFocus); |
|
55 } |
|
56 }); |
|
57 mm.loadFrameScript("data:," + encodeURI("sendAsyncMessage('test:ready');"), true); |
|
58 }); |
|
59 } |
|
60 }); |
|
61 |
|
62 // Load the given file into the frame, then copy+paste the entire frame and |
|
63 // check that the cut text matches what we expect. |
|
64 function onFocus() { |
|
65 let frame = document.getElementById("amFrame"); |
|
66 frame.focus(); |
|
67 |
|
68 function getFilePath(aFilename) { |
|
69 let file = Cc["@mozilla.org/file/directory_service;1"] |
|
70 .getService(Components.interfaces.nsIProperties) |
|
71 .get("CurWorkD", Components.interfaces.nsIFile); |
|
72 file.append("chrome"); |
|
73 file.append("toolkit"); |
|
74 file.append("components"); |
|
75 file.append("aboutmemory"); |
|
76 file.append("tests"); |
|
77 file.append(aFilename); |
|
78 return file.path; |
|
79 } |
|
80 |
|
81 let filePath = getFilePath("memory-reports-dumped.json.gz"); |
|
82 |
|
83 let e = document.createEvent('Event'); |
|
84 e.initEvent('change', true, true); |
|
85 |
|
86 let dumper = Cc["@mozilla.org/memory-info-dumper;1"]. |
|
87 getService(Ci.nsIMemoryInfoDumper); |
|
88 dumper.dumpMemoryReportsToNamedFile(filePath, loadAndCheck, null); |
|
89 |
|
90 function loadAndCheck() { |
|
91 // Load the file. |
|
92 let fileInput1 = |
|
93 frame.contentWindow.document.getElementById("fileInput1"); |
|
94 fileInput1.value = filePath; // this works because it's a chrome test |
|
95 fileInput1.dispatchEvent(e); |
|
96 |
|
97 // Initialize the clipboard contents. |
|
98 SpecialPowers.clipboardCopyString("initial clipboard value"); |
|
99 |
|
100 let numFailures = 0, maxFailures = 30; |
|
101 |
|
102 copyPasteAndCheck(); |
|
103 |
|
104 // Because the file load is async, we don't know when it will finish and |
|
105 // the output will show up. So we poll. |
|
106 function copyPasteAndCheck() { |
|
107 // Copy and paste frame contents, and filter out non-deterministic |
|
108 // differences. |
|
109 synthesizeKey("A", {accelKey: true}); |
|
110 synthesizeKey("C", {accelKey: true}); |
|
111 let actual = SpecialPowers.getClipboardData("text/unicode"); |
|
112 |
|
113 // If we have more than 1000 chars, we've probably successfully |
|
114 // copy+pasted. |
|
115 if (actual.length > 1000) { |
|
116 |
|
117 let good = true; |
|
118 |
|
119 if (actual.match("End of System")) { |
|
120 let m1 = actual.match("anonymous") && |
|
121 actual.match("shared-libraries"); |
|
122 ok(m1, "system-wide reporter") |
|
123 good = good && !!m1; |
|
124 } |
|
125 |
|
126 // Note: Match "vsize" but not "vsize-max-contiguous". |
|
127 let vsizes = actual.match(/vsize[^-]/g); |
|
128 let endOfBrowsers = actual.match(/End of Browser/g); |
|
129 let m2 = (vsizes.length == 4 && endOfBrowsers.length == 3); |
|
130 ok(m2, "three child processes present in loaded data"); |
|
131 good = good && !!m2; |
|
132 |
|
133 if (!good) { |
|
134 dump("*******ACTUAL*******\n"); |
|
135 dump(actual); |
|
136 dump("********************\n"); |
|
137 } |
|
138 |
|
139 // Close the remote processes. |
|
140 for (let i = 0; i < numRemotes; i++) { |
|
141 remotes[i].close(); |
|
142 } |
|
143 |
|
144 SimpleTest.finish(); |
|
145 |
|
146 } else { |
|
147 numFailures++; |
|
148 if (numFailures === maxFailures) { |
|
149 ok(false, "not enough chars in pasted output"); |
|
150 SimpleTest.finish(); |
|
151 } else { |
|
152 setTimeout(copyPasteAndCheck, 100); |
|
153 } |
|
154 } |
|
155 } |
|
156 } |
|
157 } |
|
158 |
|
159 SimpleTest.waitForExplicitFinish(); |
|
160 ]]> |
|
161 </script> |
|
162 </window> |