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]>
118 lines
3.7 KiB
Rust
118 lines
3.7 KiB
Rust
//! Integration tests for mounts. Boots a real VM — requires codesigned binary.
|
|
//! All #[ignore]d by default. Run with:
|
|
//! HANZO_VM_BIN=target/debug/hanzo-vm cargo test -p hanzo-vm -- --ignored
|
|
|
|
use std::process::Command;
|
|
use tempfile::tempdir;
|
|
|
|
fn vm_bin() -> String {
|
|
std::env::var("HANZO_VM_BIN")
|
|
.expect("HANZO_VM_BIN not set — point it at a codesigned hanzo-vm binary (e.g. just build)")
|
|
}
|
|
|
|
fn run_in_vm(mount_spec: &str, guest_cmd: &str) -> std::process::Output {
|
|
Command::new(vm_bin())
|
|
.args(["run", "--mount", mount_spec, "--", "sh", "-c", guest_cmd])
|
|
.output()
|
|
.expect("failed to spawn hanzo-vm — is HANZO_VM_BIN correct?")
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn ro_mount_default_discards_guest_writes() {
|
|
let tmp = tempdir().unwrap();
|
|
let host_dir = tmp.path().to_str().unwrap();
|
|
let spec = format!("{}:/workspace", host_dir);
|
|
|
|
run_in_vm(&spec, "echo guest > /workspace/test.txt");
|
|
|
|
assert!(
|
|
!tmp.path().join("test.txt").exists(),
|
|
"default mount should not write to host"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn rw_mount_writes_land_on_host() {
|
|
let tmp = tempdir().unwrap();
|
|
let host_dir = tmp.path().to_str().unwrap();
|
|
let spec = format!("{}:/workspace:rw", host_dir);
|
|
|
|
run_in_vm(&spec, "echo guest > /workspace/test.txt");
|
|
|
|
let written = std::fs::read_to_string(tmp.path().join("test.txt"))
|
|
.expect("guest write should land on host");
|
|
assert_eq!(written.trim(), "guest");
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn rw_mount_guest_reads_host_files() {
|
|
let tmp = tempdir().unwrap();
|
|
std::fs::write(tmp.path().join("original.txt"), "host\n").unwrap();
|
|
let host_dir = tmp.path().to_str().unwrap();
|
|
let spec = format!("{}:/workspace:rw", host_dir);
|
|
|
|
run_in_vm(&spec, "cp /workspace/original.txt /workspace/copy.txt");
|
|
|
|
let copied = std::fs::read_to_string(tmp.path().join("copy.txt"))
|
|
.expect("guest should be able to read and copy host files");
|
|
assert_eq!(copied.trim(), "host");
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn explicit_ro_suffix_discards_guest_writes() {
|
|
let tmp = tempdir().unwrap();
|
|
let host_dir = tmp.path().to_str().unwrap();
|
|
let spec = format!("{}:/workspace:ro", host_dir);
|
|
|
|
run_in_vm(&spec, "echo ghost > /workspace/test.txt");
|
|
|
|
assert!(
|
|
!tmp.path().join("test.txt").exists(),
|
|
":ro mount should not write to host"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn rw_mount_creates_missing_guest_dirs() {
|
|
let tmp = tempdir().unwrap();
|
|
let host_dir = tmp.path().to_str().unwrap();
|
|
let spec = format!("{}:/mnt/does/not/exist:rw", host_dir);
|
|
|
|
let output = run_in_vm(&spec, "echo ok > /mnt/does/not/exist/proof.txt");
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"rw mount to non-existent guest path should succeed; stderr: {}",
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
let written = std::fs::read_to_string(tmp.path().join("proof.txt"))
|
|
.expect("write through rw mount at auto-created guest path should land on host");
|
|
assert_eq!(written.trim(), "ok");
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn ro_mount_creates_missing_guest_dirs() {
|
|
let tmp = tempdir().unwrap();
|
|
std::fs::write(tmp.path().join("hello.txt"), "from-host\n").unwrap();
|
|
let host_dir = tmp.path().to_str().unwrap();
|
|
let spec = format!("{}:/mnt/does/not/exist:ro", host_dir);
|
|
|
|
let output = run_in_vm(&spec, "cat /mnt/does/not/exist/hello.txt");
|
|
|
|
assert!(
|
|
output.status.success(),
|
|
"ro mount to non-existent guest path should succeed; stderr: {}",
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
assert!(
|
|
String::from_utf8_lossy(&output.stdout).contains("from-host"),
|
|
"should read host file through overlay at auto-created guest path"
|
|
);
|
|
}
|