@ -12,6 +12,7 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/exp/maps"
"golang.org/x/exp/rand"
"github.com/grafana/grafana/pkg/bus"
@ -776,6 +777,14 @@ func TestIntegrationAlertRulesNotificationSettings(t *testing.T) {
t . Skip ( "skipping integration test" )
}
getKeyMap := func ( r [ ] * models . AlertRule ) map [ models . AlertRuleKey ] struct { } {
result := make ( map [ models . AlertRuleKey ] struct { } , len ( r ) )
for _ , rule := range r {
result [ rule . GetKey ( ) ] = struct { } { }
}
return result
}
sqlStore := db . InitTestReplDB ( t )
cfg := setting . NewCfg ( )
cfg . UnifiedAlerting . BaseInterval = 1 * time . Second
@ -787,15 +796,17 @@ func TestIntegrationAlertRulesNotificationSettings(t *testing.T) {
}
receiverName := "receiver\"-" + uuid . NewString ( )
timeIntervalName := "time-" + util . GenerateShortUID ( )
gen := models . RuleGen
gen = gen . With ( gen . WithOrgID ( 1 ) , gen . WithIntervalMatching ( store . Cfg . BaseInterval ) )
rules := gen . GenerateManyRef ( 3 )
receiveRules := gen . With ( gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( models . NSMuts . WithReceiver ( receiverName ) ) ) ) . GenerateManyRef ( 3 )
noise := gen . With ( gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( models . NSMuts . WithMuteTimeIntervals ( receiverName ) ) ) ) . GenerateManyRef ( 3 )
timeIntervalRules := gen . With ( gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( models . NSMuts . WithMuteTimeIntervals ( timeIntervalName ) ) ) ) . GenerateManyRef ( 3 )
noise := gen . With ( gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( models . NSMuts . WithReceiver ( timeIntervalName ) , models . NSMuts . WithMuteTimeIntervals ( receiverName ) ) ) ) . GenerateManyRef ( 3 )
deref := make ( [ ] models . AlertRule , 0 , len ( rules ) + len ( receiveRules ) + len ( noise ) )
for _ , rule := range append ( append ( rules , receiveRules ... ) , noise ... ) {
deref := make ( [ ] models . AlertRule , 0 , len ( rules ) + len ( receiveRules ) + len ( timeIntervalRules ) + len ( noise ) )
for _ , rule := range append ( append ( append ( rules , receiveRules ... ) , noise ... ) , timeIntervalRules ... ) {
r := * rule
r . ID = 0
deref = append ( deref , r )
@ -805,18 +816,60 @@ func TestIntegrationAlertRulesNotificationSettings(t *testing.T) {
require . NoError ( t , err )
t . Run ( "should find rules by receiver name" , func ( t * testing . T ) {
expectedUIDs := map [ string ] struct { } { }
for _ , rule := range receiveRules {
expectedUIDs [ rule . UID ] = struct { } { }
}
expected := getKeyMap ( receiveRules )
actual , err := store . ListAlertRules ( context . Background ( ) , & models . ListAlertRulesQuery {
OrgID : 1 ,
ReceiverName : receiverName ,
} )
require . NoError ( t , err )
assert . Len ( t , actual , len ( expectedUIDs ) )
assert . Len ( t , actual , len ( expected ) )
for _ , rule := range actual {
assert . Contains ( t , expectedUIDs , rule . UID )
assert . Contains ( t , expected , rule . GetKey ( ) )
}
} )
t . Run ( "should find rules by time interval name" , func ( t * testing . T ) {
expected := getKeyMap ( timeIntervalRules )
actual , err := store . ListAlertRules ( context . Background ( ) , & models . ListAlertRulesQuery {
OrgID : 1 ,
TimeIntervalName : timeIntervalName ,
} )
require . NoError ( t , err )
assert . Len ( t , actual , len ( expected ) )
for _ , rule := range actual {
assert . Contains ( t , expected , rule . GetKey ( ) )
}
} )
t . Run ( "should find rules by receiver and time-interval name" , func ( t * testing . T ) {
var receiver , intervalName string
var expected [ ] models . AlertRuleKey
rand . Shuffle ( len ( deref ) , func ( i , j int ) {
deref [ i ] , deref [ j ] = deref [ j ] , deref [ i ]
} )
for _ , rule := range deref {
if len ( rule . NotificationSettings ) == 0 || rule . NotificationSettings [ 0 ] . Receiver == "" || len ( rule . NotificationSettings [ 0 ] . MuteTimeIntervals ) == 0 {
continue
}
if len ( expected ) > 0 {
if rule . NotificationSettings [ 0 ] . Receiver == receiver && slices . Contains ( rule . NotificationSettings [ 0 ] . MuteTimeIntervals , intervalName ) {
expected = append ( expected , rule . GetKey ( ) )
}
} else {
receiver = rule . NotificationSettings [ 0 ] . Receiver
intervalName = rule . NotificationSettings [ 0 ] . MuteTimeIntervals [ 0 ]
expected = append ( expected , rule . GetKey ( ) )
}
}
actual , err := store . ListAlertRules ( context . Background ( ) , & models . ListAlertRulesQuery {
OrgID : 1 ,
ReceiverName : receiver ,
TimeIntervalName : intervalName ,
} )
require . NoError ( t , err )
assert . Len ( t , actual , len ( expected ) )
for _ , rule := range actual {
assert . Contains ( t , expected , rule . GetKey ( ) )
}
} )
@ -864,13 +917,17 @@ func TestIntegrationListNotificationSettings(t *testing.T) {
Cfg : cfg . UnifiedAlerting ,
}
receiverName := ` receiver %"-👍'test`
searchName := ` name- %"-👍'test`
gen := models . RuleGen
gen = gen . With ( gen . WithOrgID ( 1 ) , gen . WithIntervalMatching ( store . Cfg . BaseInterval ) )
rulesWithNotifications := gen . With (
gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( models . NSMuts . WithReceiver ( receiverName ) ) ) ,
rulesWithNotificationsAndReceiver := gen . With (
gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( models . NSMuts . WithReceiver ( searchName ) ) ) ,
) . GenerateMany ( 5 )
rulesWithNotificationsAndTimeInterval := gen . With (
gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( models . NSMuts . WithMuteTimeIntervals ( searchName ) ) ) ,
) . GenerateMany ( 5 )
rulesInOtherOrg := gen . With (
gen . WithOrgID ( 2 ) ,
gen . WithNotificationSettingsGen ( models . NotificationSettingsGen ( ) ) ,
@ -878,15 +935,18 @@ func TestIntegrationListNotificationSettings(t *testing.T) {
rulesWithNoNotifications := gen . With ( gen . WithNoNotificationSettings ( ) ) . GenerateMany ( 5 )
deref := append ( append ( rulesWithNotifications , rulesWithNoNotifications ... ) , rulesInOtherOrg ... )
deref := append ( append ( rulesWithNotificationsAndReceiver , rulesWithNoNotifications ... ) , rulesInOtherOrg ... )
deref = append ( deref , rulesWithNotificationsAndTimeInterval ... )
orgRules := append ( rulesWithNotificationsAndReceiver , rulesWithNotificationsAndTimeInterval ... )
_ , err := store . InsertAlertRules ( context . Background ( ) , deref )
require . NoError ( t , err )
result , err := store . ListNotificationSettings ( context . Background ( ) , models . ListNotificationSettingsQuery { OrgID : 1 } )
require . NoError ( t , err )
require . Len ( t , result , len ( rulesWithNotification s ) )
for _ , rule := range rulesWithNotifications {
require . Len ( t , result , len ( o rgR ules) )
for _ , rule := range rulesWithNotificationsAndReceiver {
if ! assert . Contains ( t , result , rule . GetKey ( ) ) {
continue
}
@ -895,13 +955,29 @@ func TestIntegrationListNotificationSettings(t *testing.T) {
t . Run ( "should list notification settings by receiver name" , func ( t * testing . T ) {
expectedUIDs := map [ models . AlertRuleKey ] struct { } { }
for _ , rule := range rulesWithNotifications {
for _ , rule := range rulesWithNotificationsAndReceiver {
expectedUIDs [ rule . GetKey ( ) ] = struct { } { }
}
actual , err := store . ListNotificationSettings ( context . Background ( ) , models . ListNotificationSettingsQuery {
OrgID : 1 ,
ReceiverName : receiverName ,
ReceiverName : searchName ,
} )
require . NoError ( t , err )
assert . Len ( t , actual , len ( expectedUIDs ) )
for ruleKey := range actual {
assert . Contains ( t , expectedUIDs , ruleKey )
}
} )
t . Run ( "should filter notification settings by time interval name" , func ( t * testing . T ) {
expectedUIDs := map [ models . AlertRuleKey ] struct { } { }
for _ , rule := range rulesWithNotificationsAndTimeInterval {
expectedUIDs [ rule . GetKey ( ) ] = struct { } { }
}
actual , err := store . ListNotificationSettings ( context . Background ( ) , models . ListNotificationSettingsQuery {
OrgID : 1 ,
TimeIntervalName : searchName ,
} )
require . NoError ( t , err )
assert . Len ( t , actual , len ( expectedUIDs ) )
@ -909,6 +985,44 @@ func TestIntegrationListNotificationSettings(t *testing.T) {
assert . Contains ( t , expectedUIDs , ruleKey )
}
} )
t . Run ( "should return nothing if filter does not match" , func ( t * testing . T ) {
result , err := store . ListNotificationSettings ( context . Background ( ) , models . ListNotificationSettingsQuery {
OrgID : 1 ,
ReceiverName : "not-found-receiver" ,
TimeIntervalName : "not-found-time-interval" ,
} )
require . NoError ( t , err )
require . Empty ( t , result )
} )
t . Run ( "should filter by time interval and receiver" , func ( t * testing . T ) {
var receiver , timeInterval string
var expected [ ] models . AlertRuleKey
rand . Shuffle ( len ( orgRules ) , func ( i , j int ) {
orgRules [ i ] , orgRules [ j ] = orgRules [ j ] , orgRules [ i ]
} )
for _ , rule := range orgRules {
if len ( rule . NotificationSettings ) == 0 || rule . NotificationSettings [ 0 ] . Receiver == "" || len ( rule . NotificationSettings [ 0 ] . MuteTimeIntervals ) == 0 {
continue
}
if len ( expected ) > 0 {
if rule . NotificationSettings [ 0 ] . Receiver == receiver && slices . Contains ( rule . NotificationSettings [ 0 ] . MuteTimeIntervals , timeInterval ) {
expected = append ( expected , rule . GetKey ( ) )
}
} else {
receiver = rule . NotificationSettings [ 0 ] . Receiver
timeInterval = rule . NotificationSettings [ 0 ] . MuteTimeIntervals [ 0 ]
expected = append ( expected , rule . GetKey ( ) )
}
}
actual , err := store . ListNotificationSettings ( context . Background ( ) , models . ListNotificationSettingsQuery {
OrgID : 1 ,
ReceiverName : receiver ,
TimeIntervalName : timeInterval ,
} )
require . NoError ( t , err )
require . EqualValuesf ( t , expected , maps . Keys ( actual ) , "got more rules than expected: %#v" , actual )
} )
}
func TestIntegrationGetNamespacesByRuleUID ( t * testing . T ) {