diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:33 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:33 +0000 |
commit | 086c044dc34dfc0f74fbe41f4ecb402b2cd34884 (patch) | |
tree | a4f824bd33cb075dd5aa3eb5a0a94af221bbe83a /devtools/shared/test-helpers | |
parent | Adding debian version 124.0.1-1. (diff) | |
download | firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.tar.xz firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/shared/test-helpers')
-rw-r--r-- | devtools/shared/test-helpers/allocation-tracker.js | 7 | ||||
-rw-r--r-- | devtools/shared/test-helpers/moz.build | 2 | ||||
-rw-r--r-- | devtools/shared/test-helpers/test-stepper.js | 97 | ||||
-rw-r--r-- | devtools/shared/test-helpers/test_javascript_tracer.js | 72 | ||||
-rw-r--r-- | devtools/shared/test-helpers/thread-helpers.sys.mjs | 143 | ||||
-rw-r--r-- | devtools/shared/test-helpers/xpcshell.toml | 6 |
6 files changed, 102 insertions, 225 deletions
diff --git a/devtools/shared/test-helpers/allocation-tracker.js b/devtools/shared/test-helpers/allocation-tracker.js index 17dcfafdf0..345eb23a43 100644 --- a/devtools/shared/test-helpers/allocation-tracker.js +++ b/devtools/shared/test-helpers/allocation-tracker.js @@ -41,7 +41,8 @@ const MemoryReporter = Cc["@mozilla.org/memory-reporter-manager;1"].getService( const global = Cu.getGlobalForObject(this); const { addDebuggerToGlobal } = ChromeUtils.importESModule( - "resource://gre/modules/jsdebugger.sys.mjs" + "resource://gre/modules/jsdebugger.sys.mjs", + { global: "contextual" } ); addDebuggerToGlobal(global); @@ -313,14 +314,14 @@ exports.allocationTracker = function ({ logAllocationSites(message, sources, { first = 1000 } = {}) { const allocationList = Object.entries(sources) // Sort by number of total object - .sort(([srcA, itemA], [srcB, itemB]) => itemB.count - itemA.count) + .sort(([, itemA], [, itemB]) => itemB.count - itemA.count) // Keep only the first n-th sources, with the most allocations .filter((_, i) => i < first) .map(([src, item]) => { const lines = []; Object.entries(item.lines) // Filter out lines where we only freed objects - .filter(([line, count]) => count > 0) + .filter(([, count]) => count > 0) .sort(([lineA, countA], [lineB, countB]) => { if (countA != countB) { return countB - countA; diff --git a/devtools/shared/test-helpers/moz.build b/devtools/shared/test-helpers/moz.build index 92b1d5212d..2c14b6a7b7 100644 --- a/devtools/shared/test-helpers/moz.build +++ b/devtools/shared/test-helpers/moz.build @@ -5,7 +5,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DevToolsModules( - "thread-helpers.sys.mjs", + "test-stepper.js", "tracked-objects.sys.mjs", ) diff --git a/devtools/shared/test-helpers/test-stepper.js b/devtools/shared/test-helpers/test-stepper.js new file mode 100644 index 0000000000..314a687dbf --- /dev/null +++ b/devtools/shared/test-helpers/test-stepper.js @@ -0,0 +1,97 @@ +/* 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"; + +const { + startTracing, + addTracingListener, + stopTracing, + removeTracingListener, +} = require("resource://devtools/server/tracer/tracer.jsm"); + +let testFileContent; + +function traceFrame({ frame }) { + const { script } = frame; + const { lineNumber, columnNumber } = script.getOffsetMetadata(frame.offset); + + const { url } = script.source; + const filename = url.substr(url.lastIndexOf("/") + 1); + const line = testFileContent[lineNumber - 1]; + // Grey out the beginning of the line, before frame's column, + // and display an arrow before displaying the rest of the line. + const code = + "\x1b[2m" + + line.substr(0, columnNumber - 1) + + "\x1b[0m" + + "\u21A6 " + + line.substr(columnNumber - 1); + + const position = (lineNumber + ":" + columnNumber).padEnd(7); + logStep(`${filename} @ ${position} :: ${code}`); + + // Disable builtin tracer logging + return false; +} + +function logStep(message) { + dump(` \x1b[2m[STEP]\x1b[0m ${message}\n`); +} + +const tracingListener = { + onTracingFrame: traceFrame, + onTracingFrameStep: traceFrame, +}; + +exports.start = function (testGlobal, testUrl, pause) { + const tracerOptions = { + global: testGlobal, + // Ensure tracing each execution within functions (and not only function calls) + traceSteps: true, + // Only trace the running test and nothing else + filterFrameSourceUrl: testUrl, + }; + testFileContent = readURI(testUrl).split("\n"); + // Only pause on each step if the passed value is a number, + // otherwise we are only going to print each executed line in the test script. + if (!isNaN(pause)) { + // Delay each step by an amount of milliseconds + tracerOptions.pauseOnStep = Number(pause); + logStep(`Tracing all test script steps with ${pause}ms pause`); + logStep( + `/!\\ Be conscious about each pause releasing the event loop and breaking run-to-completion.` + ); + } else { + logStep(`Tracing all test script steps`); + } + logStep( + `'\u21A6 ' symbol highlights what precise instruction is being called` + ); + startTracing(tracerOptions); + addTracingListener(tracingListener); +}; + +exports.stop = function () { + stopTracing(); + removeTracingListener(tracingListener); +}; + +function readURI(uri) { + const { NetUtil } = ChromeUtils.importESModule( + "resource://gre/modules/NetUtil.sys.mjs", + { global: "contextual" } + ); + const stream = NetUtil.newChannel({ + uri: NetUtil.newURI(uri, "UTF-8"), + loadUsingSystemPrincipal: true, + }).open(); + const count = stream.available(); + const data = NetUtil.readInputStreamToString(stream, count, { + charset: "UTF-8", + }); + + stream.close(); + return data; +} diff --git a/devtools/shared/test-helpers/test_javascript_tracer.js b/devtools/shared/test-helpers/test_javascript_tracer.js deleted file mode 100644 index 268e054c56..0000000000 --- a/devtools/shared/test-helpers/test_javascript_tracer.js +++ /dev/null @@ -1,72 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -"use strict"; - -/** - * Test for the thread helpers utility module. - * - * This uses a xpcshell test in order to avoid recording the noise - * of all Firefox components when using a mochitest. - */ - -const { traceAllJSCalls } = ChromeUtils.importESModule( - "resource://devtools/shared/test-helpers/thread-helpers.sys.mjs" -); -// ESLint thinks this is a browser test, but it's actually an xpcshell -// test and so `setTimeout` isn't available out of the box. -// eslint-disable-next-line mozilla/no-redeclare-with-import-autofix -const { setTimeout } = ChromeUtils.importESModule( - "resource://gre/modules/Timer.sys.mjs" -); - -add_task(async function sanityCheck() { - let ranTheOtherEventLoop = false; - setTimeout(function otherEventLoop() { - ranTheOtherEventLoop = true; - }, 0); - const jsTracer = traceAllJSCalls(); - function foo() {} - for (let i = 0; i < 10; i++) { - foo(); - } - jsTracer.stop(); - ok( - !ranTheOtherEventLoop, - "When we don't pause frame execution, the other event do not execute" - ); -}); - -add_task(async function withPrefix() { - const jsTracer = traceAllJSCalls({ prefix: "my-prefix" }); - function foo() {} - for (let i = 0; i < 10; i++) { - foo(); - } - jsTracer.stop(); - ok(true, "Were able to run with a prefix argument"); -}); - -add_task(async function pause() { - const start = Cu.now(); - let ranTheOtherEventLoop = false; - setTimeout(function otherEventLoop() { - ranTheOtherEventLoop = true; - }, 0); - const jsTracer = traceAllJSCalls({ pause: 100 }); - function foo() {} - for (let i = 0; i < 10; i++) { - foo(); - } - jsTracer.stop(); - const duration = Cu.now() - start; - Assert.greater( - duration, - 10 * 100, - "The execution of the for loop was slow down by at least the pause duration in each loop" - ); - ok( - ranTheOtherEventLoop, - "When we pause frame execution, the other event can execute" - ); -}); diff --git a/devtools/shared/test-helpers/thread-helpers.sys.mjs b/devtools/shared/test-helpers/thread-helpers.sys.mjs deleted file mode 100644 index b99fc16f00..0000000000 --- a/devtools/shared/test-helpers/thread-helpers.sys.mjs +++ /dev/null @@ -1,143 +0,0 @@ -/* 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/. */ - -/** - * Helper code to play with the javascript thread - **/ - -function getSandboxWithDebuggerSymbol() { - // Bug 1835268 - Changing this to an ES module import currently throws an - // assertion in test_javascript_tracer.js in debug builds. - const { addDebuggerToGlobal } = ChromeUtils.import( - "resource://gre/modules/jsdebugger.jsm" - ); - const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); - - const debuggerSandbox = Cu.Sandbox(systemPrincipal, { - // This sandbox is also reused for ChromeDebugger implementation. - // As we want to load the `Debugger` API for debugging chrome contexts, - // we have to ensure loading it in a distinct compartment from its debuggee. - freshCompartment: true, - invisibleToDebugger: true, - }); - addDebuggerToGlobal(debuggerSandbox); - - return debuggerSandbox; -} - -/** - * Implementation of a Javascript tracer logging traces to stdout. - * - * To be used like this: - - const { traceAllJSCalls } = ChromeUtils.importESModule( - "resource://devtools/shared/test-helpers/thread-helpers.sys.mjs" - ); - const jsTracer = traceAllJSCalls(); - [... execute some code to tracer ...] - jsTracer.stop(); - - * @param prefix String - * Optional, if passed, this will be displayed in front of each - * line reporting a new frame execution. - * @param pause Number - * Optional, if passed, hold off each frame for `pause` ms, - * by letting the other event loops run in between. - * Be careful that it can introduce unexpected race conditions - * that can't necessarily be reproduced without this. - */ -export function traceAllJSCalls({ prefix = "", pause } = {}) { - const debuggerSandbox = getSandboxWithDebuggerSymbol(); - - debuggerSandbox.Services = Services; - const f = Cu.evalInSandbox( - "(" + - function (pauseInMs, prefixString) { - const dbg = new Debugger(); - // Add absolutely all the globals... - dbg.addAllGlobalsAsDebuggees(); - // ...but avoid tracing this sandbox code - const global = Cu.getGlobalForObject(this); - dbg.removeDebuggee(global); - - // Add all globals created later on - dbg.onNewGlobalObject = g => dbg.addDebuggee(g); - - function formatDisplayName(frame) { - if (frame.type === "call") { - const callee = frame.callee; - return callee.name || callee.userDisplayName || callee.displayName; - } - - return `(${frame.type})`; - } - - function stop() { - dbg.onEnterFrame = undefined; - dbg.removeAllDebuggees(); - } - global.stop = stop; - - let depth = 0; - dbg.onEnterFrame = frame => { - if (depth == 100) { - dump( - "Looks like an infinite loop? We stop the js tracer, but code may still be running!\n" - ); - stop(); - return; - } - - const { script } = frame; - const { lineNumber, columnNumber } = script.getOffsetMetadata( - frame.offset - ); - const padding = new Array(depth).join(" "); - dump( - `${prefixString}${padding}--[${frame.implementation}]--> ${ - script.source.url - } @ ${lineNumber}:${columnNumber} - ${formatDisplayName(frame)}\n` - ); - - depth++; - frame.onPop = () => { - depth--; - }; - - // Optionaly pause the frame execute by letting the other event loop to run in between. - if (typeof pauseInMs == "number") { - let freeze = true; - const timer = Cc["@mozilla.org/timer;1"].createInstance( - Ci.nsITimer - ); - timer.initWithCallback( - () => { - freeze = false; - }, - pauseInMs, - Ci.nsITimer.TYPE_ONE_SHOT - ); - Services.tm.spinEventLoopUntil("debugger-slow-motion", function () { - return !freeze; - }); - } - }; - - return { stop }; - } + - ")", - debuggerSandbox, - undefined, - "debugger-javascript-tracer", - 1, - /* enforceFilenameRestrictions */ false - ); - f(pause, prefix); - - return { - stop() { - debuggerSandbox.stop(); - }, - }; -} diff --git a/devtools/shared/test-helpers/xpcshell.toml b/devtools/shared/test-helpers/xpcshell.toml deleted file mode 100644 index 5ded960f83..0000000000 --- a/devtools/shared/test-helpers/xpcshell.toml +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -tags = "devtools" -firefox-appdir = "browser" -skip-if = ["os == 'android'"] - -["test_javascript_tracer.js"] |