73 lines
3.7 KiB
JavaScript
73 lines
3.7 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import createModule from "../../build-wasm/linuxcnc-sim-core.js";
|
|
import { fnv1a64 } from "./replay.mjs";
|
|
import { loadSimulationCase, toWorkerConfiguration } from "../workspace/sim-case-loader.mjs";
|
|
import { SimSession, CONTEXT_ID } from "./sim-session.mjs";
|
|
|
|
const CASE = "linuxcnc/configs/sim/axis/vismach/3axis-tutorial/3axis-tutorial.ini";
|
|
const fetchImpl = async (url) => {
|
|
try {
|
|
const body = await readFile(new URL(`../../${String(url).replace(/^\//, "")}`, import.meta.url));
|
|
return { ok: true, text: async () => body.toString("utf8") };
|
|
} catch {
|
|
return { ok: false, text: async () => "" };
|
|
}
|
|
};
|
|
const bundle = await loadSimulationCase({ path: CASE, fetchImpl });
|
|
const wasmBinary = await readFile(new URL("../../build-wasm/linuxcnc-sim-core.wasm", import.meta.url));
|
|
|
|
async function create(id) {
|
|
const core = await createModule({ wasmBinary });
|
|
const session = new SimSession(core, { sessionId: id });
|
|
const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: id };
|
|
let seq = 0;
|
|
const send = (kind, operationId, payload = {}) => session.accept({ ...base, kind, seq: ++seq, operation_id: operationId, payload });
|
|
send("HELLO", "hello");
|
|
send("SESSION_ATTACH", "attach");
|
|
const loaded = send("LOAD_WORKSPACE", "workspace", { root_path: "/workspace", configuration: toWorkerConfiguration(bundle) });
|
|
assert.equal(loaded.payload.task_authority, "wasm_task_canonical");
|
|
send("HOME", "home", { axis: "z" });
|
|
send("PROGRAM_LOAD", "program", { path: "canonical-state.ngc", source: "G21 G90\nG0 X0 Y0 Z0\nG1 X20 Y10 F120\nG1 Z-1 F60\nM2\n" });
|
|
send("PROGRAM_RUN", "run");
|
|
return { session, send };
|
|
}
|
|
|
|
const continuous = await create("wasm-canonical-checkpoint");
|
|
continuous.send("SIM_STEP", "step-a", { cycles: 3 });
|
|
const checkpoint = continuous.send("CHECKPOINT", "checkpoint").payload.checkpoint;
|
|
assert.equal(checkpoint.state.task_authority, "wasm_task_canonical");
|
|
assert.equal(checkpoint.state.wasm_home_limit.schema, "sim_home_limit_state.v1");
|
|
continuous.send("SIM_STEP", "step-b", { cycles: 4 });
|
|
const continuousState = continuous.session.workspacePackageState();
|
|
|
|
const recovered = await create("wasm-canonical-checkpoint");
|
|
const recovery = recovered.session.restoreCheckpoint(checkpoint, continuous.session.timeline.export(), (operation) => operation);
|
|
assert.equal(recovery.status, "recovered");
|
|
const recoveredState = recovered.session.workspacePackageState();
|
|
assert.equal(fnv1a64(continuousState), fnv1a64(recoveredState));
|
|
assert.equal(recoveredState.task.state_hash, continuousState.task.state_hash);
|
|
assert.equal(recoveredState.wasm_home_limit.state_hash, continuousState.wasm_home_limit.state_hash);
|
|
|
|
const trace = continuous.session.exportTrace();
|
|
const traced = await create("wasm-canonical-checkpoint");
|
|
assert.equal(traced.session.importTrace(trace).status, "verified");
|
|
assert.equal(traced.session.workspacePackageState().wasm_home_limit.state_hash, continuousState.wasm_home_limit.state_hash);
|
|
|
|
const damaged = structuredClone(checkpoint);
|
|
damaged.state.wasm_home_limit.state_bytes = `${damaged.state.wasm_home_limit.state_bytes.startsWith("00") ? "ff" : "00"}${damaged.state.wasm_home_limit.state_bytes.slice(2)}`;
|
|
damaged.state_hash = fnv1a64(damaged.state);
|
|
assert.equal(recovered.session.restoreCheckpoint(damaged, null, (operation) => operation).status, "blocked");
|
|
|
|
console.log(JSON.stringify({
|
|
schema: "wasm-canonical-state-checkpoint-t4.v1",
|
|
status: "verified",
|
|
case: CASE,
|
|
checkpoint_hash: checkpoint.checkpoint_hash,
|
|
continuous_hash: fnv1a64(continuousState),
|
|
recovered_hash: fnv1a64(recoveredState),
|
|
endpoint_equal: fnv1a64(continuousState) === fnv1a64(recoveredState),
|
|
trace_import: "verified",
|
|
damaged_home_state: "blocked",
|
|
}));
|