Files
rea/tests/boundary/filesystem/referenceSourceFailureDetails.test.ts
T
morluto 53e7fadbd0 fix(reference)!: retain source and metadata cleanup owners
Require a caller-owned artifact resource scope for source traversal and Git metadata reads. Preserve cancellation, filesystem reasons, partial entries and bytes, and cleanup observations through import and the CLI. Transfer exact failed file owners at regular-file admission and close boundaries, including multiple failures encountered by Git reference resolution.

Validation: 169 focused tests passed across 26 files; two Windows-only cases skipped. Build, typecheck, lint, formatting, knip, architecture guards, discovery and docs checks passed.

BREAKING CHANGE: Reference source readers and imports require an ArtifactResourceScope. VCS metadata reads return Result, and CLI import failures include observed details and partial evidence.
2026-10-11 06:10:10 +08:00

136 lines
4.7 KiB
TypeScript

import { execFile } from "node:child_process";
import { chmod, mkdir, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { promisify } from "node:util";
import { describe, expect, it } from "vitest";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import {
importReferenceSource,
readReferenceSource,
} from "../../support/referenceSourceResourceScope.js";
const importTree = (root: string) =>
importReferenceSource({
root,
caller: "native-entry-failure-detail-test",
policy: { secretPatterns: [] },
});
const permissionChecksUnavailable =
process.platform === "win32" || process.getuid?.() === 0;
describe("reference import native entry failure details", () => {
it.skipIf(permissionChecksUnavailable)(
"classifies a root behind a blocked parent as an I/O failure",
async () => {
const directory = await createTestTempDirectory(
"rea-reference-root-permission-",
);
const parent = join(directory, "blocked-parent");
const root = join(parent, "source");
await mkdir(root, { recursive: true });
await chmod(parent, 0);
try {
const read = await readReferenceSource(root);
expect(read).toMatchObject({
ok: false,
error: {
tag: "reference-source-reader",
code: "io",
message: expect.stringContaining("EACCES"),
},
});
} finally {
await chmod(parent, 0o700);
}
},
);
it.skipIf(permissionChecksUnavailable)(
"retains the actual operating-system reason for an unreadable file",
async () => {
const root = await createTestTempDirectory("rea-import-native-detail-");
const path = join(root, "blocked.ts");
await writeFile(path, "export const value = 1;\n");
await chmod(path, 0);
try {
const read = await readReferenceSource(root);
if (!read.ok) throw new Error(read.error.message);
const failure = read.value.entries.find(
(entry) => entry.status === "failed" && entry.path === "blocked.ts",
);
if (failure?.status !== "failed")
throw new Error(
"Owned permission fixture did not produce a read failure",
);
expect(failure.message).toContain("EACCES");
const imported = await importTree(root);
if (!imported.ok) throw new Error(imported.error.message);
const entry = imported.value.entries.find(
(item) => item.path === failure.path,
);
expect(entry?.limitations.join(" ")).toContain(failure.message);
} finally {
await chmod(path, 0o600);
}
},
);
it.skipIf(process.platform === "win32")(
"retains the unsupported file-type reason without suggesting another OS",
async () => {
const root = await createTestTempDirectory("rea-import-native-fifo-");
await promisify(execFile)("mkfifo", [join(root, "events.pipe")], {
timeout: 2_000,
});
const imported = await importTree(root);
if (!imported.ok) throw new Error(imported.error.message);
const entry = imported.value.entries.find(
(item) => item.path === "events.pipe",
);
expect(entry?.limitations.join(" ")).toContain(
"Entry is not a regular file",
);
expect(entry?.limitations.join(" ")).not.toContain("supported system");
},
);
it.skipIf(process.platform === "win32")(
"excludes secret-patterned paths before failure projection",
async () => {
const root = await createTestTempDirectory("rea-import-native-secret-");
await promisify(execFile)("mkfifo", [join(root, "secret-events.pipe")], {
timeout: 2_000,
});
const imported = await importReferenceSource({
root,
caller: "native-entry-secret-detail-test",
policy: { secretPatterns: ["*secret*"] },
});
if (!imported.ok) throw new Error(imported.error.message);
expect(
imported.value.entries.find(
(item) => item.path === "secret-events.pipe",
),
).toBeUndefined();
expect(imported.value.exclusions).toContainEqual({
path: "secret-events.pipe",
reason: "configured-secret",
pattern: "*secret*",
});
},
);
it("preserves an ordinary readable source-file control", async () => {
const root = await createTestTempDirectory("rea-import-native-readable-");
await writeFile(join(root, "main.ts"), "export const value = 1;\n");
const imported = await importTree(root);
if (!imported.ok) throw new Error(imported.error.message);
expect(
imported.value.entries.find(({ path }) => path === "main.ts"),
).toMatchObject({ kind: "file", content_state: "hashed", limitations: [] });
});
});