import { createServer, Socket } from "node:net"; import { createInterface } from "node:readline"; import { TestContext } from "node:test"; import { stringify } from "lossless-json"; import { ActorSnapshot } from "../src/protocol"; export const REF = "abcdefghijklmnopqrstu"; export function actor(): ActorSnapshot { return { actor_ref: REF, mailbox_id: 18446744073709551615n, implementation_id: "implementation:test", incarnation: 1n, state: { type: "record", data: { minimum: { type: "integer", data: -9223372036854775808n }, maximum: { type: "integer", data: 9223372036854775807n }, reference: { type: "actor_ref", data: REF }, text: { type: "string", data: `@${REF} "雪"` }, list: { type: "list", data: [{ type: "null" }, { type: "bool", data: true }] }, }, }, status: { status: "paused" }, execution: { vm_steps: 20n, instruction_pointer: 12n, call_depth: 1n }, queued: [{ type: "bool", data: false }], reserved: { type: "null" }, }; } export function json(value: unknown): string { const result = stringify(value); if (result === undefined) throw new Error("Cannot encode test fixture"); return result; } export interface TestRequest { version: number; request_id: string; command: { operation: string; parameters?: { actor_ref: string } }; } export function response(request: TestRequest, reply: unknown): string { return json({ version: 3, request_id: request.request_id, result: { Ok: reply } }) + "\n"; } export async function fakeImage( t: TestContext, handle: (request: TestRequest, socket: Socket) => void, ): Promise { const sockets = new Set(); const server = createServer((socket) => { sockets.add(socket); socket.on("close", () => sockets.delete(socket)); socket.on("error", () => { // Transport-failure tests intentionally close a socket while the fixture is writing. }); const lines = createInterface({ input: socket }); lines.on("line", (line) => handle(JSON.parse(line), socket)); }); await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve)); t.after(async () => { for (const socket of sockets) socket.destroy(); await new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve())), ); }); const address = server.address(); if (!address || typeof address === "string") throw new Error("Missing test listener"); return `127.0.0.1:${address.port}`; }