feat: guarded Worker Restore from shared Web actions (T-701)
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
parseRuntimeCleanupExecution,
|
||||
parseRuntimeCleanupPlan,
|
||||
parseRuntimeWorkerLifecycleResult,
|
||||
parseWorkerRestoreResponse,
|
||||
parseWorkerRetentionResponse,
|
||||
} from "../src/lib/workspace/api/runtime-workers.ts";
|
||||
|
||||
@@ -19,7 +20,9 @@ function assertThrows(operation: () => unknown, expected: string): void {
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
if (message.includes(expected)) return;
|
||||
throw new Error(`expected error containing ${expected}, received ${message}`);
|
||||
throw new Error(
|
||||
`expected error containing ${expected}, received ${message}`,
|
||||
);
|
||||
}
|
||||
throw new Error("expected operation to throw");
|
||||
}
|
||||
@@ -67,7 +70,10 @@ function plan() {
|
||||
|
||||
Deno.test("Runtime cleanup parsers accept the generated exact response shapes", () => {
|
||||
const parsedPlan = parseRuntimeCleanupPlan(plan());
|
||||
assert(parsedPlan.workers[0]?.runtime_worker_id === "worker-1", "worker candidate missing");
|
||||
assert(
|
||||
parsedPlan.workers[0]?.runtime_worker_id === "worker-1",
|
||||
"worker candidate missing",
|
||||
);
|
||||
|
||||
const execution = parseRuntimeCleanupExecution({
|
||||
workspace_id: "workspace-a",
|
||||
@@ -82,7 +88,10 @@ Deno.test("Runtime cleanup parsers accept the generated exact response shapes",
|
||||
plan_after: plan(),
|
||||
diagnostics: [],
|
||||
});
|
||||
assert(execution.results[0]?.status === "deleted", "execution result missing");
|
||||
assert(
|
||||
execution.results[0]?.status === "deleted",
|
||||
"execution result missing",
|
||||
);
|
||||
|
||||
const lifecycle = parseRuntimeWorkerLifecycleResult({
|
||||
state: "accepted",
|
||||
@@ -108,15 +117,182 @@ Deno.test("Runtime cleanup parsers reject unknown fields and unsafe values", ()
|
||||
"not part of the wire contract",
|
||||
);
|
||||
assertThrows(
|
||||
() => parseRuntimeCleanupPlan({ ...plan(), workers: new Array(1_001).fill(plan().workers[0]) }),
|
||||
() =>
|
||||
parseRuntimeCleanupPlan({
|
||||
...plan(),
|
||||
workers: new Array(1_001).fill(plan().workers[0]),
|
||||
}),
|
||||
"at most 1000",
|
||||
);
|
||||
assertThrows(
|
||||
() => parseRuntimeCleanupPlan({ ...plan(), workers: [{ ...plan().workers[0], estimated_reclaim_bytes: Number.MAX_SAFE_INTEGER + 1 }] }),
|
||||
() =>
|
||||
parseRuntimeCleanupPlan({
|
||||
...plan(),
|
||||
workers: [{
|
||||
...plan().workers[0],
|
||||
estimated_reclaim_bytes: Number.MAX_SAFE_INTEGER + 1,
|
||||
}],
|
||||
}),
|
||||
"safe integer",
|
||||
);
|
||||
assertThrows(
|
||||
() => parseRuntimeWorkerLifecycleResult({ state: "future", runtime_id: "runtime-a", worker_id: "worker-1", diagnostics: [] }),
|
||||
() =>
|
||||
parseRuntimeWorkerLifecycleResult({
|
||||
state: "future",
|
||||
runtime_id: "runtime-a",
|
||||
worker_id: "worker-1",
|
||||
diagnostics: [],
|
||||
}),
|
||||
"unknown value",
|
||||
);
|
||||
});
|
||||
|
||||
function restore(state = "accepted", worker?: unknown) {
|
||||
return {
|
||||
workspace_id: "workspace-a",
|
||||
runtime_id: "runtime-a",
|
||||
worker_id: "worker-1",
|
||||
result: { state, diagnostics: [], worker },
|
||||
};
|
||||
}
|
||||
function restoredWorker() {
|
||||
return {
|
||||
runtime_id: "runtime-a",
|
||||
worker_id: "worker-1",
|
||||
resource_key: "W-1",
|
||||
host_id: "runtime-a",
|
||||
label: "Worker",
|
||||
availability: "observed",
|
||||
state: "idle",
|
||||
workspace: {
|
||||
visibility: "workspace",
|
||||
identity: "registered",
|
||||
workspace_id: "workspace-a",
|
||||
},
|
||||
implementation: { kind: "runtime", display_hint: "Runtime" },
|
||||
restore_observation_token: "generation-b",
|
||||
};
|
||||
}
|
||||
Deno.test("Restore parser preserves all four states and optional Workspace summary", () => {
|
||||
for (
|
||||
const state of [
|
||||
"accepted",
|
||||
"rejected",
|
||||
"rolled_back",
|
||||
"reconciliation_required",
|
||||
]
|
||||
) {
|
||||
assert(
|
||||
parseWorkerRestoreResponse(restore(state)).result.state === state,
|
||||
"state lost",
|
||||
);
|
||||
assert(
|
||||
parseWorkerRestoreResponse(restore(state, null)).result.worker === null,
|
||||
"null lost",
|
||||
);
|
||||
}
|
||||
const parsed = parseWorkerRestoreResponse(
|
||||
restore("accepted", restoredWorker()),
|
||||
);
|
||||
assert(
|
||||
parsed.result.worker?.resource_key === "W-1",
|
||||
"Workspace summary lost",
|
||||
);
|
||||
assert(parsed.result.worker?.state === "idle", "must not force running");
|
||||
});
|
||||
Deno.test("Restore parser bounds diagnostics, validates wrapper/summary identity and rejects malformed results", () => {
|
||||
assertThrows(() => parseWorkerRestoreResponse(restore("accepted", {
|
||||
...restoredWorker(), restore_observation_token: "😀".repeat(65),
|
||||
})), "256 UTF-8 byte limit");
|
||||
assertThrows(
|
||||
() => parseWorkerRestoreResponse(restore("future")),
|
||||
"unknown value",
|
||||
);
|
||||
assertThrows(
|
||||
() => parseWorkerRestoreResponse({ ...restore(), runtime_id: null }),
|
||||
"must be a string",
|
||||
);
|
||||
assertThrows(
|
||||
() => parseWorkerRestoreResponse({ ...restore(), extra: true }),
|
||||
"not part of the wire contract",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerRestoreResponse({
|
||||
...restore(),
|
||||
result: {
|
||||
state: "accepted",
|
||||
diagnostics: new Array(65).fill({
|
||||
code: "e",
|
||||
severity: "error",
|
||||
message: "e",
|
||||
}),
|
||||
},
|
||||
}),
|
||||
"at most 64",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerRestoreResponse({
|
||||
...restore(),
|
||||
result: {
|
||||
state: "rejected",
|
||||
diagnostics: [{
|
||||
code: "e",
|
||||
severity: "error",
|
||||
message: "x".repeat(4097),
|
||||
}],
|
||||
},
|
||||
}),
|
||||
"4096",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerRestoreResponse({
|
||||
...restore(),
|
||||
result: {
|
||||
state: "rejected",
|
||||
diagnostics: [{ code: "e", severity: "invalid", message: "e" }],
|
||||
},
|
||||
}),
|
||||
"unknown value",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerRestoreResponse(
|
||||
restore("accepted", { ...restoredWorker(), worker_id: "other" }),
|
||||
),
|
||||
"identity",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerRestoreResponse(
|
||||
restore("accepted", {
|
||||
...restoredWorker(),
|
||||
workspace: {
|
||||
visibility: "workspace",
|
||||
identity: "registered",
|
||||
workspace_id: "other",
|
||||
},
|
||||
}),
|
||||
),
|
||||
"identity",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerRestoreResponse(
|
||||
restore("accepted", { worker_id: "worker-1", state: "idle" }),
|
||||
),
|
||||
"availability",
|
||||
);
|
||||
assertThrows(
|
||||
() =>
|
||||
parseWorkerRestoreResponse({
|
||||
state: "accepted",
|
||||
runtime_id: "runtime-a",
|
||||
worker_id: "worker-1",
|
||||
diagnostics: [],
|
||||
}),
|
||||
"wire contract",
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user