Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 39 additions & 5 deletions src/lib/nim.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,24 @@ function loadNimWithMockedRunner(runCapture: Mock) {
};
}

/** Check if an argv array or legacy shell command contains a specific argument. */
function hasArg(cmd: string | string[], arg: string): boolean {
return Array.isArray(cmd) ? cmd.includes(arg) : cmd.includes(arg);
}

function hasCurlTimeoutArgs(cmd: string | string[]): boolean {
if (!Array.isArray(cmd)) {
return (
cmd.includes("curl") &&
cmd.includes("--connect-timeout 5") &&
cmd.includes("--max-time 5")
);
}
const connectTimeout = cmd.indexOf("--connect-timeout");
const maxTime = cmd.indexOf("--max-time");
return cmd[0] === "curl" && cmd[connectTimeout + 1] === "5" && cmd[maxTime + 1] === "5";
}

describe("nim", () => {
describe("listModels", () => {
it("returns 5 models", () => {
Expand Down Expand Up @@ -176,12 +194,27 @@ describe("nim", () => {
});
});

describe("nimStatusByName", () => {
/** Check if an argv array contains a specific element. */
function hasArg(cmd: string | string[], arg: string): boolean {
return Array.isArray(cmd) ? cmd.includes(arg) : cmd.includes(arg);
}
describe("waitForNimHealth", () => {
it("bounds curl health probes with connect and total timeouts", () => {
const runCapture = vi.fn((cmd: string | string[]) => {
if (!Array.isArray(cmd)) throw new Error("expected argv array");
if (cmd[0] === "curl" && hasArg(cmd, "http://127.0.0.1:9000/v1/models")) return '{"data":[]}';
return "";
});
const { nimModule, restore } = loadNimWithMockedRunner(runCapture);

try {
expect(nimModule.waitForNimHealth(9000, 1)).toBe(true);
const commands = runCapture.mock.calls.map(([c]: [string | string[]]) => c);

expect(commands.some((c) => c[0] === "curl" && hasCurlTimeoutArgs(c))).toBe(true);
} finally {
restore();
}
});
});

describe("nimStatusByName", () => {
it("uses provided port directly", () => {
const runCapture = vi.fn((cmd: string | string[]) => {
if (!Array.isArray(cmd)) throw new Error("expected argv array");
Expand All @@ -205,6 +238,7 @@ describe("nim", () => {
expect(commands.some((c) => c.includes("http://127.0.0.1:9000/v1/models"))).toBe(
true,
);
expect(commands.some((c) => c[0] === "curl" && hasCurlTimeoutArgs(c))).toBe(true);
} finally {
restore();
}
Expand Down
25 changes: 21 additions & 4 deletions src/lib/nim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,18 @@ export function waitForNimHealth(port = VLLM_PORT, timeout = 300): boolean {

while ((Date.now() - start) / 1000 < timeout) {
try {
const result = runCapture(["curl", "-sf", `http://127.0.0.1:${hostPort}/v1/models`], {
ignoreError: true,
});
const result = runCapture(
[
"curl",
"-sf",
"--connect-timeout",
"5",
"--max-time",
"5",
`http://127.0.0.1:${hostPort}/v1/models`,
],
{ ignoreError: true },
);
if (result) {
console.log(" NIM is healthy.");
return true;
Expand Down Expand Up @@ -313,7 +322,15 @@ export function nimStatusByName(name: string, port?: number): NimStatus {
resolvedHostPort = m ? Number(m[1]) : VLLM_PORT;
}
const health = runCapture(
["curl", "-sf", `http://127.0.0.1:${resolvedHostPort}/v1/models`],
[
"curl",
"-sf",
"--connect-timeout",
"5",
"--max-time",
"5",
`http://127.0.0.1:${resolvedHostPort}/v1/models`,
],
{ ignoreError: true },
);
healthy = !!health;
Expand Down
Loading