Skip to content

Commit b5a29b6

Browse files
committed
test(alerting): add tests for when to send notifcations
1 parent 6edae37 commit b5a29b6

File tree

2 files changed

+118
-84
lines changed

2 files changed

+118
-84
lines changed

pkg/services/alerting/notifier.go

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,33 @@ import (
1212
)
1313

1414
type NotifierImpl struct {
15-
log log.Logger
15+
log log.Logger
16+
getNotifications func(orgId int64, notificationGroups []int64) []*Notification
1617
}
1718

1819
func NewNotifier() *NotifierImpl {
20+
log := log.New("alerting.notifier")
1921
return &NotifierImpl{
20-
log: log.New("alerting.notifier"),
22+
log: log,
23+
getNotifications: buildGetNotifiers(log),
2124
}
2225
}
2326

27+
func (n NotifierImpl) ShouldDispath(alertResult *AlertResult, notifier *Notification) bool {
28+
warn := alertResult.State == alertstates.Warn && notifier.SendWarning
29+
crit := alertResult.State == alertstates.Critical && notifier.SendCritical
30+
return (warn || crit) || alertResult.State == alertstates.Ok
31+
}
32+
2433
func (n *NotifierImpl) Notify(alertResult *AlertResult) {
25-
notifiers := n.getNotifiers(alertResult.AlertJob.Rule.OrgId, alertResult.AlertJob.Rule.NotificationGroups)
34+
notifiers := n.getNotifications(alertResult.AlertJob.Rule.OrgId, alertResult.AlertJob.Rule.NotificationGroups)
2635

2736
for _, notifier := range notifiers {
28-
warn := alertResult.State == alertstates.Warn && notifier.SendWarning
29-
crit := alertResult.State == alertstates.Critical && notifier.SendCritical
30-
if (warn || crit) || alertResult.State == alertstates.Ok {
37+
if n.ShouldDispath(alertResult, notifier) {
3138
n.log.Info("Sending notification", "state", alertResult.State, "type", notifier.Type)
3239
go notifier.Notifierr.Dispatch(alertResult)
3340
}
3441
}
35-
3642
}
3743

3844
type Notification struct {
@@ -107,29 +113,31 @@ type NotificationDispatcher interface {
107113
Dispatch(alertResult *AlertResult)
108114
}
109115

110-
func (n *NotifierImpl) getNotifiers(orgId int64, notificationGroups []int64) []*Notification {
111-
query := &m.GetAlertNotificationQuery{
112-
OrgID: orgId,
113-
Ids: notificationGroups,
114-
IncludeAlwaysExecute: true,
115-
}
116-
err := bus.Dispatch(query)
117-
if err != nil {
118-
n.log.Error("Failed to read notifications", "error", err)
119-
}
116+
func buildGetNotifiers(log log.Logger) func(orgId int64, notificationGroups []int64) []*Notification {
117+
return func(orgId int64, notificationGroups []int64) []*Notification {
118+
query := &m.GetAlertNotificationQuery{
119+
OrgID: orgId,
120+
Ids: notificationGroups,
121+
IncludeAlwaysExecute: true,
122+
}
123+
err := bus.Dispatch(query)
124+
if err != nil {
125+
log.Error("Failed to read notifications", "error", err)
126+
}
120127

121-
var result []*Notification
122-
n.log.Info("notifiriring", "count", len(query.Result), "groups", notificationGroups)
123-
for _, notification := range query.Result {
124-
not, err := NewNotificationFromDBModel(notification)
125-
if err == nil {
126-
result = append(result, not)
127-
} else {
128-
n.log.Error("Failed to read notification model", "error", err)
128+
var result []*Notification
129+
log.Info("notifiriring", "count", len(query.Result), "groups", notificationGroups)
130+
for _, notification := range query.Result {
131+
not, err := NewNotificationFromDBModel(notification)
132+
if err == nil {
133+
result = append(result, not)
134+
} else {
135+
log.Error("Failed to read notification model", "error", err)
136+
}
129137
}
130-
}
131138

132-
return result
139+
return result
140+
}
133141
}
134142

135143
func NewNotificationFromDBModel(model *m.AlertNotification) (*Notification, error) {

pkg/services/alerting/notifier_test.go

Lines changed: 83 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,93 +7,119 @@ import (
77

88
"github.com/grafana/grafana/pkg/components/simplejson"
99
m "github.com/grafana/grafana/pkg/models"
10+
"github.com/grafana/grafana/pkg/services/alerting/alertstates"
1011
. "github.com/smartystreets/goconvey/convey"
1112
)
1213

1314
func TestAlertNotificationExtraction(t *testing.T) {
15+
Convey("Notifier tests", t, func() {
16+
Convey("rules for sending notifications", func() {
17+
dummieNotifier := NotifierImpl{}
18+
19+
result := &AlertResult{
20+
State: alertstates.Critical,
21+
}
22+
23+
notifier := &Notification{
24+
Name: "Test Notifier",
25+
Type: "TestType",
26+
SendCritical: true,
27+
SendWarning: true,
28+
}
29+
30+
Convey("Should send notification", func() {
31+
So(dummieNotifier.ShouldDispath(result, notifier), ShouldBeTrue)
32+
})
1433

15-
Convey("Parsing alert notification from settings", t, func() {
16-
Convey("Parsing email", func() {
17-
Convey("empty settings should return error", func() {
18-
json := `{ }`
34+
Convey("warn:false and state:warn should not send", func() {
35+
result.State = alertstates.Warn
36+
notifier.SendWarning = false
37+
So(dummieNotifier.ShouldDispath(result, notifier), ShouldBeFalse)
38+
})
39+
})
1940

20-
settingsJSON, _ := simplejson.NewJson([]byte(json))
21-
model := &m.AlertNotification{
22-
Name: "ops",
23-
Type: "email",
24-
Settings: settingsJSON,
25-
}
41+
Convey("Parsing alert notification from settings", func() {
42+
Convey("Parsing email", func() {
43+
Convey("empty settings should return error", func() {
44+
json := `{ }`
2645

27-
_, err := NewNotificationFromDBModel(model)
28-
So(err, ShouldNotBeNil)
29-
})
46+
settingsJSON, _ := simplejson.NewJson([]byte(json))
47+
model := &m.AlertNotification{
48+
Name: "ops",
49+
Type: "email",
50+
Settings: settingsJSON,
51+
}
3052

31-
Convey("from settings", func() {
32-
json := `
53+
_, err := NewNotificationFromDBModel(model)
54+
So(err, ShouldNotBeNil)
55+
})
56+
57+
Convey("from settings", func() {
58+
json := `
3359
{
3460
"to": "ops@grafana.org"
3561
}`
3662

37-
settingsJSON, _ := simplejson.NewJson([]byte(json))
38-
model := &m.AlertNotification{
39-
Name: "ops",
40-
Type: "email",
41-
Settings: settingsJSON,
42-
}
63+
settingsJSON, _ := simplejson.NewJson([]byte(json))
64+
model := &m.AlertNotification{
65+
Name: "ops",
66+
Type: "email",
67+
Settings: settingsJSON,
68+
}
4369

44-
not, err := NewNotificationFromDBModel(model)
70+
not, err := NewNotificationFromDBModel(model)
4571

46-
So(err, ShouldBeNil)
47-
So(not.Name, ShouldEqual, "ops")
48-
So(not.Type, ShouldEqual, "email")
49-
So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.EmailNotifier")
72+
So(err, ShouldBeNil)
73+
So(not.Name, ShouldEqual, "ops")
74+
So(not.Type, ShouldEqual, "email")
75+
So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.EmailNotifier")
5076

51-
email := not.Notifierr.(*EmailNotifier)
52-
So(email.To, ShouldEqual, "ops@grafana.org")
77+
email := not.Notifierr.(*EmailNotifier)
78+
So(email.To, ShouldEqual, "ops@grafana.org")
79+
})
5380
})
54-
})
5581

56-
Convey("Parsing webhook", func() {
57-
Convey("empty settings should return error", func() {
58-
json := `{ }`
82+
Convey("Parsing webhook", func() {
83+
Convey("empty settings should return error", func() {
84+
json := `{ }`
5985

60-
settingsJSON, _ := simplejson.NewJson([]byte(json))
61-
model := &m.AlertNotification{
62-
Name: "ops",
63-
Type: "webhook",
64-
Settings: settingsJSON,
65-
}
86+
settingsJSON, _ := simplejson.NewJson([]byte(json))
87+
model := &m.AlertNotification{
88+
Name: "ops",
89+
Type: "webhook",
90+
Settings: settingsJSON,
91+
}
6692

67-
_, err := NewNotificationFromDBModel(model)
68-
So(err, ShouldNotBeNil)
69-
})
93+
_, err := NewNotificationFromDBModel(model)
94+
So(err, ShouldNotBeNil)
95+
})
7096

71-
Convey("from settings", func() {
72-
json := `
97+
Convey("from settings", func() {
98+
json := `
7399
{
74100
"url": "http://localhost:3000",
75101
"username": "username",
76102
"password": "password"
77103
}`
78104

79-
settingsJSON, _ := simplejson.NewJson([]byte(json))
80-
model := &m.AlertNotification{
81-
Name: "slack",
82-
Type: "webhook",
83-
Settings: settingsJSON,
84-
}
105+
settingsJSON, _ := simplejson.NewJson([]byte(json))
106+
model := &m.AlertNotification{
107+
Name: "slack",
108+
Type: "webhook",
109+
Settings: settingsJSON,
110+
}
85111

86-
not, err := NewNotificationFromDBModel(model)
112+
not, err := NewNotificationFromDBModel(model)
87113

88-
So(err, ShouldBeNil)
89-
So(not.Name, ShouldEqual, "slack")
90-
So(not.Type, ShouldEqual, "webhook")
91-
So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.WebhookNotifier")
114+
So(err, ShouldBeNil)
115+
So(not.Name, ShouldEqual, "slack")
116+
So(not.Type, ShouldEqual, "webhook")
117+
So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.WebhookNotifier")
92118

93-
webhook := not.Notifierr.(*WebhookNotifier)
94-
So(webhook.Url, ShouldEqual, "http://localhost:3000")
119+
webhook := not.Notifierr.(*WebhookNotifier)
120+
So(webhook.Url, ShouldEqual, "http://localhost:3000")
121+
})
95122
})
96123
})
97-
98124
})
99125
}

0 commit comments

Comments
 (0)