diff --git a/cmd/prometheus/main.go b/cmd/prometheus/main.go index 0a255547a8..30cf95088f 100644 --- a/cmd/prometheus/main.go +++ b/cmd/prometheus/main.go @@ -696,8 +696,12 @@ func computeExternalURL(u, listenAddr string) (*url.URL, error) { return eu, nil } +type sender interface { + Send(alerts ...*notifier.Alert) +} + // sendAlerts implements the rules.NotifyFunc for a Notifier. -func sendAlerts(n *notifier.Manager, externalURL string) rules.NotifyFunc { +func sendAlerts(s sender, externalURL string) rules.NotifyFunc { return func(ctx context.Context, expr string, alerts ...*rules.Alert) { var res []*notifier.Alert @@ -717,7 +721,7 @@ func sendAlerts(n *notifier.Manager, externalURL string) rules.NotifyFunc { } if len(alerts) > 0 { - n.Send(res...) + s.Send(res...) } } } diff --git a/cmd/prometheus/main_test.go b/cmd/prometheus/main_test.go index 605ba816eb..c6697a101f 100644 --- a/cmd/prometheus/main_test.go +++ b/cmd/prometheus/main_test.go @@ -14,6 +14,7 @@ package main import ( + "context" "flag" "fmt" "net/http" @@ -24,6 +25,9 @@ import ( "testing" "time" + "github.com/prometheus/prometheus/notifier" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/rules" "github.com/prometheus/prometheus/util/testutil" ) @@ -173,3 +177,73 @@ func TestFailedStartupExitCode(t *testing.T) { t.Errorf("unable to retrieve the exit status for prometheus: %v", err) } } + +type senderFunc func(alerts ...*notifier.Alert) + +func (s senderFunc) Send(alerts ...*notifier.Alert) { + s(alerts...) +} + +func TestSendAlerts(t *testing.T) { + testCases := []struct { + in []*rules.Alert + exp []*notifier.Alert + }{ + { + in: []*rules.Alert{ + &rules.Alert{ + Labels: []labels.Label{{Name: "l1", Value: "v1"}}, + Annotations: []labels.Label{{Name: "a2", Value: "v2"}}, + ActiveAt: time.Unix(1, 0), + FiredAt: time.Unix(2, 0), + ValidUntil: time.Unix(3, 0), + }, + }, + exp: []*notifier.Alert{ + ¬ifier.Alert{ + Labels: []labels.Label{{Name: "l1", Value: "v1"}}, + Annotations: []labels.Label{{Name: "a2", Value: "v2"}}, + StartsAt: time.Unix(2, 0), + EndsAt: time.Unix(3, 0), + GeneratorURL: "http://localhost:9090/graph?g0.expr=up&g0.tab=1", + }, + }, + }, + { + in: []*rules.Alert{ + &rules.Alert{ + Labels: []labels.Label{{Name: "l1", Value: "v1"}}, + Annotations: []labels.Label{{Name: "a2", Value: "v2"}}, + ActiveAt: time.Unix(1, 0), + FiredAt: time.Unix(2, 0), + ResolvedAt: time.Unix(4, 0), + }, + }, + exp: []*notifier.Alert{ + ¬ifier.Alert{ + Labels: []labels.Label{{Name: "l1", Value: "v1"}}, + Annotations: []labels.Label{{Name: "a2", Value: "v2"}}, + StartsAt: time.Unix(2, 0), + EndsAt: time.Unix(4, 0), + GeneratorURL: "http://localhost:9090/graph?g0.expr=up&g0.tab=1", + }, + }, + }, + { + in: []*rules.Alert{}, + }, + } + + for i, tc := range testCases { + tc := tc + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + senderFunc := senderFunc(func(alerts ...*notifier.Alert) { + if len(tc.in) == 0 { + t.Fatalf("sender called with 0 alert") + } + testutil.Equals(t, tc.exp, alerts) + }) + sendAlerts(senderFunc, "http://localhost:9090")(context.TODO(), "up", tc.in...) + }) + } +}