c97975c1df
Consumes the agent v0.94.0 smart payload (MinAgent floor unchanged; feature-detect by presence). One pure verdict fn agentapi.DiskVerdictFor shared by the dashboard card and the 6h check. Card via a 60s /disks TTL cache (anti-smartctl-storm); unreachable agent -> Nincs adat, page never blocks. disk-health-check (6h) emits disk_health_degraded on a degradation only vs an in-memory baseline (first run silent, recovery/UNKNOWN never notify, multi-attr -> one event). No global banner (deliberate). Pairs with the hub allowlist bump. Tests: verdict table (>=90 red-proof), notifier emit, check first-run-silent (red-proof), degradation-once, recovery-silent, UNKNOWN-excluded, FAILING-critical, nil-smart card, TTL cache.
64 lines
2.9 KiB
Go
64 lines
2.9 KiB
Go
package agentapi
|
|
|
|
import "testing"
|
|
|
|
func ip(v int) *int { return &v }
|
|
|
|
// Verdict table (Part 2). Red-proof: change the PercentageUsed boundary from `>= 90` to `> 90` in
|
|
// DiskVerdictFor → the "NVMe percentage_used exactly 90 → Figyelmeztetés" case fails.
|
|
func TestDiskVerdictFor(t *testing.T) {
|
|
cases := []struct {
|
|
name string
|
|
in *SmartSummary
|
|
want DiskVerdict
|
|
}{
|
|
{"nil → unknown", nil, DiskVerdictUnknown},
|
|
{"empty health → unknown", &SmartSummary{Health: ""}, DiskVerdictUnknown},
|
|
{"UNKNOWN → unknown", &SmartSummary{Health: SmartUnknown}, DiskVerdictUnknown},
|
|
{"FAILING → fail", &SmartSummary{Health: SmartFailing}, DiskVerdictFail},
|
|
{"FAILING beats counters", &SmartSummary{Health: SmartFailing, ReallocatedSectors: ip(0)}, DiskVerdictFail},
|
|
{"PASSED clean → ok", &SmartSummary{Health: SmartPassed, ReallocatedSectors: ip(0), PendingSectors: ip(0), TemperatureC: ip(30)}, DiskVerdictOK},
|
|
{"PASSED nil counters → ok", &SmartSummary{Health: SmartPassed}, DiskVerdictOK},
|
|
{"reallocated>0 → warn", &SmartSummary{Health: SmartPassed, ReallocatedSectors: ip(1)}, DiskVerdictWarn},
|
|
{"pending>0 → warn", &SmartSummary{Health: SmartPassed, PendingSectors: ip(5)}, DiskVerdictWarn},
|
|
{"offline_unc>0 → warn", &SmartSummary{Health: SmartPassed, OfflineUncorrectable: ip(2)}, DiskVerdictWarn},
|
|
{"critical_warning>0 → warn", &SmartSummary{Health: SmartPassed, CriticalWarning: ip(1)}, DiskVerdictWarn},
|
|
{"media_errors>0 → warn", &SmartSummary{Health: SmartPassed, MediaErrors: ip(3)}, DiskVerdictWarn},
|
|
{"percentage_used 89 → ok", &SmartSummary{Health: SmartPassed, PercentageUsed: ip(89)}, DiskVerdictOK},
|
|
{"percentage_used exactly 90 → warn", &SmartSummary{Health: SmartPassed, PercentageUsed: ip(90)}, DiskVerdictWarn},
|
|
{"percentage_used 95 → warn", &SmartSummary{Health: SmartPassed, PercentageUsed: ip(95)}, DiskVerdictWarn},
|
|
}
|
|
for _, c := range cases {
|
|
if got := DiskVerdictFor(c.in); got != c.want {
|
|
t.Errorf("%s: DiskVerdictFor = %d, want %d", c.name, got, c.want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDiskVerdict_Label(t *testing.T) {
|
|
want := map[DiskVerdict]string{
|
|
DiskVerdictUnknown: "Nincs adat",
|
|
DiskVerdictOK: "Rendben",
|
|
DiskVerdictWarn: "Figyelmeztetés",
|
|
DiskVerdictFail: "Hiba",
|
|
}
|
|
for v, w := range want {
|
|
if got := v.Label(); got != w {
|
|
t.Errorf("verdict %d Label = %q, want %q", v, got, w)
|
|
}
|
|
}
|
|
}
|
|
|
|
// A warn lists every triggering attribute at once (Scenario "multiple attributes degrade" → ONE event).
|
|
func TestDegradedAttributes_ListsAll(t *testing.T) {
|
|
s := &SmartSummary{Health: SmartPassed, PendingSectors: ip(5), ReallocatedSectors: ip(2), PercentageUsed: ip(91)}
|
|
got := DegradedAttributes(s)
|
|
if len(got) != 3 {
|
|
t.Fatalf("want 3 attributes, got %d: %v", len(got), got)
|
|
}
|
|
// clean disk → none
|
|
if a := DegradedAttributes(&SmartSummary{Health: SmartPassed}); len(a) != 0 {
|
|
t.Errorf("clean disk should list no attributes, got %v", a)
|
|
}
|
|
}
|