@ -14,6 +14,7 @@ import (
"github.com/prometheus/alertmanager/pkg/labels"
"github.com/prometheus/common/model"
"github.com/stretchr/testify/require"
"xorm.io/xorm"
"github.com/grafana/grafana/pkg/components/simplejson"
@ -635,18 +636,22 @@ func TestDashAlertQueryMigration(t *testing.T) {
x := sqlStore . GetEngine ( )
service := NewTestMigrationService ( t , sqlStore , & setting . Cfg { } )
createAlertQuery := func ( refId string , ds string , from string , to string ) ngModels . AlertQuery {
dur , _ := calculateInterval ( legacydata . NewDataTimeRange ( from , to ) , simplejson . New ( ) , nil )
intervalMs := strconv . FormatInt ( dur . Milliseconds ( ) , 10 )
newQueryModel := ` { "datasource": { "type":"prometheus","uid":"gdev-prometheus"},"expr":"up { job=\"fake-data-gen\"}","instant":false,"interval":"%s","intervalMs":%d,"maxDataPoints":1500,"refId":"%s"} `
createAlertQueryWithModel := func ( refId string , ds string , from string , to string , model string ) ngModels . AlertQuery {
rel , _ := getRelativeDuration ( from , to )
return ngModels . AlertQuery {
RefID : refId ,
RelativeTimeRange : ngModels . RelativeTimeRange { From : rel . From , To : rel . To } ,
DatasourceUID : ds ,
Model : [ ] byte ( f mt . Sprintf ( ` { "datas ource": { "type":"prometheus","uid":"g dev-prometheus"},"expr":"up { job=\"fake-data-gen\"}","instant":false,"intervalMs":%s,"maxDataPoints":1500,"refId":"%s"} ` , intervalMs , refId ) ) ,
Model : [ ] byte ( model ) ,
}
}
createAlertQuery := func ( refId string , ds string , from string , to string ) ngModels . AlertQuery {
dur , _ := calculateInterval ( legacydata . NewDataTimeRange ( from , to ) , simplejson . New ( ) , nil )
return createAlertQueryWithModel ( refId , ds , from , to , fmt . Sprintf ( newQueryModel , "" , dur . Milliseconds ( ) , refId ) )
}
createClassicConditionQuery := func ( refId string , conditions [ ] classicConditionJSON ) ngModels . AlertQuery {
exprModel := struct {
Type string ` json:"type" `
@ -1000,6 +1005,50 @@ func TestDashAlertQueryMigration(t *testing.T) {
} ,
} ,
} ,
{
name : "simple query with interval, calculates intervalMs using it as min interval" ,
alerts : [ ] * models . Alert {
createAlertWithCond ( t , 1 , 1 , 1 , "alert1" , nil ,
[ ] migrationStore . DashAlertCondition {
withQueryModel (
createCondition ( "A" , "max" , "gt" , 42 , 1 , "5m" , "now" ) ,
fmt . Sprintf ( queryModel , "A" , "1s" ) ,
) ,
} ) ,
} ,
expected : map [ int64 ] [ ] * ngModels . AlertRule {
int64 ( 1 ) : {
genAlert ( func ( rule * ngModels . AlertRule ) {
rule . Data = append ( rule . Data , createAlertQueryWithModel ( "A" , "ds1-1" , "5m" , "now" , fmt . Sprintf ( newQueryModel , "1s" , 1000 , "A" ) ) )
rule . Data = append ( rule . Data , createClassicConditionQuery ( "B" , [ ] classicConditionJSON {
cond ( "A" , "max" , "gt" , 42 ) ,
} ) )
} ) ,
} ,
} ,
} ,
{
name : "simple query with interval as variable, calculates intervalMs using default as min interval" ,
alerts : [ ] * models . Alert {
createAlertWithCond ( t , 1 , 1 , 1 , "alert1" , nil ,
[ ] migrationStore . DashAlertCondition {
withQueryModel (
createCondition ( "A" , "max" , "gt" , 42 , 1 , "5m" , "now" ) ,
fmt . Sprintf ( queryModel , "A" , "$min_interval" ) ,
) ,
} ) ,
} ,
expected : map [ int64 ] [ ] * ngModels . AlertRule {
int64 ( 1 ) : {
genAlert ( func ( rule * ngModels . AlertRule ) {
rule . Data = append ( rule . Data , createAlertQueryWithModel ( "A" , "ds1-1" , "5m" , "now" , fmt . Sprintf ( newQueryModel , "$min_interval" , 1000 , "A" ) ) )
rule . Data = append ( rule . Data , createClassicConditionQuery ( "B" , [ ] classicConditionJSON {
cond ( "A" , "max" , "gt" , 42 ) ,
} ) )
} ) ,
} ,
} ,
} ,
}
for _ , tt := range tc {
t . Run ( tt . name , func ( t * testing . T ) {
@ -1107,7 +1156,12 @@ func createAlertNotification(t *testing.T, orgId int64, uid string, channelType
return createAlertNotificationWithReminder ( t , orgId , uid , channelType , settings , defaultChannel , false , time . Duration ( 0 ) )
}
var queryModel = ` { "datasource": { "type":"prometheus","uid":"gdev-prometheus"},"expr":"up { job=\"fake-data-gen\"}","instant":false,"refId":"%s"} `
func withQueryModel ( base migrationStore . DashAlertCondition , model string ) migrationStore . DashAlertCondition {
base . Query . Model = [ ] byte ( model )
return base
}
var queryModel = ` { "datasource": { "type":"prometheus","uid":"gdev-prometheus"},"expr":"up { job=\"fake-data-gen\"}","instant":false,"refId":"%s","interval":"%s"} `
func createCondition ( refId string , reducer string , evalType string , thresh float64 , datasourceId int64 , from string , to string ) migrationStore . DashAlertCondition {
return migrationStore . DashAlertCondition {
@ -1127,7 +1181,7 @@ func createCondition(refId string, reducer string, evalType string, thresh float
} {
Params : [ ] string { refId , from , to } ,
DatasourceID : datasourceId ,
Model : [ ] byte ( fmt . Sprintf ( queryModel , refId ) ) ,
Model : [ ] byte ( fmt . Sprintf ( queryModel , refId , "" ) ) ,
} ,
Reducer : struct {
Type string ` json:"type" `