Commit ad067712 authored by Simon Zünd's avatar Simon Zünd Committed by V8 LUCI CQ

[inspector] Add disabled tests for 'Restart frame' 1/2

Doc: https://bit.ly/revive-restart-frame
Context: https://crrev.com/c/3582395 (whole feature)

This CL adds the first batch of inspector tests for the upcoming
"Restart frame" feature. Landing the tests upfront allows us to
better discuss the proposed API as well as think early about
corner cases we should test.

The tests check for the functionality of `Debugger.restartFrame`, as
well as the newly added parameter `canBeRestarted` in
the `Debugger.paused` event.

Bug: chromium:1303521
Change-Id: Ibda6d8b6110fce893e0844f8902fbd5d901ae01d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3585946Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarKim-Anh Tran <kimanh@chromium.org>
Commit-Queue: Simon Zünd <szuend@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80013}
parent 394812a6
...@@ -6,7 +6,7 @@ restartFrame result: ...@@ -6,7 +6,7 @@ restartFrame result:
{ {
error : { error : {
code : -32000 code : -32000
message : Frame restarting not supported message : Restarting frame without 'mode' not supported
} }
id : <messageId> id : <messageId>
} }
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
RestartFrameTest = {};
RestartFrameTest.evaluateAndWaitForPause = async (expression) => {
const pausedPromise = Protocol.Debugger.oncePaused();
const evaluatePromise = Protocol.Runtime.evaluate({ expression });
const { params: { callFrames } } = await pausedPromise;
InspectorTest.log('Paused at (after evaluation):');
await session.logSourceLocation(callFrames[0].location);
// Ignore the last frame, it's always an anonymous empty frame for the
// Runtime#evaluate call.
InspectorTest.log('Pause stack:');
for (const frame of callFrames.slice(0, -1)) {
InspectorTest.log(` ${frame.functionName}:${frame.location.lineNumber} (canBeRestarted = ${frame.canBeRestarted ?? false})`);
}
InspectorTest.log('');
return { callFrames, evaluatePromise };
};
RestartFrameTest.restartFrameAndWaitForPause = async (callFrames, index) => {
const pausedPromise = Protocol.Debugger.oncePaused();
const frame = callFrames[index];
InspectorTest.log(`Restarting function "${frame.functionName}" ...`);
const response = await Protocol.Debugger.restartFrame({ callFrameId: frame.callFrameId, mode: 'StepInto' });
if (response.error) {
InspectorTest.log(`Failed to restart function "${frame.functionName}":`);
InspectorTest.logMessage(response.error);
return;
}
const { params: { callFrames: pausedCallFrames } } = await pausedPromise;
InspectorTest.log('Paused at (after restart):');
await session.logSourceLocation(pausedCallFrames[0].location);
return callFrames;
};
Checks that restarting the top frame hits a debugger statement twice
Paused at (after evaluation):
const x = 1;
#debugger;
const y = 2;
Pause stack:
foo:3 (canBeRestarted = true)
Restarting function "foo" ...
Paused at (after restart):
function foo() {
const x = #1;
debugger;
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
utils.load('test/inspector/debugger/restart-frame/restart-frame-test.js');
const {session, Protocol} =
InspectorTest.start('Checks that restarting the top frame hits a debugger statement twice');
session.setupScriptMap();
const source = `
function foo() {
const x = 1;
debugger;
const y = 2;
}
foo();
`;
(async () => {
await Protocol.Debugger.enable();
const { callFrames } = await RestartFrameTest.evaluateAndWaitForPause(source);
await RestartFrameTest.restartFrameAndWaitForPause(callFrames, 0);
Protocol.Debugger.resume(); // Resuming hits the 'debugger' stmt again.
await Protocol.Debugger.oncePaused();
await Protocol.Debugger.resume();
InspectorTest.completeTest();
})();
Checks that after restarting the top frame, local variables are reset
Paused at (after evaluation):
let z = 'some let';
#debugger;
}
Pause stack:
foo:5 (canBeRestarted = true)
Evaluating x:
{
id : <messageId>
result : {
result : {
type : string
value : some var
}
}
}
Evaluating y:
{
id : <messageId>
result : {
result : {
type : string
value : some const
}
}
}
Evaluating z:
{
id : <messageId>
result : {
result : {
type : string
value : some let
}
}
}
Restarting function "foo" ...
Paused at (after restart):
function foo() {
var x = #'some var';
const y = 'some const';
Evaluating x:
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
Evaluating y:
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
Evaluating z:
{
id : <messageId>
result : {
result : {
type : undefined
}
}
}
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
utils.load('test/inspector/debugger/restart-frame/restart-frame-test.js');
const {session, Protocol} =
InspectorTest.start('Checks that after restarting the top frame, local variables are reset');
session.setupScriptMap();
const source = `
function foo() {
var x = 'some var';
const y = 'some const';
let z = 'some let';
debugger;
}
foo();
//# sourceURL=testRestartFrame.js`;
(async () => {
await Protocol.Debugger.enable();
const { callFrames } = await RestartFrameTest.evaluateAndWaitForPause(source);
let { callFrameId } = callFrames[0];
InspectorTest.log('Evaluating x:');
InspectorTest.logMessage(await Protocol.Debugger.evaluateOnCallFrame({ callFrameId, expression: 'x' }));
InspectorTest.log('Evaluating y:');
InspectorTest.logMessage(await Protocol.Debugger.evaluateOnCallFrame({ callFrameId, expression: 'y' }));
InspectorTest.log('Evaluating z:');
InspectorTest.logMessage(await Protocol.Debugger.evaluateOnCallFrame({ callFrameId, expression: 'z' }));
const callFramesAfter = await RestartFrameTest.restartFrameAndWaitForPause(callFrames, 0);
({ callFrameId } = callFramesAfter[0]);
InspectorTest.log('Evaluating x:');
InspectorTest.logMessage(await Protocol.Debugger.evaluateOnCallFrame({ callFrameId, expression: 'x' }));
InspectorTest.log('Evaluating y:');
InspectorTest.logMessage(await Protocol.Debugger.evaluateOnCallFrame({ callFrameId, expression: 'y' }));
InspectorTest.log('Evaluating z:');
InspectorTest.logMessage(await Protocol.Debugger.evaluateOnCallFrame({ callFrameId, expression: 'z' }));
Protocol.Debugger.resume(); // Resuming hits the 'debugger' stmt again.
await Protocol.Debugger.oncePaused();
await Protocol.Debugger.resume();
InspectorTest.completeTest();
})();
Checks that restarting the top frame works with breakpoints
Paused at (after evaluation):
const x = 1;
const y = #2;
}
Pause stack:
foo:3 (canBeRestarted = true)
Restarting function "foo" ...
Paused at (after restart):
function foo() {
const x = #1;
const y = 2;
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
utils.load('test/inspector/debugger/restart-frame/restart-frame-test.js');
const {session, Protocol} =
InspectorTest.start('Checks that restarting the top frame works with breakpoints');
session.setupScriptMap();
const source = `
function foo() {
const x = 1;
const y = 2;
}
//# sourceURL=testRestartFrame.js`;
(async () => {
await Protocol.Debugger.enable();
await Protocol.Runtime.evaluate({ expression: source });
await Protocol.Debugger.setBreakpointByUrl({
lineNumber: 3,
url: 'testRestartFrame.js',
});
const { callFrames } = await RestartFrameTest.evaluateAndWaitForPause('foo()');
await RestartFrameTest.restartFrameAndWaitForPause(callFrames, 0);
Protocol.Debugger.resume(); // Resuming hits the breakpoint again.
await Protocol.Debugger.oncePaused();
await Protocol.Debugger.resume();
InspectorTest.completeTest();
})();
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
# Tests that need to run sequentially (e.g. due to memory consumption). # Tests that need to run sequentially (e.g. due to memory consumption).
'runtime/console-messages-limits': [PASS, HEAVY], 'runtime/console-messages-limits': [PASS, HEAVY],
'runtime/regression-732717': [PASS, HEAVY], 'runtime/regression-732717': [PASS, HEAVY],
# https://crbug.com/1303521, feature not yet implemented.
'debugger/restart-frame/*': [SKIP],
}], # ALWAYS }], # ALWAYS
############################################################################## ##############################################################################
...@@ -325,7 +328,10 @@ ...@@ -325,7 +328,10 @@
'debugger/regression-424142': [SKIP], 'debugger/regression-424142': [SKIP],
'debugger/remove-breakpoint-at-breakpoint': [SKIP], 'debugger/remove-breakpoint-at-breakpoint': [SKIP],
'debugger/resource-name-to-url': [SKIP], 'debugger/resource-name-to-url': [SKIP],
'debugger/restart-frame': [SKIP], 'debugger/restart-frame/fails-without-mode-param': [SKIP],
'debugger/restart-frame/restart-top-frame-debugger-stmt': [SKIP],
'debugger/restart-frame/restart-top-frame-local-variables': [SKIP],
'debugger/restart-frame/restart-top-frame-with-breakpoint': [SKIP],
'debugger/restore-breakpoint': [SKIP], 'debugger/restore-breakpoint': [SKIP],
'debugger/return-break-locations': [SKIP], 'debugger/return-break-locations': [SKIP],
'debugger/scope-skip-variables-with-empty-name': [SKIP], 'debugger/scope-skip-variables-with-empty-name': [SKIP],
......
...@@ -13,11 +13,13 @@ PROTOCOL_TEST_JS = "protocol-test.js" ...@@ -13,11 +13,13 @@ PROTOCOL_TEST_JS = "protocol-test.js"
WASM_INSPECTOR_JS = "wasm-inspector-test.js" WASM_INSPECTOR_JS = "wasm-inspector-test.js"
EXPECTED_SUFFIX = "-expected.txt" EXPECTED_SUFFIX = "-expected.txt"
RESOURCES_FOLDER = "resources" RESOURCES_FOLDER = "resources"
RESTART_FRAME_JS = "restart-frame-test.js"
class TestLoader(testsuite.JSTestLoader): class TestLoader(testsuite.JSTestLoader):
@property @property
def excluded_files(self): def excluded_files(self):
return {PROTOCOL_TEST_JS, WASM_INSPECTOR_JS} return {PROTOCOL_TEST_JS, WASM_INSPECTOR_JS, RESTART_FRAME_JS}
@property @property
def excluded_dirs(self): def excluded_dirs(self):
...@@ -55,10 +57,11 @@ class TestCase(testcase.TestCase): ...@@ -55,10 +57,11 @@ class TestCase(testcase.TestCase):
def _get_resources(self): def _get_resources(self):
return [ return [
os.path.join( os.path.join('test', 'inspector', 'debugger', 'resources',
'test', 'inspector', 'debugger', 'resources', 'break-locations.js'), 'break-locations.js'),
os.path.join( os.path.join('test', 'inspector', WASM_INSPECTOR_JS),
'test', 'inspector', 'wasm-inspector-test.js'), os.path.join('test', 'inspector', 'debugger', 'restart-frame',
RESTART_FRAME_JS),
] ]
@property @property
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment