test(07-04): RED — the CLI vectors: per-gate evidence lines, the free-tier comparison table, CLEAN exit 0, --live contract, environment-drift exit 2
This commit is contained in:
@@ -148,7 +148,8 @@ await test("BA2 a missing web/dist is notRun — NEVER a pass (exit-2 class)", a
|
||||
});
|
||||
|
||||
await test("BA3 a fixture dist over the app-bundle ceiling FAILS the gate with the overage", async () => {
|
||||
const fix = makeFixtureRoot("ba3-dist", { "assets/huge.js": "x".repeat(600000) });
|
||||
const { randomBytes } = await import("node:crypto");
|
||||
const fix = makeFixtureRoot("ba3-dist", { "assets/huge.js": randomBytes(600000).toString("base64") });
|
||||
try {
|
||||
const m = await import(gatesUrl);
|
||||
const r = await m.runBundleBudgetGate({ distDir: fix.dir });
|
||||
@@ -260,8 +261,58 @@ await test("GC2 a failing corpus FAILS the gate carrying that child's own output
|
||||
assert.match(r.evidence, /CORPUS GATE FAIL: synthetic/, "the child's own failure output must be carried verbatim");
|
||||
});
|
||||
|
||||
/* ————— summary ————— */
|
||||
/* ————— AU — the CLI ————— */
|
||||
|
||||
const cliPath = path.join(ROOT, "scripts", "budget-audit.mjs");
|
||||
|
||||
function runCli(args, env = {}) {
|
||||
return spawnSync(process.execPath, [cliPath, ...args], {
|
||||
cwd: ROOT,
|
||||
encoding: "utf8",
|
||||
timeout: 300000,
|
||||
env: { ...process.env, ...env },
|
||||
maxBuffer: 1 << 26,
|
||||
});
|
||||
}
|
||||
|
||||
await test("AU1 without --live: every required gate prints its evidence line, the free-tier comparison table is printed, and the audit is CLEAN with exit 0", () => {
|
||||
assert.ok(existsSync(cliPath), "scripts/budget-audit.mjs must exist");
|
||||
const r = runCli([]);
|
||||
assert.equal(r.status, 0, `exit 0 expected on the current tree (stdout: ${r.stdout?.slice(-400)})`);
|
||||
const out = r.stdout ?? "";
|
||||
for (const id of ["route-cpu", "bundle-budget", "kv-writes", "subrequests", "golden-corpus"]) {
|
||||
assert.match(out, new RegExp(`${id}: (PASS|FAIL|NOT RUN) — `), `${id} must print its one-line evidence`);
|
||||
}
|
||||
assert.match(out, /BUDGET AUDIT CLEAN/, "the CLEAN summary must print");
|
||||
assert.match(out, /50\/request/, "the subrequest ceiling must appear in the comparison table");
|
||||
assert.match(out, /10 ms\/invocation/, "the CPU ceiling must appear in the comparison table");
|
||||
assert.match(out, /not measured/, "unmeasured ceilings must read `not measured` — never 0");
|
||||
assert.match(out, /cache-headers: NOT RUN \(pass --live\)/, "the flag-skipped live gate is visible and honest");
|
||||
});
|
||||
|
||||
await test("AU2 with --live: the live header probe runs and the exit contract holds — a NOT RUN cache-header gate NEVER coexists with exit 0", () => {
|
||||
const r = runCli(["--live"]);
|
||||
const out = r.stdout ?? "";
|
||||
assert.ok([0, 1, 2].includes(r.status), `exit must be 0/1/2 (got ${r.status})`);
|
||||
assert.match(out, /cache-headers: /, "the cache-header gate must print with --live");
|
||||
if (out.includes("cache-headers: NOT RUN")) {
|
||||
assert.equal(r.status, 2, "a NOT RUN gate must map to exit 2 (environment drift) — never a silent pass");
|
||||
assert.match(out, /BUDGET AUDIT NOT RUN/, "the NOT RUN summary must print");
|
||||
}
|
||||
});
|
||||
|
||||
await test("AU3 environment drift (a root with no builds/graph) maps to exit 2 — BUDGET AUDIT NOT RUN, never a pass (T-07-22)", () => {
|
||||
const empty = mkdtempSync(path.join(tmpdir(), "budget-empty-"));
|
||||
try {
|
||||
const r = runCli([], { PRIVACY_AUDIT_ROOT: empty });
|
||||
assert.equal(r.status, 2, `a root without the measured surfaces must be exit 2 (stdout: ${r.stdout?.slice(-300)})`);
|
||||
assert.match(r.stdout ?? "", /BUDGET AUDIT NOT RUN/, "the NOT RUN summary must print");
|
||||
} finally {
|
||||
rmSync(empty, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
/* ————— summary ————— */
|
||||
if (failures.length > 0) {
|
||||
console.error(`\n${failures.length}/${ran} vector(s) FAILED:`);
|
||||
for (const f of failures) console.error(` - ${f.name}`);
|
||||
|
||||
Reference in New Issue
Block a user