diff options
Diffstat (limited to 'devtools/shared/protocol/tests/xpcshell/test_protocol_async.js')
-rw-r--r-- | devtools/shared/protocol/tests/xpcshell/test_protocol_async.js | 192 |
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(); +}); |