import { spawnSync } from "node:child_process"; import { mkdtempSync, readFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; import { expect } from "vitest"; import { test } from "@openwork/testkit"; const repoRoot = resolve(import.meta.dirname, "../.."); const retryClassificationTest = "GitHub sync treats 502 and TimeoutError as transient"; test("GitHub installation-token request budgets and recovery hold in focused runtime tests", ({ evidence }) => { const reportDir = mkdtempSync(join(tmpdir(), "openwork-github-budget-")); const reportPath = join(reportDir, "bun-junit.xml"); const retryReportPath = join(reportDir, "bun-retry-junit.xml"); try { const result = spawnSync("pnpm", [ "--filter", "@openwork-ee/den-api", "exec", "bun", "test", "test/github-sync-request-budget.test.ts", "--reporter=junit", "--reporter-outfile", reportPath, ], { cwd: repoRoot, encoding: "utf8", maxBuffer: 10 * 1024 * 1024, timeout: 60_000, }); const output = `${result.stdout}${result.stderr}`; expect(result.error, output).toBeUndefined(); expect(result.status, output).toBe(0); const junit = readFileSync(reportPath, "utf8"); const summary = junit.match(/]*>/)?.[0] ?? ""; expect(summary).toContain('tests="5"'); expect(summary).toContain('failures="0"'); expect(summary).toContain('skipped="0"'); expect(junit).not.toContain("]*>/)?.[0] ?? ""; expect(retrySummary).toContain('tests="1"'); expect(retrySummary).toContain('failures="0"'); expect(retrySummary).toContain('skipped="0"'); expect(retryJunit).toContain(retryClassificationTest); expect(retryJunit).not.toContain("