Compare commits

...
Author SHA1 Message Date
dev-driver 8f44641637 test(cli): give the front-door and slice-claim spawns room on loaded runners
Loaded macOS CI runners took just over 5 s to start the compiled CLI,
and a batch of eight concurrent slice creates ran past their 15 s and
30 s limits, so these tests failed on changes that don't touch them.

- front-door: the compiled-front-door spawns guard against a hang, which
  never ends; their budget is now 30 s, with each test allowed past it so
  the spawn's own result reports a hang.
- scope-slice-claims: a create waits on nothing (each claim is one
  exclusive file create), so a create still running after a minute is
  hung; the batch tests allow each batch that full minute plus one.

Each test still fails a hang through its own limit, and the slice
claims' unique-slices, no-refusals checks are unchanged.

Refs #3098, #3112, #3119
2026-11-13 04:34:11 +00:00
2 changed files with 25 additions and 12 deletions

No files matched your search

+15 -9
View File
@@ -14,6 +14,12 @@ import { runFrontDoor, resolveTuiPath, probeFrontDoor, type FrontDoorIo } from "
import { diagnoseRuntimePosture, observeClaudePermission } from "../../daemon/src/domain/permission-drift.js";
import { DaemonClient, DaemonConnectionError, DaemonResponseError, DaemonTimeoutError } from "../src/client.js";
// The compiled front door's spawns guard against a hang (the piped TUI never exiting). A hang never ends, so a budget well
// past a slow start still catches one: loaded CI runners took just over 5 s to start the CLI, and 30 s leaves room.
const HANG_LIMIT_MS = 30_000;
/** Those tests outlive their spawn's budget, so the spawn's own result is what reports a hang. */
const HANG_TEST_TIMEOUT_MS = HANG_LIMIT_MS + 10_000;
// A GUARANTEED-refused local port (bind an ephemeral port, capture it, close → connecting refuses).
// A REAL socket refusal, not a hand-built error — buys the actual Node/undici rejection shape.
async function refusedPort(): Promise<number> {
@@ -487,7 +493,7 @@ describe("PUBLIC bin ownership (guard finding 1 — the wrapper is the real fron
const started = Date.now();
const result = spawnSync(process.execPath, [binWrapper], {
input: "x\n",
timeout: 5000,
timeout: HANG_LIMIT_MS,
encoding: "utf-8",
});
expect(result.status, JSON.stringify({
@@ -496,13 +502,13 @@ describe("PUBLIC bin ownership (guard finding 1 — the wrapper is the real fron
stdout: result.stdout?.slice(-4096), stderr: result.stderr?.slice(-4096),
})).toBe(0);
expect(`${result.stderr}${result.stdout}`).toMatch(/Usage: rig/);
});
}, HANG_TEST_TIMEOUT_MS);
it.skipIf(!existsSync(binWrapper))("PUBLIC bin subcommands are untouched (rig --version via wrapper)", () => {
const result = spawnSync(process.execPath, [binWrapper, "--version"], { timeout: 5000, encoding: "utf-8" });
const result = spawnSync(process.execPath, [binWrapper, "--version"], { timeout: HANG_LIMIT_MS, encoding: "utf-8" });
expect(result.status).toBe(0);
expect(result.stdout.trim()).toMatch(/^\d+\.\d+\.\d+/);
});
}, HANG_TEST_TIMEOUT_MS);
});
describe("script-safety integration (the compiled front door)", () => {
@@ -511,22 +517,22 @@ describe("script-safety integration (the compiled front door)", () => {
const started = Date.now();
const result = spawnSync(process.execPath, [cliEntry], {
input: "x\n",
timeout: 5000,
timeout: HANG_LIMIT_MS,
encoding: "utf-8",
env: { ...process.env, OPENRIG_URL: "", OPENRIG_PORT: "" },
});
expect(Date.now() - started).toBeLessThan(5000);
expect(Date.now() - started).toBeLessThan(HANG_LIMIT_MS);
// pre-slice-17 baseline: commander's clean-help path prints usage and
// exits 0 — the front door PRESERVES the piped path byte-for-byte
expect(result.status).toBe(0);
expect(`${result.stderr}${result.stdout}`).toMatch(/Usage: rig/);
expect(`${result.stderr}${result.stdout}`).not.toMatch(/\n\s+at /);
});
}, HANG_TEST_TIMEOUT_MS);
it.skipIf(!existsSync(cliEntry))("`rig --help` still exits 0 with the full usage (front-door regression)", () => {
const result = spawnSync(process.execPath, [cliEntry, "--help"], { timeout: 5000, encoding: "utf-8" });
const result = spawnSync(process.execPath, [cliEntry, "--help"], { timeout: HANG_LIMIT_MS, encoding: "utf-8" });
expect(result.status).toBe(0);
expect(result.stdout).toMatch(/Usage: rig/);
expect(result.stdout).toMatch(/daemon/);
});
}, HANG_TEST_TIMEOUT_MS);
});
+10 -3
View File
@@ -14,6 +14,13 @@ interface Result {
stderr: string;
}
// A create waits on nothing (each claim is one exclusive file create), so one still running after a minute is hung; a
// slow start on a loaded CI runner took over 15 s. A batch's creates run together, so the batch tests allow each batch the
// full limit plus one for setup and checks, and a hung create there is reported by its own limit. A single-create test
// keeps the suite's default timeout, which reports a hang first.
const CREATE_LIMIT_MS = 60_000;
const batchesTimeout = (batches: number) => (batches + 1) * CREATE_LIMIT_MS;
describe("public slice creation ordinal claims", () => {
let root: string;
let workspace: string;
@@ -49,7 +56,7 @@ describe("public slice creation ordinal claims", () => {
];
try {
const result = await promisify(execFile)(process.execPath, args, {
env: ownedEnv, encoding: "utf8", timeout: 15000,
env: ownedEnv, encoding: "utf8", timeout: CREATE_LIMIT_MS,
});
return { exitCode: 0, ...result };
} catch (error) {
@@ -95,7 +102,7 @@ describe("public slice creation ordinal claims", () => {
expect(fs.readdirSync(path.join(mission, "slices"), { withFileTypes: true }).filter((entry) => entry.isDirectory())).toHaveLength(33);
expect(fs.readFileSync(path.join(mission, "README.md"), "utf8")).toBe(original);
expect(fs.existsSync(path.join(mission, ".openrig-slice-create-lock"))).toBe(false);
}, 30000);
}, batchesTimeout(4));
it("twenty eight-process manifest-backed batches preserve the admitted concurrency contract", async () => {
const ref = "slices/01-existing/slice.yaml";
@@ -144,7 +151,7 @@ describe("public slice creation ordinal claims", () => {
expect(new Set(successful(results).map((slice) => slice.id)).size).toBe(160);
expect(fs.readFileSync(path.join(unrelated, "PROOF.md"), "utf8")).toBe("# unrelated authored proof\n");
expect(fs.existsSync(path.join(mission, ".openrig-slice-create-lock"))).toBe(false);
}, 180000);
}, batchesTimeout(20));
it("a later create repairs only pending complete registrations and preserves authored membership", async () => {
const ref = "slices/01-existing/slice.yaml";