swactor/crates/wasm/test.mjs

159 lines
4.4 KiB
JavaScript
Raw Normal View History

import {
WasmRuntime,
WasmAddr,
spawn_counter,
spawn_relay,
} from "./pkg/wasm.js";
let passed = 0;
let failed = 0;
function assert(cond, msg) {
if (!cond) {
console.error(` FAIL: ${msg}`);
failed++;
} else {
passed++;
}
}
function assertEq(a, b, msg) {
const aj = JSON.stringify(a);
const bj = JSON.stringify(b);
if (aj !== bj) {
console.error(` FAIL: ${msg} (got ${aj}, expected ${bj})`);
failed++;
} else {
passed++;
}
}
function drainInbox(inbox) {
const results = [];
let v;
while ((v = inbox.try_recv()) !== undefined) results.push(v);
return results;
}
// ---- accumulator ----------------------------------------------------------
{
console.log("test: accumulator processes messages via WasmAddr");
const rt = new WasmRuntime();
const inbox = rt.new_inbox_u32();
const c = spawn_counter(rt, inbox.addr());
rt.send_u32(c, 1);
rt.send_u32(c, 2);
rt.send_u32(c, 10);
rt.tick();
assertEq(drainInbox(inbox), [1, 3, 13], "running totals");
inbox.free();
rt.free();
}
// ---- relay ----------------------------------------------------------------
{
console.log("test: relay forwards to counter");
const rt = new WasmRuntime();
const inbox = rt.new_inbox_u32();
const c = spawn_counter(rt, inbox.addr());
const r = spawn_relay(rt, c);
rt.send_u32(r, 5);
rt.send_u32(r, 7);
// tick 1: relay receives and forwards (same worker → pending_local)
// tick 2: counter receives forwarded messages
rt.tick();
rt.tick();
assertEq(drainInbox(inbox), [5, 12], "relayed totals");
inbox.free();
rt.free();
}
// ---- multiple counters ----------------------------------------------------
{
console.log("test: multiple independent counters");
const rt = new WasmRuntime();
const inbox = rt.new_inbox_u32();
const a = spawn_counter(rt, inbox.addr());
const b = spawn_counter(rt, inbox.addr());
rt.send_u32(a, 10);
rt.send_u32(b, 100);
rt.tick();
const results = drainInbox(inbox);
assert(
results.includes(10) && results.includes(100) && results.length === 2,
"both counters report"
);
inbox.free();
rt.free();
}
// ---- actor_count ----------------------------------------------------------
{
console.log("test: actor_count tracks spawns");
const rt = new WasmRuntime();
const inbox = rt.new_inbox_u32();
spawn_counter(rt, inbox.addr());
spawn_counter(rt, inbox.addr());
spawn_counter(rt, inbox.addr());
rt.tick(); // drain spawn queue
assertEq(rt.actor_count(), 3, "three actors");
inbox.free();
rt.free();
}
// ---- WasmAddr toString ----------------------------------------------------
{
console.log("test: WasmAddr has string representation");
const rt = new WasmRuntime();
const inbox = rt.new_inbox_u32();
const addr = spawn_counter(rt, inbox.addr());
const s = addr.toString();
// no_random generates deterministic addresses — just check it's a non-empty hex string
assert(typeof s === "string" && s.length > 0, "addr toString is non-empty string");
inbox.free();
rt.free();
}
// ---- stop_actor -----------------------------------------------------------
{
console.log("test: stop_actor removes actor");
const rt = new WasmRuntime();
const inbox = rt.new_inbox_u32();
const c = spawn_counter(rt, inbox.addr());
rt.tick(); // drain spawn
assertEq(rt.actor_count(), 1, "one actor before stop");
rt.stop_actor(c);
rt.tick(); // process stop + cleanup
assertEq(rt.actor_count(), 0, "zero actors after stop");
inbox.free();
rt.free();
}
// ---- bytes inbox ----------------------------------------------------------
{
console.log("test: byte inbox receives Uint8Array");
const rt = new WasmRuntime();
const inbox = rt.new_inbox_bytes();
// Send bytes directly (no actor — just to the inbox address)
rt.send_bytes(inbox.addr(), new Uint8Array([1, 2, 3]));
rt.tick();
const result = inbox.try_recv();
assert(result instanceof Uint8Array, "result is Uint8Array");
assertEq(Array.from(result), [1, 2, 3], "bytes match");
inbox.free();
rt.free();
}
// ---- uptime ---------------------------------------------------------------
{
console.log("test: uptime_ms returns a number");
const rt = new WasmRuntime();
const uptime = rt.uptime_ms();
assert(typeof uptime === "number" && uptime >= 0, "uptime is non-negative number");
rt.free();
}
// ---- results --------------------------------------------------------------
console.log(`\n${passed} passed, ${failed} failed`);
if (failed > 0) process.exit(1);