Merge candidate 20260908T013022Z-core-runtime

Retain exact reviewed delayed recovery receipt coverage.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-09-08 02:46:56 +01:00
@@ -71,3 +71,61 @@ func TestDeliveryReceiptPersistsAndIsClearedAfterRecovery(t *testing.T) {
t.Fatalf("receipt remained after recovery delivery: %+v", got)
}
}
// A delayed recovery for an earlier occurrence must consume only its own
// destination receipt, even when a recurrence has already fired before restart.
func TestDelayedRecoveryPreservesRecurringAndOtherDestinationReceipts(t *testing.T) {
dir := t.TempDir()
start := time.Date(2026, 9, 8, 1, 0, 0, 123, time.UTC)
old := &alerts.Alert{ID: "cpu-critical-1", StartTime: start}
current := old.Clone()
current.StartTime = start.Add(time.Nanosecond)
destinations := []WebhookConfig{
{ID: "ops", URL: "https://ops.example.test", Enabled: true},
{ID: "backup", URL: "https://backup.example.test", Enabled: true},
}
job := func(a *alerts.Alert, destination int, event notificationEvent) notificationDeliveryJob {
return notificationDeliveryJob{Type: "webhook", Event: event,
Alerts: []*alerts.Alert{a}, WebhookConfig: &destinations[destination]}
}
open := func() *NotificationManager {
m := NewNotificationManagerWithDataDir("", dir)
t.Cleanup(m.Stop)
return m
}
m := open()
for _, a := range []*alerts.Alert{old, current} {
for destination := range destinations {
m.recordSuccessfulDelivery(job(a, destination, eventAlert), start.Add(time.Minute))
}
}
m.Stop()
m = open()
assertReceipt := func(a *alerts.Alert, destination int, want bool) {
t.Helper()
got := m.filterResolvedJobsByDeliveryReceipt([]notificationDeliveryJob{job(a, destination, eventResolved)})
if (len(got) == 1) != want {
t.Fatalf("occurrence %s destination %d: eligible jobs=%d, want receipt=%t", a.StartTime, destination, len(got), want)
}
}
for _, a := range []*alerts.Alert{old, current} {
for destination := range destinations {
assertReceipt(a, destination, true)
}
}
// Duplicate completion must be harmless as well as the first completion.
for range 2 {
m.recordSuccessfulDelivery(job(old, 0, eventResolved), start.Add(2*time.Minute))
}
m.Stop()
m = open()
assertReceipt(old, 0, false)
assertReceipt(old, 1, true)
assertReceipt(current, 0, true)
assertReceipt(current, 1, true)
// The newer incident can still complete independently at either endpoint.
m.recordSuccessfulDelivery(job(current, 0, eventResolved), start.Add(3*time.Minute))
assertReceipt(current, 0, false)
assertReceipt(current, 1, true)
assertReceipt(old, 1, true)
}