influxdb/query/influxql/result_test.go

137 lines
3.5 KiB
Go

package influxql_test
import (
"bytes"
"errors"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/influxdata/flux"
"github.com/influxdata/flux/execute"
"github.com/influxdata/flux/execute/executetest"
"github.com/influxdata/influxdb/v2/query/influxql"
)
func TestMultiResultEncoder_Encode(t *testing.T) {
for _, tt := range []struct {
name string
in flux.ResultIterator
out string
}{
{
name: "Default",
in: flux.NewSliceResultIterator(
[]flux.Result{&executetest.Result{
Nm: "0",
Tbls: []*executetest.Table{{
KeyCols: []string{"_measurement", "host"},
ColMeta: []flux.ColMeta{
{Label: "_time", Type: flux.TTime},
{Label: "_measurement", Type: flux.TString},
{Label: "host", Type: flux.TString},
{Label: "value", Type: flux.TFloat},
},
Data: [][]interface{}{
{ts("2018-05-24T09:00:00Z"), "m0", "server01", float64(2)},
},
}},
}},
),
out: `{"results":[{"statement_id":0,"series":[{"name":"m0","tags":{"host":"server01"},"columns":["time","value"],"values":[["2018-05-24T09:00:00Z",2]]}]}]}`,
},
{
name: "No _time column",
in: flux.NewSliceResultIterator(
[]flux.Result{&executetest.Result{
Nm: "0",
Tbls: []*executetest.Table{{
KeyCols: []string{"_measurement", "host"},
ColMeta: []flux.ColMeta{
{Label: "_measurement", Type: flux.TString},
{Label: "host", Type: flux.TString},
{Label: "value", Type: flux.TFloat},
},
Data: [][]interface{}{
{"m0", "server01", float64(2)},
},
}},
}},
),
out: `{"results":[{"statement_id":0,"series":[{"name":"m0","tags":{"host":"server01"},"columns":["value"],"values":[[2]]}]}]}`,
},
{
name: "Just One Value Column",
in: flux.NewSliceResultIterator(
[]flux.Result{&executetest.Result{
Nm: "0",
Tbls: []*executetest.Table{{
KeyCols: []string{},
ColMeta: []flux.ColMeta{
{Label: "name", Type: flux.TString},
},
Data: [][]interface{}{
{"telegraf"},
},
}},
}},
),
out: `{"results":[{"statement_id":0,"series":[{"columns":["name"],"values":[["telegraf"]]}]}]}`,
},
{
name: "Error",
in: &resultErrorIterator{Error: "expected"},
out: `{"error":"expected"}`,
},
} {
tt := tt
t.Run(tt.name, func(t *testing.T) {
// Add expected newline to end of output
tt.out += "\n"
var buf bytes.Buffer
enc := influxql.NewMultiResultEncoder()
n, err := enc.Encode(&buf, tt.in)
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
if got, exp := buf.String(), tt.out; got != exp {
t.Fatalf("unexpected output:\nexp=%s\ngot=%s", exp, got)
}
if g, w := n, int64(len(tt.out)); g != w {
t.Errorf("unexpected encoding count -want/+got:\n%s", cmp.Diff(w, g))
}
})
}
}
type resultErrorIterator struct {
Error string
}
func (*resultErrorIterator) Statistics() flux.Statistics {
return flux.Statistics{}
}
func (*resultErrorIterator) Release() {}
func (*resultErrorIterator) More() bool { return false }
func (*resultErrorIterator) Next() flux.Result { panic("no results") }
func (ri *resultErrorIterator) Err() error {
return errors.New(ri.Error)
}
func mustParseTime(s string) time.Time {
t, err := time.Parse(time.RFC3339, s)
if err != nil {
panic(err)
}
return t
}
// ts takes an RFC3339 time string and returns an execute.Time from it using the unix timestamp.
func ts(s string) execute.Time {
return execute.Time(mustParseTime(s).UnixNano())
}