diff options
Diffstat (limited to 'browser/base/content/test/tabcrashed/head.js')
-rw-r--r-- | browser/base/content/test/tabcrashed/head.js | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/browser/base/content/test/tabcrashed/head.js b/browser/base/content/test/tabcrashed/head.js new file mode 100644 index 000000000..6eee08f13 --- /dev/null +++ b/browser/base/content/test/tabcrashed/head.js @@ -0,0 +1,110 @@ +/** + * Returns a Promise that resolves once a crash report has + * been submitted. This function will also test the crash + * reports extra data to see if it matches expectedExtra. + * + * @param expectedExtra (object) + * An Object whose key-value pairs will be compared + * against the key-value pairs in the extra data of the + * crash report. A test failure will occur if there is + * a mismatch. + * + * If the value of the key-value pair is "null", this will + * be interpreted as "this key should not be included in the + * extra data", and will cause a test failure if it is detected + * in the crash report. + * + * Note that this will ignore any keys that are not included + * in expectedExtra. It's possible that the crash report + * will contain other extra information that is not + * compared against. + * @returns Promise + */ +function promiseCrashReport(expectedExtra={}) { + return Task.spawn(function*() { + info("Starting wait on crash-report-status"); + let [subject, ] = + yield TestUtils.topicObserved("crash-report-status", (unused, data) => { + return data == "success"; + }); + info("Topic observed!"); + + if (!(subject instanceof Ci.nsIPropertyBag2)) { + throw new Error("Subject was not a Ci.nsIPropertyBag2"); + } + + let remoteID = getPropertyBagValue(subject, "serverCrashID"); + if (!remoteID) { + throw new Error("Report should have a server ID"); + } + + let file = Cc["@mozilla.org/file/local;1"] + .createInstance(Ci.nsILocalFile); + file.initWithPath(Services.crashmanager._submittedDumpsDir); + file.append(remoteID + ".txt"); + if (!file.exists()) { + throw new Error("Report should have been received by the server"); + } + + file.remove(false); + + let extra = getPropertyBagValue(subject, "extra"); + if (!(extra instanceof Ci.nsIPropertyBag2)) { + throw new Error("extra was not a Ci.nsIPropertyBag2"); + } + + info("Iterating crash report extra keys"); + let enumerator = extra.enumerator; + while (enumerator.hasMoreElements()) { + let key = enumerator.getNext().QueryInterface(Ci.nsIProperty).name; + let value = extra.getPropertyAsAString(key); + if (key in expectedExtra) { + if (expectedExtra[key] == null) { + ok(false, `Got unexpected key ${key} with value ${value}`); + } else { + is(value, expectedExtra[key], + `Crash report had the right extra value for ${key}`); + } + } + } + }); +} + + +/** + * For an nsIPropertyBag, returns the value for a given + * key. + * + * @param bag + * The nsIPropertyBag to retrieve the value from + * @param key + * The key that we want to get the value for from the + * bag + * @returns The value corresponding to the key from the bag, + * or null if the value could not be retrieved (for + * example, if no value is set at that key). +*/ +function getPropertyBagValue(bag, key) { + try { + let val = bag.getProperty(key); + return val; + } catch (e) { + if (e.result != Cr.NS_ERROR_FAILURE) { + throw e; + } + } + + return null; +} + +/** + * Monkey patches TabCrashHandler.getDumpID to return null in order to test + * about:tabcrashed when a dump is not available. + */ +function prepareNoDump() { + let originalGetDumpID = TabCrashHandler.getDumpID; + TabCrashHandler.getDumpID = function(browser) { return null; }; + registerCleanupFunction(() => { + TabCrashHandler.getDumpID = originalGetDumpID; + }); +} |