blob: 77161c35f20d9a21b3955dff3b0271c28c09d296 [file] [log] [blame] [edit]
#!/usr/bin/env -S node
const { ConformanceRequest, ConformanceResponse, WireFormat } = require('./protos/conformance_pb.js');
const { TestAllTypesProto2 } = require('./protos/test_messages_proto2_pb.js');
const { TestAllTypesProto3 } = require('./protos/test_messages_proto3_pb.js');
const { TestAllTypesEdition2023 } = require('./protos/test_messages_edition2023_pb.js');
const { TestAllTypesProto2: TestAllTypesProto2Edition2023 } = require('./protos/test_messages_proto2_editions_pb.js');
const { TestAllTypesProto3: TestAllTypesProto3Edition2023 } = require('./protos/test_messages_proto3_editions_pb.js');
const fs = require('fs');
/**
* Creates a `proto.conformance.ConformanceResponse` response according to the
* `proto.conformance.ConformanceRequest` request.
* @param {!ConformanceRequest} request
* @return {!ConformanceResponse} response
*/
function doTest(request) {
const response = new ConformanceResponse();
if (request.getPayloadCase() === ConformanceRequest.PayloadCase.JSON_PAYLOAD) {
response.setSkipped('Json is not supported as input format.');
return response;
}
if (request.getPayloadCase() === ConformanceRequest.PayloadCase.TEXT_PAYLOAD) {
response.setSkipped('Text format is not supported as input format.');
return response;
}
if (request.getPayloadCase() === ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET) {
response.setRuntimeError('Request didn\'t have payload.');
return response;
}
if (request.getPayloadCase() !== ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD) {
throw new Error('Request didn\'t have accepted input format.');
}
if (request.getRequestedOutputFormat() === WireFormat.JSON) {
response.setSkipped('Json is not supported as output format.');
return response;
}
if (request.getRequestedOutputFormat() === WireFormat.TEXT_FORMAT) {
response.setSkipped('Text format is not supported as output format.');
return response;
}
if (request.getRequestedOutputFormat() === WireFormat.TEXT_FORMAT) {
response.setRuntimeError('Unspecified output format');
return response;
}
if (request.getRequestedOutputFormat() !== WireFormat.PROTOBUF) {
throw new Error('Request didn\'t have accepted output format.');
}
if (request.getMessageType() === 'conformance.FailureSet') {
response.setProtobufPayload(new ArrayBuffer(0));
} else if (
request.getMessageType() ===
'protobuf_test_messages.proto2.TestAllTypesProto2') {
try {
const testMessage =
TestAllTypesProto2.deserializeBinary(request.getProtobufPayload());
response.setProtobufPayload(testMessage.serializeBinary());
} catch (err) {
response.setParseError(err.toString());
}
} else if (
request.getMessageType() ===
'protobuf_test_messages.proto3.TestAllTypesProto3') {
try {
const testMessage =
TestAllTypesProto3.deserializeBinary(request.getProtobufPayload());
response.setProtobufPayload(testMessage.serializeBinary());
} catch (err) {
response.setParseError(err.toString());
}
} else if (
request.getMessageType() ===
'protobuf_test_messages.editions.TestAllTypesEdition2023') {
try {
const testMessage =
TestAllTypesEdition2023.deserializeBinary(request.getProtobufPayload());
response.setProtobufPayload(testMessage.serializeBinary());
} catch (err) {
response.setParseError(err.toString());
}
} else if (
request.getMessageType() ===
'protobuf_test_messages.editions.proto2.TestAllTypesProto2') {
try {
const testMessage =
TestAllTypesProto2Edition2023.deserializeBinary(request.getProtobufPayload());
response.setProtobufPayload(testMessage.serializeBinary());
} catch (err) {
response.setParseError(err.toString());
}
} else if (
request.getMessageType() ===
'protobuf_test_messages.editions.proto3.TestAllTypesProto3') {
try {
const testMessage =
TestAllTypesProto3Edition2023.deserializeBinary(request.getProtobufPayload());
response.setProtobufPayload(testMessage.serializeBinary());
} catch (err) {
response.setParseError(err.toString());
}
} else {
throw new Error(
`Payload message not supported: ${request.getMessageType()}.`);
}
return response;
}
/**
* Reads a buffer of N bytes.
* @param {number} bytes Number of bytes to read.
* @return {!Buffer} Buffer which contains data.
*/
function readBuffer(bytes) {
// Linux cannot use process.stdin.fd (which isn't set up as sync)
const buf = new Buffer.alloc(bytes);
const fd = fs.openSync('/dev/stdin', 'r');
fs.readSync(fd, buf, 0, bytes);
fs.closeSync(fd);
return buf;
}
/**
* Writes all data in buffer.
* @param {!Buffer} buffer Buffer which contains data.
*/
function writeBuffer(buffer) {
// Under linux, process.stdout.fd is async. Needs to open stdout in a synced
// way for sync write.
const fd = fs.openSync('/dev/stdout', 'w');
fs.writeSync(fd, buffer, 0, buffer.length);
fs.closeSync(fd);
}
/**
* Returns true if the test ran successfully, false on legitimate EOF.
* @return {boolean} Whether to continue test.
*/
function runConformanceTest() {
const requestLengthBuf = readBuffer(4);
const requestLength = requestLengthBuf.readInt32LE(0);
if (!requestLength) {
return false;
}
const serializedRequest = readBuffer(requestLength);
const array = new Uint8Array(serializedRequest);
const request = ConformanceRequest.deserializeBinary(array.buffer);
const response = doTest(request);
const serializedResponse = response.serializeBinary();
const responseLengthBuf = new Buffer.alloc(4);
responseLengthBuf.writeInt32LE(serializedResponse.byteLength, 0);
writeBuffer(responseLengthBuf);
writeBuffer(new Buffer.from(serializedResponse));
return true;
}
while (true) {
if (!runConformanceTest()) {
break;
}
}