test_protocol_async.js (4494B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Make sure we get replies in the same order that we sent their 8 * requests even when earlier requests take several event ticks to 9 * complete. 10 */ 11 12 const { waitForTick } = require("resource://devtools/shared/DevToolsUtils.js"); 13 const protocol = require("resource://devtools/shared/protocol.js"); 14 const { Arg, RetVal } = protocol; 15 16 const rootSpec = protocol.generateActorSpec({ 17 typeName: "root", 18 19 methods: { 20 simpleReturn: { 21 response: { value: RetVal() }, 22 }, 23 promiseReturn: { 24 request: { toWait: Arg(0, "number") }, 25 response: { value: RetVal("number") }, 26 }, 27 simpleThrow: { 28 response: { value: RetVal("number") }, 29 }, 30 promiseThrow: { 31 request: { toWait: Arg(0, "number") }, 32 response: { value: RetVal("number") }, 33 }, 34 }, 35 }); 36 37 class RootActor extends protocol.Actor { 38 constructor(conn) { 39 super(conn, rootSpec); 40 41 // Root actor owns itself. 42 this.manage(this); 43 this.actorID = "root"; 44 this.sequence = 0; 45 } 46 47 sayHello() { 48 return { 49 from: "root", 50 applicationType: "xpcshell-tests", 51 traits: [], 52 }; 53 } 54 55 simpleReturn() { 56 return this.sequence++; 57 } 58 59 // Guarantee that this resolves after simpleReturn returns. 60 async promiseReturn(toWait) { 61 const sequence = this.sequence++; 62 63 // Wait until the number of requests specified by toWait have 64 // happened, to test queuing. 65 while (this.sequence - sequence < toWait) { 66 await waitForTick(); 67 } 68 69 return sequence; 70 } 71 72 simpleThrow() { 73 throw new Error(this.sequence++); 74 } 75 76 // Guarantee that this resolves after simpleReturn returns. 77 promiseThrow(toWait) { 78 return this.promiseReturn(toWait).then(Promise.reject); 79 } 80 } 81 82 class RootFront extends protocol.FrontClassWithSpec(rootSpec) { 83 constructor(client) { 84 super(client); 85 this.actorID = "root"; 86 // Root owns itself. 87 this.manage(this); 88 } 89 90 connect() {} 91 } 92 protocol.registerFront(RootFront); 93 94 add_task(async function () { 95 DevToolsServer.createRootActor = conn => new RootActor(conn); 96 DevToolsServer.init(); 97 98 const trace = connectPipeTracing(); 99 const client = new DevToolsClient(trace); 100 await client.connect(); 101 102 const rootFront = client.mainRoot; 103 104 const calls = []; 105 let sequence = 0; 106 107 // Execute a call that won't finish processing until 2 108 // more calls have happened 109 calls.push( 110 rootFront.promiseReturn(2).then(ret => { 111 // Check right return order 112 Assert.equal(sequence, 0); 113 // Check request handling order 114 Assert.equal(ret, sequence++); 115 }) 116 ); 117 118 // Put a few requests into the backlog 119 120 calls.push( 121 rootFront.simpleReturn().then(ret => { 122 // Check right return order 123 Assert.equal(sequence, 1); 124 // Check request handling order 125 Assert.equal(ret, sequence++); 126 }) 127 ); 128 129 calls.push( 130 rootFront.simpleReturn().then(ret => { 131 // Check right return order 132 Assert.equal(sequence, 2); 133 // Check request handling order 134 Assert.equal(ret, sequence++); 135 }) 136 ); 137 138 calls.push( 139 rootFront.simpleThrow().then( 140 () => { 141 Assert.ok(false, "simpleThrow shouldn't succeed!"); 142 }, 143 () => { 144 // Check right return order 145 Assert.equal(sequence++, 3); 146 } 147 ) 148 ); 149 150 calls.push( 151 rootFront.promiseThrow(2).then( 152 () => { 153 Assert.ok(false, "promiseThrow shouldn't succeed!"); 154 }, 155 () => { 156 // Check right return order 157 Assert.equal(sequence++, 4); 158 Assert.ok(true, "simple throw should throw"); 159 } 160 ) 161 ); 162 163 calls.push( 164 rootFront.simpleReturn().then(ret => { 165 // Check right return order 166 Assert.equal(sequence, 5); 167 // Check request handling order 168 Assert.equal(ret, sequence++); 169 }) 170 ); 171 172 // Break up the backlog with a long request that waits 173 // for another simpleReturn before completing 174 calls.push( 175 rootFront.promiseReturn(1).then(ret => { 176 // Check right return order 177 Assert.equal(sequence, 6); 178 // Check request handling order 179 Assert.equal(ret, sequence++); 180 }) 181 ); 182 183 calls.push( 184 rootFront.simpleReturn().then(ret => { 185 // Check right return order 186 Assert.equal(sequence, 7); 187 // Check request handling order 188 Assert.equal(ret, sequence++); 189 }) 190 ); 191 192 await Promise.all(calls); 193 await client.close(); 194 });