// node --test tests/conformance.test.mjs (needs ../atlibs: `cargo wasm` and `cargo host`, or ATLIBS_BIN; no network) // com.fedfork.exec.iroh.connect through both CLIs' real iroh transports (js/index.js irohSession via // ATLIBS_TRANSPORTS, src/lib.rs Iroh), dumbpipe and ssh replaced by js/fake-bin on PATH: // the same bytes out of both. And com.fedfork.exec.http.fetch to an iroh:/// URL on both engines (runModule, // runModuleRust over the bridge), through js/index.js's fetcher, fake-bin's ssh + relay and http-stub.mjs. import assert from "node:assert/strict"; import { execFile, spawn } from "node:child_process"; import { mkdtemp, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { test } from "node:test"; import { promisify } from "node:util"; import { hostBin, runModuleRust } from "../../atlibs/rust/host/conformance.mjs"; import { runModule } from "../../atlibs/javascript/src/run-module/index.js"; import { irohFetch } from "../js/index.js"; // ROOT: the sibling atlibs checkout (its Node CLI, the echo module); HERE: this repo. const ROOT = new URL("../../atlibs/", import.meta.url); const HERE = new URL("../", import.meta.url); const exec = promisify(execFile); const FAKE = new URL("js/fake-bin", HERE).pathname; const CLI = new URL("javascript/src/server/cli.mjs", ROOT).pathname; const ECHO = new URL("target/wasm32-unknown-unknown/release/echo.wasm", ROOT).pathname; const MANIFEST = new URL("examples/rust/echo/module.json", ROOT).pathname; const T = "endpointabex5k47heqqkdykv2b27ydg75jjaxeucm2ej74nt34a7up6wqlkyaiaenuhi5dqom5c6l3von3tcljrfzzgk3dbpexg4mbonfzg62bonruw42zof4"; const envOf = (dir, extra) => ({ PATH: `${FAKE}:${process.env.PATH}`, HOME: process.env.HOME, ATLIBS_SERVER_STATE: join(dir, "state"), ATLIBS_TRANSPORTS: new URL("js/index.js", HERE).pathname, ...extra }); // One `session` run through both CLIs: their stdouts. async function both(env, input) { const args = ["run", ECHO, MANIFEST, "session", JSON.stringify(input)]; const rust = (await exec(hostBin(), args, { env, maxBuffer: 1 << 24 })).stdout; const js = (await exec(process.execPath, [CLI, ...args], { env, maxBuffer: 1 << 24 })).stdout; return { rust, js }; } test("iroh sessions: raw alpn, ssh command, ssh failure and a shell stream the same through both CLIs", async () => { const dir = await mkdtemp(join(tmpdir(), "atlibs-iroh-session-")); const key = join(dir, "iroh_ed25519"); await writeFile(key, "not a real key\n", { mode: 0o600 }); const env = envOf(dir, { ATLIBS_IROH_KEY: key }); const hostKeys = [{ type: "ssh-ed25519", publicKey: "AAAAC3Bare" }]; const cases = [ [{ ticket: `iroh://${T}`, alpn: "echo/1", send: "hello\n" }, { stdout: "ready\ngot hello\n", stderr: "", exitCode: 0, error: null }], [{ ticket: T, hostKeys, command: "uname -a" }, { stdout: "line 1\nline 2\n", stderr: "oops\n", exitCode: 3, error: null }], [{ ticket: T, hostKeys, command: "fail" }, { stdout: "", stderr: "Host key verification failed.\n", exitCode: null, error: "ssh failed: Host key verification failed." }], [{ ticket: T, hostKeys, send: "hello\nexit\n" }, { stdout: "$ hello\n$ ", stderr: "", exitCode: 0, error: null }], ]; for (const [input, expected] of cases) { const { rust, js } = await both(env, input); assert.deepEqual(JSON.parse(js).result, expected, JSON.stringify(input)); assert.equal(rust, js, JSON.stringify(input)); } }); // fix3-extra #1, 3a L2: dumbpipe's "using secret key " line never reaches a module (each spawn gets a // fresh IROH_SECRET), and a dumbpipe that floods stderr fails with a bounded tail, through both CLIs' sessions. test("iroh: no secret-key line reaches the module; a flood of stderr fails with its last 16 KiB", async () => { const env = envOf(await mkdtemp(join(tmpdir(), "atlibs-iroh-secret-"))); const result = async (input) => Object.values(await both(env, input)).map((out) => JSON.parse(out).result); for (const r of await result({ ticket: T, alpn: "secret/1" })) assert.deepEqual(r, { stdout: "ok\n", stderr: "", exitCode: 0, error: null }); const [rust, js] = await result({ ticket: T, alpn: "noisy/1" }); assert.equal(rust.error, js.error); assert.ok(rust.error.startsWith("dumbpipe exited 1: x") && rust.error.endsWith("last line"), rust.error.slice(0, 40)); assert.ok(rust.error.length <= "dumbpipe exited 1: ".length + 16384, `${rust.error.length}`); }); // review 4a M3: a one-shot exchange keeps at most 512 KiB of what the peer sends, kills it there and says // truncated, the same through both CLIs (the module gets it: under its 1 MiB input). test("iroh: a one-shot call that floods stdout is cut at 512 KiB and marked truncated through both CLIs", async () => { const env = envOf(await mkdtemp(join(tmpdir(), "atlibs-iroh-flood-"))); const args = ["run", ECHO, MANIFEST, "connect", JSON.stringify({ ticket: T, alpn: "flood/1" })]; const started = performance.now(); const rust = (await exec(hostBin(), args, { env, maxBuffer: 1 << 24 })).stdout; const js = (await exec(process.execPath, [CLI, ...args], { env, maxBuffer: 1 << 24 })).stdout; assert.ok(performance.now() - started < 10000, "killed at the cap, not run to its end"); assert.deepEqual(JSON.parse(js).result, { output: "x".repeat(1 << 19), truncated: true }); assert.equal(rust, js); }); test("http.fetch to iroh://///mcp through both engines' scheme dispatch, allowed as iroh://*", async () => { const dir = await mkdtemp(join(tmpdir(), "atlibs-iroh-http-")); const key = join(dir, "iroh_ed25519"); await writeFile(key, "not a real key\n", { mode: 0o600 }); const sock = join(dir, "shell.sock"); const stub = spawn(process.execPath, [join(FAKE, "http-stub.mjs"), sock], { stdio: ["ignore", "pipe", "inherit"] }); await new Promise((r) => stub.stdout.once("data", r)); const fetch = irohFetch({ key, spawn: (cmd, args, options) => spawn(join(FAKE, cmd), args, options) }); try { const ref = Buffer.from(JSON.stringify({ ticket: T, hostKeys: [{ type: "ssh-ed25519", publicKey: "AAAAC3Bare" }] })).toString("base64url"); const url = `iroh:///${ref}/${encodeURIComponent(sock)}/mcp`; const HTTP = "com.fedfork.exec.http.fetch"; // the handler stands in for the wasm export (atlibs run-module protocol.test.mjs's ctxOf) const handler = ({ event }) => (event.type === "start" ? { calls: [{ id: "post", nsid: HTTP, input: { method: "POST", url, headers: { "content-type": "application/json" }, body: '{"jsonrpc":"2.0","id":1,"method":"ping"}' } }] } : { result: event.ok ? event.output : event.error }); const ctx = { wasm: { run: async ({ input }) => handler(input) } }; const mod = { module: new Uint8Array(), calls: [HTTP], http: ["iroh://*"] }; for (const [name, run] of [["runModule", runModule], ["runModuleRust", runModuleRust]]) { const ran = await run(ctx, mod, "go", {}, async () => assert.fail("never the XRPC call"), { http: { "iroh://*": {} }, fetchers: { "iroh:": fetch } }); assert.equal(ran.error, undefined, name); assert.equal(ran.result.status, 200, `${name}: ${JSON.stringify(ran.result)}`); const seen = JSON.parse(ran.result.body); assert.deepEqual([seen.method, seen.url, seen.body, seen.headers.host], ["POST", "/mcp", '{"jsonrpc":"2.0","id":1,"method":"ping"}', "guest"], name); } } finally { fetch.close(); stub.kill(); } });