Files
quixos-protocol/test/execution-world.test.ts
T

311 lines
15 KiB
TypeScript
Raw Normal View History

import assert from "node:assert/strict";
import { test } from "node:test";
import { createHash } from "node:crypto";
import { loadReaderWorkspace } from "./reader-fixture.js";
import {
compileExecutionPlan,
checkExecutionWorld,
checkedWorldDigest,
implementationDigest,
hexDigest,
parsePackageArtifacts,
artifactPath,
type PackageArtifacts,
type ExecutionPlan,
type ArtifactImplementation,
} from "../src/execution-world/index.js";
import { buildArtifactFixture as buildFixture } from "./artifact-fixture.js";
const resign = (implementation: ArtifactImplementation) => {
const { contentDigest, ...body } = implementation;
implementation.contentDigest = implementationDigest(body);
};
test("reader execution plan closes selector storage and traversed interface dependencies", async () => {
const workspace = await loadReaderWorkspace();
const plan = compileExecutionPlan(workspace);
assert.equal(plan.digest, compileExecutionPlan(structuredClone(workspace)).digest);
assert.equal(plan.definition.owners.length, 5);
const excerpt =
plan.definition.operations.find((o) => o.operationId === "highlight:excerpt:get") ??
plan.definition.operations.find((o) => o.binding.kind === "package" && o.binding.exportId === "reader:excerpt")!;
assert.ok(excerpt.dependencies.some((d) => d.kind === "state" && d.slot === "slot:highlight:range"));
assert.ok(
excerpt.dependencies.some(
(d) => d.kind === "edge" && d.edge === "edge:document-highlights" && d.projection === "projection:document",
),
);
const calls = excerpt.dependencies.filter((d) => d.kind === "operation");
assert.equal(calls.length, 2);
for (const call of calls) {
assert.equal(call.via?.projectionId, "projection:document");
const target = plan.definition.operations.find((o) => o.key === call.operation)!;
assert.ok(target.dependencies.some((d) => d.kind === "state" && d.slot.startsWith("slot:document:")));
}
const admission = plan.definition.queries.find((q) => q.query.checked.declaration.displayName === "ReplicaInputs")!;
assert.ok(admission.admittedOperations.includes(excerpt.key));
assert.equal(plan.definition.profiles[0]!.profile, "camino-automerge-3.4.1-structured-v1");
const factory = plan.definition.operations.find(
(o) => o.binding.kind === "package" && o.binding.exportId === "reader:create-document",
)!;
assert.equal(factory.scope, "class");
assert.ok(
factory.binding.kind === "package" && factory.binding.dependencies.some((d) => d.binding.kind === "creation"),
);
assert.ok(plan.definition.owners.some((o) => Array.isArray(o.initialization) && o.initialization.length > 0));
});
test("artifact closure checks bytes, exact source/schema, ABI, exports and target coverage", async () => {
const plan = compileExecutionPlan(await loadReaderWorkspace());
const fixture = buildFixture(plan);
const world = await checkExecutionWorld(plan, [fixture.manifest], fixture.read);
assert.equal(world.artifacts.length, 3);
assert.equal(
checkedWorldDigest(world),
checkedWorldDigest(await checkExecutionWorld(plan, [structuredClone(fixture.manifest)], fixture.read)),
);
const negative = async (change: (manifest: PackageArtifacts) => void, pattern: RegExp) => {
const manifest = structuredClone(fixture.manifest);
change(manifest);
await assert.rejects(checkExecutionWorld(plan, [manifest], fixture.read), pattern);
};
await negative((m) => {
m.bindingDigest = "0".repeat(64);
}, /Substituted binding schema/);
await negative((m) => {
m.sourceDigest = "0".repeat(64);
}, /source revision/);
await negative((m) => {
(m.versions as unknown as Record<string, string>).value = "v2";
}, /Incompatible runtime codecs/);
await negative((m) => {
m.implementations = m.implementations.filter((i) => i.target !== "browser");
}, /Missing browser implementation/);
await negative((m) => {
m.implementations = m.implementations.filter((i) => i.compatibility !== "quixos-service-v1");
}, /Missing service fallback/);
await negative((m) => {
m.implementations[0]!.exports.push("wrong-export");
resign(m.implementations[0]!);
}, /Unknown export/);
await negative((m) => {
m.implementations[0]!.files[0]!.digest = "0".repeat(64);
resign(m.implementations[0]!);
}, /Artifact bytes/);
await negative((m) => {
m.implementations[0]!.exports.pop();
}, /metadata digest mismatch/);
await assert.rejects(
checkExecutionWorld(plan, [fixture.manifest], async () => new Uint8Array([1])),
/Artifact bytes/,
);
for (const path of ["/tmp/code", "../code", "a/../b", "a//b", "a\\b", "a%2fb", "a?query"])
assert.throws(() => artifactPath(path), /normalized relative/);
const changed = structuredClone(plan);
changed.definition.versions.value = "wrong" as typeof changed.definition.versions.value;
await assert.rejects(
checkExecutionWorld(changed, [fixture.manifest], fixture.read),
/Unsupported plan codec versions/,
);
});
test("artifact identity changes when code or registry changes without hashing its own digest", async () => {
const plan = compileExecutionPlan(await loadReaderWorkspace()),
fixture = buildFixture(plan);
const before = checkedWorldDigest(await checkExecutionWorld(plan, [fixture.manifest], fixture.read));
const manifest = structuredClone(fixture.manifest);
manifest.implementations[2]!.registryExport = "anotherRegistry";
resign(manifest.implementations[2]!);
const after = checkedWorldDigest(await checkExecutionWorld(plan, [manifest], fixture.read));
assert.notEqual(before, after);
assert.equal(parsePackageArtifacts(manifest).implementations[2]!.registryExport, "anotherRegistry");
assert.equal(hexDigest(plan.definition), plan.digest);
});
test("transactions cannot derive their membership from an admitted presentation query", async () => {
const workspace = await loadReaderWorkspace(),
pkg = workspace.packageImports[0]!;
const query = pkg.queries!.find((q) => q.placement?.kind === "local")!;
const entry = pkg.exports.find((e) => e.id === "reader:add-highlight")!;
const portId = "test:query-port" as (typeof entry.dependencyPorts)[number]["id"];
entry.dependencyPorts.push({
id: portId,
displayName: "visible",
requirement: { kind: "query", packageRevisionId: pkg.revisionId, queryId: query.id },
});
const bound = workspace.conformances
.flatMap((c) => c.operationBindings)
.find((o) => o.binding.kind === "package" && o.binding.exportId === entry.id)!.binding;
assert.equal(bound.kind, "package");
if (bound.kind !== "package") return;
bound.dependencies.push({
portId,
binding: { kind: "query", packageRevisionId: pkg.revisionId, queryId: query.id, scope: "object" },
});
assert.throws(() => compileExecutionPlan(workspace), /QUERY_IN_TRANSACTION.*test:query-port/);
});
test("port ABI carries only declared port actions, never caller-selected storage IDs", async () => {
const { checkPortInvocation } = await import("../src/execution-world/index.js");
const frame = {
abi: "quixos-transaction-ports-v1",
frame: "frame1",
invocation: "invoke1",
sequence: 1,
portId: "content",
action: { kind: "state", primitive: "read" },
input: { codec: "camino-value-v1", usage: "argument", value: null },
};
assert.deepEqual(checkPortInvocation(frame), frame);
assert.throws(() => checkPortInvocation({ ...frame, slotId: "private" }), /fields or ABI/);
assert.throws(
() => checkPortInvocation({ ...frame, action: { kind: "state", primitive: "read", slotId: "private" } }),
/Invalid port action/,
);
assert.throws(() => checkPortInvocation({ ...frame, sequence: NaN }), /sequence/);
assert.throws(() => checkPortInvocation({ ...frame, action: { kind: "creation", key: "" } }), /Invalid port action/);
});
test("local queries cannot silently expand the replica relationship traversal", async () => {
const workspace = await loadReaderWorkspace((name, text) =>
name === "queries/replica-inputs.graphql" ? "query ReplicaInputs { root { sourceRevision content } }" : text,
);
assert.throws(() => compileExecutionPlan(workspace), /REPLICA_TRAVERSAL_MISSING/);
});
test("local relationships require complete source candidates even when a filter initially matches", async () => {
for (const selection of ["highlights(first: 10)", 'highlights(all: 1000, where: {color: {eq: "yellow"}})']) {
const workspace = await loadReaderWorkspace((name, text) =>
name === "queries/replica-inputs.graphql" ? text.replace("highlights(all: 1000)", selection) : text,
);
assert.throws(() => compileExecutionPlan(workspace), /REPLICA_RELATION_INCOMPLETE/);
}
});
test("closed generic applications retain distinct identities and codec shapes", async () => {
const { compileCapabilityResourceSource, compileCapabilitySource } =
await import("../src/capability-language/index.js");
const source = { repository: "https://example.test/generic.git", commit: "a".repeat(40) };
const definition = compileCapabilityResourceSource(
`interface Cell<value V : storable> id "cell" revision "cell@1" {
value content id "value" : V { get id "get" execution snapshot targets [browser, server]; }
}`,
{ source },
);
assert.ok(definition.ok && definition.resource.kind === "interface", JSON.stringify(definition.diagnostics));
const compiled = compileCapabilitySource(
`workspace Demo id "ws" revision "ws@1" commit "${source.commit}" {
import interface Cell; atom Item id "item";
conform Item as Cell<string> id "text-owner" { private state Text id "text-slot" on Item : string policy register; bind content.get to state Text.read; }
conform Item as Cell<int64> id "number-owner" { private state Number id "number-slot" on Item : int64 policy register; bind content.get to state Number.read; }
}`,
"workspace.qx",
{ interfaces: new Map([["Cell", definition.resource.revision]]) },
);
assert.ok(compiled.ok, JSON.stringify(compiled.diagnostics));
const plan = compileExecutionPlan(compiled.workspace);
assert.equal(plan.definition.operations.length, 2);
assert.notEqual(
plan.definition.operations[0]!.interfaceRevisionId,
plan.definition.operations[1]!.interfaceRevisionId,
);
assert.deepEqual(
new Set(plan.definition.operations.map((o) => (o.output.kind === "scalar" ? o.output.name : null))),
new Set(["string", "int64"]),
);
assert.ok(plan.definition.bindingSchema.interfaces.every((i) => i.application));
});
test("unbound portable exports cannot claim an unsupported transport codec", async () => {
const workspace = await loadReaderWorkspace();
workspace.packageImports[0]!.exports.find((e) => e.id === "reader:validate-range")!.outputType = {
kind: "message",
descriptorId: "opaque-message",
};
assert.throws(() => compileExecutionPlan(workspace), /UNSUPPORTED_PORTABLE_CODEC.*reader:validate-range/);
});
test("query dependencies propagate target requirements through selected getters", async () => {
const workspace = await loadReaderWorkspace(),
pkg = workspace.packageImports[0]!;
const query = pkg.queries!.find((q) => q.displayName === "HighlightList")!;
const entry = pkg.exports.find((e) => e.id === "reader:excerpt")!;
const portId = "test:selector-query" as (typeof entry.dependencyPorts)[number]["id"];
entry.dependencyPorts.push({
id: portId,
displayName: "visible",
requirement: { kind: "query", packageRevisionId: pkg.revisionId, queryId: query.id },
});
const bound = workspace.conformances
.flatMap((c) => c.operationBindings)
.find((o) => o.binding.kind === "package" && o.binding.exportId === entry.id)!.binding;
assert.equal(bound.kind, "package");
if (bound.kind !== "package") return;
bound.dependencies.push({
portId,
binding: { kind: "query", packageRevisionId: pkg.revisionId, queryId: query.id, scope: "workspace" },
});
compileExecutionPlan(workspace);
const field = workspace.interfaceImports
.find((i) => i.displayName === "HighlightData")!
.members.find((m) => m.displayName === "color")!;
field.operations.find((o) => o.displayName === "get")!.execution = { kind: "snapshot", targets: ["browser"] };
assert.throws(() => compileExecutionPlan(workspace), /MISSING_EXECUTION_TARGET.*test:selector-query.*server/);
});
test("implementation selection is explicit, target checked and independent of manifest order", async () => {
const { selectArtifactImplementation } = await import("../src/execution-world/index.js");
const plan = compileExecutionPlan(await loadReaderWorkspace());
const { manifest, read } = buildFixture(plan);
const selection = {
target: "browser",
compatibility: "quixos-js-module-v1" as const,
exports: [manifest.implementations[0]!.exports[0]!],
};
assert.equal(selectArtifactImplementation(manifest, selection).id, "browser");
const alternative = structuredClone(manifest.implementations.find((i) => i.id === "browser")!);
alternative.id = "browser-alternative";
resign(alternative);
manifest.implementations.unshift(alternative);
await checkExecutionWorld(plan, [manifest], read);
assert.throws(() => selectArtifactImplementation(manifest, selection), /AMBIGUOUS_IMPLEMENTATION/);
assert.equal(selectArtifactImplementation(manifest, { ...selection, id: alternative.id }).id, alternative.id);
manifest.implementations.reverse();
assert.equal(selectArtifactImplementation(manifest, { ...selection, id: alternative.id }).id, alternative.id);
for (const invalid of [
{ ...selection, id: "missing" },
{ ...selection, id: "service" },
{ ...selection, id: alternative.id, target: "arduino" },
{ ...selection, id: alternative.id, exports: ["not-exported"] },
])
assert.throws(() => selectArtifactImplementation(manifest, invalid), /IMPLEMENTATION_UNAVAILABLE/);
assert.equal(
selectArtifactImplementation(manifest, { ...selection, target: "server", compatibility: "quixos-service-v1" }).id,
"service",
);
});
test("execution planning rejects unsupported grouping before installing the query", async () => {
const workspace = await loadReaderWorkspace((name, text) =>
name === "queries/reader-screen.graphql"
? text.replace("aggregate { count }", "groups(by: {color: true}, first: 10) { entries { aggregate { count } } }")
: text,
);
assert.throws(() => compileExecutionPlan(workspace), /QUERY_OPERATOR_UNSUPPORTED.*grouping/);
});
test("a count-only local query still requires complete relationship admission", async () => {
for (const source of [
"query ReplicaInputs { root { sourceRevision } }",
"query ReplicaInputs { root { highlights(first: 1) { entries { node { color } } } } }",
]) {
const workspace = await loadReaderWorkspace((name, text) => {
if (name === "queries/replica-inputs.graphql") return source;
if (name === "queries/reader-screen.graphql")
return "query ReaderScreen { root { _camino { relations { highlights { aggregate { count } } } } } }";
return text;
});
assert.throws(() => compileExecutionPlan(workspace), /REPLICA_TRAVERSAL_MISSING|REPLICA_RELATION_INCOMPLETE/);
}
});