fix: exercise catalog metadata mismatch on a pending slot
This commit is contained in:
@@ -403,7 +403,13 @@ async function initializeGit(ctx) {
|
|||||||
await git(ctx, ["clone", join(ctx.run.root, "remote.git"), author], { cwd: ctx.run.root });
|
await git(ctx, ["clone", join(ctx.run.root, "remote.git"), author], { cwd: ctx.run.root });
|
||||||
await git(ctx, ["config", "user.name", "P1 Fixture Curator"], { cwd: author });
|
await git(ctx, ["config", "user.name", "P1 Fixture Curator"], { cwd: author });
|
||||||
await git(ctx, ["config", "user.email", "p1-curator@example.invalid"], { cwd: author });
|
await git(ctx, ["config", "user.email", "p1-curator@example.invalid"], { cwd: author });
|
||||||
const catalogBytes = `${JSON.stringify(catalog(ctx.descriptors), null, 2)}\n`;
|
const catalogBytes = `${JSON.stringify({
|
||||||
|
schema_version: 1,
|
||||||
|
workspaces: [
|
||||||
|
...catalog(ctx.descriptors).workspaces,
|
||||||
|
{ id: "p11-pending", name: "P1.1 pending", description: "Catalog-only slot awaiting bootstrap" },
|
||||||
|
],
|
||||||
|
}, null, 2)}\n`;
|
||||||
await atomicWrite(join(author, "thoth-workspaces.yaml"), catalogBytes, 0o644);
|
await atomicWrite(join(author, "thoth-workspaces.yaml"), catalogBytes, 0o644);
|
||||||
const evidenceRoot = join(author, "p11-filesystem", "evidence");
|
const evidenceRoot = join(author, "p11-filesystem", "evidence");
|
||||||
await mkdir(join(evidenceRoot, "domain"), { recursive: true });
|
await mkdir(join(evidenceRoot, "domain"), { recursive: true });
|
||||||
@@ -583,7 +589,7 @@ async function productionChecks(ctx) {
|
|||||||
const status = await request(ctx, "registry-status", "GET", "/workspace-registry/status");
|
const status = await request(ctx, "registry-status", "GET", "/workspace-registry/status");
|
||||||
assert(status.status === 200 && status.body.head === ctx.bootstrapCommit, "status head mismatch");
|
assert(status.status === 200 && status.body.head === ctx.bootstrapCommit, "status head mismatch");
|
||||||
const listed = await request(ctx, "workspace-list-initial", "GET", "/workspaces");
|
const listed = await request(ctx, "workspace-list-initial", "GET", "/workspaces");
|
||||||
assert(listed.status === 200 && listed.body.length === 3, "catalog listing failed");
|
assert(listed.status === 200 && listed.body.length === 4, "catalog listing failed");
|
||||||
assert(listed.body.every((entry) => entry.configurationState === "configuration_required"), "catalog entries were not configuration_required");
|
assert(listed.body.every((entry) => entry.configurationState === "configuration_required"), "catalog entries were not configuration_required");
|
||||||
ctx.baseCommit = status.body.head;
|
ctx.baseCommit = status.body.head;
|
||||||
return await check("catalog_only_listing", { head: status.body.head, ids: listed.body.map((entry) => entry.id), allConfigurationRequired: true });
|
return await check("catalog_only_listing", { head: status.body.head, ids: listed.body.map((entry) => entry.id), allConfigurationRequired: true });
|
||||||
@@ -601,8 +607,9 @@ async function productionChecks(ctx) {
|
|||||||
}
|
}
|
||||||
ctx.publishHead = base;
|
ctx.publishHead = base;
|
||||||
const listed = await request(ctx, "workspace-list-ready", "GET", "/workspaces");
|
const listed = await request(ctx, "workspace-list-ready", "GET", "/workspaces");
|
||||||
assert(listed.body.every((entry) => entry.configurationState === "ready"), "bootstrap did not activate all entries");
|
assert(listed.body.filter((entry) => entry.configurationState === "ready").length === 3, "bootstrap did not activate all published entries");
|
||||||
return await check("bootstrap_create_once", { head: base, readyIds: listed.body.map((entry) => entry.id) });
|
assert(listed.body.find((entry) => entry.id === "p11-pending")?.configurationState === "configuration_required", "pending slot was not left unconfigured");
|
||||||
|
return await check("bootstrap_create_once", { head: base, readyIds: listed.body.filter((entry) => entry.configurationState === "ready").map((entry) => entry.id) });
|
||||||
} },
|
} },
|
||||||
{ id: "api_curator_boundary", run: async () => {
|
{ id: "api_curator_boundary", run: async () => {
|
||||||
const author = join(ctx.run.root, "author");
|
const author = join(ctx.run.root, "author");
|
||||||
@@ -740,8 +747,10 @@ async function productionChecks(ctx) {
|
|||||||
unknown.workspace.id = "p11-unknown";
|
unknown.workspace.id = "p11-unknown";
|
||||||
const unknownPublish = await request(ctx, "unknown-catalog-id", "POST", "/workspaces/publish", { action: "create", workspace: unknown, baseCommit: baseline.head });
|
const unknownPublish = await request(ctx, "unknown-catalog-id", "POST", "/workspaces/publish", { action: "create", workspace: unknown, baseCommit: baseline.head });
|
||||||
safeErrorEnvelope(unknownPublish, "workspace_invalid", 400);
|
safeErrorEnvelope(unknownPublish, "workspace_invalid", 400);
|
||||||
const mismatch = structuredClone(ctx.descriptors[1]);
|
const mismatch = structuredClone(ctx.descriptors[0]);
|
||||||
mismatch.workspace.name = "Mismatched name";
|
mismatch.workspace.id = "p11-pending";
|
||||||
|
mismatch.workspace.name = "Mismatched pending name";
|
||||||
|
mismatch.semantic_index.vector_store.collection = "p11-pending";
|
||||||
const mismatchPublish = await request(ctx, "catalog-metadata-mismatch", "POST", "/workspaces/publish", { action: "create", workspace: mismatch, baseCommit: baseline.head });
|
const mismatchPublish = await request(ctx, "catalog-metadata-mismatch", "POST", "/workspaces/publish", { action: "create", workspace: mismatch, baseCommit: baseline.head });
|
||||||
safeErrorEnvelope(mismatchPublish, "workspace_invalid", 400);
|
safeErrorEnvelope(mismatchPublish, "workspace_invalid", 400);
|
||||||
const after = await registryState(ctx);
|
const after = await registryState(ctx);
|
||||||
|
|||||||
Reference in New Issue
Block a user