Pulse/internal/alerts/time_threshold_test.go
rcourtman 01f7d81d38 style: fix gofmt formatting inconsistencies
Run gofmt -w to fix tab/space inconsistencies across 33 files.
2025-11-26 23:44:36 +00:00

130 lines
3.3 KiB
Go

package alerts
import (
"testing"
"time"
)
func TestGetTimeThresholdMappings(t *testing.T) {
manager := NewManager()
manager.mu.Lock()
manager.config.TimeThresholds = map[string]int{
"guest": 300,
"node": 120,
"storage": 45,
"pbs": 90,
}
manager.config.TimeThreshold = 15
manager.mu.Unlock()
testCases := []struct {
resourceType string
expected int
}{
{"VM", 300},
{"Container", 300},
{"ct", 300},
{"guest", 300},
{"qemu", 300},
{"lxc", 300},
{"Node", 120},
{"storage", 45},
{"PBS", 90},
{"UNKNOWN", 15},
}
for _, tc := range testCases {
if got := manager.getTimeThreshold("", tc.resourceType, "cpu"); got != tc.expected {
t.Errorf("getTimeThreshold(%q, \"cpu\") = %d, want %d", tc.resourceType, got, tc.expected)
}
}
}
func TestGetTimeThresholdMetricOverrides(t *testing.T) {
manager := NewManager()
manager.mu.Lock()
manager.config.TimeThreshold = 15
manager.config.TimeThresholds = map[string]int{
"guest": 30,
"node": 60,
"storage": 90,
}
manager.config.MetricTimeThresholds = map[string]map[string]int{
"guest": {
"cpu": 5,
},
"node": {
"temperature": 120,
},
"all": {
"default": 20,
},
}
manager.mu.Unlock()
cases := []struct {
resourceID string
resourceType string
metricType string
expected int
}{
{"vm-resource", "VM", "cpu", 5}, // guest metric override
{"vm-resource", "VM", "memory", 30}, // falls back to guest type delay
{"node-1", "Node", "temperature", 120}, // node metric override
{"node-1", "Node", "cpu", 60}, // node type delay
{"storage-1", "storage", "usage", 90}, // storage type delay
{"unknown", "unknown", "cpu", 20}, // global default metric override
{"unknown", "unknown", "disk", 20},
}
for _, tc := range cases {
if got := manager.getTimeThreshold(tc.resourceID, tc.resourceType, tc.metricType); got != tc.expected {
t.Errorf("getTimeThreshold(%q, %q, %q) = %d, want %d", tc.resourceID, tc.resourceType, tc.metricType, got, tc.expected)
}
}
}
func TestCheckMetricUsesPendingStartTime(t *testing.T) {
manager := NewManager()
manager.mu.Lock()
manager.config.TimeThresholds["guest"] = 2
manager.mu.Unlock()
threshold := &HysteresisThreshold{Trigger: 80, Clear: 75}
// First exceedance should start tracking and not create an alert immediately.
manager.checkMetric("guest-123", "test-vm", "node1", "qemu/123", "VM", "cpu", 90, threshold, nil)
manager.mu.Lock()
if len(manager.activeAlerts) != 0 {
manager.mu.Unlock()
t.Fatalf("expected no active alerts after initial exceedance")
}
if _, ok := manager.pendingAlerts["guest-123-cpu"]; !ok {
manager.mu.Unlock()
t.Fatalf("expected pending alert tracking to be started")
}
forcedStart := time.Now().Add(-3 * time.Second)
manager.pendingAlerts["guest-123-cpu"] = forcedStart
manager.mu.Unlock()
// Second exceedance should trigger the alert using the pending start time.
manager.checkMetric("guest-123", "test-vm", "node1", "qemu/123", "VM", "cpu", 90, threshold, nil)
manager.mu.Lock()
alert, exists := manager.activeAlerts["guest-123-cpu"]
manager.mu.Unlock()
if !exists {
t.Fatalf("expected alert to be active after exceeding delay")
}
if !alert.StartTime.Equal(forcedStart) {
t.Fatalf("expected alert start time %v, got %v", forcedStart, alert.StartTime)
}
}