Source code
Revision control
Copy as Markdown
Other Tools
/* Any copyright is dedicated to the Public Domain.
"use strict";
var { FileUtils } = ChromeUtils.importESModule(
"resource://gre/modules/FileUtils.sys.mjs"
);
var Pipe = Components.Constructor("@mozilla.org/pipe;1", "nsIPipe", "init");
add_task(async function () {
initTestDevToolsServer();
add_test_bulk_actor();
dump(" ################# JSON REPLY\n");
await test_bulk_request_cs(socket_transport, "jsonReply", "json");
await test_bulk_request_cs(local_transport, "jsonReply", "json");
dump(" ################# BULK ECHO\n");
await test_bulk_request_cs(socket_transport, "bulkEcho", "bulk");
await test_bulk_request_cs(local_transport, "bulkEcho", "bulk");
dump(" ################# BULK ECHO WITH BUFFER\n");
await test_bulk_request_cs(socket_transport, "bulkEchoWithBuffer", "bulk");
await test_bulk_request_cs(local_transport, "bulkEchoWithBuffer", "bulk");
dump(" ################# BULK REPLY\n");
await test_json_request_cs(socket_transport, "bulkReply", "bulk");
await test_json_request_cs(local_transport, "bulkReply", "bulk");
DevToolsServer.destroy();
});
/** * Sample Bulk Actor ***/
const protocol = require("resource://devtools/shared/protocol.js");
const { Arg, RetVal } = protocol;
const { Actor } = require("resource://devtools/shared/protocol/Actor.js");
const testBulkSpec = protocol.generateActorSpec({
typeName: "testBulk",
methods: {
bulkEcho: {
request: protocol.BULK_REQUEST,
response: protocol.BULK_RESPONSE,
},
bulkEchoWithBuffer: {
request: protocol.BULK_REQUEST,
response: protocol.BULK_RESPONSE,
},
bulkReply: {
request: { foo: Arg(0, "number") },
response: protocol.BULK_RESPONSE,
},
jsonReply: {
request: protocol.BULK_REQUEST,
response: { allDone: RetVal("number") },
},
},
});
class TestBulkFront extends protocol.FrontClassWithSpec(testBulkSpec) {
formAttributeName = "testBulk";
form(form) {
this.actor = form.actor;
}
}
protocol.registerFront(TestBulkFront);
class TestBulkActor extends Actor {
constructor(conn) {
super(conn, testBulkSpec);
}
// Receives data as bulk and respond as bulk
async bulkEcho({ length, copyTo }, startBulkResponse) {
Assert.equal(length, really_long().length);
const { copyFrom } = await startBulkResponse(length);
// We'll just echo back the same thing
const pipe = new Pipe(true, true, 0, 0, null);
copyTo(pipe.outputStream).then(() => {
pipe.outputStream.close();
});
copyFrom(pipe.inputStream).then(() => {
pipe.inputStream.close();
});
}
async bulkEchoWithBuffer({ length, copyToBuffer }, startBulkResponse) {
Assert.equal(length, really_long().length);
const { copyFromBuffer } = await startBulkResponse(length);
// We'll just echo back the same thing
const buffer = new ArrayBuffer(length);
await copyToBuffer(buffer);
await copyFromBuffer(buffer);
}
// Receives data as json and respond as bulk
async bulkReply({ foo }, startBulkResponse) {
Assert.equal(foo, 42);
const { copyFrom } = await startBulkResponse(really_long().length);
const input = await new Promise(resolve => {
NetUtil.asyncFetch(
{
uri: NetUtil.newURI(getTestTempFile("bulk-input")),
loadUsingSystemPrincipal: true,
},
resolve
);
});
await copyFrom(input);
input.close();
}
// Receives data as bulk and response as json
async jsonReply({ length, copyTo }) {
Assert.equal(length, really_long().length);
const outputFile = getTestTempFile("bulk-output", true);
outputFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
const output = FileUtils.openSafeFileOutputStream(outputFile);
await copyTo(output);
FileUtils.closeSafeFileOutputStream(output);
await verify_files();
return 24;
}
}
function add_test_bulk_actor() {
ActorRegistry.addGlobalActor(
{
constructorName: "TestBulkActor",
constructorFun: TestBulkActor,
},
"testBulk"
);
}
/** * Reply Handlers ***/
var replyHandlers = {
async json(reply) {
// Receive JSON reply from server
Assert.equal(reply, 24, "The returned JSON value is correct");
},
async bulk({ length, copyTo }) {
// Receive bulk data reply from server
Assert.equal(length, really_long().length);
const outputFile = getTestTempFile("bulk-output", true);
outputFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, parseInt("666", 8));
const output = FileUtils.openSafeFileOutputStream(outputFile);
await copyTo(output);
FileUtils.closeSafeFileOutputStream(output);
await verify_files();
},
};
/** * Tests ***/
var test_bulk_request_cs = async function (
transportFactory,
frontMethod,
replyType
) {
// Ensure test files are not present from a failed run
cleanup_files();
writeTestTempFile("bulk-input", really_long());
let serverResolve;
const serverDeferred = new Promise(resolve => {
serverResolve = resolve;
});
let bulkCopyResolve;
const bulkCopyDeferred = new Promise(resolve => {
bulkCopyResolve = resolve;
});
const transport = await transportFactory();
const client = new DevToolsClient(transport);
await client.connect();
await client.mainRoot.rootForm;
function bulkSendReadyCallback({ copyFrom }) {
NetUtil.asyncFetch(
{
uri: NetUtil.newURI(getTestTempFile("bulk-input")),
loadUsingSystemPrincipal: true,
},
input => {
copyFrom(input).then(() => {
input.close();
bulkCopyResolve();
});
}
);
}
const front = await client.mainRoot.getFront("testBulk");
const response = await front[frontMethod](
{ length: really_long().length },
bulkSendReadyCallback
);
// Set up reply handling for this type
await replyHandlers[replyType](response);
const connectionListener = type => {
if (type === "closed") {
DevToolsServer.off("connectionchange", connectionListener);
serverResolve();
}
};
DevToolsServer.on("connectionchange", connectionListener);
client.close();
transport.close();
await Promise.all([bulkCopyDeferred, serverDeferred]);
};
var test_json_request_cs = async function (
transportFactory,
frontMethod,
replyType
) {
// Ensure test files are not present from a failed run
cleanup_files();
writeTestTempFile("bulk-input", really_long());
let serverResolve;
const serverDeferred = new Promise(resolve => {
serverResolve = resolve;
});
const transport = await transportFactory();
const client = new DevToolsClient(transport);
await client.connect();
await client.mainRoot.rootForm;
const front = await client.mainRoot.getFront("testBulk");
const response = await front[frontMethod]({ foo: 42 });
await replyHandlers[replyType](response);
const connectionListener = type => {
if (type === "closed") {
DevToolsServer.off("connectionchange", connectionListener);
serverResolve();
}
};
DevToolsServer.on("connectionchange", connectionListener);
client.close();
transport.close();
return serverDeferred;
};
/** * Test Utils ***/
function verify_files() {
const reallyLong = really_long();
const inputFile = getTestTempFile("bulk-input");
const outputFile = getTestTempFile("bulk-output");
Assert.equal(inputFile.fileSize, reallyLong.length);
Assert.equal(outputFile.fileSize, reallyLong.length);
// Ensure output file contents actually match
return new Promise(resolve => {
NetUtil.asyncFetch(
{
uri: NetUtil.newURI(getTestTempFile("bulk-output")),
loadUsingSystemPrincipal: true,
},
input => {
const outputData = NetUtil.readInputStreamToString(
input,
reallyLong.length
);
// Avoid Assert.strictEqual here so we don't log the contents
// eslint-disable-next-line mozilla/no-comparison-or-assignment-inside-ok
Assert.ok(outputData === reallyLong);
input.close();
resolve();
}
);
}).then(cleanup_files);
}
function cleanup_files() {
const inputFile = getTestTempFile("bulk-input", true);
if (inputFile.exists()) {
inputFile.remove(false);
}
const outputFile = getTestTempFile("bulk-output", true);
if (outputFile.exists()) {
outputFile.remove(false);
}
}