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