grafana/pkg/services/ngalert/state/persister_sync_test.go

104 lines
3.3 KiB
Go
Raw Normal View History

package state
import (
"context"
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"k8s.io/component-base/tracing"
"github.com/grafana/grafana/pkg/infra/log/logtest"
"github.com/grafana/grafana/pkg/services/ngalert/eval"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/util"
)
func TestSyncPersister_saveAlertStates(t *testing.T) {
type stateWithReason struct {
State eval.State
Reason string
}
create := func(s eval.State, r string) stateWithReason {
return stateWithReason{
State: s,
Reason: r,
}
}
allStates := [...]stateWithReason{
create(eval.Normal, ""),
create(eval.Normal, eval.NoData.String()),
create(eval.Normal, eval.Error.String()),
create(eval.Normal, util.GenerateShortUID()),
create(eval.Alerting, ""),
create(eval.Pending, ""),
create(eval.NoData, ""),
create(eval.Error, ""),
}
transitionToKey := map[ngmodels.AlertInstanceKey]StateTransition{}
transitions := make([]StateTransition, 0)
for _, fromState := range allStates {
for i, toState := range allStates {
tr := StateTransition{
State: &State{
State: toState.State,
StateReason: toState.Reason,
Labels: ngmodels.GenerateAlertLabels(5, fmt.Sprintf("%d--", i)),
},
PreviousState: fromState.State,
PreviousStateReason: fromState.Reason,
}
key, err := tr.GetAlertInstanceKey()
require.NoError(t, err)
transitionToKey[key] = tr
transitions = append(transitions, tr)
}
}
t.Run("should save all transitions if doNotSaveNormalState is false", func(t *testing.T) {
trace := tracing.NewNoopTracerProvider().Tracer("test")
_, span := trace.Start(context.Background(), "")
st := &FakeInstanceStore{}
syncStatePersister := NewSyncStatePersisiter(&logtest.Fake{}, ManagerCfg{
InstanceStore: st,
MaxStateSaveConcurrency: 1,
})
syncStatePersister.Sync(context.Background(), span, transitions, nil)
savedKeys := map[ngmodels.AlertInstanceKey]ngmodels.AlertInstance{}
for _, op := range st.RecordedOps() {
saved := op.(ngmodels.AlertInstance)
savedKeys[saved.AlertInstanceKey] = saved
}
assert.Len(t, transitionToKey, len(savedKeys))
for key, tr := range transitionToKey {
assert.Containsf(t, savedKeys, key, "state %s (%s) was not saved but should be", tr.State.State, tr.StateReason)
}
})
t.Run("should not save Normal->Normal if doNotSaveNormalState is true", func(t *testing.T) {
trace := tracing.NewNoopTracerProvider().Tracer("test")
_, span := trace.Start(context.Background(), "")
st := &FakeInstanceStore{}
syncStatePersister := NewSyncStatePersisiter(&logtest.Fake{}, ManagerCfg{
InstanceStore: st,
MaxStateSaveConcurrency: 1,
})
syncStatePersister.Sync(context.Background(), span, transitions, nil)
savedKeys := map[ngmodels.AlertInstanceKey]ngmodels.AlertInstance{}
for _, op := range st.RecordedOps() {
saved := op.(ngmodels.AlertInstance)
savedKeys[saved.AlertInstanceKey] = saved
}
for key, tr := range transitionToKey {
if tr.State.State == eval.Normal && tr.StateReason == "" && tr.PreviousState == eval.Normal && tr.PreviousStateReason == "" {
continue
}
assert.Containsf(t, savedKeys, key, "state %s (%s) was not saved but should be", tr.State.State, tr.StateReason)
}
})
}