|
| 1 | +import { readFileSync } from "node:fs"; |
| 2 | +import { describe, expect, it } from "vitest"; |
| 3 | + |
| 4 | +// #7014: these unattended, CI-workflow-driven scripts make outbound fetches with no per-request timeout, so a |
| 5 | +// single hung connection could block the job past its intended deadline (or indefinitely). Every fetch they |
| 6 | +// make must now carry an AbortSignal timeout. Asserted structurally because the scripts run against live |
| 7 | +// container/GitHub endpoints that a unit test can't stand up. |
| 8 | + |
| 9 | +it("check-mcp-release-due's githubRequest fetch carries an AbortSignal timeout", () => { |
| 10 | + const src = readFileSync("scripts/check-mcp-release-due.mjs", "utf8"); |
| 11 | + const fetchCount = (src.match(/\bfetch\(/g) ?? []).length; |
| 12 | + const timeoutCount = (src.match(/AbortSignal\.timeout\(/g) ?? []).length; |
| 13 | + expect(fetchCount).toBe(1); |
| 14 | + expect(timeoutCount).toBe(1); |
| 15 | +}); |
| 16 | + |
| 17 | +describe("smoke-observability scripts (#7014): every generated fetch is timeout-guarded", () => { |
| 18 | + for (const path of ["scripts/smoke-observability-traces.mjs", "scripts/smoke-observability-metrics.mjs"]) { |
| 19 | + it(`${path} bounds every fetch with AbortSignal.timeout`, () => { |
| 20 | + const src = readFileSync(path, "utf8"); |
| 21 | + const fetchCount = (src.match(/\bawait fetch\(/g) ?? []).length; |
| 22 | + const timeoutCount = (src.match(/AbortSignal\.timeout\(/g) ?? []).length; |
| 23 | + expect(fetchCount, `${path}: expected fetch calls`).toBeGreaterThan(0); |
| 24 | + // One timeout per fetch — no un-bounded outbound call is left in the generated smoke script. |
| 25 | + expect(timeoutCount, `${path}: every fetch guarded`).toBe(fetchCount); |
| 26 | + }); |
| 27 | + } |
| 28 | +}); |
0 commit comments