зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1707556 - [devtools] Add a thread configuration command r=ochameau,devtools-backward-compat-reviewers
Differential Revision: https://phabricator.services.mozilla.com/D113751
This commit is contained in:
Родитель
50a85d3429
Коммит
2077c29048
|
@ -318,22 +318,10 @@ async function pauseOnExceptions(
|
|||
shouldPauseOnExceptions,
|
||||
shouldPauseOnCaughtExceptions
|
||||
) {
|
||||
if (commands.targetCommand.hasTargetWatcherSupport()) {
|
||||
const threadConfigurationActor = await commands.targetCommand.watcherFront.getThreadConfigurationActor();
|
||||
await threadConfigurationActor.updateConfiguration({
|
||||
pauseOnExceptions: shouldPauseOnExceptions,
|
||||
ignoreCaughtExceptions: !shouldPauseOnCaughtExceptions,
|
||||
});
|
||||
} else {
|
||||
return forEachThread(thread =>
|
||||
thread.pauseOnExceptions(
|
||||
shouldPauseOnExceptions,
|
||||
// Providing opposite value because server
|
||||
// uses "shouldIgnoreCaughtExceptions"
|
||||
!shouldPauseOnCaughtExceptions
|
||||
)
|
||||
);
|
||||
}
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: shouldPauseOnExceptions,
|
||||
ignoreCaughtExceptions: !shouldPauseOnCaughtExceptions,
|
||||
});
|
||||
}
|
||||
|
||||
async function blackBox(sourceActor, isBlackBoxed, range) {
|
||||
|
|
|
@ -45,6 +45,7 @@ const { DevToolsServer: WorkerDevToolsServer } = worker.require(
|
|||
const { DevToolsClient } = require("devtools/client/devtools-client");
|
||||
const { ObjectFront } = require("devtools/client/fronts/object");
|
||||
const { LongStringFront } = require("devtools/client/fronts/string");
|
||||
const { createCommandsDictionary } = require("devtools/shared/commands/index");
|
||||
|
||||
const { addDebuggerToGlobal } = ChromeUtils.import(
|
||||
"resource://gre/modules/jsdebugger.jsm"
|
||||
|
@ -370,27 +371,38 @@ async function getTestTab(client, title) {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Attach to |client|'s tab whose title is |title|; and return the targetFront instance
|
||||
// referring to that tab.
|
||||
/**
|
||||
* Attach to the client's tab whose title is specified
|
||||
* @param {Object} client
|
||||
* @param {Object} title
|
||||
* @returns commands
|
||||
*/
|
||||
async function attachTestTab(client, title) {
|
||||
const descriptorFront = await getTestTab(client, title);
|
||||
const targetFront = await descriptorFront.getTarget();
|
||||
await targetFront.attach();
|
||||
return targetFront;
|
||||
const commands = await createCommandsDictionary(descriptorFront);
|
||||
await commands.targetCommand.startListening();
|
||||
return commands;
|
||||
}
|
||||
|
||||
// Attach to |client|'s tab whose title is |title|, and then attach to
|
||||
// that tab's thread. Return the TargetFront referring to the tab,
|
||||
// and a ThreadFront referring to the thread.
|
||||
/**
|
||||
* Attach to the client's tab whose title is specified, and then attach to
|
||||
* that tab's thread.
|
||||
* @param {Object} client
|
||||
* @param {Object} title
|
||||
* @returns {Object}
|
||||
* targetFront
|
||||
* threadFront
|
||||
* commands
|
||||
*/
|
||||
async function attachTestThread(client, title) {
|
||||
const targetFront = await attachTestTab(client, title);
|
||||
const commands = await attachTestTab(client, title);
|
||||
const targetFront = commands.targetCommand.targetFront;
|
||||
const threadFront = await targetFront.getFront("thread");
|
||||
await targetFront.attachThread({
|
||||
autoBlackBox: true,
|
||||
});
|
||||
Assert.equal(threadFront.state, "attached", "Thread front is attached");
|
||||
return { targetFront, threadFront };
|
||||
return { targetFront, threadFront, commands };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -857,7 +869,7 @@ function threadFrontTest(test, options = {}) {
|
|||
|
||||
// Attach to the fake tab target and retrieve the ThreadFront instance.
|
||||
// Automatically resume as the thread is paused by default after attach.
|
||||
const { targetFront, threadFront } = await attachTestThread(
|
||||
const { targetFront, threadFront, commands } = await attachTestThread(
|
||||
client,
|
||||
scriptName
|
||||
);
|
||||
|
@ -878,6 +890,7 @@ function threadFrontTest(test, options = {}) {
|
|||
client,
|
||||
server,
|
||||
targetFront,
|
||||
commands,
|
||||
};
|
||||
if (waitForFinish) {
|
||||
// Use dispatchToMainThread so that the test function does not have to
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
|
||||
add_task(
|
||||
threadFrontTest(async ({ threadFront, debuggee }) => {
|
||||
threadFrontTest(async ({ threadFront, debuggee, commands }) => {
|
||||
await executeOnNextTickAndWaitForPause(
|
||||
() => evalCode(debuggee),
|
||||
threadFront
|
||||
|
@ -20,7 +20,10 @@ add_task(
|
|||
|
||||
const sourceFront = await getSource(threadFront, BLACK_BOXED_URL);
|
||||
await blackBox(sourceFront);
|
||||
threadFront.pauseOnExceptions(true, false);
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: false,
|
||||
});
|
||||
|
||||
threadFront.resume();
|
||||
const packet = await waitForPause(threadFront);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
*/
|
||||
|
||||
add_task(
|
||||
threadFrontTest(async ({ threadFront, debuggee }) => {
|
||||
threadFrontTest(async ({ threadFront, debuggee, commands }) => {
|
||||
const packet1 = await executeOnNextTickAndWaitForPause(
|
||||
() => evalCode(debuggee),
|
||||
threadFront
|
||||
|
@ -18,7 +18,10 @@ add_task(
|
|||
|
||||
const source = await getSourceById(threadFront, packet1.frame.where.actor);
|
||||
|
||||
threadFront.pauseOnExceptions(true, false);
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: false,
|
||||
});
|
||||
const location = { sourceUrl: source.url, line: 3 };
|
||||
threadFront.setBreakpoint(location, { condition: "throw new Error()" });
|
||||
|
||||
|
|
|
@ -11,13 +11,16 @@
|
|||
|
||||
add_task(
|
||||
threadFrontTest(
|
||||
async ({ threadFront, debuggee }) => {
|
||||
async ({ threadFront, debuggee, commands }) => {
|
||||
await executeOnNextTickAndWaitForPause(
|
||||
() => evaluateTestCode(debuggee),
|
||||
threadFront
|
||||
);
|
||||
|
||||
threadFront.pauseOnExceptions(true, true);
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: true,
|
||||
});
|
||||
await resume(threadFront);
|
||||
const paused = await waitForPause(threadFront);
|
||||
Assert.equal(paused.why.type, "exception");
|
||||
|
|
|
@ -10,13 +10,16 @@
|
|||
*/
|
||||
|
||||
add_task(
|
||||
threadFrontTest(async ({ threadFront, debuggee }) => {
|
||||
threadFrontTest(async ({ threadFront, debuggee, commands }) => {
|
||||
await executeOnNextTickAndWaitForPause(
|
||||
() => evaluateTestCode(debuggee),
|
||||
threadFront
|
||||
);
|
||||
|
||||
threadFront.pauseOnExceptions(true, false);
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: false,
|
||||
});
|
||||
threadFront.resume();
|
||||
|
||||
const packet = await waitForPause(threadFront);
|
||||
|
|
|
@ -9,8 +9,11 @@
|
|||
*/
|
||||
|
||||
add_task(
|
||||
threadFrontTest(async ({ threadFront, debuggee }) => {
|
||||
threadFront.pauseOnExceptions(true, false);
|
||||
threadFrontTest(async ({ threadFront, debuggee, commands }) => {
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: false,
|
||||
});
|
||||
|
||||
const packet = await executeOnNextTickAndWaitForPause(
|
||||
() => evaluateTestCode(debuggee),
|
||||
|
|
|
@ -11,13 +11,16 @@
|
|||
|
||||
add_task(
|
||||
threadFrontTest(
|
||||
async ({ threadFront, debuggee }) => {
|
||||
async ({ threadFront, debuggee, commands }) => {
|
||||
await executeOnNextTickAndWaitForPause(
|
||||
() => evaluateTestCode(debuggee),
|
||||
threadFront
|
||||
);
|
||||
|
||||
threadFront.pauseOnExceptions(true, false);
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: false,
|
||||
});
|
||||
await resume(threadFront);
|
||||
const paused = await waitForPause(threadFront);
|
||||
Assert.equal(paused.why.type, "exception");
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { waitForTick } = require("devtools/shared/DevToolsUtils");
|
||||
|
||||
/**
|
||||
* Test that setting pauseOnExceptions to true and then to false will not cause
|
||||
* the debuggee to pause when an exception is thrown.
|
||||
|
@ -11,7 +13,7 @@
|
|||
|
||||
add_task(
|
||||
threadFrontTest(
|
||||
async ({ threadFront, client, debuggee }) => {
|
||||
async ({ threadFront, client, debuggee, commands }) => {
|
||||
let onResume = null;
|
||||
let packet = null;
|
||||
|
||||
|
@ -20,23 +22,12 @@ add_task(
|
|||
onResume = threadFront.resume();
|
||||
});
|
||||
|
||||
await threadFront.pauseOnExceptions(true, true);
|
||||
try {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(
|
||||
` // 1
|
||||
function stopMe() { // 2
|
||||
throw 42; // 3
|
||||
} // 4
|
||||
stopMe(); // 5
|
||||
`, // 6
|
||||
debuggee,
|
||||
"1.8",
|
||||
"test_pause_exceptions-04.js",
|
||||
1
|
||||
);
|
||||
/* eslint-enable */
|
||||
} catch (e) {}
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: true,
|
||||
});
|
||||
|
||||
await evaluateTestCode(debuggee, "42");
|
||||
|
||||
await onResume;
|
||||
|
||||
|
@ -50,45 +41,23 @@ add_task(
|
|||
onResume = threadFront.resume();
|
||||
});
|
||||
|
||||
await threadFront.pauseOnExceptions(false, true);
|
||||
try {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(
|
||||
` // 1
|
||||
function dontStopMe() { // 2
|
||||
throw 43; // 3
|
||||
} // 4
|
||||
dontStopMe(); // 5
|
||||
`, // 6
|
||||
debuggee,
|
||||
"1.8",
|
||||
"test_pause_exceptions-04.js",
|
||||
1
|
||||
);
|
||||
/* eslint-enable */
|
||||
} catch (e) {}
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: false,
|
||||
ignoreCaughtExceptions: true,
|
||||
});
|
||||
|
||||
await evaluateTestCode(debuggee, "43");
|
||||
|
||||
// Test that the paused listener callback hasn't been called
|
||||
// on the thrown error from dontStopMe()
|
||||
Assert.equal(!!packet, false);
|
||||
|
||||
await threadFront.pauseOnExceptions(true, true);
|
||||
try {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(
|
||||
` // 1
|
||||
function stopMeAgain() { // 2
|
||||
throw 44; // 3
|
||||
} // 4
|
||||
stopMeAgain(); // 5
|
||||
`, // 6
|
||||
debuggee,
|
||||
"1.8",
|
||||
"test_pause_exceptions-04.js",
|
||||
1
|
||||
);
|
||||
/* eslint-enable */
|
||||
} catch (e) {}
|
||||
await commands.threadConfigurationCommand.updateConfiguration({
|
||||
pauseOnExceptions: true,
|
||||
ignoreCaughtExceptions: true,
|
||||
});
|
||||
|
||||
await evaluateTestCode(debuggee, "44");
|
||||
|
||||
await onResume;
|
||||
|
||||
|
@ -104,3 +73,23 @@ add_task(
|
|||
}
|
||||
)
|
||||
);
|
||||
|
||||
async function evaluateTestCode(debuggee, throwValue) {
|
||||
await waitForTick();
|
||||
try {
|
||||
/* eslint-disable */
|
||||
Cu.evalInSandbox(
|
||||
` // 1
|
||||
function stopMeAgain() { // 2
|
||||
throw ${throwValue}; // 3
|
||||
} // 4
|
||||
stopMeAgain(); // 5
|
||||
`, // 6
|
||||
debuggee,
|
||||
"1.8",
|
||||
"test_pause_exceptions-04.js",
|
||||
1
|
||||
);
|
||||
/* eslint-enable */
|
||||
} catch (e) {}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ const Commands = {
|
|||
targetCommand: "devtools/shared/commands/target/target-command",
|
||||
targetConfigurationCommand:
|
||||
"devtools/shared/commands/target-configuration/target-configuration-command",
|
||||
threadConfigurationCommand:
|
||||
"devtools/shared/commands/thread-configuration/thread-configuration-command",
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -8,6 +8,7 @@ DIRS += [
|
|||
"resource",
|
||||
"target",
|
||||
"target-configuration",
|
||||
"thread-configuration",
|
||||
]
|
||||
|
||||
DevToolsModules(
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# 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/.
|
||||
|
||||
DevToolsModules(
|
||||
"thread-configuration-command.js",
|
||||
)
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
// General rule from /.eslintrc.js only accept folders matching **/test*/browser*/
|
||||
// where is this folder doesn't match, so manually apply browser test config
|
||||
module.exports = {
|
||||
extends: ["plugin:mozilla/browser-test"],
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
!/devtools/client/shared/test/shared-head.js
|
||||
head.js
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
/* 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";
|
||||
|
||||
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
||||
/* import-globals-from ../../../../client/shared/test/shared-head.js */
|
||||
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
|
||||
this
|
||||
);
|
|
@ -0,0 +1,53 @@
|
|||
/* 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";
|
||||
|
||||
/**
|
||||
* The ThreadConfigurationCommand should be used to maintain thread settings
|
||||
* sent from the client for the thread actor.
|
||||
*
|
||||
* See the ThreadConfigurationActor for a list of supported configuration options.
|
||||
*/
|
||||
class ThreadConfigurationCommand {
|
||||
constructor({ commands, watcherFront }) {
|
||||
this._commands = commands;
|
||||
this._watcherFront = watcherFront;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a promise that resolves to the related thread configuration actor's front.
|
||||
*
|
||||
* @return {Promise<ThreadConfigurationFront>}
|
||||
*/
|
||||
async getThreadConfigurationFront() {
|
||||
const front = await this._watcherFront.getThreadConfigurationActor();
|
||||
return front;
|
||||
}
|
||||
|
||||
async updateConfiguration(configuration) {
|
||||
if (this._commands.targetCommand.hasTargetWatcherSupport()) {
|
||||
const threadConfigurationFront = await this.getThreadConfigurationFront();
|
||||
const updatedConfiguration = await threadConfigurationFront.updateConfiguration(
|
||||
configuration
|
||||
);
|
||||
this._configuration = updatedConfiguration;
|
||||
} else {
|
||||
const threadFronts = await this._commands.targetCommand.getAllFronts(
|
||||
this._commands.targetCommand.ALL_TYPES,
|
||||
"thread"
|
||||
);
|
||||
await Promise.all(
|
||||
threadFronts.map(threadFront =>
|
||||
threadFront.pauseOnExceptions(
|
||||
configuration.pauseOnExceptions,
|
||||
configuration.ignoreCaughtExceptions
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ThreadConfigurationCommand;
|
|
@ -8,7 +8,7 @@ const { generateActorSpec, Arg, types } = require("devtools/shared/protocol");
|
|||
|
||||
types.addDictType("thread-configuration.configuration", {
|
||||
pauseOnExceptions: "nullable:boolean",
|
||||
IgnoreCaughtExceptions: "nullable:boolean",
|
||||
ignoreCaughtExceptions: "nullable:boolean",
|
||||
});
|
||||
|
||||
const threadConfigurationSpec = generateActorSpec({
|
||||
|
|
Загрузка…
Ссылка в новой задаче