Files
rea/scripts/verify-wasm-interface-comparison.mjs
T

212 lines
6.9 KiB
JavaScript

import assert from "node:assert/strict";
import { execFile } from "node:child_process";
import { mkdtemp, readFile, writeFile, rm } from "node:fs/promises";
import { join, resolve, isAbsolute } from "node:path";
import { tmpdir } from "node:os";
import { promisify } from "node:util";
import { Client } from "@modelcontextprotocol/client";
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
import { parseEvidence } from "../dist/domain/evidence.js";
import { requireMcpOutput } from "./lib/mcp-verifier-results.mjs";
const execute = promisify(execFile);
const bin = process.env.REA_WABT_BIN_DIRECTORY;
if (!isAbsolute(bin ?? ""))
throw new Error("Supply absolute REA_WABT_BIN_DIRECTORY with WABT 1.0.42");
const root = await mkdtemp(join(tmpdir(), "rea-wasm-interface-real-"));
const cli = resolve("scripts/rea.mjs");
const environment = { ...process.env };
const command = async (file, args) =>
(
await execute(file, args, {
env: environment,
cwd: root,
timeout: 120000,
maxBuffer: 64 * 1024 * 1024,
})
).stdout;
const client = new Client({
name: "wasm-interface-real-verifier",
version: "1",
});
const transport = new StdioClientTransport({
command: process.execPath,
args: [cli, "mcp"],
env: environment,
stderr: "pipe",
});
const source = (parameter) =>
`(module (type (func (param ${parameter}) (result i64))) (import "env" "f" (func (type 0))) (table 1 3 funcref) (memory 1 2) (global (mut i64) (i64.const 0)) (tag (param i32)) (export "run\\22\\ef\\bb\\bf" (func 0)) (export "table" (table 0)) (export "memory" (memory 0)) (export "global" (global 0)) (export "tag" (tag 0)))`;
const assemble = async (name, wat) => {
await writeFile(join(root, `${name}.wat`), wat);
const path = join(root, `${name}.wasm`);
await command(join(bin, "wat2wasm"), [
"--enable-all",
`${name}.wat`,
"-o",
path,
]);
return path;
};
const inspect = async (path) => {
const result = await client.callTool({
name: "inspect_wasm_artifact",
arguments: { path },
});
assert.notEqual(result.isError, true, JSON.stringify(result));
assert.notEqual(result.structuredContent, undefined);
return parseEvidence(requireMcpOutput(result, "inspect_wasm_artifact"));
};
const compare = async (left, right, scope = "both") => {
const input = {
left: { kind: "retained-evidence", evidence_id: left.evidence_id },
right: { kind: "retained-evidence", evidence_id: right.evidence_id },
scope,
};
const reply = await client.callTool({
name: "compare_wasm_interfaces",
arguments: input,
});
assert.notEqual(reply.isError, true, JSON.stringify(reply));
assert.notEqual(reply.structuredContent, undefined);
const mcp = parseEvidence(requireMcpOutput(reply, "compare_wasm_interfaces"));
const file = join(root, "comparison.json");
await writeFile(file, JSON.stringify({ left, right, scope }));
const local = parseEvidence(
JSON.parse(
await command(process.execPath, [
cli,
"compare-wasm-interfaces",
file,
"--json",
]),
),
);
assert.deepEqual(local, mcp);
return mcp.normalized_result;
};
try {
assert.equal(
(await command(join(bin, "wat2wasm"), ["--version"])).trim(),
"1.0.42",
);
await client.connect(transport);
const path = await assemble("baseline", source("i32"));
const original = await readFile(path);
assert.equal(original[8], 1);