michael@0: michael@0: Components.utils.import("resource://gre/modules/KeyValueParser.jsm"); michael@0: michael@0: const Cc = Components.classes; michael@0: const Ci = Components.interfaces; michael@0: michael@0: var success = false; michael@0: var observerFired = false; michael@0: michael@0: var testObserver = { michael@0: idleHang: true, michael@0: michael@0: observe: function(subject, topic, data) { michael@0: observerFired = true; michael@0: ok(true, "Observer fired"); michael@0: is(topic, "plugin-crashed", "Checking correct topic"); michael@0: is(data, null, "Checking null data"); michael@0: ok((subject instanceof Ci.nsIPropertyBag2), "got Propbag"); michael@0: ok((subject instanceof Ci.nsIWritablePropertyBag2), "got writable Propbag"); michael@0: michael@0: var pluginId = subject.getPropertyAsAString("pluginDumpID"); michael@0: isnot(pluginId, "", "got a non-empty plugin crash id"); michael@0: michael@0: // check plugin dump and extra files michael@0: let directoryService = michael@0: Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); michael@0: let profD = directoryService.get("ProfD", Ci.nsIFile); michael@0: profD.append("minidumps"); michael@0: let pluginDumpFile = profD.clone(); michael@0: pluginDumpFile.append(pluginId + ".dmp"); michael@0: ok(pluginDumpFile.exists(), "plugin minidump exists"); michael@0: michael@0: let pluginExtraFile = profD.clone(); michael@0: pluginExtraFile.append(pluginId + ".extra"); michael@0: ok(pluginExtraFile.exists(), "plugin extra file exists"); michael@0: michael@0: let extraData = parseKeyValuePairsFromFile(pluginExtraFile); michael@0: michael@0: // check additional dumps michael@0: michael@0: ok("additional_minidumps" in extraData, "got field for additional minidumps"); michael@0: let additionalDumps = extraData.additional_minidumps.split(','); michael@0: ok(additionalDumps.indexOf('browser') >= 0, "browser in additional_minidumps"); michael@0: michael@0: let additionalDumpFiles = []; michael@0: for (let name of additionalDumps) { michael@0: let file = profD.clone(); michael@0: file.append(pluginId + "-" + name + ".dmp"); michael@0: ok(file.exists(), "additional dump '"+name+"' exists"); michael@0: if (file.exists()) { michael@0: additionalDumpFiles.push(file); michael@0: } michael@0: } michael@0: michael@0: // check cpu usage field michael@0: michael@0: ok("PluginCpuUsage" in extraData, "got extra field for plugin cpu usage"); michael@0: let cpuUsage = parseFloat(extraData["PluginCpuUsage"]); michael@0: if (this.idleHang) { michael@0: ok(cpuUsage == 0, "plugin cpu usage is 0%"); michael@0: } else { michael@0: ok(cpuUsage > 0, "plugin cpu usage is >0%"); michael@0: } michael@0: michael@0: // check processor count field michael@0: ok("NumberOfProcessors" in extraData, "got extra field for processor count"); michael@0: ok(parseInt(extraData["NumberOfProcessors"]) > 0, "number of processors is >0"); michael@0: michael@0: // cleanup, to be nice michael@0: pluginDumpFile.remove(false); michael@0: pluginExtraFile.remove(false); michael@0: for (let file of additionalDumpFiles) { michael@0: file.remove(false); michael@0: } michael@0: }, michael@0: michael@0: QueryInterface: function(iid) { michael@0: if (iid.equals(Ci.nsIObserver) || michael@0: iid.equals(Ci.nsISupportsWeakReference) || michael@0: iid.equals(Ci.nsISupports)) michael@0: return this; michael@0: throw Components.results.NS_NOINTERFACE; michael@0: } michael@0: }; michael@0: michael@0: michael@0: function onPluginCrashed(aEvent) { michael@0: ok(true, "Plugin crashed notification received"); michael@0: ok(observerFired, "Observer should have fired first"); michael@0: is(aEvent.type, "PluginCrashed", "event is correct type"); michael@0: michael@0: var pluginElement = document.getElementById("plugin1"); michael@0: is (pluginElement, aEvent.target, "Plugin crashed event target is plugin element"); michael@0: michael@0: ok(aEvent instanceof Ci.nsIDOMCustomEvent, michael@0: "plugin crashed event has the right interface"); michael@0: michael@0: var propBag = aEvent.detail.QueryInterface(Ci.nsIPropertyBag2); michael@0: var pluginDumpID = propBag.getPropertyAsAString("pluginDumpID"); michael@0: isnot(pluginDumpID, "", "got a non-empty dump ID"); michael@0: var pluginName = propBag.getPropertyAsAString("pluginName"); michael@0: is(pluginName, "Test Plug-in", "got correct plugin name"); michael@0: var pluginFilename = propBag.getPropertyAsAString("pluginFilename"); michael@0: isnot(pluginFilename, "", "got a non-empty filename"); michael@0: var didReport = propBag.getPropertyAsBool("submittedCrashReport"); michael@0: // The app itself may or may not have decided to submit the report, so michael@0: // allow either true or false here. michael@0: ok((didReport == true || didReport == false), "event said crash report was submitted"); michael@0: michael@0: var os = Cc["@mozilla.org/observer-service;1"]. michael@0: getService(Ci.nsIObserverService); michael@0: os.removeObserver(testObserver, "plugin-crashed"); michael@0: michael@0: SimpleTest.finish(); michael@0: }