2016-10-05 03:56:34 -05:00
package influxdb
import (
2021-07-19 04:32:33 -05:00
"strings"
2016-10-05 03:56:34 -05:00
"testing"
2017-11-15 04:22:00 -06:00
"time"
2016-10-05 03:56:34 -05:00
2021-07-19 04:32:33 -05:00
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/require"
2016-10-05 03:56:34 -05:00
)
func TestInfluxdbQueryBuilder ( t * testing . T ) {
2021-07-19 04:32:33 -05:00
t . Run ( "Influxdb query builder" , func ( t * testing . T ) {
2016-10-05 13:36:05 -05:00
qp1 , _ := NewQueryPart ( "field" , [ ] string { "value" } )
qp2 , _ := NewQueryPart ( "mean" , [ ] string { } )
2017-01-11 05:10:26 -06:00
mathPartDivideBy100 , _ := NewQueryPart ( "math" , [ ] string { "/ 100" } )
mathPartDivideByIntervalMs , _ := NewQueryPart ( "math" , [ ] string { "/ $__interval_ms" } )
groupBy1 , _ := NewQueryPart ( "time" , [ ] string { "$__interval" } )
2016-10-07 08:09:54 -05:00
groupBy2 , _ := NewQueryPart ( "tag" , [ ] string { "datacenter" } )
groupBy3 , _ := NewQueryPart ( "fill" , [ ] string { "null" } )
2016-10-05 13:36:05 -05:00
2017-01-11 05:10:26 -06:00
groupByOldInterval , _ := NewQueryPart ( "time" , [ ] string { "$interval" } )
2016-10-05 13:36:05 -05:00
tag1 := & Tag { Key : "hostname" , Value : "server1" , Operator : "=" }
tag2 := & Tag { Key : "hostname" , Value : "server2" , Operator : "=" , Condition : "OR" }
2016-10-05 03:56:34 -05:00
2021-07-19 04:32:33 -05:00
timeRange := backend . TimeRange {
From : time . Date ( 2020 , 8 , 1 , 0 , 0 , 0 , 0 , time . UTC ) ,
To : time . Date ( 2020 , 8 , 1 , 0 , 5 , 0 , 0 , time . UTC ) ,
}
queryContext := & backend . QueryDataRequest {
Queries : [ ] backend . DataQuery {
{
TimeRange : timeRange ,
} ,
} ,
2016-10-06 05:51:45 -05:00
}
2021-07-19 04:32:33 -05:00
t . Run ( "can build simple query" , func ( t * testing . T ) {
2016-10-05 13:36:05 -05:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
2016-10-05 13:57:28 -05:00
Policy : "policy" ,
2016-10-07 08:09:54 -05:00
GroupBy : [ ] * QueryPart { groupBy1 , groupBy3 } ,
2017-11-15 04:22:00 -06:00
Interval : time . Second * 10 ,
2016-10-05 13:36:05 -05:00
}
2016-11-10 07:38:06 -06:00
rawQuery , err := query . Build ( queryContext )
2021-07-19 04:32:33 -05:00
require . NoError ( t , err )
2022-07-07 12:55:51 -05:00
require . Equal ( t , rawQuery , ` SELECT mean("value") FROM "policy"."cpu" WHERE time >= 1596240000000ms and time <= 1596240300000ms GROUP BY time(10s) fill(null) ` )
2016-10-05 03:56:34 -05:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can build query with tz" , func ( t * testing . T ) {
2018-12-21 09:38:53 -06:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
GroupBy : [ ] * QueryPart { groupBy1 } ,
Tz : "Europe/Paris" ,
Interval : time . Second * 5 ,
}
rawQuery , err := query . Build ( queryContext )
2021-07-19 04:32:33 -05:00
require . NoError ( t , err )
2022-07-07 12:55:51 -05:00
require . Equal ( t , rawQuery ,
` SELECT mean("value") FROM "cpu" WHERE time >= 1596240000000ms and time <= 1596240300000ms GROUP BY time(5s) tz('Europe/Paris') ` )
2018-12-21 09:38:53 -06:00
} )
2022-02-09 12:26:16 -06:00
t . Run ( "can build query with tz, limit, slimit, orderByTime and puts them in the correct order" , func ( t * testing . T ) {
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
GroupBy : [ ] * QueryPart { groupBy1 } ,
Tz : "Europe/Paris" ,
Limit : "1" ,
Slimit : "1" ,
OrderByTime : "ASC" ,
Interval : time . Second * 5 ,
}
rawQuery , err := query . Build ( queryContext )
require . NoError ( t , err )
2022-07-07 12:55:51 -05:00
require . Equal ( t , rawQuery ,
` SELECT mean("value") FROM "cpu" WHERE time >= 1596240000000ms and time <= 1596240300000ms GROUP BY time(5s) ORDER BY time ASC limit 1 slimit 1 tz('Europe/Paris') ` )
2022-02-09 12:26:16 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can build query with group bys" , func ( t * testing . T ) {
2016-10-05 13:36:05 -05:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
2016-10-07 08:09:54 -05:00
GroupBy : [ ] * QueryPart { groupBy1 , groupBy2 , groupBy3 } ,
2016-10-05 13:36:05 -05:00
Tags : [ ] * Tag { tag1 , tag2 } ,
2017-11-15 04:22:00 -06:00
Interval : time . Second * 5 ,
2016-10-05 13:36:05 -05:00
}
2016-11-10 07:38:06 -06:00
rawQuery , err := query . Build ( queryContext )
2021-07-19 04:32:33 -05:00
require . NoError ( t , err )
2022-07-07 12:55:51 -05:00
require . Equal ( t , rawQuery , ` SELECT mean("value") FROM "cpu" WHERE ("hostname" = 'server1' OR "hostname" = 'server2') AND time >= 1596240000000ms and time <= 1596240300000ms GROUP BY time(5s), "datacenter" fill(null) ` )
2016-10-07 04:23:37 -05:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can build query with math part" , func ( t * testing . T ) {
2017-01-11 05:10:26 -06:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 , * mathPartDivideBy100 } } ,
Measurement : "cpu" ,
2017-11-15 04:22:00 -06:00
Interval : time . Second * 5 ,
2017-01-11 05:10:26 -06:00
}
rawQuery , err := query . Build ( queryContext )
2021-07-19 04:32:33 -05:00
require . NoError ( t , err )
2022-07-07 12:55:51 -05:00
require . Equal ( t , rawQuery ,
` SELECT mean("value") / 100 FROM "cpu" WHERE time >= 1596240000000ms and time <= 1596240300000ms ` )
2017-01-11 05:10:26 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can build query with math part using $__interval_ms variable" , func ( t * testing . T ) {
2017-01-11 05:10:26 -06:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 , * mathPartDivideByIntervalMs } } ,
Measurement : "cpu" ,
2017-11-15 04:22:00 -06:00
Interval : time . Second * 5 ,
2017-01-11 05:10:26 -06:00
}
rawQuery , err := query . Build ( queryContext )
2021-07-19 04:32:33 -05:00
require . NoError ( t , err )
2022-07-07 12:55:51 -05:00
require . Equal ( t , rawQuery ,
` SELECT mean("value") / 5000 FROM "cpu" WHERE time >= 1596240000000ms and time <= 1596240300000ms ` )
2017-01-11 05:10:26 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can build query with old $interval variable" , func ( t * testing . T ) {
2017-01-11 05:10:26 -06:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
Policy : "" ,
GroupBy : [ ] * QueryPart { groupByOldInterval } ,
2021-07-19 04:32:33 -05:00
Interval : time . Millisecond * 200 ,
2017-01-11 05:10:26 -06:00
}
rawQuery , err := query . Build ( queryContext )
2021-07-19 04:32:33 -05:00
require . NoError ( t , err )
2022-07-07 12:55:51 -05:00
require . Equal ( t , rawQuery ,
` SELECT mean("value") FROM "cpu" WHERE time >= 1596240000000ms and time <= 1596240300000ms GROUP BY time(200ms) ` )
2017-01-11 05:10:26 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render time range" , func ( t * testing . T ) {
2016-10-07 04:33:17 -05:00
query := Query { }
2021-07-19 04:32:33 -05:00
t . Run ( "render from: 2h to now-1h" , func ( t * testing . T ) {
2016-10-07 04:33:17 -05:00
query := Query { }
2021-07-19 04:32:33 -05:00
timeRange = backend . TimeRange {
From : time . Date ( 2020 , 8 , 1 , 0 , 0 , 0 , 0 , time . UTC ) ,
To : time . Date ( 2020 , 8 , 1 , 1 , 0 , 0 , 0 , time . UTC ) ,
}
queryContext = & backend . QueryDataRequest {
Queries : [ ] backend . DataQuery {
{
TimeRange : timeRange ,
} ,
} ,
}
2022-07-07 12:55:51 -05:00
require . Equal ( t , query . renderTimeFilter ( queryContext ) ,
"time >= 1596240000000ms and time <= 1596243600000ms" )
2016-10-07 04:23:37 -05:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "render from: 10m" , func ( t * testing . T ) {
timeRange = backend . TimeRange {
From : time . Date ( 2020 , 8 , 1 , 0 , 0 , 0 , 0 , time . UTC ) ,
To : time . Date ( 2020 , 8 , 1 , 0 , 10 , 0 , 0 , time . UTC ) ,
}
queryContext = & backend . QueryDataRequest {
Queries : [ ] backend . DataQuery {
{
TimeRange : timeRange ,
} ,
} ,
}
2022-07-07 12:55:51 -05:00
require . Equal ( t , query . renderTimeFilter ( queryContext ) ,
"time >= 1596240000000ms and time <= 1596240600000ms" )
2016-10-07 04:23:37 -05:00
} )
2016-10-05 03:56:34 -05:00
} )
2016-10-11 11:29:09 -05:00
2021-07-19 04:32:33 -05:00
t . Run ( "can build query from raw query" , func ( t * testing . T ) {
2016-10-11 11:29:09 -05:00
query := & Query {
Selects : [ ] * Select { { * qp1 , * qp2 } } ,
Measurement : "cpu" ,
Policy : "policy" ,
GroupBy : [ ] * QueryPart { groupBy1 , groupBy3 } ,
2017-11-15 04:22:00 -06:00
Interval : time . Second * 10 ,
2016-10-11 11:29:09 -05:00
RawQuery : "Raw query" ,
2016-11-10 07:16:18 -06:00
UseRawQuery : true ,
2016-10-11 11:29:09 -05:00
}
2016-11-10 07:38:06 -06:00
rawQuery , err := query . Build ( queryContext )
2021-07-19 04:32:33 -05:00
require . NoError ( t , err )
require . Equal ( t , rawQuery , ` Raw query ` )
2016-10-11 11:29:09 -05:00
} )
2016-11-07 07:26:20 -06:00
2021-07-19 04:32:33 -05:00
t . Run ( "can render normal tags without operator" , func ( t * testing . T ) {
2017-01-27 08:21:02 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : "" , Value : ` value ` , Key : "key" } } }
2016-11-10 03:41:00 -06:00
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" = 'value' ` )
2016-11-10 03:41:00 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render regex tags without operator" , func ( t * testing . T ) {
2017-01-27 08:21:02 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : "" , Value : ` /value/ ` , Key : "key" } } }
2016-11-10 03:41:00 -06:00
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" =~ /value/ ` )
2016-11-10 03:41:00 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render regex tags" , func ( t * testing . T ) {
2017-01-27 08:21:02 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : "=~" , Value : ` /value/ ` , Key : "key" } } }
2016-11-07 07:26:20 -06:00
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" =~ /value/ ` )
2016-11-07 07:26:20 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render number tags" , func ( t * testing . T ) {
2017-01-27 08:21:02 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : "=" , Value : "10001" , Key : "key" } } }
2016-11-10 03:41:00 -06:00
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" = '10001' ` )
2016-11-10 03:41:00 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render numbers less then condition tags" , func ( t * testing . T ) {
2017-01-27 08:21:02 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : "<" , Value : "10001" , Key : "key" } } }
2016-11-07 07:26:20 -06:00
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" < 10001 ` )
2016-11-17 08:47:15 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render number greater then condition tags" , func ( t * testing . T ) {
2017-01-27 08:21:02 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : ">" , Value : "10001" , Key : "key" } } }
2016-11-17 08:47:15 -06:00
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" > 10001 ` )
2016-11-07 07:26:20 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render string tags" , func ( t * testing . T ) {
2017-01-27 08:21:02 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : "=" , Value : "value" , Key : "key" } } }
2016-11-07 07:26:20 -06:00
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" = 'value' ` )
2016-11-07 07:26:20 -06:00
} )
2016-11-14 01:47:45 -06:00
2021-07-19 04:32:33 -05:00
t . Run ( "can escape backslashes when rendering string tags" , func ( t * testing . T ) {
2018-02-19 03:00:09 -06:00
query := & Query { Tags : [ ] * Tag { { Operator : "=" , Value : ` C:\test\ ` , Key : "key" } } }
2021-07-19 04:32:33 -05:00
require . Equal ( t , strings . Join ( query . renderTags ( ) , "" ) , ` "key" = 'C:\\test\\' ` )
2018-02-19 03:00:09 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render regular measurement" , func ( t * testing . T ) {
2016-11-14 01:47:45 -06:00
query := & Query { Measurement : ` apa ` , Policy : "policy" }
2021-07-19 04:32:33 -05:00
require . Equal ( t , query . renderMeasurement ( ) , ` FROM "policy"."apa" ` )
2016-11-14 01:47:45 -06:00
} )
2021-07-19 04:32:33 -05:00
t . Run ( "can render regexp measurement" , func ( t * testing . T ) {
2016-11-14 01:47:45 -06:00
query := & Query { Measurement : ` /apa/ ` , Policy : "policy" }
2021-07-19 04:32:33 -05:00
require . Equal ( t , query . renderMeasurement ( ) , ` FROM "policy"./apa/ ` )
2016-11-14 01:47:45 -06:00
} )
2016-10-05 03:56:34 -05:00
} )
}