2016-06-13 03:40:46 -05:00
package alerting
import (
2021-11-05 03:41:24 -05:00
"context"
2021-04-12 07:53:51 -05:00
"fmt"
2016-06-13 03:40:46 -05:00
"testing"
2021-04-12 07:53:51 -05:00
"time"
2016-06-13 03:40:46 -05:00
2016-06-15 04:39:25 -05:00
"github.com/grafana/grafana/pkg/components/simplejson"
2019-05-14 01:15:05 -05:00
"github.com/grafana/grafana/pkg/models"
2018-12-20 09:12:47 -06:00
"github.com/grafana/grafana/pkg/services/sqlstore"
2021-11-10 04:52:16 -06:00
"github.com/grafana/grafana/pkg/tsdb/legacydata"
2020-11-19 07:47:17 -06:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2016-06-13 03:40:46 -05:00
)
2016-07-27 09:18:10 -05:00
type FakeCondition struct { }
2021-11-10 04:52:16 -06:00
func ( f * FakeCondition ) Eval ( context * EvalContext , reqHandler legacydata . RequestHandler ) ( * ConditionResult , error ) {
2016-11-03 09:26:17 -05:00
return & ConditionResult { } , nil
}
2016-07-27 09:18:10 -05:00
2019-01-10 02:35:48 -06:00
func TestAlertRuleFrequencyParsing ( t * testing . T ) {
tcs := [ ] struct {
input string
err error
result int64
} {
{ input : "10s" , result : 10 } ,
{ input : "10m" , result : 600 } ,
{ input : "1h" , result : 3600 } ,
2019-03-25 10:27:58 -05:00
{ input : "1d" , result : 86400 } ,
2021-04-12 07:53:51 -05:00
{ input : "1o" , err : ErrWrongUnitFormat } ,
2019-01-10 02:35:48 -06:00
{ input : "0s" , err : ErrFrequencyCannotBeZeroOrLess } ,
{ input : "0m" , err : ErrFrequencyCannotBeZeroOrLess } ,
{ input : "0h" , err : ErrFrequencyCannotBeZeroOrLess } ,
2021-04-12 07:53:51 -05:00
{ input : "0" , err : ErrFrequencyCouldNotBeParsed } ,
{ input : "" , err : ErrFrequencyCouldNotBeParsed } ,
2019-01-10 02:35:48 -06:00
{ input : "-1s" , err : ErrFrequencyCouldNotBeParsed } ,
}
for _ , tc := range tcs {
2020-11-19 07:47:17 -06:00
t . Run ( tc . input , func ( t * testing . T ) {
r , err := getTimeDurationStringToSeconds ( tc . input )
if tc . err == nil {
require . NoError ( t , err )
} else {
require . EqualError ( t , err , tc . err . Error ( ) )
}
assert . Equal ( t , tc . result , r )
} )
2019-01-10 02:35:48 -06:00
}
}
2021-04-12 07:53:51 -05:00
func TestAlertRuleForParsing ( t * testing . T ) {
tcs := [ ] struct {
input string
err error
result time . Duration
} {
{ input : "10s" , result : time . Duration ( 10000000000 ) } ,
{ input : "10m" , result : time . Duration ( 600000000000 ) } ,
{ input : "1h" , result : time . Duration ( 3600000000000 ) } ,
{ input : "1o" , err : fmt . Errorf ( "alert validation error: could not parse for field, error: %s" , ErrWrongUnitFormat ) } ,
{ input : "1" , err : fmt . Errorf ( "alert validation error: no specified unit, error: %s" , ErrWrongUnitFormat ) } ,
{ input : "0s" , result : time . Duration ( 0 ) } ,
{ input : "0m" , result : time . Duration ( 0 ) } ,
{ input : "0h" , result : time . Duration ( 0 ) } ,
{ input : "0" , result : time . Duration ( 0 ) } ,
{ input : "" , result : time . Duration ( 0 ) } ,
}
2016-07-27 09:18:10 -05:00
2021-04-12 07:53:51 -05:00
for _ , tc := range tcs {
t . Run ( tc . input , func ( t * testing . T ) {
r , err := getForValue ( tc . input )
if tc . err == nil {
require . NoError ( t , err )
} else {
require . EqualError ( t , err , tc . err . Error ( ) )
}
assert . Equal ( t , tc . result , r )
2016-10-11 10:36:30 -05:00
} )
2021-04-12 07:53:51 -05:00
}
}
func TestAlertRuleModel ( t * testing . T ) {
2021-10-07 09:33:50 -05:00
sqlStore := sqlstore . InitTestDB ( t )
2021-04-12 07:53:51 -05:00
RegisterCondition ( "test" , func ( model * simplejson . Json , index int ) ( Condition , error ) {
return & FakeCondition { } , nil
} )
2016-10-11 10:36:30 -05:00
2021-04-12 07:53:51 -05:00
firstNotification := models . CreateAlertNotificationCommand { Uid : "notifier1" , OrgId : 1 , Name : "1" }
2021-11-05 03:41:24 -05:00
err := sqlStore . CreateAlertNotificationCommand ( context . Background ( ) , & firstNotification )
2021-04-12 07:53:51 -05:00
require . Nil ( t , err )
secondNotification := models . CreateAlertNotificationCommand { Uid : "notifier2" , OrgId : 1 , Name : "2" }
2021-11-05 03:41:24 -05:00
err = sqlStore . CreateAlertNotificationCommand ( context . Background ( ) , & secondNotification )
2021-04-12 07:53:51 -05:00
require . Nil ( t , err )
2018-12-20 09:12:47 -06:00
2021-04-12 07:53:51 -05:00
t . Run ( "Testing alert rule with notification id and uid" , func ( t * testing . T ) {
json := `
2018-12-20 09:12:47 -06:00
{
"name" : "name2" ,
"description" : "desc2" ,
"handler" : 0 ,
"noDataMode" : "critical" ,
"enabled" : true ,
"frequency" : "60s" ,
2019-01-28 08:27:02 -06:00
"conditions" : [
{
"type" : "test" ,
"prop" : 123
2018-12-20 09:12:47 -06:00
}
2019-01-28 08:27:02 -06:00
] ,
"notifications" : [
2018-12-20 09:12:47 -06:00
{ "id" : 1 } ,
{ "uid" : "notifier2" }
]
}
`
2021-04-12 07:53:51 -05:00
alertJSON , jsonErr := simplejson . NewJson ( [ ] byte ( json ) )
require . Nil ( t , jsonErr )
2018-12-20 09:12:47 -06:00
2021-04-12 07:53:51 -05:00
alert := & models . Alert {
Id : 1 ,
OrgId : 1 ,
DashboardId : 1 ,
PanelId : 1 ,
2018-12-20 09:12:47 -06:00
2021-04-12 07:53:51 -05:00
Settings : alertJSON ,
}
2018-12-20 09:12:47 -06:00
2022-04-08 07:30:25 -05:00
alertRule , err := NewRuleFromDBAlert ( context . Background ( ) , sqlStore , alert , false )
2021-04-12 07:53:51 -05:00
require . Nil ( t , err )
2018-12-20 09:12:47 -06:00
2021-04-12 07:53:51 -05:00
require . Len ( t , alertRule . Conditions , 1 )
require . Len ( t , alertRule . Notifications , 2 )
2018-12-20 09:12:47 -06:00
2021-04-12 07:53:51 -05:00
require . Contains ( t , alertRule . Notifications , "notifier2" )
require . Contains ( t , alertRule . Notifications , "notifier1" )
} )
2018-12-20 09:12:47 -06:00
2021-04-12 07:53:51 -05:00
t . Run ( "Testing alert rule with non existing notification id" , func ( t * testing . T ) {
json := `
2020-03-18 08:00:56 -05:00
{
"name" : "name3" ,
"description" : "desc3" ,
"handler" : 0 ,
"noDataMode" : "critical" ,
"enabled" : true ,
"frequency" : "60s" ,
"conditions" : [ { "type" : "test" , "prop" : 123 } ] ,
"notifications" : [
2020-06-02 11:33:13 -05:00
{ "id" : 999 } ,
{ "uid" : "notifier2" }
2020-03-18 08:00:56 -05:00
]
}
`
2021-04-12 07:53:51 -05:00
alertJSON , jsonErr := simplejson . NewJson ( [ ] byte ( json ) )
require . Nil ( t , jsonErr )
2020-03-18 08:00:56 -05:00
2021-04-12 07:53:51 -05:00
alert := & models . Alert {
Id : 1 ,
OrgId : 1 ,
DashboardId : 1 ,
PanelId : 1 ,
2020-03-18 08:00:56 -05:00
2021-04-12 07:53:51 -05:00
Settings : alertJSON ,
}
2020-03-18 08:00:56 -05:00
2022-04-08 07:30:25 -05:00
alertRule , err := NewRuleFromDBAlert ( context . Background ( ) , sqlStore , alert , false )
2021-04-12 07:53:51 -05:00
require . Nil ( t , err )
require . NotContains ( t , alertRule . Notifications , "999" )
require . Contains ( t , alertRule . Notifications , "notifier2" )
} )
2020-03-18 08:00:56 -05:00
2021-04-12 07:53:51 -05:00
t . Run ( "Testing alert rule which can construct alert rule model with invalid frequency" , func ( t * testing . T ) {
json := `
2016-06-15 04:39:25 -05:00
{
"name" : "name2" ,
"description" : "desc2" ,
2016-09-06 13:40:12 -05:00
"noDataMode" : "critical" ,
2016-06-15 04:39:25 -05:00
"enabled" : true ,
2018-12-20 09:12:47 -06:00
"frequency" : "0s" ,
2019-01-28 08:27:02 -06:00
"conditions" : [ { "type" : "test" , "prop" : 123 } ] ,
"notifications" : [ ]
2018-12-20 09:12:47 -06:00
} `
2016-06-15 04:39:25 -05:00
2021-04-12 07:53:51 -05:00
alertJSON , jsonErr := simplejson . NewJson ( [ ] byte ( json ) )
require . Nil ( t , jsonErr )
2016-06-15 04:39:25 -05:00
2021-04-12 07:53:51 -05:00
alert := & models . Alert {
Id : 1 ,
OrgId : 1 ,
DashboardId : 1 ,
PanelId : 1 ,
Frequency : 0 ,
2016-06-15 04:39:25 -05:00
2021-04-12 07:53:51 -05:00
Settings : alertJSON ,
}
2016-06-15 04:39:25 -05:00
2022-04-08 07:30:25 -05:00
alertRule , err := NewRuleFromDBAlert ( context . Background ( ) , sqlStore , alert , false )
2021-04-12 07:53:51 -05:00
require . Nil ( t , err )
require . EqualValues ( t , alertRule . Frequency , 60 )
} )
2019-01-10 02:35:48 -06:00
2021-04-12 07:53:51 -05:00
t . Run ( "Testing alert rule which will raise error in case of missing notification id and uid" , func ( t * testing . T ) {
json := `
2019-01-10 02:35:48 -06:00
{
"name" : "name2" ,
"description" : "desc2" ,
"noDataMode" : "critical" ,
"enabled" : true ,
2018-12-20 09:12:47 -06:00
"frequency" : "60s" ,
2019-01-28 08:27:02 -06:00
"conditions" : [
{
"type" : "test" ,
"prop" : 123
2018-12-20 09:12:47 -06:00
}
2019-01-28 08:27:02 -06:00
] ,
"notifications" : [
2018-12-20 09:12:47 -06:00
{ "not_id_uid" : "1134" }
]
}
`
2019-01-10 02:35:48 -06:00
2021-04-12 07:53:51 -05:00
alertJSON , jsonErr := simplejson . NewJson ( [ ] byte ( json ) )
require . Nil ( t , jsonErr )
2019-01-10 02:35:48 -06:00
2021-04-12 07:53:51 -05:00
alert := & models . Alert {
Id : 1 ,
OrgId : 1 ,
DashboardId : 1 ,
PanelId : 1 ,
Frequency : 0 ,
2019-01-10 02:35:48 -06:00
2021-04-12 07:53:51 -05:00
Settings : alertJSON ,
}
2019-01-10 02:35:48 -06:00
2022-04-08 07:30:25 -05:00
_ , err := NewRuleFromDBAlert ( context . Background ( ) , sqlStore , alert , false )
2021-04-12 07:53:51 -05:00
require . NotNil ( t , err )
require . EqualValues ( t , err . Error ( ) , "alert validation error: Neither id nor uid is specified in 'notifications' block, type assertion to string failed AlertId: 1 PanelId: 1 DashboardId: 1" )
2016-06-13 03:40:46 -05:00
} )
}