Bug 1073352, part 1 - Make the DOMWINDOW and DOCSHELL leak detector work with e10s. r=jmaher

This reworks how the Mochitest DOMWINDOW and DOCSHELL leak detector works. Rather than
collecting immediately in the top-level script, it sends a message to all processes
telling them to carry out collections. Each process prints out a message when it has
finished the collections. This message is used by the test harness to decide when windows
and docshells for that process should be have been destroyed.
This commit is contained in:
Andrew McCreight 2015-02-14 11:43:45 -08:00
parent 3757a6dec6
commit eb177fe773
5 changed files with 70 additions and 5 deletions

View File

@ -445,7 +445,7 @@ class ShutdownLeaks(object):
self.leakedWindows = {}
self.leakedDocShells = set()
self.currentTest = None
self.seenShutdown = False
self.seenShutdown = set()
def log(self, message):
if message['action'] == 'log':
@ -454,8 +454,9 @@ class ShutdownLeaks(object):
self._logWindow(line)
elif line[2:10] == "DOCSHELL":
self._logDocShell(line)
elif line.startswith("TEST-START | Shutdown"):
self.seenShutdown = True
elif line.startswith("Completed ShutdownLeaks collections in process"):
pid = int(line.split()[-1])
self.seenShutdown.add(pid)
elif message['action'] == 'test_start':
fileName = message['test'].replace("chrome://mochitests/content/browser/", "")
self.currentTest = {"fileName": fileName, "windows": set(), "docShells": set()}
@ -499,7 +500,7 @@ class ShutdownLeaks(object):
windows.add(key)
else:
windows.discard(key)
elif self.seenShutdown and not created:
elif int(pid) in self.seenShutdown and not created:
self.leakedWindows[key] = self._parseValue(line, "url")
def _logDocShell(self, line):
@ -520,7 +521,7 @@ class ShutdownLeaks(object):
docShells.add(key)
else:
docShells.discard(key)
elif self.seenShutdown and not created:
elif int(pid) in self.seenShutdown and not created:
self.leakedDocShells.add(key)
def _parseValue(self, line, name):

View File

@ -0,0 +1,48 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
var Ci = Components.interfaces;
var Cc = Components.classes;
var Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
this.EXPORTED_SYMBOLS = ["ContentCollector"];
// This listens for the message "browser-test:collect-request". When it gets it,
// it runs some GCs and CCs, then prints out a message indicating the collections
// are complete. Mochitest uses this information to determine when windows and
// docshells should be destroyed.
var ContentCollector = {
init: function() {
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
.getService(Ci.nsISyncMessageSender);
cpmm.addMessageListener("browser-test:collect-request", this);
},
receiveMessage: function(aMessage) {
switch (aMessage.name) {
case "browser-test:collect-request":
Services.obs.notifyObservers(null, "memory-pressure", "heap-minimize");
Cu.forceGC();
Cu.forceCC();
Cu.schedulePreciseShrinkingGC(() => {
Cu.forceCC();
let pid = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).processID;
dump("Completed ShutdownLeaks collections in process " + pid + "\n")});
let cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"]
.getService(Ci.nsISyncMessageSender);
cpmm.removeMessageListener("browser-test:collect-request", this);
break;
}
}
};
ContentCollector.init();

View File

@ -86,6 +86,9 @@ function testInit() {
if (gConfig.e10s) {
e10s_init();
}
let globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
globalMM.loadFrameScript("chrome://mochikit/content/shutdown-leaks-collector.js", true);
}
function Tester(aTests, aDumper, aCallback) {
@ -571,6 +574,10 @@ Tester.prototype = {
// and thus get rid of more false leaks like already terminated workers.
Services.obs.notifyObservers(null, "memory-pressure", "heap-minimize");
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Ci.nsIMessageBroadcaster);
ppmm.broadcastAsyncMessage("browser-test:collect-request");
checkForLeakedGlobalWindows(aResults => {
if (aResults.length == 0) {
this.finish();

View File

@ -10,6 +10,8 @@ mochikit.jar:
content/cc-analyzer.js (cc-analyzer.js)
content/chrome-harness.js (chrome-harness.js)
content/mochitest-e10s-utils.js (mochitest-e10s-utils.js)
content/shutdown-leaks-collector.js (shutdown-leaks-collector.js)
content/ShutdownLeaksCollector.jsm (ShutdownLeaksCollector.jsm)
content/harness.xul (harness.xul)
content/redirect.html (redirect.html)
content/server.js (server.js)

View File

@ -0,0 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
// We run this code in a .jsm rather than here to avoid keeping the current
// compartment alive.
Components.utils.import("chrome://mochikit/content/ShutdownLeaksCollector.jsm");