Bug 1333126: plugin crash tests now wait properly for crash handling; r?gsvelto
MozReview-Commit-ID: 70AvBYhCKnE
--- a/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
+++ b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js
@@ -1,16 +1,19 @@
Cu.import("resource://gre/modules/CrashSubmit.jsm", this);
+Cu.import("resource://gre/modules/PromiseUtils.jsm");
const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
var gTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
var gTestBrowser = null;
var config = {};
+let gRegisteredCrashObserver = null;
+
add_task(async function() {
// The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin
// crash reports. This test needs them enabled. The test also needs a mock
// report server, and fortunately one is already set up by toolkit/
// crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
// which CrashSubmit.jsm uses as a server override.
let env = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
@@ -22,16 +25,19 @@ add_task(async function() {
gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
gTestBrowser = gBrowser.selectedBrowser;
// Crash immediately
Services.prefs.setIntPref("dom.ipc.plugins.timeoutSecs", 0);
registerCleanupFunction(async function() {
Services.prefs.clearUserPref("dom.ipc.plugins.timeoutSecs");
+ if (gRegisteredCrashObserver !== null) {
+ Services.obs.removeObserver(gRegisteredCrashObserver, "plugin-crashed");
+ }
env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
env.set("MOZ_CRASHREPORTER_URL", serverUrl);
env = null;
config = null;
gTestBrowser = null;
gBrowser.removeCurrentTab();
window.focus();
});
@@ -108,16 +114,35 @@ add_task(async function() {
Assert.equal(content.getComputedStyle(pleaseSubmit).display == "block",
aConfig.shouldSubmissionUIBeVisible, "The crash UI should be visible");
});
await crashReportStatus;
});
add_task(async function() {
+ // Since this test doesn't actually submit a crash report, we can't await
+ // on crashReportStatus. This ensures the crash handling mechanism is
+ // completely finished before exiting the test.
+ let crashObserverDeferred = PromiseUtils.defer();
+
+ gRegisteredCrashObserver = (subject, topic, data) => {
+ if (topic != "plugin-crashed") {
+ return;
+ }
+ let propBag = subject.QueryInterface(Ci.nsIPropertyBag2);
+ let minidumpID = propBag.getPropertyAsAString("pluginDumpID");
+
+ Services.crashmanager.ensureCrashIsPresent(minidumpID).then(() => {
+ crashObserverDeferred.resolve();
+ });
+ };
+
+ Services.obs.addObserver(gRegisteredCrashObserver, "plugin-crashed");
+
config = {
shouldSubmissionUIBeVisible: false,
comment: "",
urlOptIn: true
};
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
@@ -136,16 +161,18 @@ add_task(async function() {
// Test that the crash submission UI is not visible and do not submit a crash report.
await ContentTask.spawn(gTestBrowser, config, async function(aConfig) {
let doc = content.document;
let plugin = doc.getElementById("plugin");
let pleaseSubmit = doc.getAnonymousElementByAttribute(plugin, "anonid", "pleaseSubmit");
Assert.equal(!!pleaseSubmit && content.getComputedStyle(pleaseSubmit).display == "block",
aConfig.shouldSubmissionUIBeVisible, "Plugin crash UI should not be visible");
});
+
+ await crashObserverDeferred.promise;
});
function promisePluginCrashed() {
return new ContentTask.spawn(gTestBrowser, {}, async function() {
await new Promise((resolve) => {
addEventListener("PluginCrashReporterDisplayed", function onPluginCrashed() {
removeEventListener("PluginCrashReporterDisplayed", onPluginCrashed);
resolve();
--- a/browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js
+++ b/browser/base/content/test/plugins/browser_pluginCrashReportNonDeterminism.js
@@ -1,11 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
+Cu.import("resource://gre/modules/PromiseUtils.jsm");
+
/**
* With e10s, plugins must run in their own process. This means we have
* three processes at a minimum when we're running a plugin:
*
* 1) The main browser, or "chrome" process
* 2) The content process hosting the plugin instance
* 3) The plugin process
*
@@ -74,16 +76,19 @@ function preparePlugin(browser, pluginFa
});
return plugin.runID;
}).then((runID) => {
browser.messageManager.sendAsyncMessage("BrowserPlugins:Test:ClearCrashData");
return runID;
});
}
+// Allows tests to ensure crash handling is completely finished before exiting.
+let crashObserverDeferred = PromiseUtils.defer();
+
add_task(async function setup() {
// Bypass click-to-play
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
// Clear out any minidumps we create from plugins - we really don't care
// about them.
let crashObserver = (subject, topic, data) => {
if (topic != "plugin-crashed") {
@@ -103,16 +108,20 @@ add_task(async function setup() {
let extraFile = minidumpDir.clone();
extraFile.append(minidumpID + ".extra");
ok(pluginDumpFile.exists(), "Found minidump");
ok(extraFile.exists(), "Found extra file");
pluginDumpFile.remove(false);
extraFile.remove(false);
+
+ // Resolve and replace the deferred object so the next test can wait on it
+ crashObserverDeferred.resolve();
+ crashObserverDeferred = PromiseUtils.defer();
});
};
Services.obs.addObserver(crashObserver, "plugin-crashed");
// plugins.testmode will make BrowserPlugins:Test:ClearCrashData work.
Services.prefs.setBoolPref("plugins.testmode", true);
registerCleanupFunction(() => {
Services.prefs.clearUserPref("plugins.testmode");
@@ -178,16 +187,17 @@ add_task(async function testChromeHearsP
cancelable: true,
});
plugin.dispatchEvent(event);
Assert.equal(statusDiv.getAttribute("status"), "please",
"Should have been showing crash report UI");
});
await BrowserTestUtils.closeWindow(win);
+ await crashObserverDeferred.promise;
});
/**
* In this case, the content process hears about the crash first.
*/
add_task(async function testContentHearsCrashFirst() {
// Open a remote window so that we can run this test even if e10s is not
// enabled by default.
@@ -248,9 +258,10 @@ add_task(async function testContentHears
.getAnonymousElementByAttribute(plugin, "anonid",
"submitStatus");
Assert.equal(statusDiv.getAttribute("status"), "please",
"Should have been showing crash report UI");
});
await BrowserTestUtils.closeWindow(win);
+ await crashObserverDeferred.promise;
});