From b5a29b624670891972c129a6833cfd310e5180bb Mon Sep 17 00:00:00 2001 From: bergquist Date: Wed, 22 Jun 2016 07:58:30 +0200 Subject: [PATCH] test(alerting): add tests for when to send notifcations --- pkg/services/alerting/notifier.go | 64 ++++++----- pkg/services/alerting/notifier_test.go | 144 +++++++++++++++---------- 2 files changed, 121 insertions(+), 87 deletions(-) diff --git a/pkg/services/alerting/notifier.go b/pkg/services/alerting/notifier.go index 57da39b88e9..f39f148ce8d 100644 --- a/pkg/services/alerting/notifier.go +++ b/pkg/services/alerting/notifier.go @@ -12,27 +12,33 @@ import ( ) type NotifierImpl struct { - log log.Logger + log log.Logger + getNotifications func(orgId int64, notificationGroups []int64) []*Notification } func NewNotifier() *NotifierImpl { + log := log.New("alerting.notifier") return &NotifierImpl{ - log: log.New("alerting.notifier"), + log: log, + getNotifications: buildGetNotifiers(log), } } +func (n NotifierImpl) ShouldDispath(alertResult *AlertResult, notifier *Notification) bool { + warn := alertResult.State == alertstates.Warn && notifier.SendWarning + crit := alertResult.State == alertstates.Critical && notifier.SendCritical + return (warn || crit) || alertResult.State == alertstates.Ok +} + func (n *NotifierImpl) Notify(alertResult *AlertResult) { - notifiers := n.getNotifiers(alertResult.AlertJob.Rule.OrgId, alertResult.AlertJob.Rule.NotificationGroups) + notifiers := n.getNotifications(alertResult.AlertJob.Rule.OrgId, alertResult.AlertJob.Rule.NotificationGroups) for _, notifier := range notifiers { - warn := alertResult.State == alertstates.Warn && notifier.SendWarning - crit := alertResult.State == alertstates.Critical && notifier.SendCritical - if (warn || crit) || alertResult.State == alertstates.Ok { + if n.ShouldDispath(alertResult, notifier) { n.log.Info("Sending notification", "state", alertResult.State, "type", notifier.Type) go notifier.Notifierr.Dispatch(alertResult) } } - } type Notification struct { @@ -107,29 +113,31 @@ type NotificationDispatcher interface { Dispatch(alertResult *AlertResult) } -func (n *NotifierImpl) getNotifiers(orgId int64, notificationGroups []int64) []*Notification { - query := &m.GetAlertNotificationQuery{ - OrgID: orgId, - Ids: notificationGroups, - IncludeAlwaysExecute: true, - } - err := bus.Dispatch(query) - if err != nil { - n.log.Error("Failed to read notifications", "error", err) - } - - var result []*Notification - n.log.Info("notifiriring", "count", len(query.Result), "groups", notificationGroups) - for _, notification := range query.Result { - not, err := NewNotificationFromDBModel(notification) - if err == nil { - result = append(result, not) - } else { - n.log.Error("Failed to read notification model", "error", err) +func buildGetNotifiers(log log.Logger) func(orgId int64, notificationGroups []int64) []*Notification { + return func(orgId int64, notificationGroups []int64) []*Notification { + query := &m.GetAlertNotificationQuery{ + OrgID: orgId, + Ids: notificationGroups, + IncludeAlwaysExecute: true, + } + err := bus.Dispatch(query) + if err != nil { + log.Error("Failed to read notifications", "error", err) } - } - return result + var result []*Notification + log.Info("notifiriring", "count", len(query.Result), "groups", notificationGroups) + for _, notification := range query.Result { + not, err := NewNotificationFromDBModel(notification) + if err == nil { + result = append(result, not) + } else { + log.Error("Failed to read notification model", "error", err) + } + } + + return result + } } func NewNotificationFromDBModel(model *m.AlertNotification) (*Notification, error) { diff --git a/pkg/services/alerting/notifier_test.go b/pkg/services/alerting/notifier_test.go index a7d720d01d9..4bb24661549 100644 --- a/pkg/services/alerting/notifier_test.go +++ b/pkg/services/alerting/notifier_test.go @@ -7,93 +7,119 @@ import ( "github.com/grafana/grafana/pkg/components/simplejson" m "github.com/grafana/grafana/pkg/models" + "github.com/grafana/grafana/pkg/services/alerting/alertstates" . "github.com/smartystreets/goconvey/convey" ) func TestAlertNotificationExtraction(t *testing.T) { + Convey("Notifier tests", t, func() { + Convey("rules for sending notifications", func() { + dummieNotifier := NotifierImpl{} - Convey("Parsing alert notification from settings", t, func() { - Convey("Parsing email", func() { - Convey("empty settings should return error", func() { - json := `{ }` + result := &AlertResult{ + State: alertstates.Critical, + } - settingsJSON, _ := simplejson.NewJson([]byte(json)) - model := &m.AlertNotification{ - Name: "ops", - Type: "email", - Settings: settingsJSON, - } + notifier := &Notification{ + Name: "Test Notifier", + Type: "TestType", + SendCritical: true, + SendWarning: true, + } - _, err := NewNotificationFromDBModel(model) - So(err, ShouldNotBeNil) + Convey("Should send notification", func() { + So(dummieNotifier.ShouldDispath(result, notifier), ShouldBeTrue) }) - Convey("from settings", func() { - json := ` + Convey("warn:false and state:warn should not send", func() { + result.State = alertstates.Warn + notifier.SendWarning = false + So(dummieNotifier.ShouldDispath(result, notifier), ShouldBeFalse) + }) + }) + + Convey("Parsing alert notification from settings", func() { + Convey("Parsing email", func() { + Convey("empty settings should return error", func() { + json := `{ }` + + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "ops", + Type: "email", + Settings: settingsJSON, + } + + _, err := NewNotificationFromDBModel(model) + So(err, ShouldNotBeNil) + }) + + Convey("from settings", func() { + json := ` { "to": "ops@grafana.org" }` - settingsJSON, _ := simplejson.NewJson([]byte(json)) - model := &m.AlertNotification{ - Name: "ops", - Type: "email", - Settings: settingsJSON, - } + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "ops", + Type: "email", + Settings: settingsJSON, + } - not, err := NewNotificationFromDBModel(model) + not, err := NewNotificationFromDBModel(model) - So(err, ShouldBeNil) - So(not.Name, ShouldEqual, "ops") - So(not.Type, ShouldEqual, "email") - So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.EmailNotifier") + So(err, ShouldBeNil) + So(not.Name, ShouldEqual, "ops") + So(not.Type, ShouldEqual, "email") + So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.EmailNotifier") - email := not.Notifierr.(*EmailNotifier) - So(email.To, ShouldEqual, "ops@grafana.org") - }) - }) - - Convey("Parsing webhook", func() { - Convey("empty settings should return error", func() { - json := `{ }` - - settingsJSON, _ := simplejson.NewJson([]byte(json)) - model := &m.AlertNotification{ - Name: "ops", - Type: "webhook", - Settings: settingsJSON, - } - - _, err := NewNotificationFromDBModel(model) - So(err, ShouldNotBeNil) + email := not.Notifierr.(*EmailNotifier) + So(email.To, ShouldEqual, "ops@grafana.org") + }) }) - Convey("from settings", func() { - json := ` + Convey("Parsing webhook", func() { + Convey("empty settings should return error", func() { + json := `{ }` + + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "ops", + Type: "webhook", + Settings: settingsJSON, + } + + _, err := NewNotificationFromDBModel(model) + So(err, ShouldNotBeNil) + }) + + Convey("from settings", func() { + json := ` { "url": "http://localhost:3000", "username": "username", "password": "password" }` - settingsJSON, _ := simplejson.NewJson([]byte(json)) - model := &m.AlertNotification{ - Name: "slack", - Type: "webhook", - Settings: settingsJSON, - } + settingsJSON, _ := simplejson.NewJson([]byte(json)) + model := &m.AlertNotification{ + Name: "slack", + Type: "webhook", + Settings: settingsJSON, + } - not, err := NewNotificationFromDBModel(model) + not, err := NewNotificationFromDBModel(model) - So(err, ShouldBeNil) - So(not.Name, ShouldEqual, "slack") - So(not.Type, ShouldEqual, "webhook") - So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.WebhookNotifier") + So(err, ShouldBeNil) + So(not.Name, ShouldEqual, "slack") + So(not.Type, ShouldEqual, "webhook") + So(reflect.TypeOf(not.Notifierr).Elem().String(), ShouldEqual, "alerting.WebhookNotifier") - webhook := not.Notifierr.(*WebhookNotifier) - So(webhook.Url, ShouldEqual, "http://localhost:3000") + webhook := not.Notifierr.(*WebhookNotifier) + So(webhook.Url, ShouldEqual, "http://localhost:3000") + }) }) }) - }) }