mirror of
https://github.com/hanzoai/vm.git
synced 2026-10-01 00:47:56 +00:00
Crates keep their history: vm (lib, was shuru-vm), hanzo-vm (CLI package and binary, was shuru-cli), vm-guest, vm-proto, vm-proxy, vm-sdk, vm-store, vm-darwin, vm-linux; all at 0.1.0, Apache-2.0, hanzoai/vm. Config is vm.json, data lives in ~/.hanzo/vm (HANZO_VM_HOME), env vars are HANZO_VM_*, the guest runs as /usr/bin/vm-guest, and assets download from hanzoai/vm releases. The TypeScript SDK is @hanzo/vm. NOTICE credits shuru as the origin. prepare-rootfs.sh builds the image natively on arm64 Linux with mke2fs -d and re-execs in Docker only on macOS. Includes rustfmt over the tree and fixes for clippy 1.98 lints. Co-authored-by: Hanzo Dev <[email protected]>
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
/**
|
|
* Integration tests that run against the real hanzo-vm binary + VM.
|
|
*
|
|
* Prerequisites:
|
|
* 1. cargo build -p hanzo-vm
|
|
* 2. codesign --entitlements vm.entitlements --force -s - target/debug/hanzo-vm
|
|
* 3. hanzo-vm init
|
|
*
|
|
* Run: bun test test/integration/
|
|
*/
|
|
|
|
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
|
import { existsSync, unlinkSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
import { Sandbox } from "../../src/sandbox";
|
|
|
|
const REPO_ROOT = resolve(import.meta.dir, "../../../..");
|
|
const HANZO_VM_BIN = resolve(REPO_ROOT, "target/debug/hanzo-vm");
|
|
|
|
const canRun = existsSync(HANZO_VM_BIN);
|
|
|
|
describe.if(canRun)("sandbox lifecycle", () => {
|
|
let sb: Sandbox;
|
|
|
|
beforeAll(async () => {
|
|
sb = await Sandbox.start({ bin: HANZO_VM_BIN });
|
|
}, 60_000);
|
|
|
|
afterAll(async () => {
|
|
await sb?.stop();
|
|
}, 15_000);
|
|
|
|
test("exec echo", async () => {
|
|
const result = await sb.exec("echo hello");
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.stdout.trim()).toBe("hello");
|
|
expect(result.stderr).toBe("");
|
|
}, 30_000);
|
|
|
|
test("exec captures exit code", async () => {
|
|
const result = await sb.exec("exit 42");
|
|
expect(result.exitCode).toBe(42);
|
|
}, 30_000);
|
|
|
|
test("exec captures stderr", async () => {
|
|
const result = await sb.exec("echo err >&2");
|
|
expect(result.exitCode).toBe(0);
|
|
expect(result.stderr.trim()).toBe("err");
|
|
}, 30_000);
|
|
|
|
test("writeFile and readFile roundtrip", async () => {
|
|
const content = "hello from integration test\nline 2\n";
|
|
await sb.writeFile("/tmp/sdk-test.txt", content);
|
|
const read = await sb.readFile("/tmp/sdk-test.txt");
|
|
expect(new TextDecoder().decode(read)).toBe(content);
|
|
}, 30_000);
|
|
|
|
test("multiple sequential execs", async () => {
|
|
await sb.exec("echo a > /tmp/seq.txt");
|
|
await sb.exec("echo b >> /tmp/seq.txt");
|
|
const result = await sb.exec("cat /tmp/seq.txt");
|
|
expect(result.stdout).toBe("a\nb\n");
|
|
}, 30_000);
|
|
|
|
test("checkpoint creates disk snapshot", async () => {
|
|
const cpPath = resolve(
|
|
process.env.HOME ?? "/tmp",
|
|
".hanzo/vm/checkpoints/sdk-integration-test.ext4",
|
|
);
|
|
|
|
try {
|
|
unlinkSync(cpPath);
|
|
} catch {
|
|
// no leftover
|
|
}
|
|
|
|
await sb.exec("echo checkpoint-data > /tmp/cp-test.txt");
|
|
await sb.checkpoint("sdk-integration-test");
|
|
expect(existsSync(cpPath)).toBe(true);
|
|
|
|
try {
|
|
unlinkSync(cpPath);
|
|
} catch {
|
|
// cleanup
|
|
}
|
|
}, 30_000);
|
|
});
|
|
|
|
describe.if(!canRun)("sandbox lifecycle (skipped)", () => {
|
|
test("hanzo-vm binary not found", () => {
|
|
console.log(
|
|
"Build with: cargo build -p hanzo-vm && codesign --entitlements vm.entitlements --force -s - target/debug/hanzo-vm",
|
|
);
|
|
});
|
|
});
|