mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 11:30:15 +00:00
377 lines
8 KiB
Go
377 lines
8 KiB
Go
package alerts
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/rcourtman/pulse-go-rewrite/internal/models"
|
|
)
|
|
|
|
func TestSynologyRAIDSuppression(t *testing.T) {
|
|
m := newTestManager(t)
|
|
m.ClearActiveAlerts()
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
host := models.Host{
|
|
ID: "syno-1",
|
|
DisplayName: "Synology NAS",
|
|
OSName: "Synology DSM",
|
|
Hostname: "synology",
|
|
Status: "online",
|
|
LastSeen: time.Now(),
|
|
RAID: []models.HostRAIDArray{
|
|
{
|
|
Device: "/dev/md0", // Suppressed
|
|
Level: "raid1",
|
|
State: "degraded", // Should NOT alert
|
|
FailedDevices: 1,
|
|
},
|
|
{
|
|
Device: "/dev/md1", // Suppressed
|
|
Level: "raid1",
|
|
State: "resyncing", // Should NOT alert
|
|
RebuildPercent: 50.0,
|
|
},
|
|
{
|
|
Device: "/dev/md2", // Not suppressed
|
|
Level: "raid5",
|
|
State: "degraded", // SHOULD alert
|
|
FailedDevices: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
m.CheckHost(host)
|
|
|
|
alerts := m.GetActiveAlerts()
|
|
var md0Found, md1Found, md2Found bool
|
|
|
|
for _, a := range alerts {
|
|
if strings.Contains(a.ID, "md0") {
|
|
md0Found = true
|
|
}
|
|
if strings.Contains(a.ID, "md1") {
|
|
md1Found = true
|
|
}
|
|
if strings.Contains(a.ID, "md2") {
|
|
md2Found = true
|
|
}
|
|
}
|
|
|
|
if md0Found {
|
|
t.Error("expected md0 alert to be suppressed")
|
|
}
|
|
if md1Found {
|
|
t.Error("expected md1 alert to be suppressed")
|
|
}
|
|
if !md2Found {
|
|
t.Error("expected md2 alert to be created")
|
|
}
|
|
}
|
|
|
|
func TestSynologyRAIDClearing(t *testing.T) {
|
|
m := newTestManager(t)
|
|
m.ClearActiveAlerts()
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
// Manually inject an alert for md0
|
|
alertID := "host-syno-1-raid-md0"
|
|
m.mu.Lock()
|
|
m.activeAlerts[alertID] = &Alert{
|
|
ID: alertID,
|
|
ResourceID: "host-syno-1-raid-md0",
|
|
ResourceName: "Synology NAS - /dev/md0 (raid1)",
|
|
Message: "RAID array degraded",
|
|
}
|
|
m.mu.Unlock()
|
|
|
|
host := models.Host{
|
|
ID: "syno-1",
|
|
DisplayName: "Synology NAS",
|
|
OSName: "Synology DSM",
|
|
Hostname: "synology",
|
|
Status: "online",
|
|
LastSeen: time.Now(),
|
|
RAID: []models.HostRAIDArray{
|
|
{
|
|
Device: "/dev/md0", // Suppressed
|
|
Level: "raid1",
|
|
State: "degraded", // Should trigger clearing logic
|
|
FailedDevices: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
m.CheckHost(host)
|
|
|
|
m.mu.RLock()
|
|
_, exists := m.activeAlerts[alertID]
|
|
m.mu.RUnlock()
|
|
|
|
if exists {
|
|
t.Error("expected md0 alert to be filtered and cleared")
|
|
}
|
|
}
|
|
|
|
func TestHostDisableClearsRAID(t *testing.T) {
|
|
m := newTestManager(t)
|
|
m.ClearActiveAlerts()
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
host := models.Host{
|
|
ID: "host-raid",
|
|
DisplayName: "RAID Host",
|
|
OSName: "Synology DSM",
|
|
Hostname: "raid-host",
|
|
Status: "online",
|
|
LastSeen: time.Now(),
|
|
RAID: []models.HostRAIDArray{
|
|
{
|
|
Device: "/dev/md2",
|
|
Level: "raid5",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
// 1. Initial check - creates alert
|
|
m.CheckHost(host)
|
|
|
|
alertID := "host-host-raid-raid-md2"
|
|
m.mu.RLock()
|
|
_, exists := m.activeAlerts[alertID]
|
|
m.mu.RUnlock()
|
|
|
|
if !exists {
|
|
t.Fatal("expected RAID alert to be created")
|
|
}
|
|
|
|
// 2. Disable alerts for this host
|
|
cfg := m.GetConfig()
|
|
cfg.Overrides = map[string]ThresholdConfig{
|
|
host.ID: {
|
|
Disabled: true,
|
|
},
|
|
}
|
|
m.UpdateConfig(cfg)
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
// 3. Re-check - should clear alerts
|
|
m.CheckHost(host)
|
|
|
|
m.mu.RLock()
|
|
_, exists = m.activeAlerts[alertID]
|
|
m.mu.RUnlock()
|
|
|
|
if exists {
|
|
t.Error("expected RAID alert to be cleared when host alerts are disabled")
|
|
}
|
|
}
|
|
|
|
func TestQNAPRAIDSuppression(t *testing.T) {
|
|
m := newTestManager(t)
|
|
m.ClearActiveAlerts()
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
host := models.Host{
|
|
ID: "qnap-1",
|
|
DisplayName: "QNAP NAS",
|
|
OSName: "QuTS hero",
|
|
Hostname: "qnap",
|
|
Status: "online",
|
|
LastSeen: time.Now(),
|
|
RAID: []models.HostRAIDArray{
|
|
{
|
|
Device: "/dev/md9", // Suppressed internal OS array
|
|
Level: "raid1",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
{
|
|
Device: "/dev/md13", // Suppressed internal OS array
|
|
Level: "raid1",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
{
|
|
Device: "/dev/md0", // User-facing array on many QNAP systems
|
|
Level: "raid5",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
m.CheckHost(host)
|
|
|
|
alerts := m.GetActiveAlerts()
|
|
var md0Found, md9Found, md13Found bool
|
|
|
|
for _, a := range alerts {
|
|
if strings.Contains(a.ID, "md0") {
|
|
md0Found = true
|
|
}
|
|
if strings.Contains(a.ID, "md9") {
|
|
md9Found = true
|
|
}
|
|
if strings.Contains(a.ID, "md13") {
|
|
md13Found = true
|
|
}
|
|
}
|
|
|
|
if md9Found {
|
|
t.Error("expected md9 alert to be suppressed for QNAP")
|
|
}
|
|
if md13Found {
|
|
t.Error("expected md13 alert to be suppressed for QNAP")
|
|
}
|
|
if !md0Found {
|
|
t.Error("expected md0 alert to be created for QNAP data array")
|
|
}
|
|
}
|
|
|
|
func TestQNAPRAIDSuppressionFromOSVersionHint(t *testing.T) {
|
|
m := newTestManager(t)
|
|
m.ClearActiveAlerts()
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
host := models.Host{
|
|
ID: "qnap-osver",
|
|
DisplayName: "storage-box",
|
|
Platform: "linux",
|
|
OSVersion: "QTS 5.2.3",
|
|
Hostname: "nas-01",
|
|
Status: "online",
|
|
LastSeen: time.Now(),
|
|
RAID: []models.HostRAIDArray{
|
|
{
|
|
Device: "/dev/md9",
|
|
Level: "raid1",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
{
|
|
Device: "/dev/md0",
|
|
Level: "raid5",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
m.CheckHost(host)
|
|
|
|
m.mu.RLock()
|
|
_, md9Exists := m.activeAlerts["host-qnap-osver-raid-md9"]
|
|
_, md0Exists := m.activeAlerts["host-qnap-osver-raid-md0"]
|
|
m.mu.RUnlock()
|
|
|
|
if md9Exists {
|
|
t.Error("expected md9 alert to be suppressed when QNAP is identified from OSVersion")
|
|
}
|
|
if !md0Exists {
|
|
t.Error("expected md0 alert to remain for QNAP data array when only OSVersion identifies vendor")
|
|
}
|
|
}
|
|
|
|
func TestGenericHostMD0IsNotSuppressed(t *testing.T) {
|
|
m := newTestManager(t)
|
|
m.ClearActiveAlerts()
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
host := models.Host{
|
|
ID: "linux-1",
|
|
DisplayName: "Linux Host",
|
|
OSName: "Ubuntu",
|
|
Hostname: "linux-host",
|
|
Status: "online",
|
|
LastSeen: time.Now(),
|
|
RAID: []models.HostRAIDArray{
|
|
{
|
|
Device: "/dev/md0",
|
|
Level: "raid1",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
m.CheckHost(host)
|
|
|
|
m.mu.RLock()
|
|
_, exists := m.activeAlerts["host-linux-1-raid-md0"]
|
|
m.mu.RUnlock()
|
|
|
|
if !exists {
|
|
t.Error("expected md0 alert to be created for generic hosts")
|
|
}
|
|
}
|
|
|
|
func TestSynologyRAIDSuppressionFromPlatformHint(t *testing.T) {
|
|
m := newTestManager(t)
|
|
m.ClearActiveAlerts()
|
|
m.mu.Lock()
|
|
m.config.TimeThreshold = 0
|
|
m.config.TimeThresholds = map[string]int{}
|
|
m.mu.Unlock()
|
|
|
|
host := models.Host{
|
|
ID: "syno-platform",
|
|
DisplayName: "storage-box",
|
|
Platform: "dsm",
|
|
Hostname: "nas-02",
|
|
Status: "online",
|
|
LastSeen: time.Now(),
|
|
RAID: []models.HostRAIDArray{
|
|
{
|
|
Device: "/dev/md0",
|
|
Level: "raid1",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
{
|
|
Device: "/dev/md2",
|
|
Level: "raid5",
|
|
State: "degraded",
|
|
FailedDevices: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
m.CheckHost(host)
|
|
|
|
m.mu.RLock()
|
|
_, md0Exists := m.activeAlerts["host-syno-platform-raid-md0"]
|
|
_, md2Exists := m.activeAlerts["host-syno-platform-raid-md2"]
|
|
m.mu.RUnlock()
|
|
|
|
if md0Exists {
|
|
t.Error("expected md0 alert to be suppressed when Synology is identified from Platform")
|
|
}
|
|
if !md2Exists {
|
|
t.Error("expected md2 alert to remain for Synology data array when only Platform identifies vendor")
|
|
}
|
|
}
|