test: Add comprehensive tests for safeCallEscalateCallback function
- calls callback with alert and level - noop when callback is nil - recovers from panic in callback - clones alert to prevent concurrent modification - safeCallEscalateCallback 0%→100%
This commit is contained in:
parent
d7360c7b22
commit
9f1a5c2183
1 changed files with 109 additions and 0 deletions
|
|
@ -3771,3 +3771,112 @@ func TestCleanupDockerContainerAlerts(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSafeCallEscalateCallback(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("calls callback with alert and level", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
m := NewManager()
|
||||
|
||||
var receivedAlert *Alert
|
||||
var receivedLevel int
|
||||
done := make(chan struct{})
|
||||
|
||||
m.SetEscalateCallback(func(alert *Alert, level int) {
|
||||
receivedAlert = alert
|
||||
receivedLevel = level
|
||||
close(done)
|
||||
})
|
||||
|
||||
alert := &Alert{
|
||||
ID: "test-alert",
|
||||
Type: "test",
|
||||
ResourceName: "resource-1",
|
||||
}
|
||||
|
||||
m.safeCallEscalateCallback(alert, 2)
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
if receivedAlert == nil {
|
||||
t.Fatal("expected alert to be received")
|
||||
}
|
||||
if receivedAlert.ID != "test-alert" {
|
||||
t.Errorf("expected alert ID 'test-alert', got %q", receivedAlert.ID)
|
||||
}
|
||||
if receivedLevel != 2 {
|
||||
t.Errorf("expected level 2, got %d", receivedLevel)
|
||||
}
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatal("callback not called within timeout")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("noop when callback is nil", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
m := NewManager()
|
||||
// No callback set
|
||||
|
||||
alert := &Alert{ID: "test-alert"}
|
||||
|
||||
// Should not panic
|
||||
m.safeCallEscalateCallback(alert, 1)
|
||||
})
|
||||
|
||||
t.Run("recovers from panic in callback", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
m := NewManager()
|
||||
|
||||
done := make(chan struct{})
|
||||
m.SetEscalateCallback(func(alert *Alert, level int) {
|
||||
defer close(done)
|
||||
panic("test panic")
|
||||
})
|
||||
|
||||
alert := &Alert{ID: "panic-test"}
|
||||
|
||||
// Should not panic the caller
|
||||
m.safeCallEscalateCallback(alert, 1)
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
// Callback ran (and panicked, but recovered)
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatal("callback not called within timeout")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("clones alert to prevent modification", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
m := NewManager()
|
||||
|
||||
var receivedAlert *Alert
|
||||
done := make(chan struct{})
|
||||
|
||||
m.SetEscalateCallback(func(alert *Alert, level int) {
|
||||
receivedAlert = alert
|
||||
close(done)
|
||||
})
|
||||
|
||||
original := &Alert{
|
||||
ID: "original-alert",
|
||||
ResourceName: "original-resource",
|
||||
}
|
||||
|
||||
m.safeCallEscalateCallback(original, 1)
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
// Modify original after callback started
|
||||
original.ResourceName = "modified"
|
||||
|
||||
// Received alert should be a clone, not affected by modification
|
||||
if receivedAlert.ID != "original-alert" {
|
||||
t.Errorf("expected cloned alert ID")
|
||||
}
|
||||
case <-time.After(1 * time.Second):
|
||||
t.Fatal("callback not called within timeout")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue