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

161 lines
5.1 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Scale tests for smolvm.
#
# Verifies concurrent VM operations work correctly under contention:
# SQLite locking, per-VM flock, vsock connect retries, and concurrent exec.
#
# Usage:
# ./tests/test_scale.sh
# ./tests/run_tests.sh scale
source "$(dirname "$0")/common.sh"
init_smolvm
log_info "Pre-flight cleanup: killing orphan processes..."
kill_orphan_smolvm_processes
echo ""
echo "=========================================="
echo " smolvm Scale Tests"
echo "=========================================="
echo ""
# =============================================================================
# 10 concurrent VMs: create, start, exec, stop
# =============================================================================
test_10_concurrent_vms() {
local COUNT=10
local i
for i in $(seq 1 $COUNT); do
$SMOLVM machine stop --name "scale-$i" 2>/dev/null || true
$SMOLVM machine delete --name "scale-$i" -f 2>/dev/null || true
done
# Create
for i in $(seq 1 $COUNT); do
$SMOLVM machine create --name "scale-$i" --mem 512 --cpus 1 2>/dev/null || {
echo "FAIL: create scale-$i failed"; return 1
}
done
# Start concurrently
local pids=()
for i in $(seq 1 $COUNT); do
$SMOLVM machine start --name "scale-$i" 2>/dev/null &
pids+=($!)
done
local start_fails=0
for pid in "${pids[@]}"; do
wait "$pid" || ((start_fails++))
done
sleep 1
# Verify all running
local running=0
for i in $(seq 1 $COUNT); do
if $SMOLVM machine status --name "scale-$i" 2>&1 | grep -q "running"; then
((running++))
fi
done
# Exec on each
local exec_pass=0
for i in $(seq 1 $COUNT); do
local out
out=$($SMOLVM machine exec --name "scale-$i" -- echo "ok-$i" 2>&1) || true
if echo "$out" | grep -q "ok-$i"; then
((exec_pass++))
fi
done
# Cleanup
for i in $(seq 1 $COUNT); do
$SMOLVM machine stop --name "scale-$i" 2>/dev/null || true
$SMOLVM machine delete --name "scale-$i" -f 2>/dev/null || true
done
echo " running: $running/$COUNT, exec: $exec_pass/$COUNT, start_fails: $start_fails"
[[ $running -eq $COUNT ]] || { echo "FAIL: only $running/$COUNT running"; return 1; }
[[ $exec_pass -eq $COUNT ]] || { echo "FAIL: only $exec_pass/$COUNT exec passed"; return 1; }
}
run_test "Scale: 10 concurrent VMs start + exec" test_10_concurrent_vms || true
# =============================================================================
# Concurrent exec storm: 5 execs per VM across 10 VMs (50 total)
# =============================================================================
test_concurrent_exec_storm() {
local COUNT=10
local EXECS_PER_VM=5
local i j
for i in $(seq 1 $COUNT); do
$SMOLVM machine stop --name "storm-$i" 2>/dev/null || true
$SMOLVM machine delete --name "storm-$i" -f 2>/dev/null || true
done
# Create and start sequentially (scale test above covers concurrent start)
for i in $(seq 1 $COUNT); do
$SMOLVM machine create --name "storm-$i" --mem 512 --cpus 1 2>/dev/null || return 1
$SMOLVM machine start --name "storm-$i" 2>/dev/null || return 1
done
# Storm: 50 concurrent execs
local tmpdir
tmpdir=$(mktemp -d)
for i in $(seq 1 $COUNT); do
for j in $(seq 1 $EXECS_PER_VM); do
(
out=$($SMOLVM machine exec --name "storm-$i" -- echo "s-${i}-${j}" 2>&1)
if echo "$out" | grep -q "s-${i}-${j}"; then
touch "$tmpdir/pass-${i}-${j}"
fi
) &
done
done
wait
local pass_count
pass_count=$(find "$tmpdir" -name "pass-*" 2>/dev/null | wc -l)
rm -rf "$tmpdir"
# Cleanup
for i in $(seq 1 $COUNT); do
$SMOLVM machine stop --name "storm-$i" 2>/dev/null || true
$SMOLVM machine delete --name "storm-$i" -f 2>/dev/null || true
done
local total=$((COUNT * EXECS_PER_VM))
echo " exec pass: $pass_count/$total"
[[ $pass_count -eq $total ]] || { echo "FAIL: only $pass_count/$total execs passed"; return 1; }
}
run_test "Scale: 50 concurrent execs across 10 VMs" test_concurrent_exec_storm || true
# =============================================================================
# Rapid lifecycle: create-start-stop-delete x5
# =============================================================================
test_rapid_lifecycle() {
local i
for i in $(seq 1 5); do
$SMOLVM machine create --name "rapid-$$" --mem 512 --cpus 1 2>/dev/null || {
echo "FAIL: create iteration $i"; return 1
}
$SMOLVM machine start --name "rapid-$$" 2>/dev/null || {
echo "FAIL: start iteration $i"
$SMOLVM machine delete --name "rapid-$$" -f 2>/dev/null; return 1
}
$SMOLVM machine stop --name "rapid-$$" 2>/dev/null || true
$SMOLVM machine delete --name "rapid-$$" -f 2>/dev/null || true
done
echo " 5 create-start-stop-delete cycles completed"
}
run_test "Scale: rapid lifecycle (5 iterations)" test_rapid_lifecycle || true
print_summary "Scale Tests"