2016-10-05 16:56:34 +08:00
package influxdb
import (
"testing"
2017-11-15 18:22:00 +08:00
"time"
2016-10-05 16:56:34 +08:00
2016-11-07 21:26:20 +08:00
"strings"
2021-03-08 14:02:49 +08:00
"github.com/grafana/grafana/pkg/plugins"
2016-10-05 16:56:34 +08:00
. "github.com/smartystreets/goconvey/convey"
)
func TestInfluxdbQueryBuilder ( t * testing . T ) {
Convey ( "Influxdb query builder" , t , func ( ) {
2016-10-06 02:36:05 +08:00
qp1 , _ := NewQueryPart ( "field" , [ ] string { "value" } )
qp2 , _ := NewQueryPart ( "mean" , [ ] string { } )
2017-01-11 19:10:26 +08:00
mathPartDivideBy100 , _ := NewQueryPart ( "math" , [ ] string { "/ 100" } )
mathPartDivideByIntervalMs , _ := NewQueryPart ( "math" , [ ] string { "/ $__interval_ms" } )
groupBy1 , _ := NewQueryPart ( "time" , [ ] string { "$__interval" } )
2016-10-07 21:09:54 +08:00
groupBy2 , _ := NewQueryPart ( "tag" , [ ] string { "datacenter" } )
groupBy3 , _ := NewQueryPart ( "fill" , [ ] string { "null" } )
2016-10-06 02:36:05 +08:00
2017-01-11 19:10:26 +08:00
groupByOldInterval , _ := NewQueryPart ( "time" , [ ] string { "$interval" } )
2016-10-06 02:36:05 +08:00
tag1 := & Tag { Key : "hostname" , Value : "server1" , Operator : "=" }
tag2 := & Tag { Key : "hostname" , Value : "server2" , Operator : "=" , Condition : "OR" }
2016-10-05 16:56:34 +08:00
2021-03-08 14:02:49 +08:00
timeRange := plugins . NewDataTimeRange ( "5m" , "now" )
queryContext := plugins . DataQuery {
TimeRange : & timeRange ,
2016-10-06 18:51:45 +08:00
}
2016-10-06 20:16:26 +08:00
Convey ( "can build simple query" , func ( ) {
2016-10-06 02:36:05 +08:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
2016-10-06 02:57:28 +08:00
Policy : "policy" ,
2016-10-07 21:09:54 +08:00
GroupBy : [ ] * QueryPart { groupBy1 , groupBy3 } ,
2017-11-15 18:22:00 +08:00
Interval : time . Second * 10 ,
2016-10-06 02:36:05 +08:00
}
2016-11-10 21:38:06 +08:00
rawQuery , err := query . Build ( queryContext )
2016-10-06 02:36:05 +08:00
So ( err , ShouldBeNil )
2016-10-13 17:42:51 +08:00
So ( rawQuery , ShouldEqual , ` SELECT mean("value") FROM "policy"."cpu" WHERE time > now() - 5m GROUP BY time(10s) fill(null) ` )
2016-10-05 16:56:34 +08:00
} )
2018-12-21 23:38:53 +08:00
Convey ( "can build query with tz" , func ( ) {
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
GroupBy : [ ] * QueryPart { groupBy1 } ,
Tz : "Europe/Paris" ,
Interval : time . Second * 5 ,
}
rawQuery , err := query . Build ( queryContext )
So ( err , ShouldBeNil )
So ( rawQuery , ShouldEqual , ` SELECT mean("value") FROM "cpu" WHERE time > now() - 5m GROUP BY time(5s) tz('Europe/Paris') ` )
} )
2016-10-06 20:16:26 +08:00
Convey ( "can build query with group bys" , func ( ) {
2016-10-06 02:36:05 +08:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
2016-10-07 21:09:54 +08:00
GroupBy : [ ] * QueryPart { groupBy1 , groupBy2 , groupBy3 } ,
2016-10-06 02:36:05 +08:00
Tags : [ ] * Tag { tag1 , tag2 } ,
2017-11-15 18:22:00 +08:00
Interval : time . Second * 5 ,
2016-10-06 02:36:05 +08:00
}
2016-11-10 21:38:06 +08:00
rawQuery , err := query . Build ( queryContext )
2016-10-06 02:36:05 +08:00
So ( err , ShouldBeNil )
2017-08-31 15:33:03 +08:00
So ( rawQuery , ShouldEqual , ` SELECT mean("value") FROM "cpu" WHERE ("hostname" = 'server1' OR "hostname" = 'server2') AND time > now() - 5m GROUP BY time(5s), "datacenter" fill(null) ` )
2016-10-07 17:23:37 +08:00
} )
2017-01-11 19:10:26 +08:00
Convey ( "can build query with math part" , func ( ) {
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 , * mathPartDivideBy100 } } ,
Measurement : "cpu" ,
2017-11-15 18:22:00 +08:00
Interval : time . Second * 5 ,
2017-01-11 19:10:26 +08:00
}
rawQuery , err := query . Build ( queryContext )
So ( err , ShouldBeNil )
So ( rawQuery , ShouldEqual , ` SELECT mean("value") / 100 FROM "cpu" WHERE time > now() - 5m ` )
} )
Convey ( "can build query with math part using $__interval_ms variable" , func ( ) {
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 , * mathPartDivideByIntervalMs } } ,
Measurement : "cpu" ,
2017-11-15 18:22:00 +08:00
Interval : time . Second * 5 ,
2017-01-11 19:10:26 +08:00
}
rawQuery , err := query . Build ( queryContext )
So ( err , ShouldBeNil )
So ( rawQuery , ShouldEqual , ` SELECT mean("value") / 5000 FROM "cpu" WHERE time > now() - 5m ` )
} )
Convey ( "can build query with old $interval variable" , func ( ) {
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
Policy : "" ,
GroupBy : [ ] * QueryPart { groupByOldInterval } ,
}
rawQuery , err := query . Build ( queryContext )
So ( err , ShouldBeNil )
So ( rawQuery , ShouldEqual , ` SELECT mean("value") FROM "cpu" WHERE time > now() - 5m GROUP BY time(200ms) ` )
} )
2016-10-07 17:23:37 +08:00
Convey ( "can render time range" , func ( ) {
2016-10-07 17:33:17 +08:00
query := Query { }
2016-10-07 17:23:37 +08:00
Convey ( "render from: 2h to now-1h" , func ( ) {
2016-10-07 17:33:17 +08:00
query := Query { }
2021-03-08 14:02:49 +08:00
timeRange := plugins . NewDataTimeRange ( "2h" , "now-1h" )
queryContext := plugins . DataQuery { TimeRange : & timeRange }
2016-11-10 21:38:06 +08:00
So ( query . renderTimeFilter ( queryContext ) , ShouldEqual , "time > now() - 2h and time < now() - 1h" )
2016-10-07 17:23:37 +08:00
} )
Convey ( "render from: 10m" , func ( ) {
2021-03-08 14:02:49 +08:00
timeRange := plugins . NewDataTimeRange ( "10m" , "now" )
queryContext := plugins . DataQuery { TimeRange : & timeRange }
2016-11-10 21:38:06 +08:00
So ( query . renderTimeFilter ( queryContext ) , ShouldEqual , "time > now() - 10m" )
2016-10-07 17:23:37 +08:00
} )
2016-10-05 16:56:34 +08:00
} )
2016-10-12 00:29:09 +08:00
Convey ( "can build query from raw query" , func ( ) {
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
Policy : "policy" ,
GroupBy : [ ] * QueryPart { groupBy1 , groupBy3 } ,
2017-11-15 18:22:00 +08:00
Interval : time . Second * 10 ,
2016-10-12 00:29:09 +08:00
RawQuery : "Raw query" ,
2016-11-10 21:16:18 +08:00
UseRawQuery : true ,
2016-10-12 00:29:09 +08:00
}
2016-11-10 21:38:06 +08:00
rawQuery , err := query . Build ( queryContext )
2016-10-12 00:29:09 +08:00
So ( err , ShouldBeNil )
So ( rawQuery , ShouldEqual , ` Raw query ` )
} )
2016-11-07 21:26:20 +08:00
2016-11-10 17:41:00 +08:00
Convey ( "can render normal tags without operator" , func ( ) {
2017-01-27 22:21:02 +08:00
query := & Query { Tags : [ ] * Tag { { Operator : "" , Value : ` value ` , Key : "key" } } }
2016-11-10 17:41:00 +08:00
2016-11-10 21:38:06 +08:00
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" = 'value' ` )
2016-11-10 17:41:00 +08:00
} )
Convey ( "can render regex tags without operator" , func ( ) {
2017-01-27 22:21:02 +08:00
query := & Query { Tags : [ ] * Tag { { Operator : "" , Value : ` /value/ ` , Key : "key" } } }
2016-11-10 17:41:00 +08:00
2016-11-10 21:38:06 +08:00
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" =~ /value/ ` )
2016-11-10 17:41:00 +08:00
} )
2016-11-07 21:26:20 +08:00
Convey ( "can render regex tags" , func ( ) {
2017-01-27 22:21:02 +08:00
query := & Query { Tags : [ ] * Tag { { Operator : "=~" , Value : ` /value/ ` , Key : "key" } } }
2016-11-07 21:26:20 +08:00
2016-11-10 21:38:06 +08:00
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" =~ /value/ ` )
2016-11-07 21:26:20 +08:00
} )
Convey ( "can render number tags" , func ( ) {
2017-01-27 22:21:02 +08:00
query := & Query { Tags : [ ] * Tag { { Operator : "=" , Value : "10001" , Key : "key" } } }
2016-11-10 17:41:00 +08:00
2016-11-17 22:47:15 +08:00
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" = '10001' ` )
2016-11-10 17:41:00 +08:00
} )
2016-11-17 22:47:15 +08:00
Convey ( "can render numbers less then condition tags" , func ( ) {
2017-01-27 22:21:02 +08:00
query := & Query { Tags : [ ] * Tag { { Operator : "<" , Value : "10001" , Key : "key" } } }
2016-11-07 21:26:20 +08:00
2016-11-17 22:47:15 +08:00
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" < 10001 ` )
} )
2018-09-21 17:51:26 +08:00
Convey ( "can render number greater then condition tags" , func ( ) {
2017-01-27 22:21:02 +08:00
query := & Query { Tags : [ ] * Tag { { Operator : ">" , Value : "10001" , Key : "key" } } }
2016-11-17 22:47:15 +08:00
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" > 10001 ` )
2016-11-07 21:26:20 +08:00
} )
Convey ( "can render string tags" , func ( ) {
2017-01-27 22:21:02 +08:00
query := & Query { Tags : [ ] * Tag { { Operator : "=" , Value : "value" , Key : "key" } } }
2016-11-07 21:26:20 +08:00
2016-11-10 21:38:06 +08:00
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" = 'value' ` )
2016-11-07 21:26:20 +08:00
} )
2016-11-14 15:47:45 +08:00
2018-02-19 17:00:09 +08:00
Convey ( "can escape backslashes when rendering string tags" , func ( ) {
query := & Query { Tags : [ ] * Tag { { Operator : "=" , Value : ` C:\test\ ` , Key : "key" } } }
So ( strings . Join ( query . renderTags ( ) , "" ) , ShouldEqual , ` "key" = 'C:\\test\\' ` )
} )
2016-11-14 15:47:45 +08:00
Convey ( "can render regular measurement" , func ( ) {
query := & Query { Measurement : ` apa ` , Policy : "policy" }
So ( query . renderMeasurement ( ) , ShouldEqual , ` FROM "policy"."apa" ` )
} )
Convey ( "can render regexp measurement" , func ( ) {
query := & Query { Measurement : ` /apa/ ` , Policy : "policy" }
So ( query . renderMeasurement ( ) , ShouldEqual , ` FROM "policy"./apa/ ` )
} )
2016-10-05 16:56:34 +08:00
} )
}