v0.169.0: disk-health card + degradation notification (Lemezek állapota)
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.
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user