1
0
forked from wrenn/wrenn
Co-authored-by: Tasnim Kabir Sadik <tksadik@omukk.dev>

Reviewed-on: wrenn/wrenn#55
Co-authored-by: pptx704 <rafeed@omukk.dev>
Co-committed-by: pptx704 <rafeed@omukk.dev>
This commit is contained in:
2026-06-20 22:45:08 +00:00
committed by Rafeed M. Bhuiyan
parent cfc0c52010
commit a08e755e53
53 changed files with 1675 additions and 577 deletions

View File

@ -0,0 +1,111 @@
package sandbox
import (
"testing"
"git.omukk.dev/wrenn/wrenn/internal/envdclient"
)
func TestIsBusy(t *testing.T) {
tests := []struct {
name string
cfg Config
act envdclient.Activity
want bool
}{
// Default thresholds (zero cfg → defaults: cpu 5%, net 16K, disk 32K).
{"idle", Config{}, envdclient.Activity{CPUUsedPct: 0.5, NetBps: 100, DiskBps: 200}, false},
{"cpu just below", Config{}, envdclient.Activity{CPUUsedPct: 4.99}, false},
{"cpu at threshold", Config{}, envdclient.Activity{CPUUsedPct: 5.0}, true},
{"cpu above", Config{}, envdclient.Activity{CPUUsedPct: 80.0}, true},
{"net just below", Config{}, envdclient.Activity{NetBps: 16*1024 - 1}, false},
{"net at floor", Config{}, envdclient.Activity{NetBps: 16 * 1024}, true},
{"disk just below", Config{}, envdclient.Activity{DiskBps: 32*1024 - 1}, false},
{"disk at floor", Config{}, envdclient.Activity{DiskBps: 32 * 1024}, true},
{"download: low cpu, high net", Config{}, envdclient.Activity{CPUUsedPct: 1.0, NetBps: 5 * 1024 * 1024}, true},
// Explicit overrides take precedence over defaults.
{
"custom cpu threshold met",
Config{CPUBusyPct: 20.0},
envdclient.Activity{CPUUsedPct: 25.0},
true,
},
{
"custom cpu threshold not met",
Config{CPUBusyPct: 20.0},
envdclient.Activity{CPUUsedPct: 10.0},
false,
},
{
"custom net floor not met",
Config{NetFloorBps: 1024 * 1024},
envdclient.Activity{NetBps: 16 * 1024},
false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
m := &Manager{cfg: tt.cfg}
if got := m.isBusy(&tt.act); got != tt.want {
t.Errorf("isBusy(%+v) = %v, want %v", tt.act, got, tt.want)
}
})
}
}
func TestApplyBusySample(t *testing.T) {
// Debounce requires busyDebounceSamples consecutive busy samples before the
// first bump. Verify the streak math and bump timing.
if busyDebounceSamples != 2 {
t.Skip("test written for busyDebounceSamples=2")
}
tests := []struct {
name string
startStreak int
busy bool
wantStreak int
wantBump bool
}{
{"first busy, no bump yet", 0, true, 1, false},
{"second consecutive busy, bump", 1, true, 2, true},
{"sustained busy keeps bumping, streak held", 2, true, 2, true},
{"single noise spike from idle, no bump", 0, false, 0, false},
{"idle resets a building streak", 1, false, 0, false},
{"idle resets a saturated streak", 2, false, 0, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotStreak, gotBump := applyBusySample(tt.startStreak, tt.busy)
if gotStreak != tt.wantStreak || gotBump != tt.wantBump {
t.Errorf("applyBusySample(%d, %v) = (%d, %v), want (%d, %v)",
tt.startStreak, tt.busy, gotStreak, gotBump, tt.wantStreak, tt.wantBump)
}
})
}
}
// TestApplyBusySample_NoiseScenario walks a realistic sample sequence: brief
// noise never crosses the debounce, but sustained work does and then a return
// to idle resets — proving an isolated spike cannot keep a sandbox alive.
func TestApplyBusySample_NoiseScenario(t *testing.T) {
if busyDebounceSamples != 2 {
t.Skip("test written for busyDebounceSamples=2")
}
samples := []bool{true, false, false, true, true, true, false}
wantBumps := []bool{false, false, false, false, true, true, false}
streak := 0
for i, busy := range samples {
var bump bool
streak, bump = applyBusySample(streak, busy)
if bump != wantBumps[i] {
t.Errorf("sample %d (busy=%v): bump = %v, want %v (streak=%d)",
i, busy, bump, wantBumps[i], streak)
}
}
}