package localapi import ( "context" "errors" "io" "log/slog" "testing" "gitea.dooplex.hu/admin/felhom-agent/internal/proxmox" ) // R-1192: the freeze measured on the minimum machine (felhom.eu audits/fixes-2026-10-21/P4-freeze/) — a guest whose // swap is capped below its RAM evicts program code instead of idle memory. EnsureGuestSwap raises every pool guest's // swap to its RAM, never lowers one, skips non-LXC members, and survives one guest's failure. // COMPANION RED-PROOF: return 0 before the SetConfig call → „raised 0, want 2". type fakeSwapOps struct { cfg map[int]proxmox.GuestConfig failSet map[int]bool set map[int]map[string]string } func (f *fakeSwapOps) Pool(context.Context, string) (proxmox.PoolInfo, error) { return proxmox.PoolInfo{Members: []proxmox.PoolMember{{VMID: 9201, Type: "lxc"}, {VMID: 9202, Type: "lxc"}, {VMID: 300, Type: "qemu"}, {Type: "storage"}, {VMID: 9203, Type: "lxc"}, {VMID: 9204, Type: "lxc"}}}, nil } func (f *fakeSwapOps) GuestConfig(_ context.Context, vmid int) (proxmox.GuestConfig, error) { c, ok := f.cfg[vmid] if !ok { return c, errors.New("no such guest") } return c, nil } func (f *fakeSwapOps) SetConfig(_ context.Context, vmid int, p map[string]string) (string, error) { if f.failSet[vmid] { return "", errors.New("pve said no") } if f.set == nil { f.set = map[int]map[string]string{} } f.set[vmid] = p return "", nil } func (f *fakeSwapOps) WaitTask(context.Context, string, proxmox.WaitOptions) (proxmox.TaskStatus, error) { return proxmox.TaskStatus{}, nil } func TestR1192_EnsureGuestSwapRaisesEveryLowSwapToItsRAM(t *testing.T) { f := &fakeSwapOps{cfg: map[int]proxmox.GuestConfig{ 9201: {Memory: 4096, Swap: 512}, // the measured box: raised 9202: {Memory: 2048, Swap: 4096}, // already higher: never lowered 9203: {Memory: 6144, Swap: 0}, // none: raised 9204: {Memory: 4096, Swap: 512}, // the write fails: logged, the others still done }, failSet: map[int]bool{9204: true}} n, err := EnsureGuestSwap(context.Background(), f, "felhom", slog.New(slog.NewTextHandler(io.Discard, nil))) if err != nil { t.Fatal(err) } if n != 2 { t.Fatalf("raised %d, want 2 (9201, 9203)", n) } if f.set[9201]["swap"] != "4096" || f.set[9203]["swap"] != "6144" { t.Fatalf("writes = %v", f.set) } if _, touched := f.set[9202]; touched { t.Fatal("a swap above the RAM was lowered") } if len(f.set[9201]) != 1 { t.Fatalf("the swap raise wrote more than the swap: %v", f.set[9201]) } }