@ -9,11 +9,10 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
. "github.com/smartystreets/goconvey/convey "
"github.com/stretchr/testify/require "
)
func TestAlertRuleExtraction ( t * testing . T ) {
Convey ( "Parsing alert rules from dashboard json" , t , func ( ) {
RegisterCondition ( "query" , func ( model * simplejson . Json , index int ) ( Condition , error ) {
return & FakeCondition { } , nil
} )
@ -47,11 +46,11 @@ func TestAlertRuleExtraction(t *testing.T) {
} )
json , err := ioutil . ReadFile ( "./testdata/graphite-alert.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
Convey ( "Extractor should not modify the original json" , func ( ) {
t . Run ( "Parsing alert rules from dashboard json", func ( t * testing . T ) {
dashJSON , err := simplejson . NewJson ( json )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
@ -65,237 +64,184 @@ func TestAlertRuleExtraction(t *testing.T) {
return condition . Get ( "query" ) . Get ( "model" ) . Get ( "target" ) . MustString ( )
}
Convey ( "Dashboard json rows.panels.alert.query.model.target should be empty" , func ( ) {
So ( getTarget ( dashJSON ) , ShouldEqual , "" )
} )
require . Equal ( t , getTarget ( dashJSON ) , "" )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
_ , _ = extractor . GetAlerts ( )
Convey ( "Dashboard json should not be updated after extracting rules" , func ( ) {
So ( getTarget ( dashJSON ) , ShouldEqual , "" )
} )
require . Equal ( t , getTarget ( dashJSON ) , "" )
} )
Convey ( "Parsing and validating dashboard containing graphite alerts" , func ( ) {
t . Run ( "Parsing and validating dashboard containing graphite alerts" , func ( t * testing . T ) {
dashJSON , err := simplejson . NewJson ( json )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
alerts , err := extractor . GetAlerts ( )
Convey ( "Get rules without error" , func ( ) {
So ( err , ShouldBeNil )
} )
require . Nil ( t , err )
Convey ( "all properties have been set" , func ( ) {
So ( len ( alerts ) , ShouldEqual , 2 )
require . Len ( t , alerts , 2 )
for _ , v := range alerts {
So ( v . DashboardId , ShouldEqual , 57 )
So ( v . Name , ShouldNotBeEmpty )
So ( v . Message , ShouldNotBeEmpty )
require . EqualValues ( t , v . DashboardId , 57 )
require . NotEmpty ( t , v . Name )
require . NotEmpty ( t , v . Message )
settings := simplejson . NewFromAny ( v . Settings )
So ( settings . Get ( "interval" ) . MustString ( "" ) , ShouldEqual , "" )
require . Equal ( t , settings . Get ( "interval" ) . MustString ( "" ) , "" )
}
Convey ( "should extract handler property" , func ( ) {
So ( alerts [ 0 ] . Handler , ShouldEqual , 1 )
So ( alerts [ 1 ] . Handler , ShouldEqual , 0 )
} )
require . EqualValues ( t , alerts [ 0 ] . Handler , 1 )
require . EqualValues ( t , alerts [ 1 ] . Handler , 0 )
Convey ( "should extract frequency in seconds" , func ( ) {
So ( alerts [ 0 ] . Frequency , ShouldEqual , 60 )
So ( alerts [ 1 ] . Frequency , ShouldEqual , 60 )
} )
require . EqualValues ( t , alerts [ 0 ] . Frequency , 60 )
require . EqualValues ( t , alerts [ 1 ] . Frequency , 60 )
Convey ( "should extract panel idc" , func ( ) {
So ( alerts [ 0 ] . PanelId , ShouldEqual , 3 )
So ( alerts [ 1 ] . PanelId , ShouldEqual , 4 )
} )
require . EqualValues ( t , alerts [ 0 ] . PanelId , 3 )
require . EqualValues ( t , alerts [ 1 ] . PanelId , 4 )
Convey ( "should extract for param" , func ( ) {
So ( alerts [ 0 ] . For , ShouldEqual , time . Minute * 2 )
So ( alerts [ 1 ] . For , ShouldEqual , time . Duration ( 0 ) )
} )
require . Equal ( t , alerts [ 0 ] . For , time . Minute * 2 )
require . Equal ( t , alerts [ 1 ] . For , time . Duration ( 0 ) )
Convey ( "should extract name and desc" , func ( ) {
So ( alerts [ 0 ] . Name , ShouldEqual , "name1" )
So ( alerts [ 0 ] . Message , ShouldEqual , "desc1" )
So ( alerts [ 1 ] . Name , ShouldEqual , "name2" )
So ( alerts [ 1 ] . Message , ShouldEqual , "desc2" )
} )
require . Equal ( t , alerts [ 0 ] . Name , "name1" )
require . Equal ( t , alerts [ 0 ] . Message , "desc1" )
require . Equal ( t , alerts [ 1 ] . Name , "name2" )
require . Equal ( t , alerts [ 1 ] . Message , "desc2" )
Convey ( "should set datasourceId" , func ( ) {
condition := simplejson . NewFromAny ( alerts [ 0 ] . Settings . Get ( "conditions" ) . MustArray ( ) [ 0 ] )
query := condition . Get ( "query" )
So ( query . Get ( "datasourceId" ) . MustInt64 ( ) , ShouldEqual , 12 )
} )
require . EqualValues ( t , query . Get ( "datasourceId" ) . MustInt64 ( ) , 12 )
Convey ( "should copy query model to condition" , func ( ) {
condition := simplejson . NewFromAny ( alerts [ 0 ] . Settings . Get ( "conditions" ) . MustArray ( ) [ 0 ] )
condition = simplejson . NewFromAny ( alerts [ 0 ] . Settings . Get ( "conditions" ) . MustArray ( ) [ 0 ] )
model := condition . Get ( "query" ) . Get ( "model" )
So ( model . Get ( "target" ) . MustString ( ) , ShouldEqual , "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)" )
} )
} )
require . Equal ( t , model . Get ( "target" ) . MustString ( ) , "aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)" )
} )
Convey ( "Panels missing id should return error" , func ( ) {
t . Run ( "Panels missing id should return error" , func ( t * testing . T ) {
panelWithoutID , err := ioutil . ReadFile ( "./testdata/panels-missing-id.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dashJSON , err := simplejson . NewJson ( panelWithoutID )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
_ , err = extractor . GetAlerts ( )
Convey ( "panels without Id should return error" , func ( ) {
So ( err , ShouldNotBeNil )
} )
require . NotNil ( t , err )
} )
Convey ( "Panel with id set to zero should return error" , func ( ) {
t . Run ( "Panels missing id should return error", func ( t * testing . T ) {
panelWithIDZero , err := ioutil . ReadFile ( "./testdata/panel-with-id-0.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dashJSON , err := simplejson . NewJson ( panelWithIDZero )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
_ , err = extractor . GetAlerts ( )
Convey ( "panel with id 0 should return error" , func ( ) {
So ( err , ShouldNotBeNil )
} )
require . NotNil ( t , err )
} )
Convey ( "Panel does not have datasource configured, use the default datasource" , func ( ) {
t . Run ( "Panel does not have datasource configured, use the default datasource" , func ( t * testing . T ) {
panelWithoutSpecifiedDatasource , err := ioutil . ReadFile ( "./testdata/panel-without-specified-datasource.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dashJSON , err := simplejson . NewJson ( panelWithoutSpecifiedDatasource )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
alerts , err := extractor . GetAlerts ( )
require . Nil ( t , err )
Convey ( "Get rules without error" , func ( ) {
So ( err , ShouldBeNil )
} )
Convey ( "Use default datasource" , func ( ) {
condition := simplejson . NewFromAny ( alerts [ 0 ] . Settings . Get ( "conditions" ) . MustArray ( ) [ 0 ] )
query := condition . Get ( "query" )
So ( query . Get ( "datasourceId" ) . MustInt64 ( ) , ShouldEqual , 12 )
} )
require . EqualValues ( t , query . Get ( "datasourceId" ) . MustInt64 ( ) , 12 )
} )
Convey ( "Parse alerts from dashboard without rows" , func ( ) {
t . Run ( "Parse alerts from dashboard without rows" , func ( t * testing . T ) {
json , err := ioutil . ReadFile ( "./testdata/v5-dashboard.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dashJSON , err := simplejson . NewJson ( json )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
alerts , err := extractor . GetAlerts ( )
require . Nil ( t , err )
Convey ( "Get rules without error" , func ( ) {
So ( err , ShouldBeNil )
} )
Convey ( "Should have 2 alert rule" , func ( ) {
So ( len ( alerts ) , ShouldEqual , 2 )
} )
require . Len ( t , alerts , 2 )
} )
Convey ( "Alert notifications are in DB" , func ( ) {
t . Run ( "Alert notifications are in DB" , func ( t * testing . T ) {
sqlstore . InitTestDB ( t )
firstNotification := models . CreateAlertNotificationCommand { Uid : "notifier1" , OrgId : 1 , Name : "1" }
err = sqlstore . CreateAlertNotificationCommand ( & firstNotification )
So ( err , ShouldBeNil )
require . Nil ( t , err )
secondNotification := models . CreateAlertNotificationCommand { Uid : "notifier2" , OrgId : 1 , Name : "2" }
err = sqlstore . CreateAlertNotificationCommand ( & secondNotification )
So ( err , ShouldBeNil )
require . Nil ( t , err )
Convey ( "Parse and validate dashboard containing influxdb alert" , func ( ) {
json , err := ioutil . ReadFile ( "./testdata/influxdb-alert.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dashJSON , err := simplejson . NewJson ( json )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
alerts , err := extractor . GetAlerts ( )
require . Nil ( t , err )
Convey ( "Get rules without error" , func ( ) {
So ( err , ShouldBeNil )
} )
Convey ( "should be able to read interval" , func ( ) {
So ( len ( alerts ) , ShouldEqual , 1 )
require . Len ( t , alerts , 1 )
for _ , alert := range alerts {
So ( alert . DashboardId , ShouldEqual , 4 )
require . EqualValues ( t , alert . DashboardId , 4 )
conditions := alert . Settings . Get ( "conditions" ) . MustArray ( )
cond := simplejson . NewFromAny ( conditions [ 0 ] )
So ( cond . Get ( "query" ) . Get ( "model" ) . Get ( "interval" ) . MustString ( ) , ShouldEqual , ">10s" )
require . Equal ( t , cond . Get ( "query" ) . Get ( "model" ) . Get ( "interval" ) . MustString ( ) , ">10s" )
}
} )
} )
Convey ( "Should be able to extract collapsed panels" , func ( ) {
t . Run ( "Should be able to extract collapsed panels" , func ( t * testing . T ) {
json , err := ioutil . ReadFile ( "./testdata/collapsed-panels.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dashJSON , err := simplejson . NewJson ( json )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
alerts , err := extractor . GetAlerts ( )
require . Nil ( t , err )
Convey ( "Get rules without error" , func ( ) {
So ( err , ShouldBeNil )
require . Len ( t , alerts , 4 )
} )
Convey ( "should be able to extract collapsed alerts" , func ( ) {
So ( len ( alerts ) , ShouldEqual , 4 )
} )
} )
Convey ( "Parse and validate dashboard without id and containing an alert" , func ( ) {
t . Run ( "Parse and validate dashboard without id and containing an alert" , func ( t * testing . T ) {
json , err := ioutil . ReadFile ( "./testdata/dash-without-id.json" )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dashJSON , err := simplejson . NewJson ( json )
So ( err , ShouldBeNil )
require . Nil ( t , err )
dash := models . NewDashboardFromJson ( dashJSON )
extractor := NewDashAlertExtractor ( dash , 1 , nil )
err = extractor . ValidateAlerts ( )
Convey ( "Should validate without error" , func ( ) {
So ( err , ShouldBeNil )
} )
require . Nil ( t , err )
Convey ( "Should fail on save" , func ( ) {
_ , err := extractor . GetAlerts ( )
So ( err . Error ( ) , ShouldEqual , "alert validation error: Panel id is not correct, alertName=Influxdb, panelId=1" )
} )
} )
} )
_ , err = extractor . GetAlerts ( )
require . Equal ( t , err . Error ( ) , "alert validation error: Panel id is not correct, alertName=Influxdb, panelId=1" )
} )
}