Files
2026-07-13 13:13:07 +08:00

161 lines
6.1 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Packed Machine Tests
#
# Part of the smolvm test suite. Run with: ./tests/test_machine_packed.sh
#
source "$(dirname "$0")/common.sh"
init_smolvm
log_info "Pre-flight cleanup: killing orphan processes..."
kill_orphan_smolvm_processes
trap cleanup_machine EXIT
echo ""
echo "=========================================="
echo " Packed Machine Tests"
echo "=========================================="
echo ""
test_create_from_smolmachine() {
local vm_name="from-smolmachine-$$"
local tmpdir
tmpdir=$(mktemp -d)
local pack_output="$tmpdir/from-sm-pack"
# 1. Pack alpine into a .smolmachine
$SMOLVM pack create --image alpine:latest -o "$pack_output" --cpus 1 --mem 512 2>&1 || {
echo "SKIP: pack create failed"
return 0
}
[[ -f "$pack_output.smolmachine" ]] || { echo "FAIL: no sidecar"; return 1; }
# 2. Create a named machine from it
$SMOLVM machine create --name "$vm_name" --from "$pack_output.smolmachine" 2>&1 || return 1
# 3. Start the machine (should NOT pull — uses extracted layers)
$SMOLVM machine start --name "$vm_name" 2>&1 || {
echo "FAIL: start failed"
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$tmpdir"; return 1
}
# 4. Exec works
local exec_result
exec_result=$($SMOLVM machine exec --name "$vm_name" -- echo "from-sm-ok" 2>&1)
[[ "$exec_result" == *"from-sm-ok"* ]] || {
echo "FAIL: exec failed: $exec_result"
$SMOLVM machine stop --name "$vm_name" 2>/dev/null
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$tmpdir"; return 1
}
# 5. Persistence: write then read. Write to the container's persistent
# overlay (/sm-persist.txt), NOT /tmp — /tmp is a per-container tmpfs that is
# reset for each `machine exec` once the workload has exited, so it cannot
# test overlay persistence.
$SMOLVM machine exec --name "$vm_name" -- sh -c 'echo persist > /sm-persist.txt' 2>&1 || true
local read_result
read_result=$($SMOLVM machine exec --name "$vm_name" -- cat /sm-persist.txt 2>&1)
[[ "$read_result" == *"persist"* ]] || {
echo "FAIL: persistence failed"
$SMOLVM machine stop --name "$vm_name" 2>/dev/null
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$tmpdir"; return 1
}
# 6. Stop and restart — persistence survives
$SMOLVM machine stop --name "$vm_name" 2>&1 || true
$SMOLVM machine start --name "$vm_name" 2>&1 || {
echo "FAIL: restart failed"
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$tmpdir"; return 1
}
read_result=$($SMOLVM machine exec --name "$vm_name" -- cat /sm-persist.txt 2>&1)
[[ "$read_result" == *"persist"* ]] || {
echo "FAIL: persistence across restart failed"
$SMOLVM machine stop --name "$vm_name" 2>/dev/null
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$tmpdir"; return 1
}
# 7. Shows in ls
$SMOLVM machine ls --json 2>&1 | grep -q "$vm_name" || {
echo "FAIL: not in ls"
$SMOLVM machine stop --name "$vm_name" 2>/dev/null
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$tmpdir"; return 1
}
# 8. Cleanup
$SMOLVM machine stop --name "$vm_name" 2>/dev/null || true
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null || true
rm -rf "$tmpdir"
}
test_cp_preserves_state_on_packed_vm() {
local vm_name="cp-pack-$$"
local pack_dir
pack_dir=$(mktemp -d)
# Create source VM, write marker, pack it
$SMOLVM machine create --name "cp-pack-src-$$" --image alpine:latest --net 2>&1 || return 1
$SMOLVM machine start --name "cp-pack-src-$$" 2>&1 || {
$SMOLVM machine delete --name "cp-pack-src-$$" -f 2>/dev/null; return 1
}
$SMOLVM machine exec --name "cp-pack-src-$$" -- sh -c 'echo marker > /etc/pack-marker' 2>&1
$SMOLVM machine stop --name "cp-pack-src-$$" 2>&1
$SMOLVM pack create --from-vm "cp-pack-src-$$" -o "$pack_dir/packed" 2>&1 || {
$SMOLVM machine delete --name "cp-pack-src-$$" -f 2>/dev/null; rm -rf "$pack_dir"; return 1
}
$SMOLVM machine delete --name "cp-pack-src-$$" -f 2>/dev/null
# Create destination from pack, start, mutate via exec
$SMOLVM machine create --name "$vm_name" --from "$pack_dir/packed.smolmachine" --net 2>&1 || {
rm -rf "$pack_dir"; return 1
}
$SMOLVM machine start --name "$vm_name" 2>&1 || {
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$pack_dir"; return 1
}
$SMOLVM machine exec --name "$vm_name" -- adduser -D alice 2>&1
# Verify alice exists before cp
local before
before=$($SMOLVM machine exec --name "$vm_name" -- id alice 2>&1) || {
echo "alice not found before cp"; $SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$pack_dir"; return 1
}
# Run cp
echo "probe" > "$pack_dir/probe.txt"
$SMOLVM machine cp "$pack_dir/probe.txt" "$vm_name":/tmp/probe.txt 2>&1 || {
echo "cp failed"; $SMOLVM machine delete --name "$vm_name" -f 2>/dev/null; rm -rf "$pack_dir"; return 1
}
# Verify alice STILL exists after cp
local after
after=$($SMOLVM machine exec --name "$vm_name" -- id alice 2>&1) || {
echo "FAIL: alice gone after cp"
$SMOLVM machine stop --name "$vm_name" 2>/dev/null
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null
rm -rf "$pack_dir"
return 1
}
# Verify probe file landed
local probe
probe=$($SMOLVM machine exec --name "$vm_name" -- cat /tmp/probe.txt 2>&1)
[[ "$probe" == *"probe"* ]] || {
echo "FAIL: probe file missing after cp"
$SMOLVM machine stop --name "$vm_name" 2>/dev/null
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null
rm -rf "$pack_dir"
return 1
}
$SMOLVM machine stop --name "$vm_name" 2>/dev/null
$SMOLVM machine delete --name "$vm_name" -f 2>/dev/null
rm -rf "$pack_dir"
}
run_test "Create from .smolmachine" test_create_from_smolmachine || true
run_test "File cp preserves state on packed VM" test_cp_preserves_state_on_packed_vm || true
print_summary "Packed Machine Tests"