215 lines
8.7 KiB
HTML
215 lines
8.7 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
|
|
<script src="../debugger/resources/log-pause-location.js"></script>
|
|
<script>
|
|
let worker1, worker2;
|
|
let testVariable = "main thread";
|
|
|
|
function triggerStartWorkers() {
|
|
worker1 = new Worker("resources/worker-debugger-thread-1.js");
|
|
worker2 = new Worker("resources/worker-debugger-thread-2.js");
|
|
}
|
|
|
|
function triggerWork() {
|
|
worker1.postMessage("doWork");
|
|
worker2.postMessage("doWork");
|
|
setTimeout(workOnMainThread, 250);
|
|
}
|
|
|
|
function workOnMainThread() {
|
|
TestPage.dispatchEventToFrontend("MainThreadDidWork");
|
|
Date.now();
|
|
}
|
|
|
|
function test()
|
|
{
|
|
let mainTarget = WI.mainTarget;
|
|
let workerTarget1;
|
|
let workerTarget2;
|
|
|
|
function areAllTargetsPaused() {
|
|
for (let target of WI.targets) {
|
|
let targetData = WI.debuggerManager.dataForTarget(target);
|
|
if (!targetData.paused)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function areAllTargetsUnpaused() {
|
|
for (let target of WI.targets) {
|
|
let targetData = WI.debuggerManager.dataForTarget(target);
|
|
if (targetData.paused)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
function dumpCallFrames() {
|
|
InspectorTest.log("");
|
|
for (let target of WI.targets) {
|
|
InspectorTest.log(`TARGET: ${target.displayName}`);
|
|
let targetData = WI.debuggerManager.dataForTarget(target);
|
|
let callFrames = targetData.callFrames;
|
|
for (let i = 0; i < callFrames.length; ++i) {
|
|
let callFrame = callFrames[i];
|
|
let active = callFrame === WI.debuggerManager.activeCallFrame;
|
|
InspectorTest.log(` ${active ? "*" : " "} CALL FRAME #${i + 1}: ${callFrame.functionName}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
let okayToReceiveMainThreadEvent = false;
|
|
InspectorTest.singleFireEventListener("MainThreadDidWork", (event) => {
|
|
if (!okayToReceiveMainThreadEvent) {
|
|
InspectorTest.fail("Main Thread's work fired before it could pause. Failing early.");
|
|
InspectorTest.completeTest();
|
|
}
|
|
});
|
|
|
|
let suite = InspectorTest.createAsyncSuite("Worker.Debugger.Threads");
|
|
|
|
suite.addTestCase({
|
|
name: "Worker.Debugger.Threads.CreateThreads",
|
|
description: "Spawn multiple targets.",
|
|
test(resolve, reject) {
|
|
InspectorTest.evaluateInPage(`triggerStartWorkers()`);
|
|
WI.targetManager.singleFireEventListener(WI.TargetManager.Event.TargetAdded, (event) => {
|
|
InspectorTest.pass("Created Worker 1");
|
|
workerTarget1 = event.data.target;
|
|
WI.targetManager.singleFireEventListener(WI.TargetManager.Event.TargetAdded, (event) => {
|
|
InspectorTest.pass("Created Worker 2");
|
|
workerTarget2 = event.data.target;
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "Worker.Debugger.Threads.Pause",
|
|
description: "Should be able to pause in multiple targets.",
|
|
test(resolve, reject) {
|
|
InspectorTest.evaluateInPage(`triggerWork()`);
|
|
|
|
let receivedCallFramesDidChange = false;
|
|
let receivedPauseBeforeCallFramesDidChange = false;
|
|
let otherTargetsPausing = false;
|
|
|
|
WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Paused, (event) => {
|
|
receivedPauseBeforeCallFramesDidChange = !receivedCallFramesDidChange;
|
|
otherTargetsPausing = WI.debuggerManager.dataForTarget(mainTarget).pausing && WI.debuggerManager.dataForTarget(workerTarget2).pausing;
|
|
});
|
|
|
|
let listener = WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.CallFramesDidChange, (event) => {
|
|
receivedCallFramesDidChange = true;
|
|
if (!areAllTargetsPaused())
|
|
return;
|
|
|
|
WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.CallFramesDidChange, listener);
|
|
|
|
let activeCallFrame = WI.debuggerManager.activeCallFrame;
|
|
InspectorTest.assert(activeCallFrame.target === workerTarget1);
|
|
|
|
InspectorTest.expectThat(receivedPauseBeforeCallFramesDidChange, "Paused event should happen before CallFramesDidChange event.");
|
|
InspectorTest.expectThat(otherTargetsPausing, "In Paused event all other Targets should be pausing.");
|
|
InspectorTest.expectEqual(activeCallFrame.target.displayName, "worker-debugger-thread-1.js", "Worker 1 should be the first to pause.");
|
|
InspectorTest.pass("All Targets should eventually pause.");
|
|
dumpCallFrames();
|
|
resolve();
|
|
});
|
|
}
|
|
});
|
|
|
|
function addEvaluateTestCase({name, targetResolver, expected}) {
|
|
suite.addTestCase({
|
|
name, description: "Should be able to evaluate in different threads while paused.",
|
|
test(resolve, reject) {
|
|
let target = targetResolver();
|
|
let targetData = WI.debuggerManager.dataForTarget(target);
|
|
WI.debuggerManager.activeCallFrame = targetData.callFrames[0];
|
|
WI.runtimeManager.evaluateInInspectedWindow("testVariable", {objectGroup: "test", includeCommandLineAPI: true}, (remoteObject) => {
|
|
InspectorTest.expectEqual(remoteObject.description, expected, `Evaluated result in ${target.displayName} should be ${JSON.stringify(expected)}.`)
|
|
resolve();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
addEvaluateTestCase({
|
|
name: "Worker.Debugger.Threads.Paused.Worker1Evaluate",
|
|
targetResolver: () => workerTarget1,
|
|
expected: "worker thread 1",
|
|
});
|
|
|
|
addEvaluateTestCase({
|
|
name: "Worker.Debugger.Threads.Paused.Worker2Evaluate",
|
|
targetResolver: () => workerTarget2,
|
|
expected: "worker thread 2",
|
|
});
|
|
|
|
addEvaluateTestCase({
|
|
name: "Worker.Debugger.Threads.Paused.MainEvaluate",
|
|
targetResolver: () => mainTarget,
|
|
expected: "main thread",
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "Worker.Debugger.Threads.Paused.Worker1.StepOut",
|
|
description: "Should be able to step in individual threads and not affect the others.",
|
|
test(resolve, reject) {
|
|
let targetData = WI.debuggerManager.dataForTarget(workerTarget1);
|
|
WI.debuggerManager.activeCallFrame = targetData.callFrames[0];
|
|
WI.debuggerManager.stepOut();
|
|
WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.CallFramesDidChange, (event) => {
|
|
InspectorTest.expectEqual(event.data.target, workerTarget1, "Should receive CallFramesDidChange for Worker 1.");
|
|
dumpCallFrames();
|
|
resolve();
|
|
});
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "Worker.Debugger.Threads.Paused.Worker2.ResumeThread",
|
|
description: "Should be able to resume an individual thread and not affect the others.",
|
|
test(resolve, reject) {
|
|
let targetData = WI.debuggerManager.dataForTarget(workerTarget2);
|
|
WI.debuggerManager.continueUntilNextRunLoop(workerTarget2);
|
|
WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.CallFramesDidChange, (event) => {
|
|
InspectorTest.expectEqual(event.data.target, workerTarget2, "Should Receive CallFramesDidChange for Worker 2.");
|
|
InspectorTest.expectThat(targetData.pausing, "Worker 2 should be pausing.");
|
|
WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.CallFramesDidChange, (event) => {
|
|
InspectorTest.expectEqual(event.data.target, workerTarget2, "Should Receive CallFramesDidChange for Worker 2.");
|
|
InspectorTest.expectThat(targetData.paused, "Worker 2 should be paused.");
|
|
dumpCallFrames();
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
});
|
|
|
|
suite.addTestCase({
|
|
name: "Worker.Debugger.Threads.Complete",
|
|
description: "Resume all threads for the test to complete.",
|
|
test(resolve, reject) {
|
|
okayToReceiveMainThreadEvent = true;
|
|
WI.debuggerManager.resume();
|
|
WI.debuggerManager.singleFireEventListener(WI.DebuggerManager.Event.Resumed, () => {
|
|
InspectorTest.pass("Received Resume event.");
|
|
InspectorTest.expectThat(areAllTargetsUnpaused(), "All Targets should be unpaused.");
|
|
resolve();
|
|
});
|
|
}
|
|
});
|
|
|
|
suite.runTestCasesAndFinish();
|
|
}
|
|
</script>
|
|
</head>
|
|
<body onload="runTest()">
|
|
<p>Ensure we can pause in multiple targets and evaluate in each.</p>
|
|
</body>
|
|
</html>
|