Test the merge iterator for every type instead of just floats
parent
03ad7a4e40
commit
3dd6aa17f3
|
@ -0,0 +1,160 @@
|
|||
// Generated by tmpl
|
||||
// https://github.com/benbjohnson/tmpl
|
||||
|
||||
package influxql_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/influxdb/influxdb/influxql"
|
||||
"github.com/influxdb/influxdb/pkg/deep"
|
||||
)
|
||||
|
||||
// Test implementation of influxql.FloatIterator
|
||||
type FloatIterator struct {
|
||||
Points []influxql.FloatPoint
|
||||
}
|
||||
|
||||
// Close is a no-op.
|
||||
func (itr *FloatIterator) Close() error { return nil }
|
||||
|
||||
// Next returns the next value and shifts it off the beginning of the points slice.
|
||||
func (itr *FloatIterator) Next() *influxql.FloatPoint {
|
||||
if len(itr.Points) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := &itr.Points[0]
|
||||
itr.Points = itr.Points[1:]
|
||||
return v
|
||||
}
|
||||
|
||||
type TestFloatIterator struct {
|
||||
Iterator influxql.Iterator
|
||||
Points []influxql.FloatPoint
|
||||
}
|
||||
|
||||
func (ti *TestFloatIterator) run(t *testing.T) {
|
||||
itr := ti.Iterator.(influxql.FloatIterator)
|
||||
|
||||
points := make([]influxql.FloatPoint, 0, len(ti.Points))
|
||||
for p := itr.Next(); p != nil; p = itr.Next() {
|
||||
points = append(points, *p)
|
||||
}
|
||||
|
||||
if !deep.Equal(ti.Points, points) {
|
||||
t.Fatalf("unexpected points: %s %s", spew.Sdump(points), spew.Sdump(ti.Points))
|
||||
}
|
||||
}
|
||||
|
||||
// Test implementation of influxql.IntegerIterator
|
||||
type IntegerIterator struct {
|
||||
Points []influxql.IntegerPoint
|
||||
}
|
||||
|
||||
// Close is a no-op.
|
||||
func (itr *IntegerIterator) Close() error { return nil }
|
||||
|
||||
// Next returns the next value and shifts it off the beginning of the points slice.
|
||||
func (itr *IntegerIterator) Next() *influxql.IntegerPoint {
|
||||
if len(itr.Points) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := &itr.Points[0]
|
||||
itr.Points = itr.Points[1:]
|
||||
return v
|
||||
}
|
||||
|
||||
type TestIntegerIterator struct {
|
||||
Iterator influxql.Iterator
|
||||
Points []influxql.IntegerPoint
|
||||
}
|
||||
|
||||
func (ti *TestIntegerIterator) run(t *testing.T) {
|
||||
itr := ti.Iterator.(influxql.IntegerIterator)
|
||||
|
||||
points := make([]influxql.IntegerPoint, 0, len(ti.Points))
|
||||
for p := itr.Next(); p != nil; p = itr.Next() {
|
||||
points = append(points, *p)
|
||||
}
|
||||
|
||||
if !deep.Equal(ti.Points, points) {
|
||||
t.Fatalf("unexpected points: %s %s", spew.Sdump(points), spew.Sdump(ti.Points))
|
||||
}
|
||||
}
|
||||
|
||||
// Test implementation of influxql.StringIterator
|
||||
type StringIterator struct {
|
||||
Points []influxql.StringPoint
|
||||
}
|
||||
|
||||
// Close is a no-op.
|
||||
func (itr *StringIterator) Close() error { return nil }
|
||||
|
||||
// Next returns the next value and shifts it off the beginning of the points slice.
|
||||
func (itr *StringIterator) Next() *influxql.StringPoint {
|
||||
if len(itr.Points) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := &itr.Points[0]
|
||||
itr.Points = itr.Points[1:]
|
||||
return v
|
||||
}
|
||||
|
||||
type TestStringIterator struct {
|
||||
Iterator influxql.Iterator
|
||||
Points []influxql.StringPoint
|
||||
}
|
||||
|
||||
func (ti *TestStringIterator) run(t *testing.T) {
|
||||
itr := ti.Iterator.(influxql.StringIterator)
|
||||
|
||||
points := make([]influxql.StringPoint, 0, len(ti.Points))
|
||||
for p := itr.Next(); p != nil; p = itr.Next() {
|
||||
points = append(points, *p)
|
||||
}
|
||||
|
||||
if !deep.Equal(ti.Points, points) {
|
||||
t.Fatalf("unexpected points: %s %s", spew.Sdump(points), spew.Sdump(ti.Points))
|
||||
}
|
||||
}
|
||||
|
||||
// Test implementation of influxql.BooleanIterator
|
||||
type BooleanIterator struct {
|
||||
Points []influxql.BooleanPoint
|
||||
}
|
||||
|
||||
// Close is a no-op.
|
||||
func (itr *BooleanIterator) Close() error { return nil }
|
||||
|
||||
// Next returns the next value and shifts it off the beginning of the points slice.
|
||||
func (itr *BooleanIterator) Next() *influxql.BooleanPoint {
|
||||
if len(itr.Points) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := &itr.Points[0]
|
||||
itr.Points = itr.Points[1:]
|
||||
return v
|
||||
}
|
||||
|
||||
type TestBooleanIterator struct {
|
||||
Iterator influxql.Iterator
|
||||
Points []influxql.BooleanPoint
|
||||
}
|
||||
|
||||
func (ti *TestBooleanIterator) run(t *testing.T) {
|
||||
itr := ti.Iterator.(influxql.BooleanIterator)
|
||||
|
||||
points := make([]influxql.BooleanPoint, 0, len(ti.Points))
|
||||
for p := itr.Next(); p != nil; p = itr.Next() {
|
||||
points = append(points, *p)
|
||||
}
|
||||
|
||||
if !deep.Equal(ti.Points, points) {
|
||||
t.Fatalf("unexpected points: %s %s", spew.Sdump(points), spew.Sdump(ti.Points))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package influxql_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/influxdb/influxdb/influxql"
|
||||
"github.com/influxdb/influxdb/pkg/deep"
|
||||
)
|
||||
|
||||
{{range .}}
|
||||
|
||||
// Test implementation of influxql.{{.Name}}Iterator
|
||||
type {{.Name}}Iterator struct {
|
||||
Points []influxql.{{.Name}}Point
|
||||
}
|
||||
|
||||
// Close is a no-op.
|
||||
func (itr *{{.Name}}Iterator) Close() error { return nil }
|
||||
|
||||
// Next returns the next value and shifts it off the beginning of the points slice.
|
||||
func (itr *{{.Name}}Iterator) Next() *influxql.{{.Name}}Point {
|
||||
if len(itr.Points) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := &itr.Points[0]
|
||||
itr.Points = itr.Points[1:]
|
||||
return v
|
||||
}
|
||||
|
||||
type Test{{.Name}}Iterator struct {
|
||||
Iterator influxql.Iterator
|
||||
Points []influxql.{{.Name}}Point
|
||||
}
|
||||
|
||||
func (ti *Test{{.Name}}Iterator) run(t *testing.T) {
|
||||
itr := ti.Iterator.(influxql.{{.Name}}Iterator)
|
||||
|
||||
points := make([]influxql.{{.Name}}Point, 0, len(ti.Points))
|
||||
for p := itr.Next(); p != nil; p = itr.Next() {
|
||||
points = append(points, *p)
|
||||
}
|
||||
|
||||
if !deep.Equal(ti.Points, points) {
|
||||
t.Fatalf("unexpected points: %s %s", spew.Sdump(points), spew.Sdump(ti.Points))
|
||||
}
|
||||
}
|
||||
{{end}}
|
|
@ -13,9 +13,12 @@ import (
|
|||
"github.com/influxdb/influxdb/pkg/deep"
|
||||
)
|
||||
|
||||
//go:generate tmpl -data=@tmpldata iterator.gen_test.go.tmpl
|
||||
|
||||
// Ensure that a set of iterators can be merged together, sorted by window and name/tag.
|
||||
func TestMergeIterator(t *testing.T) {
|
||||
itr := influxql.NewMergeIterator([]influxql.Iterator{
|
||||
func TestMergeIterator_Float(t *testing.T) {
|
||||
test := TestFloatIterator{
|
||||
Iterator: influxql.NewMergeIterator([]influxql.Iterator{
|
||||
&FloatIterator{Points: []influxql.FloatPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: 1},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: 2},
|
||||
|
@ -32,26 +35,120 @@ func TestMergeIterator(t *testing.T) {
|
|||
Duration: 10 * time.Nanosecond,
|
||||
},
|
||||
Ascending: true,
|
||||
}).(influxql.FloatIterator)
|
||||
}),
|
||||
Points: []influxql.FloatPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: 1},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: 2},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: 3},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: 5},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: 6},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: 7},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: 4},
|
||||
},
|
||||
}
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
if p := itr.Next(); !reflect.DeepEqual(p, &influxql.FloatPoint{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: 1}) {
|
||||
t.Fatalf("unexpected point: %#v", p)
|
||||
} else if p = itr.Next(); !reflect.DeepEqual(p, &influxql.FloatPoint{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: 2}) {
|
||||
t.Fatalf("unexpected point: %#v", p)
|
||||
// Ensure that a set of iterators can be merged together, sorted by window and name/tag.
|
||||
func TestMergeIterator_Integer(t *testing.T) {
|
||||
test := TestIntegerIterator{
|
||||
Iterator: influxql.NewMergeIterator([]influxql.Iterator{
|
||||
&IntegerIterator{Points: []influxql.IntegerPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: 1},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: 2},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: 3},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: 4},
|
||||
}},
|
||||
&IntegerIterator{Points: []influxql.IntegerPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: 5},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: 6},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: 7},
|
||||
}},
|
||||
}, influxql.IteratorOptions{
|
||||
Interval: influxql.Interval{
|
||||
Duration: 10 * time.Nanosecond,
|
||||
},
|
||||
Ascending: true,
|
||||
}),
|
||||
Points: []influxql.IntegerPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: 1},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: 2},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: 3},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: 5},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: 6},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: 7},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: 4},
|
||||
},
|
||||
}
|
||||
if p := itr.Next(); !reflect.DeepEqual(p, &influxql.FloatPoint{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: 3}) {
|
||||
t.Fatalf("unexpected point: %#v", p)
|
||||
} else if p = itr.Next(); !reflect.DeepEqual(p, &influxql.FloatPoint{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: 5}) {
|
||||
t.Fatalf("unexpected point: %#v", p)
|
||||
} else if p := itr.Next(); !reflect.DeepEqual(p, &influxql.FloatPoint{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: 6}) {
|
||||
t.Fatalf("unexpected point: %#v", p)
|
||||
test.run(t)
|
||||
}
|
||||
if p := itr.Next(); !reflect.DeepEqual(p, &influxql.FloatPoint{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: 7}) {
|
||||
t.Fatalf("unexpected point: %#v", p)
|
||||
|
||||
// Ensure that a set of iterators can be merged together, sorted by window and name/tag.
|
||||
func TestMergeIterator_String(t *testing.T) {
|
||||
test := TestStringIterator{
|
||||
Iterator: influxql.NewMergeIterator([]influxql.Iterator{
|
||||
&StringIterator{Points: []influxql.StringPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: "a"},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: "b"},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: "c"},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: "d"},
|
||||
}},
|
||||
&StringIterator{Points: []influxql.StringPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: "e"},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: "f"},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: "g"},
|
||||
}},
|
||||
}, influxql.IteratorOptions{
|
||||
Interval: influxql.Interval{
|
||||
Duration: 10 * time.Nanosecond,
|
||||
},
|
||||
Ascending: true,
|
||||
}),
|
||||
Points: []influxql.StringPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: "a"},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: "b"},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: "c"},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: "e"},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: "f"},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: "g"},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: "d"},
|
||||
},
|
||||
}
|
||||
if p := itr.Next(); !reflect.DeepEqual(p, &influxql.FloatPoint{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: 4}) {
|
||||
t.Fatalf("unexpected point: %#v", p)
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
// Ensure that a set of iterators can be merged together, sorted by window and name/tag.
|
||||
func TestMergeIterator_Boolean(t *testing.T) {
|
||||
test := TestBooleanIterator{
|
||||
Iterator: influxql.NewMergeIterator([]influxql.Iterator{
|
||||
&BooleanIterator{Points: []influxql.BooleanPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: true},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: false},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: true},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: false},
|
||||
}},
|
||||
&BooleanIterator{Points: []influxql.BooleanPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: true},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: false},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: true},
|
||||
}},
|
||||
}, influxql.IteratorOptions{
|
||||
Interval: influxql.Interval{
|
||||
Duration: 10 * time.Nanosecond,
|
||||
},
|
||||
Ascending: true,
|
||||
}),
|
||||
Points: []influxql.BooleanPoint{
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 0, Value: true},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 1, Value: false},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 12, Value: true},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 11, Value: true},
|
||||
{Name: "cpu", Tags: ParseTags("host=B"), Time: 13, Value: false},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 20, Value: true},
|
||||
{Name: "cpu", Tags: ParseTags("host=A"), Time: 30, Value: false},
|
||||
},
|
||||
}
|
||||
test.run(t)
|
||||
}
|
||||
|
||||
func TestMergeIterator_Nil(t *testing.T) {
|
||||
|
@ -223,25 +320,6 @@ func (ic *IteratorCreator) FieldDimensions(sources influxql.Sources) (fields, di
|
|||
return ic.FieldDimensionsFn(sources)
|
||||
}
|
||||
|
||||
// Test implementation of influxql.FloatIterator.
|
||||
type FloatIterator struct {
|
||||
Points []influxql.FloatPoint
|
||||
}
|
||||
|
||||
// Close is a no-op.
|
||||
func (itr *FloatIterator) Close() error { return nil }
|
||||
|
||||
// Next returns the next value and shifts it off the beginning of the points slice.
|
||||
func (itr *FloatIterator) Next() *influxql.FloatPoint {
|
||||
if len(itr.Points) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := &itr.Points[0]
|
||||
itr.Points = itr.Points[1:]
|
||||
return v
|
||||
}
|
||||
|
||||
// GenerateFloatIterator creates a FloatIterator with random data.
|
||||
func GenerateFloatIterator(rand *rand.Rand, valueN int) *FloatIterator {
|
||||
const interval = 10 * time.Second
|
||||
|
|
|
@ -140,6 +140,8 @@ func deepValueEqual(v1, v2 reflect.Value, visited map[visit]bool, depth int) boo
|
|||
return true
|
||||
}
|
||||
return f1 == f2
|
||||
case reflect.Bool:
|
||||
return v1.Bool() == v2.Bool()
|
||||
default:
|
||||
panic(fmt.Sprintf("cannot compare type: %s", v1.Kind().String()))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue