fix(plugin): close kubernetes exec timeout edges
This commit is contained in:
@@ -153,7 +153,7 @@ export async function execInPod(
|
|||||||
websocketPromise
|
websocketPromise
|
||||||
.then((webSocket) => {
|
.then((webSocket) => {
|
||||||
ws = webSocket as WebSocketLike;
|
ws = webSocket as WebSocketLike;
|
||||||
if (stdinStream && stdinPayload) {
|
if (!settled && stdinStream && stdinPayload) {
|
||||||
stdinStream.end(stdinPayload);
|
stdinStream.end(stdinPayload);
|
||||||
}
|
}
|
||||||
ws.on("close", (code: number, reason: Buffer) => {
|
ws.on("close", (code: number, reason: Buffer) => {
|
||||||
@@ -168,6 +168,7 @@ export async function execInPod(
|
|||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (settled) return;
|
if (settled) return;
|
||||||
|
if (timeout) clearTimeout(timeout);
|
||||||
reject(err);
|
reject(err);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,6 +63,17 @@ describe("execInPod", () => {
|
|||||||
expect(result.stderr).toContain("Kubernetes exec timed out after 5ms");
|
expect(result.stderr).toContain("Kubernetes exec timed out after 5ms");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("clears the timeout when websocket setup rejects", async () => {
|
||||||
|
const clearTimeoutSpy = vi.spyOn(globalThis, "clearTimeout");
|
||||||
|
execMock.mockRejectedValue(new Error("network unreachable"));
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
execInPod({} as never, "ns", "pod-1", "agent", ["echo", "ok"], undefined, 1000),
|
||||||
|
).rejects.toThrow("network unreachable");
|
||||||
|
expect(clearTimeoutSpy).toHaveBeenCalled();
|
||||||
|
clearTimeoutSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
it("wraps stdin commands with a byte-counted head prefix", async () => {
|
it("wraps stdin commands with a byte-counted head prefix", async () => {
|
||||||
let observedCommand: string[] | undefined;
|
let observedCommand: string[] | undefined;
|
||||||
let observedStdin = "";
|
let observedStdin = "";
|
||||||
@@ -89,4 +100,31 @@ describe("execInPod", () => {
|
|||||||
expect(observedStdin).toBe("abc");
|
expect(observedStdin).toBe("abc");
|
||||||
expect(observedStdinFinished).toBe(true);
|
expect(observedStdinFinished).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("does not send stdin if the exec timed out before websocket setup completed", async () => {
|
||||||
|
let resolveWebsocket: ((ws: EventEmitter) => void) | undefined;
|
||||||
|
let observedStdin = "";
|
||||||
|
let observedStdinFinished = false;
|
||||||
|
|
||||||
|
execMock.mockImplementation((_namespace, _pod, _container, _command, _stdout, _stderr, stdin) => {
|
||||||
|
stdin?.on("data", (chunk: Buffer) => {
|
||||||
|
observedStdin += chunk.toString("utf8");
|
||||||
|
});
|
||||||
|
stdin?.on("finish", () => {
|
||||||
|
observedStdinFinished = true;
|
||||||
|
});
|
||||||
|
return new Promise<EventEmitter>((resolve) => {
|
||||||
|
resolveWebsocket = resolve;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await execInPod({} as never, "ns", "pod-1", "agent", ["base64", "-d"], "abc", 5);
|
||||||
|
expect(result.timedOut).toBe(true);
|
||||||
|
|
||||||
|
resolveWebsocket?.(new EventEmitter());
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
expect(observedStdin).toBe("");
|
||||||
|
expect(observedStdinFinished).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user