mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Decouple schedule package from store (#55858)
* Separate out fake for scheduler tests * Delete extracted methods from older fake
This commit is contained in:
@@ -29,7 +29,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/metrics"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
@@ -38,8 +37,8 @@ func TestSchedule_ruleRoutine(t *testing.T) {
|
||||
createSchedule := func(
|
||||
evalAppliedChan chan time.Time,
|
||||
senderMock *AlertsSenderMock,
|
||||
) (*schedule, *store.FakeRuleStore, *state.FakeInstanceStore, prometheus.Gatherer) {
|
||||
ruleStore := store.NewFakeRuleStore(t)
|
||||
) (*schedule, *fakeRulesStore, *state.FakeInstanceStore, prometheus.Gatherer) {
|
||||
ruleStore := newFakeRulesStore()
|
||||
instanceStore := &state.FakeInstanceStore{}
|
||||
|
||||
registry := prometheus.NewPedanticRegistry()
|
||||
@@ -63,7 +62,7 @@ func TestSchedule_ruleRoutine(t *testing.T) {
|
||||
|
||||
rule := models.AlertRuleGen(withQueryForState(t, evalState))()
|
||||
ruleStore.PutRule(context.Background(), rule)
|
||||
folder, _ := ruleStore.GetNamespaceByUID(context.Background(), rule.NamespaceUID, rule.OrgID, nil)
|
||||
folderTitle := ruleStore.getNamespaceTitle(rule.NamespaceUID)
|
||||
go func() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
@@ -75,7 +74,7 @@ func TestSchedule_ruleRoutine(t *testing.T) {
|
||||
evalChan <- &evaluation{
|
||||
scheduledAt: expectedTime,
|
||||
rule: rule,
|
||||
folderTitle: folder.Title,
|
||||
folderTitle: folderTitle,
|
||||
}
|
||||
|
||||
actualTime := waitForTimeChannel(t, evalAppliedChan)
|
||||
@@ -87,7 +86,7 @@ func TestSchedule_ruleRoutine(t *testing.T) {
|
||||
assert.Equal(t, rule.UID, s.Labels[models.RuleUIDLabel])
|
||||
assert.Equal(t, rule.NamespaceUID, s.Labels[models.NamespaceUIDLabel])
|
||||
assert.Equal(t, rule.Title, s.Labels[prometheusModel.AlertNameLabel])
|
||||
assert.Equal(t, folder.Title, s.Labels[models.FolderTitleLabel])
|
||||
assert.Equal(t, folderTitle, s.Labels[models.FolderTitleLabel])
|
||||
}
|
||||
})
|
||||
|
||||
@@ -481,14 +480,14 @@ func TestSchedule_DeleteAlertRule(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func setupScheduler(t *testing.T, rs *store.FakeRuleStore, is *state.FakeInstanceStore, registry *prometheus.Registry, senderMock *AlertsSenderMock, evalMock *eval.FakeEvaluator) *schedule {
|
||||
func setupScheduler(t *testing.T, rs *fakeRulesStore, is *state.FakeInstanceStore, registry *prometheus.Registry, senderMock *AlertsSenderMock, evalMock *eval.FakeEvaluator) *schedule {
|
||||
t.Helper()
|
||||
|
||||
mockedClock := clock.NewMock()
|
||||
logger := log.New("ngalert schedule test")
|
||||
|
||||
if rs == nil {
|
||||
rs = store.NewFakeRuleStore(t)
|
||||
rs = newFakeRulesStore()
|
||||
}
|
||||
|
||||
if is == nil {
|
||||
@@ -529,7 +528,9 @@ func setupScheduler(t *testing.T, rs *store.FakeRuleStore, is *state.FakeInstanc
|
||||
Metrics: m.GetSchedulerMetrics(),
|
||||
AlertSender: senderMock,
|
||||
}
|
||||
st := state.NewManager(schedCfg.Logger, m.GetStateMetrics(), nil, rs, is, &dashboards.FakeDashboardService{}, &image.NoopImageService{}, mockedClock, annotationstest.NewFakeAnnotationsRepo())
|
||||
|
||||
stateRs := state.FakeRuleReader{}
|
||||
st := state.NewManager(schedCfg.Logger, m.GetStateMetrics(), nil, &stateRs, is, &dashboards.FakeDashboardService{}, &image.NoopImageService{}, mockedClock, annotationstest.NewFakeAnnotationsRepo())
|
||||
return NewScheduler(schedCfg, appUrl, st)
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,11 @@
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
||||
)
|
||||
|
||||
// waitForTimeChannel blocks the execution until either the channel ch has some data or a timeout of 10 second expires.
|
||||
@@ -31,3 +34,43 @@ func waitForErrChannel(t *testing.T, ch chan error) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type fakeRulesStore struct {
|
||||
rules map[string]*models.AlertRule
|
||||
}
|
||||
|
||||
func newFakeRulesStore() *fakeRulesStore {
|
||||
return &fakeRulesStore{
|
||||
rules: map[string]*models.AlertRule{},
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fakeRulesStore) GetAlertRulesKeysForScheduling(ctx context.Context) ([]models.AlertRuleKeyWithVersion, error) {
|
||||
result := make([]models.AlertRuleKeyWithVersion, 0, len(f.rules))
|
||||
for _, rule := range f.rules {
|
||||
result = append(result, models.AlertRuleKeyWithVersion{
|
||||
Version: rule.Version,
|
||||
AlertRuleKey: rule.GetKey(),
|
||||
})
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (f *fakeRulesStore) GetAlertRulesForScheduling(ctx context.Context, query *models.GetAlertRulesForSchedulingQuery) error {
|
||||
query.ResultFoldersTitles = map[string]string{}
|
||||
for _, rule := range f.rules {
|
||||
query.ResultRules = append(query.ResultRules, rule)
|
||||
query.ResultFoldersTitles[rule.NamespaceUID] = f.getNamespaceTitle(rule.NamespaceUID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeRulesStore) PutRule(_ context.Context, rules ...*models.AlertRule) {
|
||||
for _, r := range rules {
|
||||
f.rules[r.UID] = r
|
||||
}
|
||||
}
|
||||
|
||||
func (f *fakeRulesStore) getNamespaceTitle(uid string) string {
|
||||
return "TEST-FOLDER-" + uid
|
||||
}
|
||||
|
@@ -222,53 +222,6 @@ func (f *FakeRuleStore) GetAlertRulesGroupByRuleUID(_ context.Context, q *models
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (f *FakeRuleStore) GetAlertRulesKeysForScheduling(_ context.Context) ([]models.AlertRuleKeyWithVersion, error) {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
f.RecordedOps = append(f.RecordedOps, GenericRecordedQuery{
|
||||
Name: "GetAlertRulesKeysForScheduling",
|
||||
Params: []interface{}{},
|
||||
})
|
||||
result := make([]models.AlertRuleKeyWithVersion, 0, len(f.Rules))
|
||||
for _, rules := range f.Rules {
|
||||
for _, rule := range rules {
|
||||
result = append(result, models.AlertRuleKeyWithVersion{
|
||||
Version: rule.Version,
|
||||
AlertRuleKey: rule.GetKey(),
|
||||
})
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// For now, we're not implementing namespace filtering.
|
||||
func (f *FakeRuleStore) GetAlertRulesForScheduling(_ context.Context, q *models.GetAlertRulesForSchedulingQuery) error {
|
||||
f.mtx.Lock()
|
||||
defer f.mtx.Unlock()
|
||||
f.RecordedOps = append(f.RecordedOps, *q)
|
||||
if err := f.Hook(*q); err != nil {
|
||||
return err
|
||||
}
|
||||
q.ResultFoldersTitles = make(map[string]string)
|
||||
for _, rules := range f.Rules {
|
||||
for _, rule := range rules {
|
||||
q.ResultRules = append(q.ResultRules, rule)
|
||||
if !q.PopulateFolders {
|
||||
continue
|
||||
}
|
||||
if _, ok := q.ResultFoldersTitles[rule.NamespaceUID]; !ok {
|
||||
if folders, ok := f.Folders[rule.OrgID]; ok {
|
||||
for _, folder := range folders {
|
||||
if folder.Uid == rule.NamespaceUID {
|
||||
q.ResultFoldersTitles[rule.NamespaceUID] = folder.Title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FakeRuleStore) ListAlertRules(_ context.Context, q *models.ListAlertRulesQuery) error {
|
||||
f.mtx.Lock()
|
||||
|
Reference in New Issue
Block a user