|
1 |
|
2 Components.utils.import("resource://gre/modules/KeyValueParser.jsm"); |
|
3 |
|
4 const Cc = Components.classes; |
|
5 const Ci = Components.interfaces; |
|
6 |
|
7 var success = false; |
|
8 var observerFired = false; |
|
9 |
|
10 var testObserver = { |
|
11 idleHang: true, |
|
12 |
|
13 observe: function(subject, topic, data) { |
|
14 observerFired = true; |
|
15 ok(true, "Observer fired"); |
|
16 is(topic, "plugin-crashed", "Checking correct topic"); |
|
17 is(data, null, "Checking null data"); |
|
18 ok((subject instanceof Ci.nsIPropertyBag2), "got Propbag"); |
|
19 ok((subject instanceof Ci.nsIWritablePropertyBag2), "got writable Propbag"); |
|
20 |
|
21 var pluginId = subject.getPropertyAsAString("pluginDumpID"); |
|
22 isnot(pluginId, "", "got a non-empty plugin crash id"); |
|
23 |
|
24 // check plugin dump and extra files |
|
25 let directoryService = |
|
26 Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties); |
|
27 let profD = directoryService.get("ProfD", Ci.nsIFile); |
|
28 profD.append("minidumps"); |
|
29 let pluginDumpFile = profD.clone(); |
|
30 pluginDumpFile.append(pluginId + ".dmp"); |
|
31 ok(pluginDumpFile.exists(), "plugin minidump exists"); |
|
32 |
|
33 let pluginExtraFile = profD.clone(); |
|
34 pluginExtraFile.append(pluginId + ".extra"); |
|
35 ok(pluginExtraFile.exists(), "plugin extra file exists"); |
|
36 |
|
37 let extraData = parseKeyValuePairsFromFile(pluginExtraFile); |
|
38 |
|
39 // check additional dumps |
|
40 |
|
41 ok("additional_minidumps" in extraData, "got field for additional minidumps"); |
|
42 let additionalDumps = extraData.additional_minidumps.split(','); |
|
43 ok(additionalDumps.indexOf('browser') >= 0, "browser in additional_minidumps"); |
|
44 |
|
45 let additionalDumpFiles = []; |
|
46 for (let name of additionalDumps) { |
|
47 let file = profD.clone(); |
|
48 file.append(pluginId + "-" + name + ".dmp"); |
|
49 ok(file.exists(), "additional dump '"+name+"' exists"); |
|
50 if (file.exists()) { |
|
51 additionalDumpFiles.push(file); |
|
52 } |
|
53 } |
|
54 |
|
55 // check cpu usage field |
|
56 |
|
57 ok("PluginCpuUsage" in extraData, "got extra field for plugin cpu usage"); |
|
58 let cpuUsage = parseFloat(extraData["PluginCpuUsage"]); |
|
59 if (this.idleHang) { |
|
60 ok(cpuUsage == 0, "plugin cpu usage is 0%"); |
|
61 } else { |
|
62 ok(cpuUsage > 0, "plugin cpu usage is >0%"); |
|
63 } |
|
64 |
|
65 // check processor count field |
|
66 ok("NumberOfProcessors" in extraData, "got extra field for processor count"); |
|
67 ok(parseInt(extraData["NumberOfProcessors"]) > 0, "number of processors is >0"); |
|
68 |
|
69 // cleanup, to be nice |
|
70 pluginDumpFile.remove(false); |
|
71 pluginExtraFile.remove(false); |
|
72 for (let file of additionalDumpFiles) { |
|
73 file.remove(false); |
|
74 } |
|
75 }, |
|
76 |
|
77 QueryInterface: function(iid) { |
|
78 if (iid.equals(Ci.nsIObserver) || |
|
79 iid.equals(Ci.nsISupportsWeakReference) || |
|
80 iid.equals(Ci.nsISupports)) |
|
81 return this; |
|
82 throw Components.results.NS_NOINTERFACE; |
|
83 } |
|
84 }; |
|
85 |
|
86 |
|
87 function onPluginCrashed(aEvent) { |
|
88 ok(true, "Plugin crashed notification received"); |
|
89 ok(observerFired, "Observer should have fired first"); |
|
90 is(aEvent.type, "PluginCrashed", "event is correct type"); |
|
91 |
|
92 var pluginElement = document.getElementById("plugin1"); |
|
93 is (pluginElement, aEvent.target, "Plugin crashed event target is plugin element"); |
|
94 |
|
95 ok(aEvent instanceof Ci.nsIDOMCustomEvent, |
|
96 "plugin crashed event has the right interface"); |
|
97 |
|
98 var propBag = aEvent.detail.QueryInterface(Ci.nsIPropertyBag2); |
|
99 var pluginDumpID = propBag.getPropertyAsAString("pluginDumpID"); |
|
100 isnot(pluginDumpID, "", "got a non-empty dump ID"); |
|
101 var pluginName = propBag.getPropertyAsAString("pluginName"); |
|
102 is(pluginName, "Test Plug-in", "got correct plugin name"); |
|
103 var pluginFilename = propBag.getPropertyAsAString("pluginFilename"); |
|
104 isnot(pluginFilename, "", "got a non-empty filename"); |
|
105 var didReport = propBag.getPropertyAsBool("submittedCrashReport"); |
|
106 // The app itself may or may not have decided to submit the report, so |
|
107 // allow either true or false here. |
|
108 ok((didReport == true || didReport == false), "event said crash report was submitted"); |
|
109 |
|
110 var os = Cc["@mozilla.org/observer-service;1"]. |
|
111 getService(Ci.nsIObserverService); |
|
112 os.removeObserver(testObserver, "plugin-crashed"); |
|
113 |
|
114 SimpleTest.finish(); |
|
115 } |