grafana/pkg/services/ngalert/notifier/alert_reception_test.go
gotjosh 9b52ffc6a9
Alerting: Fetch configuration from the database and run a notification service (#32175)
* Alerting: Fetch configuration from the database and run a notification
instance

Co-Authored-By: Ganesh Vernekar <15064823+codesome@users.noreply.github.com>
2021-03-24 14:20:44 +00:00

130 lines
3.6 KiB
Go

package notifier
import (
"context"
"errors"
"testing"
"github.com/go-kit/kit/log"
"github.com/prometheus/alertmanager/api/v2/models"
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/provider"
"github.com/prometheus/alertmanager/types"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
)
func TestAlertProvider_PutPostableAlert(t *testing.T) {
marker := types.NewMarker(prometheus.DefaultRegisterer)
stage := &mockStage{alerts: make(map[string][]*types.Alert)}
provider := &mockAlertProvider{}
ap, err := NewAlertProvider(stage, marker)
require.NoError(t, err)
ap.Alerts = provider
postableAlerts := []*PostableAlert{
{
// Goes through routing since no receiver.
PostableAlert: models.PostableAlert{
Annotations: models.LabelSet{"msg": "AlertOne annotation"},
Alert: models.Alert{
Labels: models.LabelSet{"alertname": "AlertOne"},
},
},
}, {
// Goes directly through notification pipeling since there is receiver.
PostableAlert: models.PostableAlert{
Annotations: models.LabelSet{"msg": "AlertTwo annotation"},
Alert: models.Alert{
Labels: models.LabelSet{"alertname": "AlertTwo"},
},
},
Receivers: []string{"recv1", "recv2"},
}, {
// Goes directly through notification pipeling since there is receiver.
PostableAlert: models.PostableAlert{
Annotations: models.LabelSet{"msg": "AlertThree annotation"},
Alert: models.Alert{
Labels: models.LabelSet{"alertname": "AlertThree"},
},
},
Receivers: []string{"recv2", "recv3"},
},
}
require.NoError(t, ap.PutPostableAlert(postableAlerts...))
// Alerts that should be sent for routing.
expProviderAlerts := []*types.Alert{
{
Alert: model.Alert{
Annotations: model.LabelSet{"msg": "AlertOne annotation"},
Labels: model.LabelSet{"alertname": "AlertOne"},
},
},
}
require.Equal(t, expProviderAlerts, provider.alerts)
// Alerts that should go directly to the notification pipeline.
expPipelineAlerts := map[string][]*types.Alert{
"recv1": {
{
Alert: model.Alert{
Annotations: model.LabelSet{"msg": "AlertTwo annotation"},
Labels: model.LabelSet{"alertname": "AlertTwo"},
},
},
},
"recv2": {
{
Alert: model.Alert{
Annotations: model.LabelSet{"msg": "AlertTwo annotation"},
Labels: model.LabelSet{"alertname": "AlertTwo"},
},
}, {
Alert: model.Alert{
Annotations: model.LabelSet{"msg": "AlertThree annotation"},
Labels: model.LabelSet{"alertname": "AlertThree"},
},
},
},
"recv3": {
{
Alert: model.Alert{
Annotations: model.LabelSet{"msg": "AlertThree annotation"},
Labels: model.LabelSet{"alertname": "AlertThree"},
},
},
},
}
require.Equal(t, expPipelineAlerts, stage.alerts)
}
type mockAlertProvider struct {
alerts []*types.Alert
}
func (a *mockAlertProvider) Subscribe() provider.AlertIterator { return nil }
func (a *mockAlertProvider) GetPending() provider.AlertIterator { return nil }
func (a *mockAlertProvider) Get(model.Fingerprint) (*types.Alert, error) { return nil, nil }
func (a *mockAlertProvider) Put(alerts ...*types.Alert) error {
a.alerts = append(a.alerts, alerts...)
return nil
}
type mockStage struct {
alerts map[string][]*types.Alert
}
func (s *mockStage) Exec(ctx context.Context, _ log.Logger, alerts ...*types.Alert) (context.Context, []*types.Alert, error) {
recv, ok := notify.ReceiverName(ctx)
if !ok {
return ctx, nil, errors.New("receiver name not found")
}
s.alerts[recv] = append(s.alerts[recv], alerts...)
return ctx, nil, nil
}