mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-04-28 11:30:15 +00:00
130 lines
3.3 KiB
Go
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)
|
|
}
|
|
}
|