test_client_server_bulk.js (8448B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 var { FileUtils } = ChromeUtils.importESModule( 7 "resource://gre/modules/FileUtils.sys.mjs" 8 ); 9 var Pipe = Components.Constructor("@mozilla.org/pipe;1", "nsIPipe", "init"); 10 11 add_task(async function () { 12 initTestDevToolsServer(); 13 add_test_bulk_actor(); 14 15 dump(" ################# JSON REPLY\n"); 16 await test_bulk_request_cs(socket_transport, "jsonReply", "json"); 17 await test_bulk_request_cs(local_transport, "jsonReply", "json"); 18 19 dump(" ################# BULK ECHO\n"); 20 await test_bulk_request_cs(socket_transport, "bulkEcho", "bulk"); 21 await test_bulk_request_cs(local_transport, "bulkEcho", "bulk"); 22 23 dump(" ################# BULK ECHO WITH BUFFER\n"); 24 await test_bulk_request_cs(socket_transport, "bulkEchoWithBuffer", "bulk"); 25 await test_bulk_request_cs(local_transport, "bulkEchoWithBuffer", "bulk"); 26 27 dump(" ################# BULK REPLY\n"); 28 await test_json_request_cs(socket_transport, "bulkReply", "bulk"); 29 await test_json_request_cs(local_transport, "bulkReply", "bulk"); 30 31 DevToolsServer.destroy(); 32 }); 33 34 /*** Sample Bulk Actor ***/ 35 const protocol = require("resource://devtools/shared/protocol.js"); 36 const { Arg, RetVal } = protocol; 37 const { Actor } = require("resource://devtools/shared/protocol/Actor.js"); 38 39 const testBulkSpec = protocol.generateActorSpec({ 40 typeName: "testBulk", 41 42 methods: { 43 bulkEcho: { 44 request: protocol.BULK_REQUEST, 45 response: protocol.BULK_RESPONSE, 46 }, 47 bulkEchoWithBuffer: { 48 request: protocol.BULK_REQUEST, 49 response: protocol.BULK_RESPONSE, 50 }, 51 bulkReply: { 52 request: { foo: Arg(0, "number") }, 53 response: protocol.BULK_RESPONSE, 54 }, 55 jsonReply: { 56 request: protocol.BULK_REQUEST, 57 response: { allDone: RetVal("number") }, 58 }, 59 }, 60 }); 61 62 class TestBulkFront extends protocol.FrontClassWithSpec(testBulkSpec) { 63 formAttributeName = "testBulk"; 64 form(form) { 65 this.actor = form.actor; 66 } 67 } 68 protocol.registerFront(TestBulkFront); 69 70 class TestBulkActor extends Actor { 71 constructor(conn) { 72 super(conn, testBulkSpec); 73 } 74 75 // Receives data as bulk and respond as bulk 76 async bulkEcho({ length, copyTo }, startBulkResponse) { 77 Assert.equal(length, really_long().length); 78 79 const { copyFrom } = await startBulkResponse(length); 80 81 // We'll just echo back the same thing 82 const pipe = new Pipe(true, true, 0, 0, null); 83 copyTo(pipe.outputStream).then(() => { 84 pipe.outputStream.close(); 85 }); 86 copyFrom(pipe.inputStream).then(() => { 87 pipe.inputStream.close(); 88 }); 89 } 90 91 async bulkEchoWithBuffer({ length, copyToBuffer }, startBulkResponse) { 92 Assert.equal(length, really_long().length); 93 94 const { copyFromBuffer } = await startBulkResponse(length); 95 96 // We'll just echo back the same thing 97 const buffer = new ArrayBuffer(length); 98 await copyToBuffer(buffer); 99 await copyFromBuffer(buffer); 100 } 101 102 // Receives data as json and respond as bulk 103 async bulkReply({ foo }, startBulkResponse) { 104 Assert.equal(foo, 42); 105 106 const { copyFrom } = await startBulkResponse(really_long().length); 107 const input = await new Promise(resolve => { 108 NetUtil.asyncFetch( 109 { 110 uri: NetUtil.newURI(getTestTempFile("bulk-input")), 111 loadUsingSystemPrincipal: true, 112 }, 113 resolve 114 ); 115 }); 116 await copyFrom(input); 117 input.close(); 118 } 119 120 // Receives data as bulk and response as json 121 async jsonReply({ length, copyTo }) { 122 Assert.equal(length, really_long().length); 123 124 const outputFile = getTestTempFile("bulk-output", true); 125 outputFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8)); 126 127 const output = FileUtils.openSafeFileOutputStream(outputFile); 128 129 await copyTo(output); 130 FileUtils.closeSafeFileOutputStream(output); 131 await verify_files(); 132 133 return 24; 134 } 135 } 136 137 function add_test_bulk_actor() { 138 ActorRegistry.addGlobalActor( 139 { 140 constructorName: "TestBulkActor", 141 constructorFun: TestBulkActor, 142 }, 143 "testBulk" 144 ); 145 } 146 147 /*** Reply Handlers ***/ 148 149 var replyHandlers = { 150 async json(reply) { 151 // Receive JSON reply from server 152 Assert.equal(reply, 24, "The returned JSON value is correct"); 153 }, 154 155 async bulk({ length, copyTo }) { 156 // Receive bulk data reply from server 157 Assert.equal(length, really_long().length); 158 159 const outputFile = getTestTempFile("bulk-output", true); 160 outputFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8)); 161 162 const output = FileUtils.openSafeFileOutputStream(outputFile); 163 164 await copyTo(output); 165 FileUtils.closeSafeFileOutputStream(output); 166 167 await verify_files(); 168 }, 169 }; 170 171 /*** Tests ***/ 172 173 var test_bulk_request_cs = async function ( 174 transportFactory, 175 frontMethod, 176 replyType 177 ) { 178 // Ensure test files are not present from a failed run 179 cleanup_files(); 180 writeTestTempFile("bulk-input", really_long()); 181 182 let serverResolve; 183 const serverDeferred = new Promise(resolve => { 184 serverResolve = resolve; 185 }); 186 187 let bulkCopyResolve; 188 const bulkCopyDeferred = new Promise(resolve => { 189 bulkCopyResolve = resolve; 190 }); 191 192 const transport = await transportFactory(); 193 194 const client = new DevToolsClient(transport); 195 await client.connect(); 196 await client.mainRoot.rootForm; 197 198 function bulkSendReadyCallback({ copyFrom }) { 199 NetUtil.asyncFetch( 200 { 201 uri: NetUtil.newURI(getTestTempFile("bulk-input")), 202 loadUsingSystemPrincipal: true, 203 }, 204 input => { 205 copyFrom(input).then(() => { 206 input.close(); 207 bulkCopyResolve(); 208 }); 209 } 210 ); 211 } 212 213 const front = await client.mainRoot.getFront("testBulk"); 214 const response = await front[frontMethod]( 215 { length: really_long().length }, 216 bulkSendReadyCallback 217 ); 218 219 // Set up reply handling for this type 220 await replyHandlers[replyType](response); 221 222 const connectionListener = type => { 223 if (type === "closed") { 224 DevToolsServer.off("connectionchange", connectionListener); 225 serverResolve(); 226 } 227 }; 228 DevToolsServer.on("connectionchange", connectionListener); 229 230 client.close(); 231 transport.close(); 232 233 await Promise.all([bulkCopyDeferred, serverDeferred]); 234 }; 235 236 var test_json_request_cs = async function ( 237 transportFactory, 238 frontMethod, 239 replyType 240 ) { 241 // Ensure test files are not present from a failed run 242 cleanup_files(); 243 writeTestTempFile("bulk-input", really_long()); 244 245 let serverResolve; 246 const serverDeferred = new Promise(resolve => { 247 serverResolve = resolve; 248 }); 249 250 const transport = await transportFactory(); 251 252 const client = new DevToolsClient(transport); 253 await client.connect(); 254 await client.mainRoot.rootForm; 255 const front = await client.mainRoot.getFront("testBulk"); 256 const response = await front[frontMethod]({ foo: 42 }); 257 258 await replyHandlers[replyType](response); 259 260 const connectionListener = type => { 261 if (type === "closed") { 262 DevToolsServer.off("connectionchange", connectionListener); 263 serverResolve(); 264 } 265 }; 266 DevToolsServer.on("connectionchange", connectionListener); 267 client.close(); 268 transport.close(); 269 270 return serverDeferred; 271 }; 272 273 /*** Test Utils ***/ 274 275 function verify_files() { 276 const reallyLong = really_long(); 277 278 const inputFile = getTestTempFile("bulk-input"); 279 const outputFile = getTestTempFile("bulk-output"); 280 281 Assert.equal(inputFile.fileSize, reallyLong.length); 282 Assert.equal(outputFile.fileSize, reallyLong.length); 283 284 // Ensure output file contents actually match 285 return new Promise(resolve => { 286 NetUtil.asyncFetch( 287 { 288 uri: NetUtil.newURI(getTestTempFile("bulk-output")), 289 loadUsingSystemPrincipal: true, 290 }, 291 input => { 292 const outputData = NetUtil.readInputStreamToString( 293 input, 294 reallyLong.length 295 ); 296 // Avoid Assert.strictEqual here so we don't log the contents 297 // eslint-disable-next-line mozilla/no-comparison-or-assignment-inside-ok 298 Assert.ok(outputData === reallyLong); 299 input.close(); 300 resolve(); 301 } 302 ); 303 }).then(cleanup_files); 304 } 305 306 function cleanup_files() { 307 const inputFile = getTestTempFile("bulk-input", true); 308 if (inputFile.exists()) { 309 inputFile.remove(false); 310 } 311 312 const outputFile = getTestTempFile("bulk-output", true); 313 if (outputFile.exists()) { 314 outputFile.remove(false); 315 } 316 }