package api
import (
"strings"
"testing"
"time"
"craftdesign.group/quarry/internal/obs"
)
// The memory verdict: quiet under the target, a finding over it that
// says by how much, for how long and how much is unexplained, and a
// warning for heavy swap alone.
func TestMemoryFindings(t *testing.T) {
const gib = 1 << 30
quiet := opsMemory{Memory: obs.Memory{Heap: 2 * gib, Limit: 7 * gib, Cap: 9 * gib}}
if f := memoryFindings(quiet); len(f) != 0 {
t.Fatalf("FAIL: a heap under its target is a finding: %+v", f)
}
over := opsMemory{Memory: obs.Memory{Heap: 10 * gib, Limit: 7 * gib, Cap: 9 * gib, Swap: 3 * gib,
OverSince: time.Now().Add(-6 * time.Hour)}, Unaccounted: 9 * gib}
f := memoryFindings(over)
if len(f) != 1 || f[0].Severity != "bad" || f[0].About != "memory" {
t.Fatalf("FAIL: a heap over its target: %+v", f)
}
for _, want := range []string{"1.4×", "6h", "3.0 GB swapped", "9.0 GB of it not accounted"} {
if !strings.Contains(f[0].Text, want) {
t.Errorf("FAIL: the finding does not say %q: %s", want, f[0].Text)
}
}
nearCap := opsMemory{Memory: obs.Memory{Heap: 8_800 << 20, Cap: 9 * gib}}
if f := memoryFindings(nearCap); len(f) != 1 || f[0].Severity != "bad" {
t.Fatalf("FAIL: a heap at 95%% of the cap with no target set: %+v", f)
}
swapped := opsMemory{Memory: obs.Memory{Heap: 2 * gib, Limit: 7 * gib, Swap: 2 * gib}}
if f := memoryFindings(swapped); len(f) != 1 || f[0].Severity != "warn" {
t.Fatalf("FAIL: heavy swap under the target: %+v", f)
}
t.Log("ok: quiet, over target, near cap, swap")
}