Files
linuxcncWebWASM/web/worker/test_hal_runtime.mjs

64 lines
3.8 KiB
JavaScript

import assert from "node:assert/strict";
import { HalRuntime, parseCompSource } from "./hal-runtime.mjs";
import { SimSession, CONTEXT_ID } from "./sim-session.mjs";
const parsed = parseCompSource("component and2;\npin in bit in0;\npin in bit in1;\npin out bit out;\nfunction _ nofp;\n");
assert.equal(parsed.status, "verified");
assert.equal(parseCompSource("pin in bit missing;").code, "hal_component_missing");
assert.equal(parseCompSource("component unknown;\n").code, "hal_component_unsupported");
assert.equal(parseCompSource("component abs_s64;\npin in s64 in;\n").code, "hal_type_unsupported");
const hal = new HalRuntime();
assert.equal(hal.configure({ threads: [{ name: "servo-thread", period_ticks: 1 }], components: [
{ instance: "gate", type: "and2", thread: "servo-thread" },
{ instance: "constant", type: "constant", thread: "servo-thread" },
{ instance: "xy", type: "corexy_by_hal", thread: "servo-thread" },
] }).status, "verified");
assert.equal(hal.setPin("gate.in0", 1).status, "verified");
assert.equal(hal.setPin("gate.in1", 1).status, "verified");
assert.equal(hal.setParam("constant.value", 3.5).status, "verified");
assert.equal(hal.setPin("xy.j0-motor-pos-cmd", 6).status, "verified");
assert.equal(hal.setPin("xy.j1-motor-pos-cmd", 2).status, "verified");
assert.equal(hal.setPin("xy.alpha-fb", 4).status, "verified");
assert.equal(hal.setPin("xy.beta-fb", 1).status, "verified");
assert.equal(hal.step(1).status, "verified");
assert.equal(hal.getPin("gate.out").value, 1);
assert.equal(hal.getPin("constant.out").value, 3.5);
assert.equal(hal.getPin("xy.alpha-cmd").value, 4);
assert.equal(hal.getPin("xy.j0-motor-pos-fb").value, 5);
assert.equal(hal.state.components.find((item) => item.instance === "xy").calls, 1);
assert.equal(hal.setFailure("gate", true).status, "verified");
assert.equal(hal.step(2).code, "hal_function_failure");
assert.equal(hal.state.tick, 1);
const saved = hal.export();
const restored = new HalRuntime();
assert.deepEqual(restored.restore(saved), saved);
assert.equal(hal.setPin("constant.out", Number.NaN).code, "hal_value_invalid");
const batch = new HalRuntime();
assert.equal(batch.configure({ components: [{ module: "constant", instances: ["c0", "c1"] }] }).status, "verified");
assert.equal(batch.state.components.length, 2);
const core = {
_sim_protocol_reset() {},
_sim_protocol_accept() { return 0; },
_sim_create() { return 0; },
_sim_load_workspace() { return 0; },
_sim_step() { return 0; },
_sim_protocol_set_tick() { return 0; },
};
const session = new SimSession(core, { sessionId: "hal-state" });
const base = { schema_version: 1, context_id: CONTEXT_ID, session_id: "hal-state" };
const send = (kind, seq, operation_id, payload = {}) => session.accept({ ...base, kind, seq, operation_id, payload });
send("HELLO", 1);
send("SESSION_ATTACH", 2, "attach");
send("LOAD_WORKSPACE", 3, "workspace", { root_path: "/workspace" });
assert.equal(send("HAL_COMMAND", 4, "hal-thread", { action: "thread", name: "servo-thread", period_ticks: 1 }).payload.hal_runtime.threads["servo-thread"].period_ticks, 1);
assert.equal(send("HAL_COMMAND", 5, "hal-component", { action: "component", instance: "gate", type: "and2", thread: "servo-thread" }).payload.hal_runtime.components.length, 1);
send("HAL_SET", 6, "hal-in0", { target: "pin", name: "gate.in0", value: 1 });
send("HAL_SET", 7, "hal-in1", { target: "pin", name: "gate.in1", value: 1 });
const stepped = send("SIM_STEP", 8, "hal-step", { cycles: 1 });
assert.equal(stepped.payload.hal_runtime.pins["gate.out"].value, 1);
const checkpoint = send("CHECKPOINT", 9, "hal-checkpoint").payload.checkpoint;
assert.equal(checkpoint.state.hal_runtime.schema, "sim_hal_runtime.v1");
console.log(`hal_runtime=passed tick=${hal.state.tick} components=${hal.state.components.length} worker_tick=${stepped.payload.hal_runtime.tick}`);