diff --git a/pkg/services/annotations/annotationsimpl/loki/historian_store_test.go b/pkg/services/annotations/annotationsimpl/loki/historian_store_test.go index c69b3ff67a2..b29272563c5 100644 --- a/pkg/services/annotations/annotationsimpl/loki/historian_store_test.go +++ b/pkg/services/annotations/annotationsimpl/loki/historian_store_test.go @@ -56,14 +56,19 @@ func TestIntegrationAlertStateHistoryStore(t *testing.T) { }) knownUIDs := &sync.Map{} + generator := ngmodels.AlertRuleGen( + ngmodels.WithUniqueUID(knownUIDs), + ngmodels.WithUniqueID(), + ngmodels.WithOrgID(1), + ) dashboardRules := map[string][]*ngmodels.AlertRule{ dashboard1.UID: { - createAlertRuleWithDashboard(t, sql, knownUIDs, "Test Rule 1", dashboard1.UID), - createAlertRuleWithDashboard(t, sql, knownUIDs, "Test Rule 2", dashboard1.UID), + createAlertRuleFromDashboard(t, sql, "Test Rule 1", *dashboard1, generator), + createAlertRuleFromDashboard(t, sql, "Test Rule 2", *dashboard1, generator), }, dashboard2.UID: { - createAlertRuleWithDashboard(t, sql, knownUIDs, "Test Rule 3", dashboard2.UID), + createAlertRuleFromDashboard(t, sql, "Test Rule 3", *dashboard2, generator), }, } @@ -274,7 +279,7 @@ func TestIntegrationAlertStateHistoryStore(t *testing.T) { rule := dashboardRules[dashboard1.UID][0] stream1 := historian.StatesToStream(ruleMetaFromRule(t, rule), transitions, map[string]string{}, log.NewNopLogger()) - rule = createAlertRule(t, sql, knownUIDs, "Test rule") + rule = createAlertRule(t, sql, "Test rule", generator) stream2 := historian.StatesToStream(ruleMetaFromRule(t, rule), transitions, map[string]string{}, log.NewNopLogger()) stream := historian.Stream{ @@ -504,22 +509,23 @@ func createTestLokiStore(t *testing.T, sql db.DB, client lokiQueryClient) *LokiH } } -func createAlertRule(t *testing.T, sql db.DB, knownUIDs *sync.Map, title string) *ngmodels.AlertRule { +// createAlertRule creates an alert rule in the database and returns it. +// If a generator is not specified, uniqueness of primary key is not guaranteed. +func createAlertRule(t *testing.T, sql db.DB, title string, generator func() *ngmodels.AlertRule) *ngmodels.AlertRule { t.Helper() - if knownUIDs == nil { - knownUIDs = &sync.Map{} + if generator == nil { + generator = ngmodels.AlertRuleGen(ngmodels.WithTitle(title), withDashboardUID(nil), withPanelID(nil), ngmodels.WithOrgID(1)) } - generator := ngmodels.AlertRuleGen( - ngmodels.WithTitle(title), - ngmodels.WithUniqueUID(knownUIDs), - withDashboardUID(""), // no dashboard - ngmodels.WithUniqueID(), - ngmodels.WithOrgID(1), - ) - rule := generator() + // ensure rule has correct values + if rule.Title != title { + rule.Title = title + } + // rule should not have linked dashboard or panel + rule.DashboardUID = nil + rule.PanelID = nil err := sql.WithDbSession(context.Background(), func(sess *db.Session) error { _, err := sess.Table(ngmodels.AlertRule{}).InsertOne(rule) @@ -544,23 +550,29 @@ func createAlertRule(t *testing.T, sql db.DB, knownUIDs *sync.Map, title string) return rule } -func createAlertRuleWithDashboard(t *testing.T, sql db.DB, knownUIDs *sync.Map, title string, dashboardUID string) *ngmodels.AlertRule { +// createAlertRuleFromDashboard creates an alert rule with a linked dashboard and panel in the database and returns it. +// If a generator is not specified, uniqueness of primary key is not guaranteed. +func createAlertRuleFromDashboard(t *testing.T, sql db.DB, title string, dashboard dashboards.Dashboard, generator func() *ngmodels.AlertRule) *ngmodels.AlertRule { t.Helper() - if knownUIDs == nil { - knownUIDs = &sync.Map{} + panelID := new(int64) + *panelID = 123 + + if generator == nil { + generator = ngmodels.AlertRuleGen(ngmodels.WithTitle(title), ngmodels.WithOrgID(1), withDashboardUID(&dashboard.UID), withPanelID(panelID)) } - generator := ngmodels.AlertRuleGen( - ngmodels.WithTitle(title), - ngmodels.WithUniqueUID(knownUIDs), - ngmodels.WithUniqueID(), - ngmodels.WithOrgID(1), - withDashboardUID(dashboardUID), - withPanelID(123), - ) - rule := generator() + // ensure rule has correct values + if rule.Title != title { + rule.Title = title + } + if rule.DashboardUID == nil || (rule.DashboardUID != nil && *rule.DashboardUID != dashboard.UID) { + rule.DashboardUID = &dashboard.UID + } + if rule.PanelID == nil || (rule.PanelID != nil && *rule.PanelID != *panelID) { + rule.PanelID = panelID + } err := sql.WithDbSession(context.Background(), func(sess *db.Session) error { _, err := sess.Table(ngmodels.AlertRule{}).InsertOne(rule) @@ -649,15 +661,15 @@ func genStateTransitions(t *testing.T, num int, start time.Time) []state.StateTr return transitions } -func withDashboardUID(dashboardUID string) ngmodels.AlertRuleMutator { +func withDashboardUID(dashboardUID *string) ngmodels.AlertRuleMutator { return func(rule *ngmodels.AlertRule) { - rule.DashboardUID = &dashboardUID + rule.DashboardUID = dashboardUID } } -func withPanelID(panelID int64) ngmodels.AlertRuleMutator { +func withPanelID(panelID *int64) ngmodels.AlertRuleMutator { return func(rule *ngmodels.AlertRule) { - rule.PanelID = &panelID + rule.PanelID = panelID } } diff --git a/pkg/services/annotations/testutil/testutil.go b/pkg/services/annotations/testutil/testutil.go index aa340cb4f1b..40bd57b614d 100644 --- a/pkg/services/annotations/testutil/testutil.go +++ b/pkg/services/annotations/testutil/testutil.go @@ -90,6 +90,7 @@ func CreateDashboard(t *testing.T, sql *sqlstore.SQLStore, features featuremgmt. dash, err := dashboardStore.SaveDashboard(context.Background(), cmd) require.NoError(t, err) + require.NotNil(t, dash) return dash } diff --git a/pkg/services/ngalert/store/alert_rule_test.go b/pkg/services/ngalert/store/alert_rule_test.go index 86bc28eeccf..ccbc18c9c6a 100644 --- a/pkg/services/ngalert/store/alert_rule_test.go +++ b/pkg/services/ngalert/store/alert_rule_test.go @@ -577,10 +577,12 @@ func TestIntegrationInsertAlertRules(t *testing.T) { } } +// createAlertRule creates an alert rule in the database and returns it. +// If a generator is not specified, uniqueness of primary key is not guaranteed. func createRule(t *testing.T, store *DBstore, generate func() *models.AlertRule) *models.AlertRule { t.Helper() if generate == nil { - generate = models.AlertRuleGen(withIntervalMatching(store.Cfg.BaseInterval), models.WithUniqueID()) + generate = models.AlertRuleGen(withIntervalMatching(store.Cfg.BaseInterval)) } rule := generate() err := store.SQLStore.WithDbSession(context.Background(), func(sess *db.Session) error {