/* * Create a pipe connection, and return an object |{ conn, transport }|, * where |conn| is the new DevToolsServerConnection instance, and * |transport| is the client side of the transport on which it communicates * (that is, packets sent on |transport| go to the new connection, and * |transport|'s hooks receive replies). * * |prefix| is optional; if present, it's the prefix (minus the '/') for * actors in the new connection.
*/ function newConnection(prefix) {
let conn;
DevToolsServer.createRootActor = function (connection) {
conn = connection; returnnew RootActor(connection, {});
};
const transport = DevToolsServer.connectPipe(prefix);
return { conn, transport };
}
/* Create the main connection for these tests. */ function createMainConnection() {
({ conn: gMainConnection, transport: gMainTransport } = newConnection());
gClient = new DevToolsClient(gMainTransport);
gClient.connect().then(() => run_next_test());
}
/* * Exchange 'echo' messages with five actors: * - root * - prefix1/root * - prefix1/actor * - prefix2/root * - prefix2/actor * * Expect proper echos from those named in |reachables|, and 'noSuchActor' * errors from the others. When we've gotten all our replies (errors or * otherwise), call |completed|. * * To avoid deep stacks, we call completed from the next tick.
*/
async function tryActors(reachables, completed) { for (const actor of [ "root", "prefix1/root", "prefix1/actor", "prefix2/root", "prefix2/actor",
]) {
let response; try { if (actor.endsWith("root")) { // Root actor doesn't expose any echo method, // so fallback on getRoot which returns `{ from: "root" }`. // For the top level root actor, we have to use its front. if (actor == "root") {
response = await gClient.mainRoot.getRoot();
} else {
response = await gClient.request({ to: actor, type: "getRoot" });
}
} else {
response = await gClient.request({
to: actor,
type: "echo",
value: "tango",
});
}
} catch (e) {
response = e;
} if (reachables.has(actor)) { if (actor.endsWith("root")) { // RootActor's getRoot response is almost empty on xpcshell Assert.deepEqual({ from: actor }, response);
} else { Assert.deepEqual(
{ from: actor, to: actor, type: "echo", value: "tango" },
response
);
}
} else { Assert.deepEqual(
{
from: actor,
error: "noSuchActor",
message: "No such actor for ID: " + actor,
},
response
);
}
}
executeSoon(completed, "tryActors callback " + completed.name);
}
/* * With no forwarding established, sending messages to root should work, * but sending messages to prefixed actor names, or anyone else, should get * an error.
*/ function TestNoForwardingYet() {
tryActors(new Set(["root"]), run_next_test);
}
/* * Create a new pipe connection which forwards its reply packets to * gMainConnection's client, and to which gMainConnection forwards packets * directed to actors whose names begin with |prefix + '/'|, and. * * Return an object { conn, transport }, as for newConnection.
*/ function newSubconnection(prefix) { const { conn, transport } = newConnection(prefix);
transport.hooks = {
onPacket: packet => gMainConnection.send(packet),
};
gMainConnection.setForwarding(prefix, transport);
return { conn, transport };
}
/* Create a second root actor, to which we can forward things. */ function createSubconnection1() { const { conn, transport } = newSubconnection("prefix1");
gSubconnection1 = conn;
transport.ready();
gClient.expectReply("prefix1/root", () => run_next_test());
}
// Establish forwarding, but don't put any actors in that server. function TestForwardPrefix1OnlyRoot() {
tryActors(new Set(["root", "prefix1/root"]), run_next_test);
}
/* Create a third root actor, to which we can forward things. */ function createSubconnection2() { const { conn, transport } = newSubconnection("prefix2");
gSubconnection2 = conn;
transport.ready();
gClient.expectReply("prefix2/root", () => run_next_test());
}
function TestForwardPrefix12OnlyRoot() {
tryActors(new Set(["root", "prefix1/root", "prefix2/root"]), run_next_test);
}
// A dumb actor that implements 'echo'. // // It's okay that both subconnections' actors behave identically, because // the reply-sending code attaches the replying actor's name to the packet, // so simply matching the 'from' field in the reply ensures that we heard // from the right actor. const { Actor } = require("resource://devtools/shared/protocol/Actor.js"); class EchoActor extends Actor {
constructor(conn) { super(conn, { typeName: "EchoActor", methods: [] });
onEcho(request) { /* * Request packets are frozen. Copy request, so that * DevToolsServerConnection.onPacket can attach a 'from' property.
*/ return JSON.parse(JSON.stringify(request));
}
}
function TestForwardPrefix12WithActor1() { const actor = new EchoActor(gSubconnection1);
actor.actorID = "prefix1/actor";
gSubconnection1.addActor(actor);
tryActors( new Set(["root", "prefix1/root", "prefix1/actor", "prefix2/root"]),
run_next_test
);
}
function TestForwardPrefix12WithActor12() { const actor = new EchoActor(gSubconnection2);
actor.actorID = "prefix2/actor";
gSubconnection2.addActor(actor);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.