test: Add suppressGuestAlerts and guestHasMonitorOnlyAlerts tests
Coverage improvements: - suppressGuestAlerts: 37% -> 96.3% - guestHasMonitorOnlyAlerts: 40% -> 90% Tests cover: - No alerts returns false - Exact ResourceID match clears - Prefix match (e.g., "vm100/disk1") clears - All auxiliary maps cleared (pending, recent, suppressed, rateLimit) - Multiple alerts cleared - Monitor-only detection via metadata (bool and string types)
This commit is contained in:
parent
f661c5a6a8
commit
9791fc07cb
1 changed files with 300 additions and 0 deletions
|
|
@ -10893,3 +10893,303 @@ func TestApplyThresholdOverride(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSuppressGuestAlerts(t *testing.T) {
|
||||
t.Run("no alerts for guest returns false", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
result := m.suppressGuestAlerts("vm100")
|
||||
if result {
|
||||
t.Error("expected false when no alerts exist for guest")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("active alert with exact ResourceID match clears and returns true", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100-cpu"] = &Alert{
|
||||
ID: "vm100-cpu",
|
||||
ResourceID: "vm100",
|
||||
Type: "cpu",
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.suppressGuestAlerts("vm100")
|
||||
if !result {
|
||||
t.Error("expected true when active alert was cleared")
|
||||
}
|
||||
|
||||
m.mu.RLock()
|
||||
if _, exists := m.activeAlerts["vm100-cpu"]; exists {
|
||||
t.Error("expected alert to be cleared from activeAlerts")
|
||||
}
|
||||
m.mu.RUnlock()
|
||||
})
|
||||
|
||||
t.Run("active alert with prefix match clears", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100/disk1-disk"] = &Alert{
|
||||
ID: "vm100/disk1-disk",
|
||||
ResourceID: "vm100/disk1",
|
||||
Type: "disk",
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.suppressGuestAlerts("vm100")
|
||||
if !result {
|
||||
t.Error("expected true when active alert was cleared")
|
||||
}
|
||||
|
||||
m.mu.RLock()
|
||||
if _, exists := m.activeAlerts["vm100/disk1-disk"]; exists {
|
||||
t.Error("expected alert with prefix match to be cleared")
|
||||
}
|
||||
m.mu.RUnlock()
|
||||
})
|
||||
|
||||
t.Run("clears from all auxiliary maps", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
now := time.Now()
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100-cpu"] = &Alert{
|
||||
ID: "vm100-cpu",
|
||||
ResourceID: "vm100",
|
||||
Type: "cpu",
|
||||
}
|
||||
m.pendingAlerts["vm100-memory"] = now
|
||||
m.recentAlerts["vm100-disk"] = &Alert{ID: "vm100-disk", ResourceID: "vm100"}
|
||||
m.suppressedUntil["vm100-network"] = now.Add(time.Hour)
|
||||
m.alertRateLimit["vm100-io"] = []time.Time{now}
|
||||
m.offlineConfirmations["vm100"] = 1
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.suppressGuestAlerts("vm100")
|
||||
if !result {
|
||||
t.Error("expected true when active alert was cleared")
|
||||
}
|
||||
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
if _, exists := m.activeAlerts["vm100-cpu"]; exists {
|
||||
t.Error("expected activeAlerts to be cleared")
|
||||
}
|
||||
if _, exists := m.pendingAlerts["vm100-memory"]; exists {
|
||||
t.Error("expected pendingAlerts to be cleared")
|
||||
}
|
||||
if _, exists := m.recentAlerts["vm100-disk"]; exists {
|
||||
t.Error("expected recentAlerts to be cleared")
|
||||
}
|
||||
if _, exists := m.suppressedUntil["vm100-network"]; exists {
|
||||
t.Error("expected suppressedUntil to be cleared")
|
||||
}
|
||||
if _, exists := m.alertRateLimit["vm100-io"]; exists {
|
||||
t.Error("expected alertRateLimit to be cleared")
|
||||
}
|
||||
if _, exists := m.offlineConfirmations["vm100"]; exists {
|
||||
t.Error("expected offlineConfirmations to be cleared")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("multiple alerts cleared", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100-cpu"] = &Alert{
|
||||
ID: "vm100-cpu",
|
||||
ResourceID: "vm100",
|
||||
Type: "cpu",
|
||||
}
|
||||
m.activeAlerts["vm100-memory"] = &Alert{
|
||||
ID: "vm100-memory",
|
||||
ResourceID: "vm100",
|
||||
Type: "memory",
|
||||
}
|
||||
m.activeAlerts["vm100/disk0-disk"] = &Alert{
|
||||
ID: "vm100/disk0-disk",
|
||||
ResourceID: "vm100/disk0",
|
||||
Type: "disk",
|
||||
}
|
||||
// Also add an alert for a different guest that should NOT be cleared
|
||||
m.activeAlerts["vm200-cpu"] = &Alert{
|
||||
ID: "vm200-cpu",
|
||||
ResourceID: "vm200",
|
||||
Type: "cpu",
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.suppressGuestAlerts("vm100")
|
||||
if !result {
|
||||
t.Error("expected true when alerts were cleared")
|
||||
}
|
||||
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
if _, exists := m.activeAlerts["vm100-cpu"]; exists {
|
||||
t.Error("expected vm100-cpu to be cleared")
|
||||
}
|
||||
if _, exists := m.activeAlerts["vm100-memory"]; exists {
|
||||
t.Error("expected vm100-memory to be cleared")
|
||||
}
|
||||
if _, exists := m.activeAlerts["vm100/disk0-disk"]; exists {
|
||||
t.Error("expected vm100/disk0-disk to be cleared")
|
||||
}
|
||||
if _, exists := m.activeAlerts["vm200-cpu"]; !exists {
|
||||
t.Error("expected vm200-cpu to NOT be cleared")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("clears auxiliary maps even without active alerts", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
now := time.Now()
|
||||
m.mu.Lock()
|
||||
// No active alerts, but has entries in auxiliary maps
|
||||
m.pendingAlerts["vm100-memory"] = now
|
||||
m.recentAlerts["vm100-disk"] = &Alert{ID: "vm100-disk", ResourceID: "vm100"}
|
||||
m.suppressedUntil["vm100-network"] = now.Add(time.Hour)
|
||||
m.alertRateLimit["vm100-io"] = []time.Time{now}
|
||||
m.offlineConfirmations["vm100"] = 1
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.suppressGuestAlerts("vm100")
|
||||
// Returns false because no active alerts were cleared
|
||||
if result {
|
||||
t.Error("expected false when no active alerts were cleared")
|
||||
}
|
||||
|
||||
m.mu.RLock()
|
||||
defer m.mu.RUnlock()
|
||||
|
||||
// But auxiliary maps should still be cleared
|
||||
if _, exists := m.pendingAlerts["vm100-memory"]; exists {
|
||||
t.Error("expected pendingAlerts to be cleared")
|
||||
}
|
||||
if _, exists := m.recentAlerts["vm100-disk"]; exists {
|
||||
t.Error("expected recentAlerts to be cleared")
|
||||
}
|
||||
if _, exists := m.suppressedUntil["vm100-network"]; exists {
|
||||
t.Error("expected suppressedUntil to be cleared")
|
||||
}
|
||||
if _, exists := m.alertRateLimit["vm100-io"]; exists {
|
||||
t.Error("expected alertRateLimit to be cleared")
|
||||
}
|
||||
if _, exists := m.offlineConfirmations["vm100"]; exists {
|
||||
t.Error("expected offlineConfirmations to be cleared")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestGuestHasMonitorOnlyAlerts(t *testing.T) {
|
||||
t.Run("no alerts returns false", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
result := m.guestHasMonitorOnlyAlerts("vm100")
|
||||
if result {
|
||||
t.Error("expected false when no alerts exist")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("has non-monitor-only alert returns false", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100-cpu"] = &Alert{
|
||||
ID: "vm100-cpu",
|
||||
ResourceID: "vm100",
|
||||
Type: "cpu",
|
||||
Metadata: nil, // No metadata means not monitor-only
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.guestHasMonitorOnlyAlerts("vm100")
|
||||
if result {
|
||||
t.Error("expected false when alert is not monitor-only")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("has monitor-only alert with bool metadata returns true", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100-cpu"] = &Alert{
|
||||
ID: "vm100-cpu",
|
||||
ResourceID: "vm100",
|
||||
Type: "cpu",
|
||||
Metadata: map[string]interface{}{
|
||||
"monitorOnly": true,
|
||||
},
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.guestHasMonitorOnlyAlerts("vm100")
|
||||
if !result {
|
||||
t.Error("expected true when monitor-only alert exists")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("has monitor-only alert with string metadata returns true", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100-cpu"] = &Alert{
|
||||
ID: "vm100-cpu",
|
||||
ResourceID: "vm100",
|
||||
Type: "cpu",
|
||||
Metadata: map[string]interface{}{
|
||||
"monitorOnly": "true",
|
||||
},
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.guestHasMonitorOnlyAlerts("vm100")
|
||||
if !result {
|
||||
t.Error("expected true when monitor-only alert exists (string metadata)")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("alert for different guest not matched", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm200-cpu"] = &Alert{
|
||||
ID: "vm200-cpu",
|
||||
ResourceID: "vm200",
|
||||
Type: "cpu",
|
||||
Metadata: map[string]interface{}{
|
||||
"monitorOnly": true,
|
||||
},
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.guestHasMonitorOnlyAlerts("vm100")
|
||||
if result {
|
||||
t.Error("expected false when monitor-only alert is for different guest")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("monitorOnly false returns false", func(t *testing.T) {
|
||||
m := newTestManager(t)
|
||||
|
||||
m.mu.Lock()
|
||||
m.activeAlerts["vm100-cpu"] = &Alert{
|
||||
ID: "vm100-cpu",
|
||||
ResourceID: "vm100",
|
||||
Type: "cpu",
|
||||
Metadata: map[string]interface{}{
|
||||
"monitorOnly": false,
|
||||
},
|
||||
}
|
||||
m.mu.Unlock()
|
||||
|
||||
result := m.guestHasMonitorOnlyAlerts("vm100")
|
||||
if result {
|
||||
t.Error("expected false when monitorOnly is explicitly false")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue