Bug 1559244 - Step 1: make BrowserTestUtils@crashBrowser function work with JSWindowActor. r=mconley

Differential Revision: https://phabricator.services.mozilla.com/D37318

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Abdoulaye O. Ly 2019-08-15 17:01:45 +00:00
Родитель bd5ab026e1
Коммит e029a89c66
6 изменённых файлов: 100 добавлений и 24 удалений

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/Base64.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/CycleCollectedJSRuntime.h"
#include "mozilla/IntentionalCrash.h"
#include "mozilla/PerformanceMetricsCollector.h"
#include "mozilla/PerfStats.h"
#include "mozilla/Preferences.h"
@ -1118,5 +1119,15 @@ bool ChromeUtils::IsClassifierBlockingErrorCode(GlobalObject& aGlobal,
static_cast<nsresult>(aError));
}
/* static */
void ChromeUtils::PrivateNoteIntentionalCrash(const GlobalObject& aGlobal,
ErrorResult& aError) {
if (XRE_IsContentProcess()) {
NoteIntentionalCrash("tab");
return;
}
aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
}
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -192,6 +192,9 @@ class ChromeUtils {
static bool IsClassifierBlockingErrorCode(GlobalObject& aGlobal,
uint32_t aError);
static void PrivateNoteIntentionalCrash(const GlobalObject& aGlobal,
ErrorResult& aError);
};
} // namespace dom

Просмотреть файл

@ -427,6 +427,14 @@ partial namespace ChromeUtils {
[ChromeOnly]
// aError should a nsresult.
boolean isClassifierBlockingErrorCode(unsigned long aError);
/**
* If leak detection is enabled, print a note to the leak log that this
* process will intentionally crash. This should be called only on child
* processes for testing purpose.
*/
[ChromeOnly, Throws]
void privateNoteIntentionalCrash();
};
/**

Просмотреть файл

@ -88,6 +88,23 @@ var gSynthesizeCompositionChangeCount = 0;
const kAboutPageRegistrationContentScript =
"chrome://mochikit/content/tests/BrowserTestUtils/content-about-page-utils.js";
/**
* Create and register BrowserTestUtils Window Actor.
*/
function registerActor() {
let actorOptions = {
child: {
moduleURI: "resource://testing-common/BrowserTestUtilsChild.jsm",
},
allFrames: true,
includeChrome: true,
};
ChromeUtils.registerWindowActor("BrowserTestUtils", actorOptions);
}
registerActor();
var BrowserTestUtils = {
/**
* Loads a page in a new tab, executes a Task and closes the tab.
@ -1660,26 +1677,6 @@ var BrowserTestUtils = {
}
}
// This frame script is injected into the remote browser, and used to
// intentionally crash the tab. We crash by using js-ctypes and dereferencing
// a bad pointer. The crash should happen immediately upon loading this
// frame script.
let frame_script = () => {
const { ctypes } = ChromeUtils.import(
"resource://gre/modules/ctypes.jsm"
);
let dies = function() {
privateNoteIntentionalCrash();
let zero = new ctypes.intptr_t(8);
let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
badptr.contents;
};
dump("\nEt tu, Brute?\n");
dies();
};
let expectedPromises = [];
let crashCleanupPromise = new Promise((resolve, reject) => {
@ -1771,10 +1768,12 @@ var BrowserTestUtils = {
);
}
// This frame script will crash the remote browser as soon as it is
// evaluated.
let mm = browser.messageManager;
mm.loadFrameScript("data:,(" + frame_script.toString() + ")();", false);
// Trigger crash by sending a message to BrowserTestUtils actor.
this.sendAsyncMessage(
browser.browsingContext,
"BrowserTestUtils:CrashFrame",
{}
);
await Promise.all(expectedPromises);
@ -2207,4 +2206,24 @@ var BrowserTestUtils = {
}
return tabbrowser.addTab(uri, params);
},
/**
* Sends a message to a specific BrowserTestUtils window actor.
* @param aBrowsingContext
* The browsing context where the actor lives.
* @param {string} aMessageName
* Name of the message to be sent to the actor.
* @param {object} aMessageData
* Extra information to pass to the actor.
*/
async sendAsyncMessage(aBrowsingContext, aMessageName, aMessageData) {
if (!aBrowsingContext.currentWindowGlobal) {
await this.waitForCondition(() => aBrowsingContext.currentWindowGlobal);
}
let actor = aBrowsingContext.currentWindowGlobal.getActor(
"BrowserTestUtils"
);
actor.sendAsyncMessage(aMessageName, aMessageData);
},
};

Просмотреть файл

@ -0,0 +1,34 @@
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["BrowserTestUtilsChild"];
class BrowserTestUtilsChild extends JSWindowActorChild {
receiveMessage(aMessage) {
switch (aMessage.name) {
case "BrowserTestUtils:CrashFrame": {
// This is to intentionally crash the frame.
// We crash by using js-ctypes and dereferencing
// a bad pointer. The crash should happen immediately
// upon loading this frame script.
const { ctypes } = ChromeUtils.import(
"resource://gre/modules/ctypes.jsm"
);
let dies = function() {
ChromeUtils.privateNoteIntentionalCrash();
let zero = new ctypes.intptr_t(8);
let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
badptr.contents;
};
dump("\nEt tu, Brute?\n");
dies();
}
}
}
}

Просмотреть файл

@ -6,6 +6,7 @@
TESTING_JS_MODULES += [
'BrowserTestUtils.jsm',
'BrowserTestUtilsChild.jsm',
'content/content-task.js',
'ContentTask.jsm',
'ContentTaskUtils.jsm',