summaryrefslogtreecommitdiffstats
path: root/devtools/shared/protocol/tests/xpcshell/test_protocol_async.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/shared/protocol/tests/xpcshell/test_protocol_async.js')
-rw-r--r--devtools/shared/protocol/tests/xpcshell/test_protocol_async.js192
1 files changed, 192 insertions, 0 deletions
diff --git a/devtools/shared/protocol/tests/xpcshell/test_protocol_async.js b/devtools/shared/protocol/tests/xpcshell/test_protocol_async.js
new file mode 100644
index 0000000000..dd7196710b
--- /dev/null
+++ b/devtools/shared/protocol/tests/xpcshell/test_protocol_async.js
@@ -0,0 +1,192 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+/**
+ * Make sure we get replies in the same order that we sent their
+ * requests even when earlier requests take several event ticks to
+ * complete.
+ */
+
+const { waitForTick } = require("resource://devtools/shared/DevToolsUtils.js");
+const protocol = require("resource://devtools/shared/protocol.js");
+const { Arg, RetVal } = protocol;
+
+const rootSpec = protocol.generateActorSpec({
+ typeName: "root",
+
+ methods: {
+ simpleReturn: {
+ response: { value: RetVal() },
+ },
+ promiseReturn: {
+ request: { toWait: Arg(0, "number") },
+ response: { value: RetVal("number") },
+ },
+ simpleThrow: {
+ response: { value: RetVal("number") },
+ },
+ promiseThrow: {
+ request: { toWait: Arg(0, "number") },
+ response: { value: RetVal("number") },
+ },
+ },
+});
+
+class RootActor extends protocol.Actor {
+ constructor(conn) {
+ super(conn, rootSpec);
+
+ // Root actor owns itself.
+ this.manage(this);
+ this.actorID = "root";
+ this.sequence = 0;
+ }
+
+ sayHello() {
+ return {
+ from: "root",
+ applicationType: "xpcshell-tests",
+ traits: [],
+ };
+ }
+
+ simpleReturn() {
+ return this.sequence++;
+ }
+
+ // Guarantee that this resolves after simpleReturn returns.
+ async promiseReturn(toWait) {
+ const sequence = this.sequence++;
+
+ // Wait until the number of requests specified by toWait have
+ // happened, to test queuing.
+ while (this.sequence - sequence < toWait) {
+ await waitForTick();
+ }
+
+ return sequence;
+ }
+
+ simpleThrow() {
+ throw new Error(this.sequence++);
+ }
+
+ // Guarantee that this resolves after simpleReturn returns.
+ promiseThrow(toWait) {
+ return this.promiseReturn(toWait).then(Promise.reject);
+ }
+}
+
+class RootFront extends protocol.FrontClassWithSpec(rootSpec) {
+ constructor(client) {
+ super(client);
+ this.actorID = "root";
+ // Root owns itself.
+ this.manage(this);
+ }
+}
+protocol.registerFront(RootFront);
+
+add_task(async function () {
+ DevToolsServer.createRootActor = conn => new RootActor(conn);
+ DevToolsServer.init();
+
+ const trace = connectPipeTracing();
+ const client = new DevToolsClient(trace);
+ await client.connect();
+
+ const rootFront = client.mainRoot;
+
+ const calls = [];
+ let sequence = 0;
+
+ // Execute a call that won't finish processing until 2
+ // more calls have happened
+ calls.push(
+ rootFront.promiseReturn(2).then(ret => {
+ // Check right return order
+ Assert.equal(sequence, 0);
+ // Check request handling order
+ Assert.equal(ret, sequence++);
+ })
+ );
+
+ // Put a few requests into the backlog
+
+ calls.push(
+ rootFront.simpleReturn().then(ret => {
+ // Check right return order
+ Assert.equal(sequence, 1);
+ // Check request handling order
+ Assert.equal(ret, sequence++);
+ })
+ );
+
+ calls.push(
+ rootFront.simpleReturn().then(ret => {
+ // Check right return order
+ Assert.equal(sequence, 2);
+ // Check request handling order
+ Assert.equal(ret, sequence++);
+ })
+ );
+
+ calls.push(
+ rootFront.simpleThrow().then(
+ () => {
+ Assert.ok(false, "simpleThrow shouldn't succeed!");
+ },
+ error => {
+ // Check right return order
+ Assert.equal(sequence++, 3);
+ }
+ )
+ );
+
+ calls.push(
+ rootFront.promiseThrow(2).then(
+ () => {
+ Assert.ok(false, "promiseThrow shouldn't succeed!");
+ },
+ error => {
+ // Check right return order
+ Assert.equal(sequence++, 4);
+ Assert.ok(true, "simple throw should throw");
+ }
+ )
+ );
+
+ calls.push(
+ rootFront.simpleReturn().then(ret => {
+ // Check right return order
+ Assert.equal(sequence, 5);
+ // Check request handling order
+ Assert.equal(ret, sequence++);
+ })
+ );
+
+ // Break up the backlog with a long request that waits
+ // for another simpleReturn before completing
+ calls.push(
+ rootFront.promiseReturn(1).then(ret => {
+ // Check right return order
+ Assert.equal(sequence, 6);
+ // Check request handling order
+ Assert.equal(ret, sequence++);
+ })
+ );
+
+ calls.push(
+ rootFront.simpleReturn().then(ret => {
+ // Check right return order
+ Assert.equal(sequence, 7);
+ // Check request handling order
+ Assert.equal(ret, sequence++);
+ })
+ );
+
+ await Promise.all(calls);
+ await client.close();
+});