test: strengthen evidence runtime handoff coverage
This commit is contained in:
@@ -141,7 +141,7 @@ async function fixture(workspaceSource = filesystemWorkspace) {
|
||||
};
|
||||
for (const [name, value] of Object.entries(environment)) vi.stubEnv(name, value);
|
||||
vi.stubEnv("THT_HOME", join(root, "home"));
|
||||
return { root, dataRoot, secretRoot, registry, registryConfig, revision };
|
||||
return { root, source, dataRoot, secretRoot, registry, registryConfig, revision };
|
||||
}
|
||||
|
||||
function runnerFor(f: Awaited<ReturnType<typeof fixture>>): ThtRunner {
|
||||
@@ -234,6 +234,52 @@ test("separate runtime leases hand off byte-identical revision Evidence configs
|
||||
}
|
||||
});
|
||||
|
||||
test("real Evidence-content-only commit changes runtime identity and root with identical descriptor YAML", async () => {
|
||||
const f = await fixture();
|
||||
const runner = runnerFor(f);
|
||||
const first = runner.acquireWorkspaceRuntime(f.revision.snapshotPath);
|
||||
const descriptorBefore = readFileSync(f.revision.snapshotPath, "utf8");
|
||||
writeFileSync(
|
||||
join(f.source, "workspace-content", "psd-clinical", "evidence", "guide.md"),
|
||||
"# Content-only revision two\n",
|
||||
);
|
||||
await git(f.source, ["add", "workspace-content/psd-clinical/evidence/guide.md"]);
|
||||
await git(f.source, ["commit", "-m", "Update Evidence content only"]);
|
||||
await git(f.source, ["push", "origin", "main"]);
|
||||
await f.registry.pull();
|
||||
const current = (await f.registry.list())[0];
|
||||
const second = runner.acquireWorkspaceRuntime(current.snapshotPath);
|
||||
|
||||
try {
|
||||
expect(current.commit).not.toBe(f.revision.commit);
|
||||
expect(current.blob).toBe(f.revision.blob);
|
||||
expect(readFileSync(current.snapshotPath, "utf8")).toBe(descriptorBefore);
|
||||
const firstRendered = parse(readFileSync(first.path, "utf8"));
|
||||
const secondRendered = parse(readFileSync(second.path, "utf8"));
|
||||
expect(firstRendered.runtime_identity.workspace_revision).toBe(f.revision.commit);
|
||||
expect(secondRendered.runtime_identity.workspace_revision).toBe(current.commit);
|
||||
expect(secondRendered.evidence.sources[0].root).toBe(join(
|
||||
f.registryConfig.root,
|
||||
"snapshots",
|
||||
current.commit,
|
||||
"workspace-content",
|
||||
"psd-clinical",
|
||||
"evidence",
|
||||
));
|
||||
expect(secondRendered.evidence.sources[0].root).not.toBe(firstRendered.evidence.sources[0].root);
|
||||
|
||||
for (const lease of [first, second]) {
|
||||
await expect(runFile(thtBin, ["config", "check", "-c", lease.path], {
|
||||
cwd: harnessDir,
|
||||
env: { ...process.env, THT_HOME: join(f.root, "home") },
|
||||
})).resolves.toBeDefined();
|
||||
}
|
||||
} finally {
|
||||
first.release();
|
||||
second.release();
|
||||
}
|
||||
});
|
||||
|
||||
test("signed HTTP Evidence resolves its file binding and config check never captures its contents", async () => {
|
||||
const f = await fixture(evidenceWorkspace(` type: http
|
||||
uris: [https://evidence.example.test/guide.md]
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { expect, test } from "vitest";
|
||||
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, expect, test } from "vitest";
|
||||
import { parse } from "yaml";
|
||||
import {
|
||||
renderRuntimeConfig,
|
||||
@@ -300,6 +303,20 @@ test("renders REST bindings through the legacy rest sections without secret valu
|
||||
expect(yaml).not.toContain("\n api_key: ");
|
||||
});
|
||||
|
||||
const evidenceSecretRoots: string[] = [];
|
||||
|
||||
afterEach(() => {
|
||||
evidenceSecretRoots.splice(0).forEach((root) => rmSync(root, { recursive: true, force: true }));
|
||||
});
|
||||
|
||||
function evidenceSecretFile(name: string, contents: string): string {
|
||||
const root = mkdtempSync(join(tmpdir(), "tht-renderer-evidence-secret-"));
|
||||
evidenceSecretRoots.push(root);
|
||||
const path = join(root, name);
|
||||
writeFileSync(path, contents, { mode: 0o600 });
|
||||
return path;
|
||||
}
|
||||
|
||||
function evidenceWorkspace(source: Record<string, unknown>, policy?: Record<string, unknown>) {
|
||||
return parseWorkspaceYaml(`${canonicalEvidenceWorkspace}\nevidence:\n source: ${JSON.stringify(source)}${
|
||||
policy === undefined ? "" : `\n policy: ${JSON.stringify(policy)}`
|
||||
@@ -410,7 +427,8 @@ test("renders public HTTP Evidence with exact fractional-second timeouts and eve
|
||||
});
|
||||
|
||||
test("renders signed HTTP Evidence as provenance plus a validated file path only", () => {
|
||||
const signedFile = "/run/secrets/evidence-signed-urls.json";
|
||||
const canary = "SIGNED-URL-CANARY-CONTENT";
|
||||
const signedFile = evidenceSecretFile("evidence-signed-urls.json", canary);
|
||||
const yaml = evidenceRender({
|
||||
type: "http",
|
||||
uris: [
|
||||
@@ -437,7 +455,7 @@ test("renders signed HTTP Evidence as provenance plus a validated file path only
|
||||
allow_private_hosts: false,
|
||||
max_cache_bytes: 67_108_864,
|
||||
}]);
|
||||
expect(yaml).not.toContain("SIGNED-URL-CANARY-CONTENT");
|
||||
expect(yaml).not.toContain(canary);
|
||||
});
|
||||
|
||||
test("renders ambient S3 Evidence without credential keys", () => {
|
||||
@@ -465,7 +483,13 @@ test("renders ambient S3 Evidence without credential keys", () => {
|
||||
});
|
||||
|
||||
test("renders static S3 Evidence with endpoint policy, limits, and file paths but no contents", () => {
|
||||
const yaml = evidenceRender({
|
||||
const accessCanary = "ACCESS-CANARY-CONTENT";
|
||||
const secretCanary = "SECRET-CANARY-CONTENT";
|
||||
const tokenCanary = "TOKEN-CANARY-CONTENT";
|
||||
const accessFile = evidenceSecretFile("evidence-access", accessCanary);
|
||||
const secretFile = evidenceSecretFile("evidence-secret", secretCanary);
|
||||
const tokenFile = evidenceSecretFile("evidence-token", tokenCanary);
|
||||
const source = {
|
||||
type: "s3",
|
||||
uri: "s3://clinical-evidence/published/",
|
||||
credentials: "static_files",
|
||||
@@ -478,14 +502,13 @@ test("renders static S3 Evidence with endpoint policy, limits, and file paths bu
|
||||
max_objects: 33,
|
||||
max_pages: 4,
|
||||
page_size: 5,
|
||||
}, {
|
||||
missing: [],
|
||||
values: {
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_ACCESS_KEY_FILE: "/run/secrets/evidence-access",
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_SECRET_KEY_FILE: "/run/secrets/evidence-secret",
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_SESSION_TOKEN_FILE: "/run/secrets/evidence-token",
|
||||
},
|
||||
});
|
||||
};
|
||||
const values = {
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_ACCESS_KEY_FILE: accessFile,
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_SECRET_KEY_FILE: secretFile,
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_SESSION_TOKEN_FILE: tokenFile,
|
||||
};
|
||||
const yaml = evidenceRender(source, { missing: [], values });
|
||||
|
||||
expect(parse(yaml).evidence.sources).toEqual([{
|
||||
type: "s3",
|
||||
@@ -493,9 +516,9 @@ test("renders static S3 Evidence with endpoint policy, limits, and file paths bu
|
||||
prefix: "published/",
|
||||
endpoint_url: "http://minio.internal:9000/",
|
||||
region: "eu-central-1",
|
||||
access_key_file: "/run/secrets/evidence-access",
|
||||
secret_key_file: "/run/secrets/evidence-secret",
|
||||
session_token_file: "/run/secrets/evidence-token",
|
||||
access_key_file: accessFile,
|
||||
secret_key_file: secretFile,
|
||||
session_token_file: tokenFile,
|
||||
trusted_endpoint: true,
|
||||
allow_private_endpoint: true,
|
||||
allow_insecure_endpoint: true,
|
||||
@@ -504,9 +527,19 @@ test("renders static S3 Evidence with endpoint policy, limits, and file paths bu
|
||||
max_pages: 4,
|
||||
page_size: 5,
|
||||
}]);
|
||||
expect(yaml).not.toContain("ACCESS-CANARY-CONTENT");
|
||||
expect(yaml).not.toContain("SECRET-CANARY-CONTENT");
|
||||
expect(yaml).not.toContain("TOKEN-CANARY-CONTENT");
|
||||
expect(yaml).not.toContain(accessCanary);
|
||||
expect(yaml).not.toContain(secretCanary);
|
||||
expect(yaml).not.toContain(tokenCanary);
|
||||
|
||||
const withoutToken = parse(evidenceRender(source, {
|
||||
missing: [],
|
||||
values: {
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_ACCESS_KEY_FILE: accessFile,
|
||||
THT_WS_PSD_CLINICAL_EVIDENCE_SECRET_KEY_FILE: secretFile,
|
||||
},
|
||||
})).evidence.sources[0];
|
||||
expect(withoutToken).toMatchObject({ access_key_file: accessFile, secret_key_file: secretFile });
|
||||
expect(withoutToken).not.toHaveProperty("session_token_file");
|
||||
});
|
||||
|
||||
test("omits Evidence configuration and policy when the descriptor has no Evidence", () => {
|
||||
|
||||
Reference in New Issue
Block a user