mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 15:58:36 +00:00
fix(voice-call): bound tailscale status output
This commit is contained in:
@@ -18,12 +18,14 @@ vi.mock("node:child_process", async () => {
|
||||
});
|
||||
|
||||
import {
|
||||
appendTailscaleCommandStdout,
|
||||
cleanupTailscaleExposure,
|
||||
cleanupTailscaleExposureRoute,
|
||||
getTailscaleDnsName,
|
||||
getTailscaleSelfInfo,
|
||||
setupTailscaleExposure,
|
||||
setupTailscaleExposureRoute,
|
||||
TAILSCALE_COMMAND_STDOUT_MAX_BYTES,
|
||||
} from "./tailscale.js";
|
||||
|
||||
function createProc(params?: { code?: number; stdout?: string }) {
|
||||
@@ -104,6 +106,21 @@ describe("voice-call tailscale helpers", () => {
|
||||
await expect(getTailscaleSelfInfo()).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it("tracks tailscale stdout without retaining over-limit output", () => {
|
||||
let stdout = appendTailscaleCommandStdout({ bytes: 0, exceeded: false, text: "" }, "ok", 4);
|
||||
stdout = appendTailscaleCommandStdout(stdout, "boom", 4);
|
||||
|
||||
expect(stdout).toEqual({ bytes: 6, exceeded: true, text: "" });
|
||||
});
|
||||
|
||||
it("kills tailscale status when stdout exceeds the capture limit", async () => {
|
||||
const proc = createProc({ stdout: "x".repeat(TAILSCALE_COMMAND_STDOUT_MAX_BYTES + 1) });
|
||||
spawnMock.mockReturnValueOnce(proc);
|
||||
|
||||
await expect(getTailscaleSelfInfo()).resolves.toBeNull();
|
||||
expect(proc.kill).toHaveBeenCalledWith("SIGKILL");
|
||||
});
|
||||
|
||||
it("sets up and cleans up exposure routes with the selected mode", async () => {
|
||||
spawnMock
|
||||
.mockReturnValueOnce(
|
||||
@@ -127,7 +144,7 @@ describe("voice-call tailscale helpers", () => {
|
||||
expect(spawnMock).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
"tailscale",
|
||||
["status", "--json"],
|
||||
["status", "--json", "--peers=false"],
|
||||
tailscaleSpawnOptions,
|
||||
);
|
||||
expect(spawnMock).toHaveBeenNthCalledWith(
|
||||
|
||||
@@ -6,6 +6,30 @@ type TailscaleSelfInfo = {
|
||||
nodeId: string | null;
|
||||
};
|
||||
|
||||
export const TAILSCALE_COMMAND_STDOUT_MAX_BYTES = 4 * 1024 * 1024;
|
||||
|
||||
type TailscaleCommandStdout = {
|
||||
bytes: number;
|
||||
exceeded: boolean;
|
||||
text: string;
|
||||
};
|
||||
|
||||
export function appendTailscaleCommandStdout(
|
||||
current: TailscaleCommandStdout,
|
||||
data: Buffer | string,
|
||||
maxBytes = TAILSCALE_COMMAND_STDOUT_MAX_BYTES,
|
||||
): TailscaleCommandStdout {
|
||||
if (current.exceeded) {
|
||||
return current;
|
||||
}
|
||||
const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
|
||||
const bytes = current.bytes + buffer.byteLength;
|
||||
if (bytes > maxBytes) {
|
||||
return { bytes, exceeded: true, text: "" };
|
||||
}
|
||||
return { bytes, exceeded: false, text: `${current.text}${buffer.toString("utf8")}` };
|
||||
}
|
||||
|
||||
function runTailscaleCommand(
|
||||
args: string[],
|
||||
timeoutMs = 2500,
|
||||
@@ -15,7 +39,7 @@ function runTailscaleCommand(
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
|
||||
let stdout = "";
|
||||
let stdout: TailscaleCommandStdout = { bytes: 0, exceeded: false, text: "" };
|
||||
let settled = false;
|
||||
let timer: ReturnType<typeof setTimeout>;
|
||||
const finish = (result: { code: number; stdout: string }) => {
|
||||
@@ -28,7 +52,11 @@ function runTailscaleCommand(
|
||||
};
|
||||
|
||||
proc.stdout.on("data", (data) => {
|
||||
stdout += data;
|
||||
stdout = appendTailscaleCommandStdout(stdout, data);
|
||||
if (stdout.exceeded) {
|
||||
proc.kill("SIGKILL");
|
||||
finish({ code: -1, stdout: "" });
|
||||
}
|
||||
});
|
||||
|
||||
timer = setTimeout(() => {
|
||||
@@ -41,13 +69,13 @@ function runTailscaleCommand(
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
finish({ code: code ?? -1, stdout });
|
||||
finish({ code: code ?? -1, stdout: stdout.text });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function getTailscaleSelfInfo(): Promise<TailscaleSelfInfo | null> {
|
||||
const { code, stdout } = await runTailscaleCommand(["status", "--json"]);
|
||||
const { code, stdout } = await runTailscaleCommand(["status", "--json", "--peers=false"]);
|
||||
if (code !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user