influxdb/pkg/data/gen/specs_test.go

221 lines
4.7 KiB
Go

package gen
import (
"testing"
"time"
"github.com/BurntSushi/toml"
"github.com/google/go-cmp/cmp"
"github.com/influxdata/influxdb/models"
)
func countableSequenceFnCmp(a, b NewCountableSequenceFn) bool {
// these aren't comparable
return true
}
func timeValuesSequenceFnCmp(a, b NewTimeValuesSequenceFn) bool {
// these aren't comparable
return true
}
func TestSpecFromSchema(t *testing.T) {
in := `
title = "example schema"
[[measurements]]
name = "m0"
tags = [
{ name = "tag0", source = [ "host1", "host2" ] },
{ name = "tag1", source = [ "process1", "process2" ] },
{ name = "tag2", source = { type = "sequence", format = "value%s", start = 0, count = 100 } }
]
fields = [
{ name = "f0", count = 5000, source = 0.5 },
{ name = "f1", count = 5000, source = 2 },
]
[[measurements]]
name = "m1"
tags = [
{ name = "tag0", source = [ "host1", "host2" ] },
]
fields = [
{ name = "f0", count = 5000, source = 0.5 },
]
`
var out Schema
if _, err := toml.Decode(in, &out); err != nil {
t.Fatalf("unxpected error: %v", err)
}
got, err := NewSpecFromSchema(&out)
if err != nil {
t.Error(err)
}
samples := []sample{0.5}
exp := &Spec{
SeriesLimit: nil,
Measurements: []MeasurementSpec{
{
Name: "m0",
SeriesLimit: nil,
TagsSpec: &TagsSpec{
Tags: []*TagValuesSpec{
{TagKey: "tag0"},
{TagKey: "tag1"},
{TagKey: "tag2"},
},
Sample: &samples[0],
},
FieldValuesSpec: &FieldValuesSpec{
TimeSequenceSpec: TimeSequenceSpec{
Count: 5000,
Precision: time.Millisecond,
},
Name: "f0",
DataType: models.Float,
},
},
{
Name: "m0",
SeriesLimit: nil,
TagsSpec: &TagsSpec{
Tags: []*TagValuesSpec{
{TagKey: "tag0"},
{TagKey: "tag1"},
{TagKey: "tag2"},
},
Sample: &samples[0],
},
FieldValuesSpec: &FieldValuesSpec{
TimeSequenceSpec: TimeSequenceSpec{
Count: 5000,
Precision: time.Millisecond,
},
Name: "f1",
DataType: models.Integer,
},
},
{
Name: "m1",
SeriesLimit: nil,
TagsSpec: &TagsSpec{
Tags: []*TagValuesSpec{
{TagKey: "tag0"},
},
Sample: &samples[0],
},
FieldValuesSpec: &FieldValuesSpec{
TimeSequenceSpec: TimeSequenceSpec{
Count: 5000,
Precision: time.Millisecond,
},
Name: "f0",
DataType: models.Float,
},
},
},
}
// TODO(sgc): use a Spec rather than closures for NewCountableSequenceFn and NewTimeValuesSequenceFn
if !cmp.Equal(got, exp, cmp.Comparer(countableSequenceFnCmp), cmp.Comparer(timeValuesSequenceFnCmp)) {
t.Errorf("unexpected spec; -got/+exp\n%s", cmp.Diff(got, exp, cmp.Comparer(countableSequenceFnCmp), cmp.Comparer(timeValuesSequenceFnCmp)))
}
}
func TestSpecFromSchemaError(t *testing.T) {
tests := []struct {
name string
in string
decodeErr string
specErr string
}{
{
in: `
[[measurements]]
tags = [ { name = "tag0", source = [ "host1", "host2" ] } ]
fields = [ { name = "f0", count = 5000, source = 0.5 } ]
`,
specErr: "error processing schema: missing measurement name",
},
{
in: `
[[measurements]]
sample = -0.1
tags = [ { name = "tag0", source = [ "host1", "host2" ] } ]
fields = [ { name = "f0", count = 5000, source = 0.5 } ]
`,
decodeErr: "sample: must be 0 < sample ≤ 1.0",
},
{
in: `
[[measurements]]
name = "m0"
tags = [ { source = [ "host1", "host2" ] } ]
fields = [ { name = "f0", count = 5000, source = 0.5 } ]
`,
decodeErr: "tag: missing or invalid value for name",
},
{
in: `
[[measurements]]
name = "m0"
tags = [ { name = "tag0" } ]
fields = [ { name = "f0", count = 5000, source = 0.5 } ]
`,
decodeErr: `missing source for tag "tag0"`,
},
{
in: `
[[measurements]]
name = "m0"
tags = [ { name = "tag0", source = [ "host1", "host2" ] } ]
fields = [ { count = 5000, source = 0.5 } ]
`,
decodeErr: `field: missing or invalid value for name`,
},
{
in: `
[[measurements]]
name = "m0"
tags = [ { name = "tag0", source = [ "host1", "host2" ] } ]
fields = [ { name = "f0", count = 5000 } ]
`,
decodeErr: `missing source for field "f0"`,
},
}
checkErr := func(t *testing.T, err error, exp string) {
t.Helper()
if exp == "" {
if err == nil {
return
}
t.Errorf("unexpected error, got %v", err)
}
if err == nil {
t.Errorf("expected error, got nil")
} else if err.Error() != exp {
t.Errorf("unexpected error, -got/+exp\n%s", cmp.Diff(err.Error(), exp))
}
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var out Schema
_, err := toml.Decode(test.in, &out)
checkErr(t, err, test.decodeErr)
if test.decodeErr == "" {
_, err = NewSpecFromSchema(&out)
checkErr(t, err, test.specErr)
}
})
}
}