import assert from "node:assert/strict"; import { test } from "node:test"; import { bindParameters, exportOf, validateComposition } from "./index.js"; import { checkBound } from "./params.js"; const manifest = () => ({ instances: [{ name: "vm", module: "m", input: { cpus: { $param: "cpus" }, who: [{ $param: "who" }], key: { $host: "sshKey" }, token: { $param: "token" } } }], parameters: [ { key: "cpus", type: "integer", minimum: 1, maximum: 4, values: { default: 2 } }, { key: "who", values: { enum: ["a", "b"] } }, { key: "token", secret: true, required: true }, ], exports: [{ nsid: "computer.socialweb.machine.provision", instance: "vm", entry: "contract" }], }); test("parameters bind, validate and export as rust/host/src/params.rs does", () => { const m = manifest(); validateComposition(m); const host = { sshKey: "ssh-ed25519 K" }; const secrets = { token: "t" }; const bound = bindParameters(m, { secrets, host }); assert.deepEqual(bound.instances[0].input, { cpus: 2, who: [null], key: "ssh-ed25519 K", token: "t" }); checkBound(bound); assert.throws(() => checkBound(m), { message: "composition: parameter cpus is not bound" }); for (const [inputs, err] of [ [{ cpus: 9 }, "parameter cpus must be at most 4"], [{ cpus: "2" }, "parameter cpus must be of type integer"], [{ who: "c" }, 'parameter who must be one of ["a","b"]'], [{ token: "t" }, "parameter token is a secret: give it in secrets, not inputs"], [{ nope: 1 }, "parameter nope is not declared"], ]) { assert.throws(() => bindParameters(m, { inputs, secrets, host }), { message: `composition: ${err}` }); } assert.throws(() => bindParameters(m, { host }), { message: "composition: parameter token is required" }); assert.throws(() => bindParameters(m, { secrets }), { message: "composition: host value sshKey is not given by this host" }); assert.equal(exportOf(m, "computer.socialweb.machine.provision").entry, "contract"); const bad = manifest(); bad.parameters[0].values.default = 7; assert.throws(() => validateComposition(bad), { message: "composition: parameter cpus: 7 must be at most 4" }); });