blob: bbf77386a787e11135a59dd42e43a2b5b857528a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
"use strict";
const path = require("node:path");
const readline = require("node:readline");
const { runCLI } = require("jest");
const PROTOCOL_READY = "__FORY_XLANG_READY__";
const PROTOCOL_RESULT = "__FORY_XLANG_RESULT__";
const PROTOCOL_SHUTDOWN = "__FORY_XLANG_SHUTDOWN__";
const CROSS_LANGUAGE_TEST_FILE = path.join("test", "crossLanguage.test.ts");
function escapeRegex(value) {
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function normalizeMessage(message) {
return message.replace(/[\r\n\t]+/g, " ").trim();
}
function failureMessage(results) {
if (!results) {
return "Unknown test failure";
}
if (results.numFailedTests > 0) {
return `Failed tests: ${results.numFailedTests}`;
}
if (results.numRuntimeErrorTestSuites > 0) {
return `Runtime error suites: ${results.numRuntimeErrorTestSuites}`;
}
if (results.numTotalTests === 0) {
return "No tests executed for case";
}
return "Test execution failed";
}
async function runCase(caseName, dataFile) {
process.env.DATA_FILE = dataFile;
const { results } = await runCLI(
{
$0: "xlang-peer",
_: [CROSS_LANGUAGE_TEST_FILE],
runInBand: true,
testNamePattern: `${escapeRegex(caseName)}$`,
coverage: false,
silent: true,
passWithNoTests: false,
ci: true,
},
[process.cwd()]
);
return results;
}
function writeProtocol(status, message) {
if (status === "OK") {
process.stdout.write(`${PROTOCOL_RESULT}\tOK\n`);
return;
}
process.stdout.write(`${PROTOCOL_RESULT}\tERR\t${normalizeMessage(message)}\n`);
}
async function handleCommand(line) {
if (line === PROTOCOL_SHUTDOWN) {
writeProtocol("OK");
process.exit(0);
return;
}
const separatorIndex = line.indexOf("\t");
if (separatorIndex <= 0 || separatorIndex === line.length - 1) {
writeProtocol("ERR", "Invalid command format, expected <caseName>\\t<dataFile>");
return;
}
const caseName = line.substring(0, separatorIndex);
const dataFile = line.substring(separatorIndex + 1);
try {
const results = await runCase(caseName, dataFile);
if (!results.success) {
writeProtocol("ERR", failureMessage(results));
return;
}
writeProtocol("OK");
} catch (error) {
writeProtocol(
"ERR",
error && error.message ? error.message : "Unexpected peer execution error"
);
}
}
const input = readline.createInterface({
input: process.stdin,
crlfDelay: Infinity,
});
let commandQueue = Promise.resolve();
input.on("line", (line) => {
commandQueue = commandQueue.then(() => handleCommand(line));
});
input.on("close", () => {
commandQueue.finally(() => process.exit(0));
});
process.stdout.write(`${PROTOCOL_READY}\n`);