@ -1,12 +1,12 @@
package cloudwatch
package cloudwatch
import (
import (
"encoding/json"
"fmt"
"fmt"
"testing"
"testing"
"time"
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
)
)
@ -37,32 +37,33 @@ func TestRequestParser(t *testing.T) {
migratedQuery := migratedQueries [ 0 ]
migratedQuery := migratedQueries [ 0 ]
assert . Equal ( t , "A" , migratedQuery . RefID )
assert . Equal ( t , "A" , migratedQuery . RefID )
model , err := simplejson . NewJson ( migratedQuery . JSON )
var model QueryJson
err = json . Unmarshal ( migratedQuery . JSON , & model )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Equal ( t , "Average" , model . Get ( "statistic" ) . MustString ( ) )
assert . Equal ( t , "Average" , * model . Statistic )
res , err := model . Get ( "statistic" ) . Array ( )
assert . Error ( t , err )
assert . Nil ( t , res )
} )
} )
} )
} )
t . Run ( "New dimensions structure" , func ( t * testing . T ) {
t . Run ( "New dimensions structure" , func ( t * testing . T ) {
query := simplejson . NewFromAny ( map [ string ] interface { } {
fixtureJSON := [ ] byte ( ` {
"refId" : "ref1" ,
"refId" : "ref1" ,
"region" : "us-east-1" ,
"region" : "us-east-1" ,
"namespace" : "ec2" ,
"namespace" : "ec2" ,
"metricName" : "CPUUtilization" ,
"metricName" : "CPUUtilization" ,
"id" : "" ,
"id" : "" ,
"expression" : "" ,
"expression" : "" ,
"dimensions" : map [ string ] interface { } {
"dimensions" : {
"InstanceId" : [ ] interface { } { "test" } ,
"InstanceId" : [ "test" ] ,
"InstanceType" : [ ] interface { } { "test2" , "test3" } ,
"InstanceType" : [ "test2" , "test3" ]
} ,
} ,
"statistic" : "Average" ,
"statistic" : "Average" ,
"period" : "600" ,
"period" : "600" ,
"hide" : false ,
"hide" : false
} )
} ` )
var query QueryJson
err := json . Unmarshal ( fixtureJSON , & query )
require . NoError ( t , err )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Equal ( t , "us-east-1" , res . Region )
assert . Equal ( t , "us-east-1" , res . Region )
@ -81,21 +82,25 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Old dimensions structure (backwards compatibility)" , func ( t * testing . T ) {
t . Run ( "Old dimensions structure (backwards compatibility)" , func ( t * testing . T ) {
query := simplejson . NewFromAny ( map [ string ] interface { } {
fixtureJSON := [ ] byte ( ` {
"refId" : "ref1" ,
"refId" : "ref1" ,
"region" : "us-east-1" ,
"region" : "us-east-1" ,
"namespace" : "ec2" ,
"namespace" : "ec2" ,
"metricName" : "CPUUtilization" ,
"metricName" : "CPUUtilization" ,
"id" : "" ,
"id" : "" ,
"expression" : "" ,
"expression" : "" ,
"dimensions" : map [ string ] interface { } {
"dimensions" : {
"InstanceId" : "test" ,
"InstanceId" : [ "test" ] ,
"InstanceType" : "test2" ,
"InstanceType" : [ "test2" ]
} ,
} ,
"statistic" : "Average" ,
"statistic" : "Average" ,
"period" : "600" ,
"period" : "600" ,
"hide" : false ,
"hide" : false
} )
} ` )
var query QueryJson
err := json . Unmarshal ( fixtureJSON , & query )
require . NoError ( t , err )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
require . NoError ( t , err )
require . NoError ( t , err )
@ -115,21 +120,25 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Period defined in the editor by the user is being used when time range is short" , func ( t * testing . T ) {
t . Run ( "Period defined in the editor by the user is being used when time range is short" , func ( t * testing . T ) {
query := simplejson . NewFromAny ( map [ string ] interface { } {
fixtureJSON := [ ] byte ( ` {
"refId" : "ref1" ,
"refId" : "ref1" ,
"region" : "us-east-1" ,
"region" : "us-east-1" ,
"namespace" : "ec2" ,
"namespace" : "ec2" ,
"metricName" : "CPUUtilization" ,
"metricName" : "CPUUtilization" ,
"id" : "" ,
"id" : "" ,
"expression" : "" ,
"expression" : "" ,
"dimensions" : map [ string ] interface { } {
"dimensions" : {
"InstanceId" : "test" ,
"InstanceId" : [ "test" ] ,
"InstanceType" : "test2" ,
"InstanceType" : [ "test2" ]
} ,
} ,
"statistic" : "Average" ,
"statistic" : "Average" ,
"hide" : false ,
"hide" : false
} )
} ` )
query . Set ( "period" , "900" )
var query QueryJson
err := json . Unmarshal ( fixtureJSON , & query )
require . NoError ( t , err )
query . Period = "900"
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
require . NoError ( t , err )
require . NoError ( t , err )
@ -137,24 +146,28 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Period is parsed correctly if not defined by user" , func ( t * testing . T ) {
t . Run ( "Period is parsed correctly if not defined by user" , func ( t * testing . T ) {
query := simplejson . NewFromAny ( map [ string ] interface { } {
fixtureJSON := [ ] byte ( ` {
"refId" : "ref1" ,
"refId" : "ref1" ,
"region" : "us-east-1" ,
"region" : "us-east-1" ,
"namespace" : "ec2" ,
"namespace" : "ec2" ,
"metricName" : "CPUUtilization" ,
"metricName" : "CPUUtilization" ,
"id" : "" ,
"id" : "" ,
"expression" : "" ,
"expression" : "" ,
"dimensions" : map [ string ] interface { } {
"dimensions" : {
"InstanceId" : "test" ,
"InstanceId" : [ "test" ] ,
"InstanceType" : "test2" ,
"InstanceType" : [ "test2" ]
} ,
} ,
"statistic" : "Average" ,
"statistic" : "Average" ,
"hide" : false ,
"hide" : false ,
"period" : "auto" ,
"period" : "auto"
} )
} ` )
var query QueryJson
err := json . Unmarshal ( fixtureJSON , & query )
require . NoError ( t , err )
t . Run ( "Time range is 5 minutes" , func ( t * testing . T ) {
t . Run ( "Time range is 5 minutes" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . Local ( ) . Add ( time . Minute * time . Duration ( 5 ) )
from := to . Local ( ) . Add ( time . Minute * time . Duration ( 5 ) )
@ -164,7 +177,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 1 day" , func ( t * testing . T ) {
t . Run ( "Time range is 1 day" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . AddDate ( 0 , 0 , - 1 )
from := to . AddDate ( 0 , 0 , - 1 )
@ -174,7 +187,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 2 days" , func ( t * testing . T ) {
t . Run ( "Time range is 2 days" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . AddDate ( 0 , 0 , - 2 )
from := to . AddDate ( 0 , 0 , - 2 )
res , err := parseRequestQuery ( query , "ref1" , from , to )
res , err := parseRequestQuery ( query , "ref1" , from , to )
@ -183,7 +196,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 7 days" , func ( t * testing . T ) {
t . Run ( "Time range is 7 days" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . AddDate ( 0 , 0 , - 7 )
from := to . AddDate ( 0 , 0 , - 7 )
@ -193,7 +206,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 30 days" , func ( t * testing . T ) {
t . Run ( "Time range is 30 days" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . AddDate ( 0 , 0 , - 30 )
from := to . AddDate ( 0 , 0 , - 30 )
@ -203,7 +216,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 90 days" , func ( t * testing . T ) {
t . Run ( "Time range is 90 days" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . AddDate ( 0 , 0 , - 90 )
from := to . AddDate ( 0 , 0 , - 90 )
@ -213,7 +226,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 1 year" , func ( t * testing . T ) {
t . Run ( "Time range is 1 year" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . AddDate ( - 1 , 0 , 0 )
from := to . AddDate ( - 1 , 0 , 0 )
@ -223,7 +236,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 2 years" , func ( t * testing . T ) {
t . Run ( "Time range is 2 years" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( )
to := time . Now ( )
from := to . AddDate ( - 2 , 0 , 0 )
from := to . AddDate ( - 2 , 0 , 0 )
@ -233,7 +246,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 2 days, but 16 days ago" , func ( t * testing . T ) {
t . Run ( "Time range is 2 days, but 16 days ago" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( ) . AddDate ( 0 , 0 , - 14 )
to := time . Now ( ) . AddDate ( 0 , 0 , - 14 )
from := to . AddDate ( 0 , 0 , - 2 )
from := to . AddDate ( 0 , 0 , - 2 )
res , err := parseRequestQuery ( query , "ref1" , from , to )
res , err := parseRequestQuery ( query , "ref1" , from , to )
@ -242,7 +255,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 2 days, but 90 days ago" , func ( t * testing . T ) {
t . Run ( "Time range is 2 days, but 90 days ago" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( ) . AddDate ( 0 , 0 , - 88 )
to := time . Now ( ) . AddDate ( 0 , 0 , - 88 )
from := to . AddDate ( 0 , 0 , - 2 )
from := to . AddDate ( 0 , 0 , - 2 )
res , err := parseRequestQuery ( query , "ref1" , from , to )
res , err := parseRequestQuery ( query , "ref1" , from , to )
@ -251,7 +264,7 @@ func TestRequestParser(t *testing.T) {
} )
} )
t . Run ( "Time range is 2 days, but 456 days ago" , func ( t * testing . T ) {
t . Run ( "Time range is 2 days, but 456 days ago" , func ( t * testing . T ) {
query . Set ( "period" , "auto" )
query . Period = "auto"
to := time . Now ( ) . AddDate ( 0 , 0 , - 454 )
to := time . Now ( ) . AddDate ( 0 , 0 , - 454 )
from := to . AddDate ( 0 , 0 , - 2 )
from := to . AddDate ( 0 , 0 , - 2 )
res , err := parseRequestQuery ( query , "ref1" , from , to )
res , err := parseRequestQuery ( query , "ref1" , from , to )
@ -273,7 +286,7 @@ func TestRequestParser(t *testing.T) {
t . Run ( "and an expression is specified it should be metric search builder" , func ( t * testing . T ) {
t . Run ( "and an expression is specified it should be metric search builder" , func ( t * testing . T ) {
query := getBaseJsonQuery ( )
query := getBaseJsonQuery ( )
query . Set ( "expression" , "SUM(a)" )
query . Expression = "SUM(a)"
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Equal ( t , MetricQueryTypeSearch , res . MetricQueryType )
assert . Equal ( t , MetricQueryTypeSearch , res . MetricQueryType )
@ -284,7 +297,7 @@ func TestRequestParser(t *testing.T) {
t . Run ( "and an expression is specified it should be metric search builder" , func ( t * testing . T ) {
t . Run ( "and an expression is specified it should be metric search builder" , func ( t * testing . T ) {
query := getBaseJsonQuery ( )
query := getBaseJsonQuery ( )
query . Set ( "expression" , "SUM(a)" )
query . Expression = "SUM(a)"
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Equal ( t , MetricQueryTypeSearch , res . MetricQueryType )
assert . Equal ( t , MetricQueryTypeSearch , res . MetricQueryType )
@ -303,7 +316,7 @@ func TestRequestParser(t *testing.T) {
t . Run ( "Valid id is generated if ID is not provided and refId is not a valid MetricData ID" , func ( t * testing . T ) {
t . Run ( "Valid id is generated if ID is not provided and refId is not a valid MetricData ID" , func ( t * testing . T ) {
query := getBaseJsonQuery ( )
query := getBaseJsonQuery ( )
query . Set ( "refId" , "$$" )
query . RefId = "$$"
res , err := parseRequestQuery ( query , "$$" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
res , err := parseRequestQuery ( query , "$$" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
require . NoError ( t , err )
require . NoError ( t , err )
assert . Equal ( t , "$$" , res . RefId )
assert . Equal ( t , "$$" , res . RefId )
@ -312,8 +325,11 @@ func TestRequestParser(t *testing.T) {
t . Run ( "parseRequestQuery sets label when label is present in json query" , func ( t * testing . T ) {
t . Run ( "parseRequestQuery sets label when label is present in json query" , func ( t * testing . T ) {
query := getBaseJsonQuery ( )
query := getBaseJsonQuery ( )
query . Set ( "alias" , "some alias" )
alias := "some alias"
query . Set ( "label" , "some label" )
query . Alias = & alias
label := "some label"
query . Label = & label
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
res , err := parseRequestQuery ( query , "ref1" , time . Now ( ) . Add ( - 2 * time . Hour ) , time . Now ( ) . Add ( - time . Hour ) )
@ -323,15 +339,22 @@ func TestRequestParser(t *testing.T) {
} )
} )
}
}
func getBaseJsonQuery ( ) * simplejson . Json {
func getBaseJsonQuery ( ) Query Json {
return simplejson . NewFromAny ( map [ string ] interface { } {
fixtureJSON := [ ] byte ( ` {
"refId" : "ref1" ,
"refId" : "ref1" ,
"region" : "us-east-1" ,
"region" : "us-east-1" ,
"namespace" : "ec2" ,
"namespace" : "ec2" ,
"metricName" : "CPUUtilization" ,
"metricName" : "CPUUtilization" ,
"statistic" : "Average" ,
"statistic" : "Average" ,
"period" : "900" ,
"period" : "900"
} )
} ` )
var query QueryJson
err := json . Unmarshal ( fixtureJSON , & query )
if err != nil {
panic ( err )
}
return query
}
}
func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_creates_new_label ( t * testing . T ) {
func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_creates_new_label ( t * testing . T ) {
@ -352,7 +375,7 @@ func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_create
}
}
for name , tc := range testCases {
for name , tc := range testCases {
t . Run ( name , func ( t * testing . T ) {
t . Run ( name , func ( t * testing . T ) {
queryJson , err := simplejson . NewJson ( [ ] byte ( fmt . Sprintf ( ` {
queryJson := [ ] byte ( fmt . Sprintf ( ` {
"region" : "us-east-1" ,
"region" : "us-east-1" ,
"namespace" : "ec2" ,
"namespace" : "ec2" ,
"metricName" : "CPUUtilization" ,
"metricName" : "CPUUtilization" ,
@ -363,26 +386,35 @@ func Test_migrateAliasToDynamicLabel_single_query_preserves_old_alias_and_create
"statistic" : "Average" ,
"statistic" : "Average" ,
"period" : "600" ,
"period" : "600" ,
"hide" : false
"hide" : false
} ` , tc . inputAlias ) ) )
} ` , tc . inputAlias ) )
var query QueryJson
err := json . Unmarshal ( queryJson , & query )
require . NoError ( t , err )
require . NoError ( t , err )
migrateAliasToDynamicLabel ( queryJson )
migrateAliasToDynamicLabel ( & query )
assert . Equal ( t , simplejson . NewFromAny (
matchedJson := [ ] byte ( fmt . Sprintf ( ` {
map [ string ] interface { } {
"alias" : "%s" ,
"alias" : tc . inputAlias ,
"dimensions" : {
"dimensions" : map [ string ] interface { } { "InstanceId" : [ ] interface { } { "test" } } ,
"InstanceId" : [ "test" ]
"hide" : false ,
} ,
"label" : tc . expectedLabel ,
"hide" : false ,
"metricName" : "CPUUtilization" ,
"label" : "%s" ,
"namespace" : "ec2" ,
"metricName" : "CPUUtilization" ,
"period" : "600" ,
"namespace" : "ec2" ,
"region" : "us-east-1" ,
"period" : "600" ,
"statistic" : "Average" } ) , queryJson )
"region" : "us-east-1" ,
"statistic" : "Average"
} ` , tc . inputAlias , tc . expectedLabel ) )
result , err := json . Marshal ( query )
require . NoError ( t , err )
assert . JSONEq ( t , string ( matchedJson ) , string ( result ) )
} )
} )
}
}
}
}
func Test_Test_migrateLegacyQuery ( t * testing . T ) {
func Test_Test_migrateLegacyQuery ( t * testing . T ) {
t . Run ( "migrates alias to label when label does not already exist and feature toggle enabled" , func ( t * testing . T ) {
t . Run ( "migrates alias to label when label does not already exist and feature toggle enabled" , func ( t * testing . T ) {
migratedQueries , err := migrateLegacyQuery (
migratedQueries , err := migrateLegacyQuery (