72 lines · 3.1 KB · TypeScript
RawDownload
import { readFileSync } from "node:fs";import { fileURLToPath } from "node:url";import { describe, expect, test } from "vitest"; // Regression guard for #11 and #59.//// Both issues were caused by the removed `@secure-exec/v8` runtime.js// (a stdout/socket-path handshake plus a TDZ bug) together with a host-side// `node:v8.deserialize()` decode of `run()` results. That host-side V8// serialization made result decoding sensitive to the host Node version /// V8 engine build (#11) and crashed on constrained hosts such as Lambda// cold-starts (#59).//// The current architecture runs guest code in a process-isolated sidecar// binary and decodes `run()` results as plain JSON read back over the VFS// (`packages/core/src/node-runtime.ts`), with NO host-side `node:v8`. These// tests lock in that root-cause fix at the source level (so they run in a// plain Node-host CI without booting a sidecar) and verify the structured// JSON-over-VFS decode behaves correctly for nested values. const nodeRuntimeSource = readFileSync(	fileURLToPath(new URL("../src/node-runtime.ts", import.meta.url)),	"utf8",); describe("node-runtime run() result transport (#11, #59)", () => {	test("the host transport never uses node:v8 deserialize", () => {		// The whole point of the fix: no host-side V8 serialization in the		// run()/decode path, which is what made #11 host-engine-sensitive and		// crashed Lambda cold-starts in #59.		expect(nodeRuntimeSource).not.toContain("node:v8");		expect(nodeRuntimeSource).not.toContain("v8.deserialize");		expect(nodeRuntimeSource).not.toContain("deserialize(");	}); 	test("run() decodes structured results as JSON read back over the VFS", () => {		// The decode must go through a VFS result file plus JSON.parse over a		// TextDecoder, not a host-engine-specific binary deserializer.		expect(nodeRuntimeSource).toContain("this.kernel.readFile(resultPath)");		expect(nodeRuntimeSource).toMatch(			/JSON\.parse\(\s*new TextDecoder\(\)\.decode\(bytes\)/,		);		// And the guest writes its return value as JSON to that same VFS file.		expect(nodeRuntimeSource).toContain(			"JSON.stringify(value === undefined ? null : value)",		);	}); 	test("structured nested values round-trip through the JSON-over-VFS path", () => {		// Model the exact host/guest decode used by run(): the guest writes		// JSON.stringify(value) into a VFS file; the host reads the bytes back		// and decodes them with JSON.parse(new TextDecoder().decode(bytes)).		// A nested object with numbers must survive intact, with no dependency		// on host V8 structured-clone serialization.		const value = {			ok: true,			count: 3,			ratio: 1.5,			nested: { items: [1, 2, 3], label: "x", deep: { n: 42 } },		}; 		// Guest side: __return() writes JSON.stringify(value) to the result file.		const guestBytes = new TextEncoder().encode(JSON.stringify(value)); 		// Host side: node-runtime reads the file bytes and JSON.parses them.		const decoded = JSON.parse(new TextDecoder().decode(guestBytes)); 		expect(decoded).toEqual(value);		expect(decoded.nested.items).toEqual([1, 2, 3]);		expect(decoded.nested.deep.n).toBe(42);	});});