Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion tests/control_plane_ts/agent_preferences.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ for (const [name, Store] of [["file", FileAuthorityStore], ["sqlite", SqliteAuth
}

test("known filesystem denial is not missing or corrupt preferences", async t => {
if (process.getuid?.() === 0) { t.skip("root bypasses POSIX read permission"); return; }
if (process.platform === "win32" || process.getuid?.() === 0) {
t.skip("mode 000 read denial needs a non-root POSIX host"); return;
}
const root = await mkdtemp(join(tmpdir(), "preferences-permission-"));
t.after(() => rm(root, {recursive: true, force: true}));
const call = (fields: JsonObject = {}) => agentPreferences({...request, runtime_root: root, ...fields});
Expand Down
7 changes: 6 additions & 1 deletion tests/control_plane_ts/authority_archive.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ function sqliteSkipReason(): string | undefined {
const sqliteSkip = sqliteSkipReason();

for (const platform of ["win32", "linux"] as const) {
test(`archive publication preserves the ${platform} directory-sync boundary`, async () => {
test(`archive publication preserves the ${platform} directory-sync boundary`, {
// A Windows kernel cannot fsync a directory handle, so the simulated Linux
// boundary is only reproducible on a POSIX host.
skip: platform === "linux" && process.platform === "win32"
? "the linux directory-sync boundary needs a POSIX host" : false,
}, async () => {
const root = await mkdtemp(join(tmpdir(), "authority-archive-"));
const source = new FileAuthorityStore(join(root, "source"), "goal");
const descriptor = Object.getOwnPropertyDescriptor(process, "platform")!;
Expand Down
20 changes: 16 additions & 4 deletions tests/control_plane_ts/canonical_task_lease_renew.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,10 @@ for (const provider of ["file", "sqlite"] as const) {
await writeFile(config, JSON.stringify({...command, operation: "acquire", now: acquireNow.toISOString()}));
const before = await store.loadAuthority();
const child = spawnSync(process.execPath, ["--no-warnings", "--experimental-sqlite", "--experimental-strip-types", CHILD, config, boundary, "600"], {encoding: "utf8", timeout: 30000});
assert.equal(child.signal, "SIGKILL", child.stderr);
assert.equal(child.error, undefined);
assert.notEqual(child.status, 0);
// Windows has no POSIX signals; TerminateProcess reports an exit status instead.
if (process.platform !== "win32") assert.equal(child.signal, "SIGKILL", child.stderr);
if (boundary === "before") assert.deepEqual(await store.loadAuthority(), before);
const result = await executeTaskLeaseAcquire(command, {now: () => acquireNow});
assert.equal(result.ok, true, JSON.stringify(result)); assert.equal(result.status, boundary === "before" ? "applied" : "replayed");
Expand Down Expand Up @@ -266,7 +269,10 @@ for (const provider of ["file", "sqlite"] as const) {
const config = join(root, "child.json"); await writeFile(config, JSON.stringify({...request, now: NOW.toISOString()}));
const before = await store.loadAuthority();
const child = spawnSync(process.execPath, ["--no-warnings", "--experimental-sqlite", "--experimental-strip-types", CHILD, config, boundary, "600"], {encoding: "utf8", timeout: 30000});
assert.equal(child.signal, "SIGKILL", child.stderr);
assert.equal(child.error, undefined);
assert.notEqual(child.status, 0);
// Windows has no POSIX signals; TerminateProcess reports an exit status instead.
if (process.platform !== "win32") assert.equal(child.signal, "SIGKILL", child.stderr);
if (boundary === "before") assert.deepEqual(await store.loadAuthority(), before);
const result = await executeTaskLeaseLifecycle(request, {now: () => NOW});
assert.equal(result.ok, true); assert.equal(result.status, boundary === "before" ? "applied" : "replayed");
Expand Down Expand Up @@ -315,7 +321,10 @@ for (const provider of ["file", "sqlite"] as const) {
const before = await store.loadAuthority();
const child = spawnSync(process.execPath, ["--no-warnings", "--experimental-sqlite", "--experimental-strip-types", CHILD,
config, boundary, "600"], {encoding: "utf8", timeout: 30000});
assert.equal(child.signal, "SIGKILL", child.stderr);
assert.equal(child.error, undefined);
assert.notEqual(child.status, 0);
// Windows has no POSIX signals; TerminateProcess reports an exit status instead.
if (process.platform !== "win32") assert.equal(child.signal, "SIGKILL", child.stderr);
if (boundary === "before") assert.deepEqual(await store.loadAuthority(), before);
const recovered = await executeTaskLeaseLifecycle(command, {now: () => NOW});
assert.equal(recovered.ok, true, JSON.stringify(recovered));
Expand Down Expand Up @@ -355,7 +364,10 @@ for (const provider of ["file", "sqlite"] as const) {
const before = await store.loadAuthority();
const child = spawnSync(process.execPath, ["--no-warnings", "--experimental-sqlite", "--experimental-strip-types", CHILD,
config, boundary, "600"], {encoding: "utf8", timeout: 30000});
assert.equal(child.signal, "SIGKILL", child.stderr);
assert.equal(child.error, undefined);
assert.notEqual(child.status, 0);
// Windows has no POSIX signals; TerminateProcess reports an exit status instead.
if (process.platform !== "win32") assert.equal(child.signal, "SIGKILL", child.stderr);
if (boundary === "before") assert.deepEqual(await store.loadAuthority(), before);
const recovered = await executeTaskLeaseLifecycle(command, {now: () => NOW});
assert.equal(recovered.ok, true, JSON.stringify(recovered));
Expand Down
4 changes: 4 additions & 0 deletions tests/control_plane_ts/cold_source_import.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ test("a committed original receipt remains readable after backup loss", async t

for (const variant of ["expired_active", "orphan_active", "symlink", "unsupported_filename"] as const) {
test(`cold import rejects ${variant} lease facts rather than deleting them`, async t => {
if (variant === "symlink" && process.platform === "win32") {
t.skip("file symlink creation needs Windows host privileges");
return;
}
const f = await fixture(t);
const directory = join(f.f.root, "goals", "goal-a", "task-leases");
await mkdir(directory, {recursive: true});
Expand Down
11 changes: 8 additions & 3 deletions tests/control_plane_ts/coordination_runtime_shadow.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ test("bootstrap is exactly replayable, has no mutation receipt and cannot overwr

for (const kind of ["unsupported_name", "file_symlink", "directory_symlink", "parent_symlink", "non_file"] as const) {
test(`source admission rejects ${kind} without changing the candidate`, async (t) => {
if (kind === "file_symlink" && process.platform === "win32") {
t.skip("file symlink creation needs Windows host privileges");
return;
}
const f = await fixture(t);
const before = await f.store.loadAuthority();
let source = await sourceRequest(f, f.baseline);
Expand All @@ -80,12 +84,12 @@ for (const kind of ["unsupported_name", "file_symlink", "directory_symlink", "pa
if (kind === "non_file") await mkdir(join(directory, "todo_retained.json"));
if (kind === "directory_symlink") {
await rm(directory, {recursive: true});
await symlink(outside, directory);
await symlink(outside, directory, process.platform === "win32" ? "junction" : "dir");
}
if (kind === "parent_symlink") {
const goalDirectory = join(f.root, "goals", "goal-a");
await rm(goalDirectory, {recursive: true});
await symlink(outside, goalDirectory);
await symlink(outside, goalDirectory, process.platform === "win32" ? "junction" : "dir");
}
if (kind !== "non_file") source = await sourceRequest(f, f.baseline);
const result = await inspectCoordinationRuntimeShadow({...source,
Expand Down Expand Up @@ -186,7 +190,8 @@ test("qualification preserves unrecognized residue, symlink partitions and inval
await writeFile(cursorPath, Buffer.concat([invalid.subarray(0, offset), Buffer.from([0xff]), invalid.subarray(offset + 3)]));
assert.equal((await qualify(f, head)).reason_code, "outbox_file_invalid");
await writeFile(cursorPath, original);
await symlink(directory, join(f.root, "authority-shadow", "outbox", "goal-a", "leases"));
await symlink(directory, join(f.root, "authority-shadow", "outbox", "goal-a", "leases"),
process.platform === "win32" ? "junction" : "dir");
assert.equal((await qualify(f, head)).qualified, false);
});

Expand Down
19 changes: 13 additions & 6 deletions tests/control_plane_ts/effect_runtime_snapshot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,19 @@ test("local snapshot accepts exact private bytes and rejects altered or unsafe r
/snapshot unavailable or invalid/);
await assert.rejects(readPrivateJsonSnapshot({...ref, byte_count: bytes.length - 1}),
/snapshot unavailable or invalid/);
await chmod(path, 0o644);
await assert.rejects(readPrivateJsonSnapshot(ref), /snapshot unavailable or invalid/);
const link = join(directory, "link.json");
await symlink(path, link);
await assert.rejects(readPrivateJsonSnapshot({...ref, path: link}),
/snapshot unavailable or invalid/);
// Windows has no POSIX mode denial: the private-mode rejection is only
// observable where process.getuid exists.
if (process.getuid) {
await chmod(path, 0o644);
await assert.rejects(readPrivateJsonSnapshot(ref), /snapshot unavailable or invalid/);
}
// File symlink creation needs Developer Mode or admin on Windows.
if (process.platform !== "win32") {
const link = join(directory, "link.json");
await symlink(path, link);
await assert.rejects(readPrivateJsonSnapshot({...ref, path: link}),
/snapshot unavailable or invalid/);
}
} finally {
await rm(directory, {recursive: true, force: true});
}
Expand Down
2 changes: 1 addition & 1 deletion tests/control_plane_ts/goal_acceptance_authority.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const goalA = {goal_id: goal, goal_instance_id: "ginst_aaaaaaaaaaaaaaaaaaaaaaaaa
const goalB = {goal_id: goal, goal_instance_id: "ginst_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"};
test("documented owner configuration satisfies the canonical acceptance contract", async () => {
const reference = await readFile(new URL("../../docs/reference/goal-acceptance-observations.md", import.meta.url), "utf8");
const example = reference.match(/```json\n([\s\S]*?)\n```/);
const example = reference.match(/```json\r?\n([\s\S]*?)\r?\n```/);
assert.ok(example, "the operation guide must include a runnable configuration");
assert.doesNotThrow(() => normalizeGoalAcceptanceDocument(JSON.parse(example[1])));
});
Expand Down
18 changes: 11 additions & 7 deletions tests/control_plane_ts/quota_void_commit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -724,13 +724,17 @@ test("receipt repair rejects paths outside the run directory and symbolic links"
...receipt.value,
status: "prepared",
}, null, 2)}\n`, "utf8");
await unlink(String(written.payload.json_path));
await symlink(outsidePath, String(written.payload.json_path));
await assert.rejects(
() => evaluateQuotaVoidCommit(params),
/JSON artifact must not be a symbolic link/,
);
await assert.rejects(() => readFile(outsidePath), /ENOENT/);
// File symlink creation needs Developer Mode or admin on Windows; the
// escaped-path rejection above still covers the outside-run-directory rule.
if (process.platform !== "win32") {
await unlink(String(written.payload.json_path));
await symlink(outsidePath, String(written.payload.json_path));
await assert.rejects(
() => evaluateQuotaVoidCommit(params),
/JSON artifact must not be a symbolic link/,
);
await assert.rejects(() => readFile(outsidePath), /ENOENT/);
}
});

test("legacy slot coercion truncates numeric strings and clamps both slot floors", async (t) => {
Expand Down
4 changes: 4 additions & 0 deletions tests/control_plane_ts/shadow_entry_delivery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ for (const field of ["resolution", "partition_projection", "partition_digest", "

for (const changed of ["prepared", "marker", "symlink", "stale_lineage"] as const) {
test(`changed ${changed} is rejected without a candidate commit`, async t => {
if (changed === "symlink" && process.platform === "win32") {
t.skip("file symlink creation needs Windows host privileges");
return;
}
const f = await fixture(t);
const request = await pendingEntry(f, 1, {handoff_mode: "hard_lease", todos: [todo()]});
const r = selection(request), before = await f.store.loadAuthority();
Expand Down
7 changes: 5 additions & 2 deletions tests/control_plane_ts/sqlite_backup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ test("snapshot rejects existing destinations and source aliases without modifyin
await assert.rejects(snapshotSqliteDatabase(source, target), /EEXIST/);
assert.equal(await readFile(target, "utf8"), "keep existing");
await assert.rejects(snapshotSqliteDatabase(source, source), /distinct absolute/);
const alias = join(directory, "alias"); await symlink(source, alias);
await assert.rejects(snapshotSqliteDatabase(source, alias), /EEXIST/);
// File symlink creation needs Developer Mode or admin on Windows.
if (process.platform !== "win32") {
const alias = join(directory, "alias"); await symlink(source, alias);
await assert.rejects(snapshotSqliteDatabase(source, alias), /EEXIST/);
}
assert.deepEqual(await readFile(source), original);
});

Expand Down
Loading