The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/services/alerting/notifiers/base_test.go

214 lines
5.7 KiB

package notifiers
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
. "github.com/smartystreets/goconvey/convey"
)
func TestShouldSendAlertNotification(t *testing.T) {
tnow := time.Now()
tcs := []struct {
name string
prevState models.AlertStateType
newState models.AlertStateType
sendReminder bool
frequency time.Duration
state *models.AlertNotificationState
expect bool
}{
{
name: "pending -> ok should not trigger an notification",
newState: models.AlertStateOK,
prevState: models.AlertStatePending,
sendReminder: false,
expect: false,
},
{
name: "ok -> alerting should trigger an notification",
newState: models.AlertStateAlerting,
prevState: models.AlertStateOK,
sendReminder: false,
expect: true,
},
{
name: "ok -> pending should not trigger an notification",
newState: models.AlertStatePending,
prevState: models.AlertStateOK,
sendReminder: false,
expect: false,
},
{
name: "ok -> ok should not trigger an notification",
newState: models.AlertStateOK,
prevState: models.AlertStateOK,
sendReminder: false,
expect: false,
},
{
name: "ok -> ok with reminder should not trigger an notification",
newState: models.AlertStateOK,
prevState: models.AlertStateOK,
sendReminder: true,
expect: false,
},
{
name: "alerting -> ok should trigger an notification",
newState: models.AlertStateOK,
prevState: models.AlertStateAlerting,
sendReminder: false,
expect: true,
},
{
name: "alerting -> ok should trigger an notification when reminders enabled",
newState: models.AlertStateOK,
prevState: models.AlertStateAlerting,
frequency: time.Minute * 10,
sendReminder: true,
state: &models.AlertNotificationState{UpdatedAt: tnow.Add(-time.Minute).Unix()},
expect: true,
},
{
name: "alerting -> alerting with reminder and no state should trigger",
newState: models.AlertStateAlerting,
prevState: models.AlertStateAlerting,
frequency: time.Minute * 10,
sendReminder: true,
expect: true,
},
{
name: "alerting -> alerting with reminder and last notification sent 1 minute ago should not trigger",
newState: models.AlertStateAlerting,
prevState: models.AlertStateAlerting,
frequency: time.Minute * 10,
sendReminder: true,
state: &models.AlertNotificationState{UpdatedAt: tnow.Add(-time.Minute).Unix()},
expect: false,
},
{
name: "alerting -> alerting with reminder and last notifciation sent 11 minutes ago should trigger",
newState: models.AlertStateAlerting,
prevState: models.AlertStateAlerting,
frequency: time.Minute * 10,
sendReminder: true,
state: &models.AlertNotificationState{UpdatedAt: tnow.Add(-11 * time.Minute).Unix()},
expect: true,
},
{
name: "OK -> alerting with notifciation state pending and updated 30 seconds ago should not trigger",
newState: models.AlertStateAlerting,
prevState: models.AlertStateOK,
state: &models.AlertNotificationState{State: models.AlertNotificationStatePending, UpdatedAt: tnow.Add(-30 * time.Second).Unix()},
expect: false,
},
{
name: "OK -> alerting with notifciation state pending and updated 2 minutes ago should trigger",
newState: models.AlertStateAlerting,
prevState: models.AlertStateOK,
state: &models.AlertNotificationState{State: models.AlertNotificationStatePending, UpdatedAt: tnow.Add(-2 * time.Minute).Unix()},
expect: true,
},
{
name: "unknown -> ok",
prevState: models.AlertStateUnknown,
newState: models.AlertStateOK,
expect: false,
},
{
name: "unknown -> pending",
prevState: models.AlertStateUnknown,
newState: models.AlertStatePending,
expect: false,
},
{
name: "unknown -> alerting",
prevState: models.AlertStateUnknown,
newState: models.AlertStateAlerting,
expect: true,
},
{
name: "no_data -> pending",
prevState: models.AlertStateNoData,
newState: models.AlertStatePending,
expect: false,
},
}
for _, tc := range tcs {
evalContext := alerting.NewEvalContext(context.Background(), &alerting.Rule{
State: tc.prevState,
})
if tc.state == nil {
tc.state = &models.AlertNotificationState{}
}
evalContext.Rule.State = tc.newState
nb := &NotifierBase{SendReminder: tc.sendReminder, Frequency: tc.frequency}
r := nb.ShouldNotify(evalContext.Ctx, evalContext, tc.state)
assert.Equal(t, r, tc.expect, "failed test %s. expected %+v to return: %v", tc.name, tc, tc.expect)
}
}
func TestBaseNotifier(t *testing.T) {
Convey("default constructor for notifiers", t, func() {
bJson := simplejson.New()
model := &models.AlertNotification{
Uid: "1",
Name: "name",
Type: "email",
Settings: bJson,
}
Convey("can parse false value", func() {
bJson.Set("uploadImage", false)
base := NewNotifierBase(model)
So(base.UploadImage, ShouldBeFalse)
})
Convey("can parse true value", func() {
bJson.Set("uploadImage", true)
base := NewNotifierBase(model)
So(base.UploadImage, ShouldBeTrue)
})
Convey("default value should be true for backwards compatibility", func() {
base := NewNotifierBase(model)
So(base.UploadImage, ShouldBeTrue)
})
Convey("default value should be false for backwards compatibility", func() {
base := NewNotifierBase(model)
So(base.DisableResolveMessage, ShouldBeFalse)
})
})
}