Files
api/services/edge-agent/test-support/fake-agent.mjs
T

121 lines
2.9 KiB
JavaScript

import process from "node:process";
const EDGE_TEST_BROKER_URL = process.env.EDGE_TEST_BROKER_URL || "";
const EDGE_TEST_GATEWAY_ID = process.env.EDGE_TEST_GATEWAY_ID || "";
const EDGE_TEST_AGENT_TOKEN = process.env.EDGE_TEST_AGENT_TOKEN || "";
const EDGE_TEST_BEHAVIOR = process.env.EDGE_TEST_BEHAVIOR || "success";
function normalizeBrokerUrl(rawUrl) {
if (!rawUrl) {
throw new Error("Missing EDGE_TEST_BROKER_URL");
}
const url = new URL(rawUrl);
if (["127.0.0.1", "localhost", "0.0.0.0"].includes(url.hostname)) {
url.hostname = "host.docker.internal";
}
return url;
}
function buildAgentWsUrl() {
if (!EDGE_TEST_GATEWAY_ID) {
throw new Error("Missing EDGE_TEST_GATEWAY_ID");
}
if (!EDGE_TEST_AGENT_TOKEN) {
throw new Error("Missing EDGE_TEST_AGENT_TOKEN");
}
const url = normalizeBrokerUrl(EDGE_TEST_BROKER_URL);
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
url.pathname = "/ws/agent";
url.search = new URLSearchParams({
gatewayId: EDGE_TEST_GATEWAY_ID,
token: EDGE_TEST_AGENT_TOKEN,
}).toString();
return url.toString();
}
function sendJson(socket, payload) {
socket.send(JSON.stringify(payload));
}
if (EDGE_TEST_BEHAVIOR === "offline") {
console.log("fake-agent-offline");
process.exit(0);
}
const socket = new WebSocket(buildAgentWsUrl());
const keepAlive = setInterval(() => {}, 1_000);
socket.addEventListener("open", () => {
console.log(`fake-agent-open:${EDGE_TEST_BEHAVIOR}`);
});
socket.addEventListener("message", ({ data }) => {
const message = JSON.parse(String(data));
if (message.type === "COMMAND") {
if (EDGE_TEST_BEHAVIOR === "timeout") {
return;
}
sendJson(socket, {
type: "COMMAND_RESULT",
commandId: message.commandId,
ok: true,
payload: {
source: "fake-agent",
commandType: message.commandType,
echo: message.payload || {},
},
});
return;
}
if (message.type === "OPEN_ROOT_SHELL") {
if (EDGE_TEST_BEHAVIOR === "shell-open-fail") {
socket.close();
return;
}
sendJson(socket, {
type: "SHELL_OPENED",
sessionId: message.payload.sessionId,
});
sendJson(socket, {
type: "SHELL_OUTPUT",
sessionId: message.payload.sessionId,
data: "root@fake-agent:~# ",
});
return;
}
if (message.type === "SHELL_INPUT") {
sendJson(socket, {
type: "SHELL_OUTPUT",
sessionId: message.payload.sessionId,
data: `echo:${String(message.payload.data || "")}`,
});
return;
}
if (message.type === "CLOSE_ROOT_SHELL") {
sendJson(socket, {
type: "SHELL_EXIT",
sessionId: message.payload.sessionId,
code: 0,
});
socket.close();
}
});
socket.addEventListener("error", (event) => {
console.error("fake-agent-error", event?.message || "");
process.exitCode = 1;
});
socket.addEventListener("close", () => {
clearInterval(keepAlive);
setTimeout(() => process.exit(process.exitCode || 0), 25);
});