|
| 1 | +import { createServer } from "node:net"; |
1 | 2 | /** |
2 | 3 | * Tests QA runtime command loading and private CLI gating. |
3 | 4 | */ |
4 | 5 | import { Command } from "commander"; |
5 | | -import { createServer } from "node:net"; |
6 | 6 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
7 | 7 | import { |
8 | 8 | cleanupTempDirs, |
@@ -60,6 +60,21 @@ describe("plugin-sdk qa-runtime", () => {
|
60 | 60 | }; |
61 | 61 | } |
62 | 62 | |
| 63 | +function cancelTrackedFetchResponse(ok = true) { |
| 64 | +let canceled = false; |
| 65 | +return { |
| 66 | +response: { |
| 67 | + ok, |
| 68 | +body: { |
| 69 | +cancel: vi.fn(async () => { |
| 70 | +canceled = true; |
| 71 | +}), |
| 72 | +}, |
| 73 | +}, |
| 74 | +wasCanceled: () => canceled, |
| 75 | +}; |
| 76 | +} |
| 77 | + |
63 | 78 | it("stays cold until the runtime seam is used", async () => { |
64 | 79 | const module = await import("./qa-runtime.js"); |
65 | 80 | |
@@ -341,6 +356,52 @@ describe("plugin-sdk qa-runtime", () => {
|
341 | 356 | expect(fetchImpl).toHaveBeenCalledWith("http://172.18.0.4:18789/healthz"); |
342 | 357 | }); |
343 | 358 | |
| 359 | +it("cancels compose service health probe response bodies", async () => { |
| 360 | +const module = await import("./qa-runtime.js"); |
| 361 | +const runtime = module.createQaDockerRuntime({ auditContext: "qa-test" }); |
| 362 | +const runCommand = vi.fn(async (_command: string, args: string[]) => { |
| 363 | +if (args.includes("ps")) { |
| 364 | +return { stdout: "qa-gateway-one\n", stderr: "" }; |
| 365 | +} |
| 366 | +return { stdout: "172.18.0.4\n", stderr: "" }; |
| 367 | +}); |
| 368 | +const probe = cancelTrackedFetchResponse(true); |
| 369 | +const fetchImpl = vi.fn(async () => probe.response); |
| 370 | + |
| 371 | +await expect( |
| 372 | +runtime.resolveComposeServiceUrl( |
| 373 | +"gateway", |
| 374 | +18789, |
| 375 | +"/tmp/docker-compose.yml", |
| 376 | +"/repo", |
| 377 | +runCommand, |
| 378 | +fetchImpl, |
| 379 | +), |
| 380 | +).resolves.toBe("http://172.18.0.4:18789/"); |
| 381 | +expect(probe.wasCanceled()).toBe(true); |
| 382 | +}); |
| 383 | + |
| 384 | +it("cancels waitForHealth response bodies after each probe", async () => { |
| 385 | +const module = await import("./qa-runtime.js"); |
| 386 | +const runtime = module.createQaDockerRuntime({ auditContext: "qa-test" }); |
| 387 | +const first = cancelTrackedFetchResponse(false); |
| 388 | +const second = cancelTrackedFetchResponse(true); |
| 389 | +const responses = [first.response, second.response]; |
| 390 | +const fetchImpl = vi.fn(async () => responses.shift() ?? second.response); |
| 391 | +const sleepImpl = vi.fn(async () => {}); |
| 392 | + |
| 393 | +await runtime.waitForHealth("http://127.0.0.1:18789/healthz", { |
| 394 | + fetchImpl, |
| 395 | + sleepImpl, |
| 396 | +timeoutMs: 1000, |
| 397 | +pollMs: 1, |
| 398 | +}); |
| 399 | + |
| 400 | +expect(fetchImpl).toHaveBeenCalledTimes(2); |
| 401 | +expect(first.wasCanceled()).toBe(true); |
| 402 | +expect(second.wasCanceled()).toBe(true); |
| 403 | +}); |
| 404 | + |
344 | 405 | it("resolves an unpinned QA Docker host port away from an occupied loopback default", async () => { |
345 | 406 | const module = await import("./qa-runtime.js"); |
346 | 407 | const reservation = await occupyLoopbackPort(); |
|