1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
const HISTOGRAM_NAME = "FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM";
/**
* Test that an OOM in sendAsyncMessage in a framescript will be reported
* to Telemetry.
*/
add_task(function* init() {
Services.telemetry.canRecordExtended = true;
});
function frameScript() {
// Make send[A]syncMessage("SessionStore:update", ...) simulate OOM.
// Other operations are unaffected.
let mm = docShell.sameTypeRootTreeItem.
QueryInterface(Ci.nsIDocShell).
QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIContentFrameMessageManager);
let wrap = function(original) {
return function(name, ...args) {
if (name != "SessionStore:update") {
return original(name, ...args);
}
throw new Components.Exception("Simulated OOM", Cr.NS_ERROR_OUT_OF_MEMORY);
}
}
mm.sendAsyncMessage = wrap(mm.sendAsyncMessage);
mm.sendSyncMessage = wrap(mm.sendSyncMessage);
}
add_task(function*() {
// Capture original state.
let snapshot = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
// Open a browser, configure it to cause OOM.
let newTab = gBrowser.addTab("about:robots");
let browser = newTab.linkedBrowser;
yield ContentTask.spawn(browser, null, frameScript);
let promiseReported = new Promise(resolve => {
browser.messageManager.addMessageListener("SessionStore:error", resolve);
});
// Attempt to flush. This should fail.
let promiseFlushed = TabStateFlusher.flush(browser);
promiseFlushed.then((success) => {
if (success) {
throw new Error("Flush should have failed")
}
});
// The frame script should report an error.
yield promiseReported;
// Give us some time to handle that error.
yield new Promise(resolve => setTimeout(resolve, 10));
// By now, Telemetry should have been updated.
let snapshot2 = Services.telemetry.getHistogramById(HISTOGRAM_NAME).snapshot();
gBrowser.removeTab(newTab);
Assert.ok(snapshot2.sum > snapshot.sum);
});
add_task(function* cleanup() {
Services.telemetry.canRecordExtended = false;
});
|