OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Processes API test for Chrome. | 5 // Processes API test for Chrome. |
6 // browser_tests.exe --gtest_filter=ExtensionApiTest.Processes | 6 // browser_tests.exe --gtest_filter=ExtensionApiTest.Processes |
7 | 7 |
8 var pass = chrome.test.callbackPass; | 8 var pass = chrome.test.callbackPass; |
9 var fail = chrome.test.callbackFail; | 9 var fail = chrome.test.callbackFail; |
10 var assertEq = chrome.test.assertEq; | 10 var assertEq = chrome.test.assertEq; |
11 var assertTrue = chrome.test.assertTrue; | 11 var assertTrue = chrome.test.assertTrue; |
| 12 var assertFalse = chrome.test.assertFalse; |
12 var listenOnce = chrome.test.listenOnce; | 13 var listenOnce = chrome.test.listenOnce; |
13 | 14 |
14 var tabs = []; | 15 var tabs = []; |
| 16 var hangingTabProcess = -1; |
15 | 17 |
16 function createTab(index, url) { | 18 function createTab(index, url) { |
17 chrome.tabs.create({"url": url}, pass(function(tab) { | 19 chrome.tabs.create({"url": url}, pass(function(tab) { |
18 tabs[index] = tab; | 20 tabs[index] = tab; |
19 })); | 21 })); |
20 } | 22 } |
21 | 23 |
22 var getProcessId = chrome.experimental.processes.getProcessIdForTab; | 24 var getProcessId = chrome.experimental.processes.getProcessIdForTab; |
23 | 25 |
24 function pageUrl(letter) { | 26 function pageUrl(letter) { |
25 return chrome.extension.getURL(letter + ".html"); | 27 return chrome.extension.getURL(letter + ".html"); |
26 } | 28 } |
27 | 29 |
| 30 function dumpProcess(process) { |
| 31 console.log("id " + process.id); |
| 32 console.log("osProcId " + process.osProcessId); |
| 33 console.log("type " + process.type); |
| 34 console.log("profile " + process.profile); |
| 35 console.log("tabs " + process.tabs); |
| 36 console.log("cpu " + process.cpu); |
| 37 console.log("privMem " + process.privateMemory); |
| 38 console.log("network " + process.network); |
| 39 console.log("jsMemAlloc " + process.jsMemoryAllocated); |
| 40 console.log("jsMemUsed " + process.jsMemoryUsed); |
| 41 console.log("sqliteMem " + process.sqliteMemory); |
| 42 console.log("fps " + process.fps); |
| 43 if ("imageCache" in process) { |
| 44 console.log("imageCache.size " + process.imageCache.size); |
| 45 console.log("imageCache.liveSize " + process.imageCache.liveSize); |
| 46 } |
| 47 if ("scriptCache" in process) { |
| 48 console.log("scriptCache.size " + process.scriptCache.size); |
| 49 console.log("scriptCache.liveSize " + process.scriptCache.liveSize); |
| 50 } |
| 51 if ("cssCache" in process) { |
| 52 console.log("cssCache.size " + process.cssCache.size); |
| 53 console.log("cssCache .liveSize " + process.cssCache.liveSize); |
| 54 } |
| 55 } |
| 56 |
| 57 function validateProcessProperties(process, updating, memory_included) { |
| 58 dumpProcess(process); |
| 59 |
| 60 // Always present. |
| 61 assertTrue("id" in process); |
| 62 assertTrue("osProcessId" in process); |
| 63 assertTrue("type" in process); |
| 64 assertTrue("profile" in process); |
| 65 assertTrue("tabs" in process); |
| 66 |
| 67 // Present if onUpdate(WithMemory) listener is registered. |
| 68 assertEq(("cpu" in process), updating); |
| 69 assertEq(("network" in process), updating); |
| 70 assertEq(("fps" in process), updating); |
| 71 |
| 72 // Present if memory details are requested. |
| 73 assertEq(("privateMemory" in process), memory_included); |
| 74 |
| 75 // sqliteMemory is only reported for the browser process |
| 76 if (process.type == "browser") { |
| 77 assertEq(("sqliteMemory" in process), updating); |
| 78 } else { |
| 79 // The rest are not present in the browser process |
| 80 assertEq(("jsMemoryAllocated" in process), updating); |
| 81 assertEq(("jsMemoryUsed" in process), updating); |
| 82 assertEq(("imageCache" in process), updating); |
| 83 assertEq(("scriptCache" in process), updating); |
| 84 assertEq(("cssCache" in process), updating); |
| 85 } |
| 86 } |
| 87 |
28 chrome.test.runTests([ | 88 chrome.test.runTests([ |
29 function setupProcessTests() { | 89 function setupProcessTests() { |
30 // Open 4 tabs for test, then wait and create a 5th | 90 // Open 4 tabs for test, then wait and create a 5th |
31 createTab(0, "about:blank"); | 91 createTab(0, "about:blank"); |
32 createTab(1, pageUrl("a")); | 92 createTab(1, pageUrl("a")); |
33 createTab(2, pageUrl("b")); | 93 createTab(2, pageUrl("b")); |
34 createTab(3, "chrome://newtab/"); | 94 createTab(3, "chrome://newtab/"); |
35 | 95 |
36 // Wait for all loads to complete. | 96 // Wait for all loads to complete. |
37 var completedCount = 0; | 97 var completedCount = 0; |
(...skipping 30 matching lines...) Expand all Loading... |
68 | 128 |
69 function extensionPagesShareProcess() { | 129 function extensionPagesShareProcess() { |
70 getProcessId(tabs[1].id, pass(function(pid1) { | 130 getProcessId(tabs[1].id, pass(function(pid1) { |
71 getProcessId(tabs[2].id, pass(function(pid2) { | 131 getProcessId(tabs[2].id, pass(function(pid2) { |
72 // Pages from same extension should share a process | 132 // Pages from same extension should share a process |
73 assertEq(pid1, pid2); | 133 assertEq(pid1, pid2); |
74 })); | 134 })); |
75 })); | 135 })); |
76 }, | 136 }, |
77 | 137 |
| 138 function extensionPagesMatchTabs() { |
| 139 getProcessId(tabs[1].id, pass(function(pid1) { |
| 140 getProcessId(tabs[2].id, pass(function(pid2) { |
| 141 // Pages from same extension should share a process |
| 142 assertEq(pid1, pid2); |
| 143 chrome.experimental.processes.getProcessInfo(pid1, false, |
| 144 function(pl1) { |
| 145 chrome.experimental.processes.getProcessInfo(pid2, false, |
| 146 function (pl2) { |
| 147 var proc1 = pl1[pid1]; |
| 148 var proc2 = pl2[pid2]; |
| 149 assertTrue(proc1.tabs.length == proc2.tabs.length); |
| 150 for (var i = 0; i < proc1.tabs.length; ++i) { |
| 151 assertEq(proc1.tabs[i], proc2.tabs[i]); |
| 152 } |
| 153 }); |
| 154 }); |
| 155 })); |
| 156 })); |
| 157 }, |
| 158 |
78 function newTabPageInOwnProcess() { | 159 function newTabPageInOwnProcess() { |
79 getProcessId(tabs[0].id, pass(function(pid0) { | 160 getProcessId(tabs[0].id, pass(function(pid0) { |
80 getProcessId(tabs[3].id, pass(function(pid3) { | 161 getProcessId(tabs[3].id, pass(function(pid3) { |
81 // NTP should not share a process with current tabs | 162 // NTP should not share a process with current tabs |
82 assertTrue(pid0 != pid3); | 163 assertTrue(pid0 != pid3); |
83 })); | 164 })); |
84 })); | 165 })); |
85 }, | 166 }, |
86 | 167 |
87 function newTabPagesShareProcess() { | 168 function newTabPagesShareProcess() { |
88 getProcessId(tabs[3].id, pass(function(pid3) { | 169 getProcessId(tabs[3].id, pass(function(pid3) { |
89 getProcessId(tabs[4].id, pass(function(pid4) { | 170 getProcessId(tabs[4].id, pass(function(pid4) { |
90 // Multiple NTPs should share a process | 171 // Multiple NTPs should share a process |
91 assertEq(pid3, pid4); | 172 assertEq(pid3, pid4); |
92 })); | 173 })); |
93 })); | 174 })); |
94 }, | 175 }, |
95 | 176 |
96 function idsInUpdateEvent() { | 177 function idsInUpdateEvent() { |
97 listenOnce(chrome.experimental.processes.onUpdated, function(processes) { | 178 listenOnce(chrome.experimental.processes.onUpdated, function(processes) { |
98 // onUpdated should return a valid dictionary of processes, | 179 // onUpdated should return a valid dictionary of processes, |
99 // indexed by process ID. | 180 // indexed by process ID. |
100 var pids = Object.keys(processes); | 181 var pids = Object.keys(processes); |
101 // There should be at least 5 processes: 1 browser, 1 extension, and 3 | 182 // There should be at least 5 processes: 1 browser, 1 extension, and 3 |
102 // renderers (for the 5 tabs). | 183 // renderers (for the 5 tabs). |
103 assertTrue(pids.length >= 5); | 184 assertTrue(pids.length >= 5, "Unexpected size of pids"); |
104 | 185 |
105 // Should be able to look up process object by ID. | 186 // Should be able to look up process object by ID. |
106 assertTrue(processes[pids[0]].id == pids[0]); | 187 assertTrue(processes[pids[0]].id == pids[0]); |
107 assertTrue(processes[pids[0]].id != processes[pids[1]].id); | 188 assertTrue(processes[pids[0]].id != processes[pids[1]].id); |
108 | 189 |
109 getProcessId(tabs[0].id, pass(function(pidTab0) { | 190 getProcessId(tabs[0].id, pass(function(pidTab0) { |
110 // Process ID for tab 0 should be listed in pids. | 191 // Process ID for tab 0 should be listed in pids. |
111 assertTrue(processes[pidTab0] != undefined); | 192 assertTrue(processes[pidTab0] != undefined, "Undefined Process"); |
112 assertEq("renderer", processes[pidTab0].type); | 193 assertEq("renderer", processes[pidTab0].type, "Tab0 is not renderer"); |
113 })); | 194 })); |
114 }); | 195 }); |
115 }, | 196 }, |
116 | 197 |
117 function typesInUpdateEvent() { | 198 function typesInUpdateEvent() { |
118 listenOnce(chrome.experimental.processes.onUpdated, function(processes) { | 199 listenOnce(chrome.experimental.processes.onUpdated, function(processes) { |
119 // Check types: 1 browser, 3 renderers, and 1 extension | 200 // Check types: 1 browser, 3 renderers, and 1 extension |
120 var browserCount = 0; | 201 var browserCount = 0; |
121 var rendererCount = 0; | 202 var rendererCount = 0; |
122 var extensionCount = 0; | 203 var extensionCount = 0; |
(...skipping 16 matching lines...) Expand all Loading... |
139 assertEq(1, browserCount); | 220 assertEq(1, browserCount); |
140 assertTrue(rendererCount >= 3); | 221 assertTrue(rendererCount >= 3); |
141 assertTrue(extensionCount >= 1); | 222 assertTrue(extensionCount >= 1); |
142 }); | 223 }); |
143 }, | 224 }, |
144 | 225 |
145 function propertiesOfProcesses() { | 226 function propertiesOfProcesses() { |
146 listenOnce(chrome.experimental.processes.onUpdated, function(processes) { | 227 listenOnce(chrome.experimental.processes.onUpdated, function(processes) { |
147 for (pid in processes) { | 228 for (pid in processes) { |
148 var process = processes[pid]; | 229 var process = processes[pid]; |
149 assertTrue("id" in process); | 230 validateProcessProperties(process, true, false); |
150 assertTrue("type" in process); | |
151 assertTrue("cpu" in process); | |
152 assertTrue("network" in process); | |
153 assertTrue("sharedMemory" in process); | |
154 assertTrue("privateMemory" in process); | |
155 } | 231 } |
156 }); | 232 }); |
157 }, | 233 }, |
158 | 234 |
| 235 function propertiesOfProcessesWithMemory() { |
| 236 listenOnce(chrome.experimental.processes.onUpdatedWithMemory, |
| 237 function(processes) { |
| 238 for (pid in processes) { |
| 239 var process = processes[pid]; |
| 240 validateProcessProperties(process, true, true); |
| 241 } |
| 242 }); |
| 243 }, |
| 244 |
| 245 function terminateProcess() { |
| 246 listenOnce(chrome.experimental.processes.onExited, |
| 247 function(processId, type, code) { |
| 248 assertTrue(processId > 0); |
| 249 }); |
| 250 getProcessId(tabs[4].id, function(pid0) { |
| 251 chrome.experimental.processes.terminate(pid0, function(killed) { |
| 252 chrome.test.assertTrue(killed); |
| 253 }); |
| 254 }); |
| 255 }, |
| 256 |
| 257 function terminateProcessNonExisting() { |
| 258 chrome.experimental.processes.terminate(31337, |
| 259 fail("Process not found: 31337.")); |
| 260 }, |
| 261 |
| 262 function testOnCreated() { |
| 263 listenOnce(chrome.experimental.processes.onCreated, function(id, process) { |
| 264 assertTrue("id" in process, "process doesn't have id property"); |
| 265 assertTrue(id > 0, "id is not positive " + id); |
| 266 }); |
| 267 createTab(5, "chrome://newtab/"); |
| 268 }, |
| 269 |
| 270 function testOnExited() { |
| 271 listenOnce(chrome.experimental.processes.onExited, |
| 272 function(processId, type, code) { |
| 273 assertTrue(type >= 0 && type < 5); |
| 274 }); |
| 275 chrome.tabs.create({"url": "http://google.com/"}, pass(function(tab) { |
| 276 chrome.tabs.remove(tab.id); |
| 277 })); |
| 278 }, |
| 279 |
| 280 function testGetProcessInfoList() { |
| 281 chrome.experimental.processes.getProcessInfo([0, 2], false, |
| 282 pass(function(processes) { |
| 283 assertTrue(Object.keys(processes).length == 2); |
| 284 })); |
| 285 }, |
| 286 |
| 287 function testGetProcessInfoSingle() { |
| 288 chrome.experimental.processes.getProcessInfo(0, false, |
| 289 pass(function(processes) { |
| 290 assertTrue(Object.keys(processes).length == 1); |
| 291 })); |
| 292 }, |
| 293 |
| 294 function testGetProcessInfoAll() { |
| 295 chrome.experimental.processes.getProcessInfo([], false, |
| 296 pass(function(processes) { |
| 297 assertTrue(Object.keys(processes).length >= 1); |
| 298 })); |
| 299 }, |
| 300 |
| 301 function testGetProcessInfo() { |
| 302 chrome.experimental.processes.getProcessInfo([], false, |
| 303 pass(function(processes) { |
| 304 for (pid in processes) { |
| 305 var process = processes[pid]; |
| 306 validateProcessProperties(process, false, false); |
| 307 assertFalse("privateMemory" in process); |
| 308 } |
| 309 })); |
| 310 }, |
| 311 |
| 312 function testGetProcessInfoWithMemory() { |
| 313 chrome.experimental.processes.getProcessInfo(0, true, |
| 314 pass(function(processes) { |
| 315 for (pid in processes) { |
| 316 var process = processes[pid]; |
| 317 validateProcessProperties(process, false, true); |
| 318 assertTrue("privateMemory" in process); |
| 319 } |
| 320 })); |
| 321 }, |
| 322 |
| 323 function testOnUnresponsive() { |
| 324 listenOnce(chrome.experimental.processes.onUnresponsive, |
| 325 function(process) { |
| 326 assertTrue(process.id == hangingTabProcess); |
| 327 // actually kill the process, just to make sure it won't hang the test |
| 328 chrome.experimental.processes.terminate(process.id, function(killed) { |
| 329 chrome.test.assertTrue(killed); |
| 330 }); |
| 331 }); |
| 332 chrome.tabs.create({"url": "chrome://hang" }, function(tab) { |
| 333 getProcessId(tab.id, function(pid0) { |
| 334 hangingTabProcess = pid0; |
| 335 }); |
| 336 chrome.tabs.update(tab.id, { "url": "chrome://flags" }); |
| 337 }); |
| 338 } |
159 ]); | 339 ]); |
OLD | NEW |