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