104 lines
3.0 KiB
TypeScript
104 lines
3.0 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import path from "node:path";
|
|
import { EventEmitter } from "node:events";
|
|
import { createRequire, syncBuiltinESMExports } from "node:module";
|
|
import { pathToFileURL } from "node:url";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const childProcess = require("node:child_process");
|
|
const modulePath = path.join(process.cwd(), "scripts/build/runtime-env.mjs");
|
|
|
|
const originalSpawn = childProcess.spawn;
|
|
const originalProcessOn = process.on;
|
|
const originalProcessExit = process.exit;
|
|
const originalProcessKill = process.kill;
|
|
|
|
async function loadRuntimeEnv(label) {
|
|
return import(`${pathToFileURL(modulePath).href}?case=${label}-${Date.now()}`);
|
|
}
|
|
|
|
test.afterEach(() => {
|
|
childProcess.spawn = originalSpawn;
|
|
process.on = originalProcessOn;
|
|
process.exit = originalProcessExit;
|
|
process.kill = originalProcessKill;
|
|
syncBuiltinESMExports();
|
|
});
|
|
|
|
test("runtime env helpers normalize runtime ports and conflicting color flags", async () => {
|
|
const runtimeEnv = await loadRuntimeEnv("helpers");
|
|
|
|
assert.deepEqual(
|
|
runtimeEnv.withRuntimePortEnv(
|
|
{ NODE_ENV: "test" },
|
|
{ basePort: 20128, apiPort: 21128, dashboardPort: 22128 }
|
|
),
|
|
{
|
|
NODE_ENV: "test",
|
|
OMNIROUTE_PORT: "20128",
|
|
PORT: "22128",
|
|
DASHBOARD_PORT: "22128",
|
|
API_PORT: "21128",
|
|
}
|
|
);
|
|
|
|
assert.deepEqual(
|
|
runtimeEnv.sanitizeColorEnv({ FORCE_COLOR: "1", NO_COLOR: "1", TERM: "xterm-256color" }),
|
|
{ NO_COLOR: "1", TERM: "xterm-256color" }
|
|
);
|
|
assert.deepEqual(runtimeEnv.sanitizeColorEnv({ FORCE_COLOR: "1" }), { FORCE_COLOR: "1" });
|
|
});
|
|
|
|
test("spawnWithForwardedSignals forwards process signals and exit status", async () => {
|
|
const signalHandlers = new Map();
|
|
const childKillSignals = [];
|
|
const processKills = [];
|
|
const processExits = [];
|
|
const spawnCalls = [];
|
|
let child;
|
|
|
|
childProcess.spawn = (command, args, options) => {
|
|
spawnCalls.push({ command, args, options });
|
|
child = new EventEmitter();
|
|
child.kill = (signal) => childKillSignals.push(signal);
|
|
return child;
|
|
};
|
|
process.on = (signal, handler) => {
|
|
signalHandlers.set(signal, handler);
|
|
return process;
|
|
};
|
|
process.exit = (code) => {
|
|
processExits.push(code);
|
|
};
|
|
process.kill = (pid, signal) => {
|
|
processKills.push({ pid, signal });
|
|
return true;
|
|
};
|
|
syncBuiltinESMExports();
|
|
|
|
const runtimeEnv = await loadRuntimeEnv("spawn");
|
|
const returnedChild = runtimeEnv.spawnWithForwardedSignals("node", ["server.js"], {
|
|
stdio: "inherit",
|
|
});
|
|
|
|
assert.equal(returnedChild, child);
|
|
assert.deepEqual(spawnCalls, [
|
|
{
|
|
command: "node",
|
|
args: ["server.js"],
|
|
options: { stdio: "inherit" },
|
|
},
|
|
]);
|
|
|
|
signalHandlers.get("SIGINT")();
|
|
signalHandlers.get("SIGTERM")();
|
|
assert.deepEqual(childKillSignals, ["SIGINT", "SIGTERM"]);
|
|
|
|
child.emit("exit", 3, null);
|
|
child.emit("exit", null, "SIGTERM");
|
|
|
|
assert.deepEqual(processExits, [3]);
|
|
assert.deepEqual(processKills, [{ pid: process.pid, signal: "SIGTERM" }]);
|
|
});
|