influxdb/influx/query_test.go

582 lines
16 KiB
Go

package influx
import (
"reflect"
"testing"
"github.com/influxdata/chronograf"
)
func TestConvert(t *testing.T) {
tests := []struct {
name string
influxQL string
RawText string
want chronograf.QueryConfig
wantErr bool
}{
{
name: "Test field order",
influxQL: `SELECT "usage_idle", "usage_guest_nice", "usage_system", "usage_guest" FROM "telegraf"."autogen"."cpu" WHERE time > :dashboardTime:`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_guest_nice",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_system",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_guest",
Funcs: []string{},
},
},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test field function order",
influxQL: `SELECT mean("usage_idle"), median("usage_idle"), count("usage_guest_nice"), mean("usage_guest_nice") FROM "telegraf"."autogen"."cpu" WHERE time > :dashboardTime:`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{
"mean",
"median",
},
},
chronograf.Field{
Field: "usage_guest_nice",
Funcs: []string{
"count",
"mean",
},
},
},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test named count field",
influxQL: `SELECT moving_average(mean("count"),14) FROM "usage_computed"."autogen".unique_clusters_by_day WHERE time > now() - 90d AND product = 'influxdb' group by time(1d)`,
RawText: `SELECT moving_average(mean("count"),14) FROM "usage_computed"."autogen".unique_clusters_by_day WHERE time > now() - 90d AND product = 'influxdb' group by time(1d)`,
want: chronograf.QueryConfig{
Fields: []chronograf.Field{},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test math",
influxQL: `SELECT count("event_id")/3 as "event_count_id" from discource.autogen.discourse_events where time > now() - 7d group by time(1d), "event_type"`,
RawText: `SELECT count("event_id")/3 as "event_count_id" from discource.autogen.discourse_events where time > now() - 7d group by time(1d), "event_type"`,
want: chronograf.QueryConfig{
Fields: []chronograf.Field{},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test range",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where "host" != 'myhost' and time > now() - 15m`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_user",
Funcs: []string{},
},
},
Tags: map[string][]string{"host": []string{"myhost"}},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: false,
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test invalid range",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where "host" != 'myhost' and time > now() - 15`,
RawText: `SELECT usage_user from telegraf.autogen.cpu where "host" != 'myhost' and time > now() - 15`,
want: chronograf.QueryConfig{
Fields: []chronograf.Field{},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test range with no duration",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where "host" != 'myhost' and time > now()`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_user",
Funcs: []string{},
},
},
Tags: map[string][]string{"host": []string{"myhost"}},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: false,
Range: &chronograf.DurationRange{
Lower: "now() - 0s",
},
},
},
{
name: "Test range with no tags",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where time > now() - 15m`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Tags: map[string][]string{},
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_user",
Funcs: []string{},
},
},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: false,
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test range with no tags nor duration",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where time`,
RawText: `SELECT usage_user from telegraf.autogen.cpu where time`,
want: chronograf.QueryConfig{
Fields: []chronograf.Field{},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test with no time range",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where "host" != 'myhost' and time`,
RawText: `SELECT usage_user from telegraf.autogen.cpu where "host" != 'myhost' and time`,
want: chronograf.QueryConfig{
Fields: []chronograf.Field{},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test with no where clauses",
influxQL: `SELECT usage_user from telegraf.autogen.cpu`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_user",
Funcs: []string{},
},
},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
},
},
{
name: "Test tags accepted",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where "host" = 'myhost' and time > now() - 15m`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_user",
Funcs: []string{},
},
},
Tags: map[string][]string{"host": []string{"myhost"}},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: true,
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
Upper: "",
},
},
},
{
name: "Test multible tags not accepted",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where time > now() - 15m and "host" != 'myhost' and "cpu" != 'cpu-total'`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_user",
Funcs: []string{},
},
},
Tags: map[string][]string{
"host": []string{
"myhost",
},
"cpu": []string{
"cpu-total",
},
},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: false,
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
Upper: "",
},
},
},
{
name: "Test mixed tag logic",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where ("host" = 'myhost' or "this" = 'those') and ("howdy" != 'doody') and time > now() - 15m`,
RawText: `SELECT usage_user from telegraf.autogen.cpu where ("host" = 'myhost' or "this" = 'those') and ("howdy" != 'doody') and time > now() - 15m`,
want: chronograf.QueryConfig{
Fields: []chronograf.Field{},
Tags: map[string][]string{},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
},
},
{
name: "Test tags accepted",
influxQL: `SELECT usage_user from telegraf.autogen.cpu where ("host" = 'myhost' OR "host" = 'yourhost') and ("these" = 'those') and time > now() - 15m`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_user",
Funcs: []string{},
},
},
Tags: map[string][]string{
"host": []string{"myhost", "yourhost"},
"these": []string{"those"},
},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: true,
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Complex Logic with tags not accepted",
influxQL: `SELECT "usage_idle", "usage_guest_nice", "usage_system", "usage_guest" FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m AND ("cpu"!='cpu-total' OR "cpu"!='cpu0') AND ("host"!='dev-052978d6-us-east-2-meta-0' OR "host"!='dev-052978d6-us-east-2-data-5' OR "host"!='dev-052978d6-us-east-2-data-4' OR "host"!='dev-052978d6-us-east-2-data-3')`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_guest_nice",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_system",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_guest",
Funcs: []string{},
},
},
Tags: map[string][]string{
"host": []string{
"dev-052978d6-us-east-2-meta-0",
"dev-052978d6-us-east-2-data-5",
"dev-052978d6-us-east-2-data-4",
"dev-052978d6-us-east-2-data-3",
},
"cpu": []string{
"cpu-total",
"cpu0",
},
},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: false,
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Complex Logic with tags accepted",
influxQL: `SELECT "usage_idle", "usage_guest_nice", "usage_system", "usage_guest" FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m AND ("cpu" = 'cpu-total' OR "cpu" = 'cpu0') AND ("host" = 'dev-052978d6-us-east-2-meta-0' OR "host" = 'dev-052978d6-us-east-2-data-5' OR "host" = 'dev-052978d6-us-east-2-data-4' OR "host" = 'dev-052978d6-us-east-2-data-3')`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_guest_nice",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_system",
Funcs: []string{},
},
chronograf.Field{
Field: "usage_guest",
Funcs: []string{},
},
},
Tags: map[string][]string{
"host": []string{
"dev-052978d6-us-east-2-meta-0",
"dev-052978d6-us-east-2-data-5",
"dev-052978d6-us-east-2-data-4",
"dev-052978d6-us-east-2-data-3",
},
"cpu": []string{
"cpu-total",
"cpu0",
},
},
GroupBy: chronograf.GroupBy{
Time: "",
Tags: []string{},
},
AreTagsAccepted: true,
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test explicit non-null fill accepted",
influxQL: `SELECT mean("usage_idle") FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m GROUP BY time(1m) FILL(linear)`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{
"mean",
},
},
},
GroupBy: chronograf.GroupBy{
Time: "1m",
Tags: []string{},
},
Tags: map[string][]string{},
AreTagsAccepted: false,
Fill: "linear",
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test explicit null fill accepted",
influxQL: `SELECT mean("usage_idle") FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m GROUP BY time(1m) FILL(null)`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{
"mean",
},
},
},
GroupBy: chronograf.GroupBy{
Time: "1m",
Tags: []string{},
},
Tags: map[string][]string{},
AreTagsAccepted: false,
Fill: "null",
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test implicit null fill accepted and made explicit",
influxQL: `SELECT mean("usage_idle") FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m GROUP BY time(1m)`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{
"mean",
},
},
},
GroupBy: chronograf.GroupBy{
Time: "1m",
Tags: []string{},
},
Tags: map[string][]string{},
AreTagsAccepted: false,
Fill: "null",
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test fill number (int) accepted",
influxQL: `SELECT mean("usage_idle") FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m GROUP BY time(1m) FILL(1337)`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{
"mean",
},
},
},
GroupBy: chronograf.GroupBy{
Time: "1m",
Tags: []string{},
},
Tags: map[string][]string{},
AreTagsAccepted: false,
Fill: "1337",
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test fill number (float) accepted",
influxQL: `SELECT mean("usage_idle") FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m GROUP BY time(1m) FILL(1.337)`,
want: chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
chronograf.Field{
Field: "usage_idle",
Funcs: []string{
"mean",
},
},
},
GroupBy: chronograf.GroupBy{
Time: "1m",
Tags: []string{},
},
Tags: map[string][]string{},
AreTagsAccepted: false,
Fill: "1.337",
Range: &chronograf.DurationRange{
Lower: "now() - 15m",
},
},
},
{
name: "Test invalid fill rejected",
influxQL: `SELECT mean("usage_idle") FROM "telegraf"."autogen"."cpu" WHERE time > now() - 15m GROUP BY time(1m) FILL(LINEAR)`,
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Convert(tt.influxQL)
if (err != nil) != tt.wantErr {
t.Errorf("Convert() error = %v, wantErr %v", err, tt.wantErr)
return
}
if tt.RawText != "" {
tt.want.RawText = &tt.RawText
if got.RawText == nil {
t.Errorf("Convert() = nil, want %s", tt.RawText)
} else if *got.RawText != tt.RawText {
t.Errorf("Convert() = %s, want %s", *got.RawText, tt.RawText)
}
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("Convert() = \n%#v\n want \n%#v\n", got, tt.want)
}
})
}
}