diff options
Diffstat (limited to 'js/xpconnect/tests/browser')
-rw-r--r-- | js/xpconnect/tests/browser/browser.ini | 7 | ||||
-rw-r--r-- | js/xpconnect/tests/browser/browser_consoleStack.html | 21 | ||||
-rw-r--r-- | js/xpconnect/tests/browser/browser_deadObjectOnUnload.html | 18 | ||||
-rw-r--r-- | js/xpconnect/tests/browser/browser_dead_object.js | 36 | ||||
-rw-r--r-- | js/xpconnect/tests/browser/browser_exception_leak.js | 73 | ||||
-rw-r--r-- | js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js | 51 | ||||
-rw-r--r-- | js/xpconnect/tests/browser/moz.build | 7 |
7 files changed, 213 insertions, 0 deletions
diff --git a/js/xpconnect/tests/browser/browser.ini b/js/xpconnect/tests/browser/browser.ini new file mode 100644 index 0000000000..87a7547d86 --- /dev/null +++ b/js/xpconnect/tests/browser/browser.ini @@ -0,0 +1,7 @@ +[DEFAULT] +support-files = + browser_consoleStack.html + browser_deadObjectOnUnload.html +[browser_dead_object.js] +[browser_exception_leak.js] +[browser_parent_process_hang_telemetry.js] diff --git a/js/xpconnect/tests/browser/browser_consoleStack.html b/js/xpconnect/tests/browser/browser_consoleStack.html new file mode 100644 index 0000000000..37bfdb32f6 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_consoleStack.html @@ -0,0 +1,21 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test page for https://bugzilla.mozilla.org/show_bug.cgi?id=1471989 +--> +<head> + <meta charset="utf-8"> + <title>Test page for Bug 1471989</title> +</head> +<body onUnload="onUnload();"> +<p><span id="samplepage">sample page</span></p> +<script type="application/javascript"> + // Get something sent to ConsoleStorageAPI that has a stack. + console.trace("whatever"); + + function onUnload() { + console.log('in unload'); + } +</script> +</body> +</html> diff --git a/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html b/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html new file mode 100644 index 0000000000..ceb40b20b6 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html @@ -0,0 +1,18 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test page for https://bugzilla.mozilla.org/show_bug.cgi?id=1242643 +--> +<head> + <meta charset="utf-8"> + <title>Test page for Bug 1242643</title> +</head> +<body onUnload="onUnload();"> +<p><span id="samplepage">sample page</span></p> +<script type="application/javascript"> + function onUnload() { + console.log('in unload'); + } +</script> +</body> +</html> diff --git a/js/xpconnect/tests/browser/browser_dead_object.js b/js/xpconnect/tests/browser/browser_dead_object.js new file mode 100644 index 0000000000..b101c64848 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_dead_object.js @@ -0,0 +1,36 @@ +/* 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/. + */ + +// For bug 773980, test that Components.utils.isDeadWrapper works as expected. + +add_task(async function test() { + const url = + "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_deadObjectOnUnload.html"; + let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + let browser = gBrowser.selectedBrowser; + let innerWindowId = browser.innerWindowID; + let contentDocDead = await ContentTask.spawn( + browser, + { innerWindowId }, + async function(args) { + let doc = content.document; + let { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" + ); + let promise = TestUtils.topicObserved( + "inner-window-nuked", + (subject, data) => { + let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; + return id == args.innerWindowId; + } + ); + content.location = "http://mochi.test:8888/"; + await promise; + return Cu.isDeadWrapper(doc); + } + ); + is(contentDocDead, true, "wrapper is dead"); + BrowserTestUtils.removeTab(newTab); +}); diff --git a/js/xpconnect/tests/browser/browser_exception_leak.js b/js/xpconnect/tests/browser/browser_exception_leak.js new file mode 100644 index 0000000000..13df33783d --- /dev/null +++ b/js/xpconnect/tests/browser/browser_exception_leak.js @@ -0,0 +1,73 @@ +/* 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/. + */ + +// For bug 1471989, test that an exception saved by chrome code can't leak the page. + +add_task(async function test() { + const url = + "http://mochi.test:8888/browser/js/xpconnect/tests/browser/browser_consoleStack.html"; + let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url); + let browser = gBrowser.selectedBrowser; + let innerWindowId = browser.innerWindowID; + + let stackTraceEmpty = await ContentTask.spawn( + browser, + { innerWindowId }, + async function(args) { + let { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" + ); + let { Assert } = ChromeUtils.import( + "resource://testing-common/Assert.jsm" + ); + + const ConsoleAPIStorage = Cc[ + "@mozilla.org/consoleAPI-storage;1" + ].getService(Ci.nsIConsoleAPIStorage); + let consoleEvents = ConsoleAPIStorage.getEvents(args.innerWindowId); + Assert.equal( + consoleEvents.length, + 1, + "Should only be one console event for the window" + ); + + // Intentionally hold a reference to the console event. + let leakedConsoleEvent = consoleEvents[0]; + + let doc = content.document; + let promise = TestUtils.topicObserved( + "inner-window-nuked", + (subject, data) => { + let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data; + return id == args.innerWindowId; + } + ); + content.location = "http://mochi.test:8888/"; + await promise; + + // This string should be empty. For that to happen, two things + // need to be true: + // + // a) ConsoleCallData::mStack is not null. This means that the + // stack trace was not reified before the page was nuked. If it + // was, then the correct |filename| value would be stored on the + // object. (This is not a problem, except that it stops us from + // testing the next condition.) + // + // b) ConsoleData::mStack.mStack is null. This means that the + // JSStackFrame is keeping alive the JS object in the page after + // the page was nuked, which leaks the page. + return leakedConsoleEvent.stacktrace[0].filename; + } + ); + + is( + stackTraceEmpty, + "", + "JSStackFrame shouldn't leak mStack after window nuking" + ); + + BrowserTestUtils.removeTab(newTab); +}); diff --git a/js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js b/js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js new file mode 100644 index 0000000000..e312f2ab85 --- /dev/null +++ b/js/xpconnect/tests/browser/browser_parent_process_hang_telemetry.js @@ -0,0 +1,51 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Check that we record hangs in the parent process in telemetry events. + * This test would be an xpcshell test except xpcshell does not think + * it is running e10s (see bug 1568333). + */ +add_task(async function test_browser_hang() { + // Trip some testing code to ensure we can test this. Sadly, this is a magic + // number corresponding to code in XPCJSContext.cpp + await SpecialPowers.pushPrefEnv({ + set: [["dom.max_chrome_script_run_time", 2]] + }); + + // Hang for 1.2 seconds. + let now = Date.now(); + let i = 0; + info("Start loop"); + while (Date.now() - now < 2500) { + // The system clock can go backwards. Don't time out the test: + if (Date.now() - now < 0) { + info("Yikes, the system clock changed while running this test."); + now = Date.now(); + } + i++; + } + let duration = (Date.now() - now) / 1000; + info("Looped " + i + " iterations."); + + let events; + await TestUtils.waitForCondition(() => { + events = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_ALL_CHANNELS, + false + ); + return events.parent?.some(e => e[1] == "slow_script_warning"); + }, "Should find an event after doing this.").catch(e => ok(false, e)); + events = (events.parent || []); + let event = events.find(e => e[1] == "slow_script_warning"); + ok(event, "Should have registered an event."); + if (event) { + is(event[3], "browser", "Should register as browser hang."); + let args = event[5]; + is(args.uri_type, "browser", "Should register browser uri type."); + Assert.greater(duration + 1, parseFloat(args.hang_duration), "hang duration should not exaggerate."); + Assert.less(duration - 1, parseFloat(args.hang_duration), "hang duration should not undersell."); + } +}); diff --git a/js/xpconnect/tests/browser/moz.build b/js/xpconnect/tests/browser/moz.build new file mode 100644 index 0000000000..67b1ac4bbb --- /dev/null +++ b/js/xpconnect/tests/browser/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +BROWSER_CHROME_MANIFESTS += ["browser.ini"] |