Bug 1596114 - Refactor server unit tests part5 r=bhackett,jlast

`test_breakpoint-25.js` is wip.

Differential Revision: https://phabricator.services.mozilla.com/D59667

--HG--
extra : moz-landing-system : lando
This commit is contained in:
chujun 2020-01-15 13:29:52 +00:00
Родитель 3f7af7626e
Коммит 4600f1d844
11 изменённых файлов: 317 добавлений и 398 удалений

Просмотреть файл

@ -10,36 +10,33 @@
*/
add_task(
threadFrontTest(({ threadFront, client, debuggee, targetFront }) => {
threadFrontTest(({ threadFront, debuggee, targetFront }) => {
return new Promise(resolve => {
threadFront.once("paused", async function(packet) {
(async () => {
await executeOnNextTickAndWaitForPause(evalCode, threadFront);
ok(true, "The page is paused");
ok(!debuggee.foo, "foo is still false after we hit the breakpoint");
await targetFront.detach();
// `detach` will force the destruction of the thread actor, which,
// will resume the page execution. But all of that seems to be
// synchronous and we have to spin the event loop in order to ensure
// having the content javascript to execute the resumed code.
await new Promise(executeSoon);
// Closing the connection will force the thread actor to resume page
// execution
ok(debuggee.foo, "foo is true after target's detach request");
executeSoon(resolve);
});
resolve();
})();
/* eslint-disable */
Cu.evalInSandbox(
"var foo = false;\n" +
"debugger;\n" +
"foo = true;\n",
debuggee
);
/* eslint-enable */
ok(debuggee.foo, "foo is false at startup");
function evalCode() {
/* eslint-disable */
Cu.evalInSandbox("var foo = false;\n", debuggee);
/* eslint-enable */
ok(!debuggee.foo, "foo is false at startup");
/* eslint-disable */
Cu.evalInSandbox("debugger;\n" + "foo = true;\n", debuggee);
/* eslint-enable */
}
});
})
);
@ -47,13 +44,15 @@ add_task(
add_task(
threadFrontTest(({ threadFront, client, debuggee }) => {
return new Promise(resolve => {
threadFront.once("paused", async function(packet) {
(async () => {
await executeOnNextTickAndWaitForPause(evalCode, threadFront);
ok(true, "The page is paused");
ok(!debuggee.foo, "foo is still false after we hit the breakpoint");
await client.close();
// `detach` will force the destruction of the thread actor, which,
// `close` will force the destruction of the thread actor, which,
// will resume the page execution. But all of that seems to be
// synchronous and we have to spin the event loop in order to ensure
// having the content javascript to execute the resumed code.
@ -62,20 +61,20 @@ add_task(
// Closing the connection will force the thread actor to resume page
// execution
ok(debuggee.foo, "foo is true after client close");
executeSoon(resolve);
dump("resolved\n");
});
})();
/* eslint-disable */
Cu.evalInSandbox(
"var foo = false;\n" +
"debugger;\n" +
"foo = true;\n",
debuggee
);
/* eslint-enable */
ok(debuggee.foo, "foo is false at startup");
function evalCode() {
/* eslint-disable */
Cu.evalInSandbox("var foo = false;\n", debuggee);
/* eslint-enable */
ok(!debuggee.foo, "foo is false at startup");
/* eslint-disable */
Cu.evalInSandbox("debugger;\n" + "foo = true;\n", debuggee);
/* eslint-enable */
}
});
})
);

Просмотреть файл

@ -3,87 +3,81 @@
"use strict";
var gDebuggee;
var gThreadFront;
add_task(
threadFrontTest(
async ({ threadFront, debuggee }) => {
gThreadFront = threadFront;
gDebuggee = debuggee;
test_named_function();
},
{ waitForFinish: true }
)
);
threadFrontTest(async ({ threadFront, debuggee }) => {
// Test named function
function evalCode() {
debuggee.eval(
function stopMe(arg1) {
debugger;
}.toString()
);
debuggee.eval("stopMe(stopMe)");
}
function test_named_function() {
gThreadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
const packet1 = await executeOnNextTickAndWaitForPause(
() => evalCode(),
threadFront
);
Assert.equal(args[0].class, "Function");
Assert.equal(args[0].name, "stopMe");
Assert.equal(args[0].displayName, "stopMe");
const args1 = packet1.frame.arguments;
const objClient = gThreadFront.pauseGrip(args[0]);
const response = await objClient.getParameterNames();
Assert.equal(response.parameterNames.length, 1);
Assert.equal(response.parameterNames[0], "arg1");
Assert.equal(args1[0].class, "Function");
Assert.equal(args1[0].name, "stopMe");
Assert.equal(args1[0].displayName, "stopMe");
await gThreadFront.resume();
test_inferred_name_function();
});
const objClient1 = threadFront.pauseGrip(args1[0]);
const response1 = await objClient1.getParameterNames();
Assert.equal(response1.parameterNames.length, 1);
Assert.equal(response1.parameterNames[0], "arg1");
gDebuggee.eval(
function stopMe(arg1) {
debugger;
}.toString()
);
gDebuggee.eval("stopMe(stopMe)");
}
await threadFront.resume();
function test_inferred_name_function() {
gThreadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
// Test inferred name function
const packet2 = await executeOnNextTickAndWaitForPause(
() =>
debuggee.eval(
"var o = { m: function(foo, bar, baz) { } }; stopMe(o.m)"
),
threadFront
);
Assert.equal(args[0].class, "Function");
const args2 = packet2.frame.arguments;
Assert.equal(args2[0].class, "Function");
// No name for an anonymous function, but it should have an inferred name.
Assert.equal(args[0].name, undefined);
Assert.equal(args[0].displayName, "m");
Assert.equal(args2[0].name, undefined);
Assert.equal(args2[0].displayName, "m");
const objClient = gThreadFront.pauseGrip(args[0]);
const response = await objClient.getParameterNames();
Assert.equal(response.parameterNames.length, 3);
Assert.equal(response.parameterNames[0], "foo");
Assert.equal(response.parameterNames[1], "bar");
Assert.equal(response.parameterNames[2], "baz");
const objClient2 = threadFront.pauseGrip(args2[0]);
const response2 = await objClient2.getParameterNames();
Assert.equal(response2.parameterNames.length, 3);
Assert.equal(response2.parameterNames[0], "foo");
Assert.equal(response2.parameterNames[1], "bar");
Assert.equal(response2.parameterNames[2], "baz");
await gThreadFront.resume();
test_anonymous_function();
});
await threadFront.resume();
gDebuggee.eval("var o = { m: function(foo, bar, baz) { } }; stopMe(o.m)");
}
// Test anonymous function
const packet3 = await executeOnNextTickAndWaitForPause(
() => debuggee.eval("stopMe(function(foo, bar, baz) { })"),
threadFront
);
function test_anonymous_function() {
gThreadFront.once("paused", async function(packet) {
const args = packet.frame.arguments;
const args3 = packet3.frame.arguments;
Assert.equal(args[0].class, "Function");
Assert.equal(args3[0].class, "Function");
// No name for an anonymous function, and no inferred name, either.
Assert.equal(args[0].name, undefined);
Assert.equal(args[0].displayName, undefined);
Assert.equal(args3[0].name, undefined);
Assert.equal(args3[0].displayName, undefined);
const objClient = gThreadFront.pauseGrip(args[0]);
const response = await objClient.getParameterNames();
Assert.equal(response.parameterNames.length, 3);
Assert.equal(response.parameterNames[0], "foo");
Assert.equal(response.parameterNames[1], "bar");
Assert.equal(response.parameterNames[2], "baz");
const objClient3 = threadFront.pauseGrip(args3[0]);
const response3 = await objClient3.getParameterNames();
Assert.equal(response3.parameterNames.length, 3);
Assert.equal(response3.parameterNames[0], "foo");
Assert.equal(response3.parameterNames[1], "bar");
Assert.equal(response3.parameterNames[2], "baz");
await gThreadFront.resume();
threadFrontTestFinished();
});
gDebuggee.eval("stopMe(function(foo, bar, baz) { })");
}
await threadFront.resume();
})
);

Просмотреть файл

@ -6,56 +6,51 @@
/**
* Check basic getSources functionality.
*/
var gDebuggee;
var gThreadFront;
var gNumTimesSourcesSent = 0;
add_task(
threadFrontTest(
async ({ threadFront, debuggee, client }) => {
gThreadFront = threadFront;
gDebuggee = debuggee;
client.request = (function(origRequest) {
return function(request, onResponse) {
if (request.type === "sources") {
++gNumTimesSourcesSent;
}
return origRequest.call(this, request, onResponse);
};
})(client.request);
test_simple_listsources();
},
{ waitForFinish: true }
)
threadFrontTest(async ({ threadFront, debuggee, client }) => {
client.request = (function(origRequest) {
return function(request, onResponse) {
if (request.type === "sources") {
++gNumTimesSourcesSent;
}
return origRequest.call(this, request, onResponse);
};
})(client.request);
await executeOnNextTickAndWaitForPause(
() => evalCode(debuggee),
threadFront
);
const response = await threadFront.getSources();
Assert.ok(
response.sources.some(function(s) {
return s.url && s.url.match(/test_listsources-01.js/);
})
);
Assert.ok(
gNumTimesSourcesSent <= 1,
"Should only send one sources request at most, even though we" +
" might have had to send one to determine feature support."
);
threadFront.resume();
})
);
function test_simple_listsources() {
gThreadFront.once("paused", function(packet) {
gThreadFront.getSources().then(function(response) {
Assert.ok(
response.sources.some(function(s) {
return s.url && s.url.match(/test_listsources-01.js/);
})
);
Assert.ok(
gNumTimesSourcesSent <= 1,
"Should only send one sources request at most, even though we" +
" might have had to send one to determine feature support."
);
gThreadFront.resume().then(function() {
threadFrontTestFinished();
});
});
});
function evalCode(debuggee) {
/* eslint-disable */
Cu.evalInSandbox("var line0 = Error().lineNumber;\n" +
"debugger;\n" + // line0 + 1
"var a = 1;\n" + // line0 + 2
"var b = 2;\n", // line0 + 3
gDebuggee);
Cu.evalInSandbox(
"var line0 = Error().lineNumber;\n" +
"debugger;\n" + // line0 + 1
"var a = 1;\n" + // line0 + 2
"var b = 2;\n", // line0 + 3
debuggee
);
/* eslint-enable */
}

Просмотреть файл

@ -7,30 +7,22 @@
* Check getting sources before there are any.
*/
var gThreadFront;
var gNumTimesSourcesSent = 0;
add_task(
threadFrontTest(
async ({ threadFront, debuggee, client }) => {
gThreadFront = threadFront;
client.request = (function(origRequest) {
return function(request, onResponse) {
if (request.type === "sources") {
++gNumTimesSourcesSent;
}
return origRequest.call(this, request, onResponse);
};
})(client.request);
test_listing_zero_sources();
},
{ waitForFinish: true }
)
);
threadFrontTest(async ({ threadFront, client }) => {
client.request = (function(origRequest) {
return function(request, onResponse) {
if (request.type === "sources") {
++gNumTimesSourcesSent;
}
return origRequest.call(this, request, onResponse);
};
})(client.request);
// Test listing zero sources
const packet = await threadFront.getSources();
function test_listing_zero_sources() {
gThreadFront.getSources().then(function(packet) {
Assert.ok(!packet.error);
Assert.ok(!!packet.sources);
Assert.equal(packet.sources.length, 0);
@ -40,7 +32,5 @@ function test_listing_zero_sources() {
"Should only send one sources request at most, even though we" +
" might have had to send one to determine feature support."
);
threadFrontTestFinished();
});
}
})
);

Просмотреть файл

@ -7,48 +7,39 @@
* Check getSources functionality when there are lots of sources.
*/
var gDebuggee;
var gThreadFront;
add_task(
threadFrontTest(
async ({ threadFront, debuggee }) => {
gThreadFront = threadFront;
gDebuggee = debuggee;
test_simple_listsources();
},
{ waitForFinish: true }
)
threadFrontTest(async ({ threadFront, debuggee }) => {
await executeOnNextTickAndWaitForPause(
() => evalCode(debuggee),
threadFront
);
const response = await threadFront.getSources();
Assert.ok(
!response.error,
"There shouldn't be an error fetching large amounts of sources."
);
Assert.ok(
response.sources.some(function(s) {
return s.url.match(/foo-999.js$/);
})
);
threadFront.resume();
})
);
function test_simple_listsources() {
gThreadFront.once("paused", function(packet) {
gThreadFront.getSources().then(function(response) {
Assert.ok(
!response.error,
"There shouldn't be an error fetching large amounts of sources."
);
Assert.ok(
response.sources.some(function(s) {
return s.url.match(/foo-999.js$/);
})
);
gThreadFront.resume().then(function() {
threadFrontTestFinished();
});
});
});
function evalCode(debuggee) {
for (let i = 0; i < 1000; i++) {
Cu.evalInSandbox(
"function foo###() {return ###;}".replace(/###/g, i),
gDebuggee,
debuggee,
"1.8",
"http://example.com/foo-" + i + ".js",
1
);
}
gDebuggee.eval("debugger;");
debuggee.eval("debugger;");
}

Просмотреть файл

@ -8,61 +8,53 @@
* Check that logpoints generate console messages.
*/
var gDebuggee;
var gClient;
var gThreadFront;
add_task(
threadFrontTest(
async ({ threadFront, debuggee, client }) => {
gThreadFront = threadFront;
gDebuggee = debuggee;
gClient = client;
test_simple_breakpoint();
},
{ waitForFinish: true }
)
);
threadFrontTest(async ({ threadFront, debuggee, client }) => {
const rootActor = client.transport._serverConnection.rootActor;
const threadActor =
rootActor._parameters.tabList._targetActors[0].threadActor;
function test_simple_breakpoint() {
const rootActor = gClient.transport._serverConnection.rootActor;
const threadActor =
rootActor._parameters.tabList._targetActors[0].threadActor;
let lastMessage;
threadActor._parent._consoleActor = {
onConsoleAPICall(message) {
lastMessage = message;
},
};
let lastMessage;
threadActor._parent._consoleActor = {
onConsoleAPICall(message) {
lastMessage = message;
},
};
const packet = await executeOnNextTickAndWaitForPause(
() => evalCode(debuggee),
threadFront
);
gThreadFront.once("paused", async function(packet) {
const source = await getSourceById(gThreadFront, packet.frame.where.actor);
const source = await getSourceById(threadFront, packet.frame.where.actor);
// Set a logpoint which should invoke console.log.
gThreadFront.setBreakpoint(
threadFront.setBreakpoint(
{
sourceUrl: source.url,
line: 3,
},
{ logValue: "a" }
);
await gClient.waitForRequestsToSettle();
await client.waitForRequestsToSettle();
// Execute the rest of the code.
await gThreadFront.resume();
await threadFront.resume();
Assert.equal(lastMessage.level, "logPoint");
Assert.equal(lastMessage.arguments[0], "three");
threadFrontTestFinished();
});
})
);
function evalCode(debuggee) {
/* eslint-disable */
Cu.evalInSandbox("debugger;\n" + // 1
"var a = 'three';\n" + // 2
"var b = 2;\n", // 3
gDebuggee,
"1.8",
"test.js",
1);
Cu.evalInSandbox(
"debugger;\n" + // 1
"var a = 'three';\n" + // 2
"var b = 2;\n", // 3
debuggee,
"1.8",
"test.js",
1
);
/* eslint-enable */
}

Просмотреть файл

@ -8,62 +8,54 @@
* Check that conditions are respected when specified in a logpoint.
*/
var gDebuggee;
var gClient;
var gThreadFront;
add_task(
threadFrontTest(
async ({ threadFront, debuggee, client }) => {
gThreadFront = threadFront;
gDebuggee = debuggee;
gClient = client;
test_simple_breakpoint();
},
{ waitForFinish: true }
)
);
threadFrontTest(async ({ threadFront, debuggee, client }) => {
const rootActor = client.transport._serverConnection.rootActor;
const threadActor =
rootActor._parameters.tabList._targetActors[0].threadActor;
function test_simple_breakpoint() {
const rootActor = gClient.transport._serverConnection.rootActor;
const threadActor =
rootActor._parameters.tabList._targetActors[0].threadActor;
let lastMessage;
threadActor._parent._consoleActor = {
onConsoleAPICall(message) {
lastMessage = message;
},
};
let lastMessage;
threadActor._parent._consoleActor = {
onConsoleAPICall(message) {
lastMessage = message;
},
};
const packet = await executeOnNextTickAndWaitForPause(
() => evalCode(debuggee),
threadFront
);
gThreadFront.once("paused", async function(packet) {
const source = await getSourceById(gThreadFront, packet.frame.where.actor);
const source = await getSourceById(threadFront, packet.frame.where.actor);
// Set a logpoint which should invoke console.log.
gThreadFront.setBreakpoint(
threadFront.setBreakpoint(
{
sourceUrl: source.url,
line: 4,
},
{ logValue: "a", condition: "a === 5" }
);
await gClient.waitForRequestsToSettle();
await client.waitForRequestsToSettle();
// Execute the rest of the code.
await gThreadFront.resume();
await threadFront.resume();
Assert.equal(lastMessage.arguments[0], 5);
threadFrontTestFinished();
});
})
);
function evalCode(debuggee) {
/* eslint-disable */
Cu.evalInSandbox("debugger;\n" + // 1
"var a = 1;\n" + // 2
"while (a < 10) {\n" + // 3
" a++;\n" + // 4
"}",
gDebuggee,
"1.8",
"test.js",
1);
Cu.evalInSandbox(
"debugger;\n" + // 1
"var a = 1;\n" + // 2
"while (a < 10) {\n" + // 3
" a++;\n" + // 4
"}",
debuggee,
"1.8",
"test.js",
1
);
/* eslint-enable */
}

Просмотреть файл

@ -8,39 +8,28 @@
* Check that logpoints generate console errors if the logpoint statement is invalid.
*/
var gDebuggee;
var gClient;
var gThreadFront;
add_task(
threadFrontTest(
async ({ threadFront, debuggee, client }) => {
gThreadFront = threadFront;
gDebuggee = debuggee;
gClient = client;
test_simple_breakpoint();
},
{ waitForFinish: true }
)
);
threadFrontTest(async ({ threadFront, debuggee, client }) => {
const rootActor = client.transport._serverConnection.rootActor;
const threadActor =
rootActor._parameters.tabList._targetActors[0].threadActor;
function test_simple_breakpoint() {
const rootActor = gClient.transport._serverConnection.rootActor;
const threadActor =
rootActor._parameters.tabList._targetActors[0].threadActor;
let lastMessage;
threadActor._parent._consoleActor = {
onConsoleAPICall(message) {
lastMessage = message;
},
};
let lastMessage;
threadActor._parent._consoleActor = {
onConsoleAPICall(message) {
lastMessage = message;
},
};
const packet = await executeOnNextTickAndWaitForPause(
() => evalCode(debuggee),
threadFront
);
gThreadFront.once("paused", async function(packet) {
const source = await getSourceById(gThreadFront, packet.frame.where.actor);
const source = await getSourceById(threadFront, packet.frame.where.actor);
// Set a logpoint which should throw an error message.
await gThreadFront.setBreakpoint(
await threadFront.setBreakpoint(
{
sourceUrl: source.url,
line: 3,
@ -49,18 +38,19 @@ function test_simple_breakpoint() {
);
// Execute the rest of the code.
await gThreadFront.resume();
await threadFront.resume();
Assert.equal(lastMessage.level, "logPointError");
Assert.equal(lastMessage.arguments[0], "c is not defined");
threadFrontTestFinished();
});
})
);
function evalCode(debuggee) {
/* eslint-disable */
Cu.evalInSandbox(
"debugger;\n" + // 1
"var a = 'three';\n" + // 2
"var b = 2;\n", // 3
gDebuggee,
debuggee,
"1.8",
"test.js",
1

Просмотреть файл

@ -7,32 +7,18 @@
* Check basic newSource packet sent from server.
*/
var gDebuggee;
var gThreadFront;
add_task(
threadFrontTest(
async ({ threadFront, debuggee }) => {
gThreadFront = threadFront;
gDebuggee = debuggee;
test_simple_new_source();
},
{ waitForFinish: true }
)
threadFrontTest(async ({ threadFront, debuggee }) => {
Cu.evalInSandbox(
function inc(n) {
return n + 1;
}.toString(),
debuggee
);
const sourcePacket = await waitForEvent(threadFront, "newSource");
Assert.ok(!!sourcePacket.source);
Assert.ok(!!sourcePacket.source.url.match(/test_new_source-01.js$/));
})
);
function test_simple_new_source() {
gThreadFront.once("newSource", function(packet) {
Assert.ok(!!packet.source);
Assert.ok(!!packet.source.url.match(/test_new_source-01.js$/));
threadFrontTestFinished();
});
Cu.evalInSandbox(
function inc(n) {
return n + 1;
}.toString(),
gDebuggee
);
}

Просмотреть файл

@ -4,51 +4,44 @@
"use strict";
/**
* Check that sourceURL has the correct effect when using gThreadFront.eval.
* Check that sourceURL has the correct effect when using threadFront.eval.
*/
var gDebuggee;
var gTargetFront;
var gThreadFront;
add_task(
threadFrontTest(
async ({ threadFront, debuggee, targetFront }) => {
gThreadFront = threadFront;
gTargetFront = targetFront;
gDebuggee = debuggee;
test_simple_new_source();
},
{ waitForFinish: true }
)
threadFrontTest(async ({ threadFront, debuggee, targetFront }) => {
await executeOnNextTickAndWaitForPause(
() => evalCode(debuggee),
threadFront
);
const packet1 = await waitForEvent(threadFront, "newSource");
Assert.ok(!!packet1.source);
Assert.ok(packet1.source.introductionType, "eval");
const consoleFront = await targetFront.getFront("console");
consoleFront.evaluateJSAsync(
"function f() { }\n//# sourceURL=http://example.com/code.js"
);
const packet2 = await waitForEvent(threadFront, "newSource");
dump(JSON.stringify(packet2, null, 2));
Assert.ok(!!packet2.source);
Assert.ok(!!packet2.source.url.match(/example\.com/));
})
);
function test_simple_new_source() {
gThreadFront.once("paused", function() {
gThreadFront.once("newSource", async function(packet2) {
// The "stopMe" eval source is emitted first.
Assert.ok(!!packet2.source);
Assert.ok(packet2.source.introductionType, "eval");
gThreadFront.once("newSource", function(packet) {
dump(JSON.stringify(packet, null, 2));
Assert.ok(!!packet.source);
Assert.ok(!!packet.source.url.match(/example\.com/));
threadFrontTestFinished();
});
const consoleFront = await gTargetFront.getFront("console");
consoleFront.evaluateJSAsync(
"function f() { }\n//# sourceURL=http://example.com/code.js"
);
});
});
function evalCode(debuggee) {
/* eslint-disable */
gDebuggee.eval("(" + function () {
function stopMe(arg1) { debugger; }
stopMe({obj: true});
} + ")()");
debuggee.eval(
"(" +
function() {
function stopMe(arg1) {
debugger;
}
stopMe({ obj: true });
} +
")()"
);
/* eslint-enable */
}

Просмотреть файл

@ -38,37 +38,34 @@ add_task(async function() {
// Even though we have no tabs, getMainProcess gives us the chrome debugger.
const front = await client.mainRoot.getMainProcess();
const [, threadFront] = await front.attachThread();
const onResumed = new Promise(resolve => {
threadFront.once("paused", packet => {
equal(
packet.why.type,
"breakpoint",
"yay - hit the breakpoint at the first line in our script"
);
// Resume again - next stop should be our "debugger" statement.
threadFront.once("paused", packet => {
equal(
packet.why.type,
"debuggerStatement",
"yay - hit the 'debugger' statement in our script"
);
threadFront.resume().then(resolve);
});
threadFront.resume();
});
});
// tell the thread to do the initial resume. This would cause the
// tell the thread to do the initial resume. This would cause the
// xpcshell test harness to resume and load the file under test.
threadFront.resume().then(() => {
// should have been told to resume the test itself.
ok(testResumed);
// Now load our test script.
load(testFile.path);
// and our "paused" listener above should get hit.
// and our "paused" listener below should get hit.
});
await onResumed;
const packet1 = await waitForPause(threadFront);
equal(
packet1.why.type,
"breakpoint",
"yay - hit the breakpoint at the first line in our script"
);
// Resume again - next stop should be our "debugger" statement.
threadFront.resume();
const packet2 = await waitForPause(threadFront);
equal(
packet2.why.type,
"debuggerStatement",
"yay - hit the 'debugger' statement in our script"
);
threadFront.resume();
finishClient(client);
});