package web import ( "encoding/json" "os" "testing" "gitea.dooplex.hu/admin/felhom-controller/internal/agentapi" ) // R-1192 follow-up (night 2026-10-21): the install page adds „A gépen nincs elég cserehely (swap)…" when memory is // tight AND the agent reports the host's swap below the guest's RAM. An older agent (no number) is not judged. // RED-PROOF: swapShort returning false always → the first case fails. func TestR1192_SwapShortJudgesTheHostSwapAgainstTheGuestRAM(t *testing.T) { mb := func(v int64) *int64 { return &v } for _, c := range []struct { name string info agentapi.GuestMemoryInfo want bool }{ {"a host with no swap", agentapi.GuestMemoryInfo{AllocatedMB: 4096, HostSwapMB: mb(0)}, true}, {"a host with 2 GB swap behind a 4 GB guest", agentapi.GuestMemoryInfo{AllocatedMB: 4096, HostSwapMB: mb(2048)}, true}, {"the installer's 8 GB host (7.75 GB swap)", agentapi.GuestMemoryInfo{AllocatedMB: 4096, HostSwapMB: mb(7935)}, false}, {"an older agent (no number)", agentapi.GuestMemoryInfo{AllocatedMB: 4096}, false}, } { if got := swapShort(c.info); got != c.want { t.Errorf("%s: swapShort = %v, want %v", c.name, got, c.want) } } } // R-1216 / D28 = A: the shared case table (byte-identical in felhom.eu hub/internal/api/testdata/, checked by felhom.eu // scripts/host_swap_rule_gate.py), plus the page's own input: a 12 GB guest on an 8 GB-swap host (demo-felhom) is NOT // short; the guest's RAM stands in when the agent sends no guest_swap_mb. // RED-PROOF: with the morning's rule (`host < the guest's RAM`) the demo-hp, demo-felhom and 32 GB rows fail — seen // failing 2026-10-22. func TestR1216_HostSwapRuleCases(t *testing.T) { b, err := os.ReadFile("testdata/host_swap_rule_cases.json") if err != nil { t.Fatal(err) } var f struct { Cases []struct { Name string `json:"name"` Host int64 `json:"host_swap_mb"` Guest int64 `json:"guest_swap_mb"` Short bool `json:"short"` } `json:"cases"` } if err := json.Unmarshal(b, &f); err != nil || len(f.Cases) < 10 { t.Fatalf("case table: %v (%d cases)", err, len(f.Cases)) } mb := func(v int64) *int64 { return &v } for _, c := range f.Cases { if got := hostSwapRuleShort(c.Host, c.Guest); got != c.Short { t.Errorf("%s: host %d / guests %d → short=%t, want %t", c.Name, c.Host, c.Guest, got, c.Short) } // Through the page's own input, the agent's answer. if got := swapShort(agentapi.GuestMemoryInfo{AllocatedMB: c.Guest, HostSwapMB: mb(c.Host), GuestSwapMB: mb(c.Guest)}); got != c.Short { t.Errorf("%s (page input): short=%t, want %t", c.Name, got, c.Short) } } if swapShort(agentapi.GuestMemoryInfo{AllocatedMB: 12288, HostSwapMB: mb(8191)}) { t.Error("demo-felhom without guest_swap_mb (the guest's RAM stands in) must not be short") } }