feedback(influx_tools): Add +ve and -ve test cases for processing schema

pull/12211/head
Stuart Carnie 2019-02-26 15:55:50 -07:00
parent 9b7ffd36ad
commit 4ff74ff971
3 changed files with 182 additions and 29 deletions

1
.gitignore vendored
View File

@ -81,3 +81,4 @@ man/*.1.gz
# vendored files
/vendor
/gen

View File

@ -13,6 +13,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/influxdata/influxdb/models"
"github.com/pkg/errors"
)
type Spec struct {
@ -227,7 +228,10 @@ func (s *schemaToSpec) visit(node SchemaNode) bool {
s.push(mss)
case *Measurement:
var ms []MeasurementSpec
if len(n.Name) == 0 {
s.err = errors.New("missing measurement name")
return false
}
fields := s.pop().([]*FieldValuesSpec)
tagsSpec := s.pop().(*TagsSpec)
@ -240,6 +244,12 @@ func (s *schemaToSpec) visit(node SchemaNode) bool {
tagsSpec.Sample = &s
}
if *tagsSpec.Sample <= 0.0 || *tagsSpec.Sample > 1.0 {
s.err = errors.New("invalid sample, must be 0 < sample ≤ 1.0")
return false
}
var ms []MeasurementSpec
for _, spec := range fields {
ms = append(ms, MeasurementSpec{
Name: n.Name,

View File

@ -2,10 +2,23 @@ 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"
@ -19,10 +32,11 @@ tags = [
]
fields = [
{ name = "f0", count = 5000, source = 0.5 },
{ name = "f1", count = 5000, source = 0.5 },
{ name = "f1", count = 5000, source = 2 },
]
[[measurements]]
name = "m1"
tags = [
{ name = "tag0", source = [ "host1", "host2" ] },
]
@ -35,44 +49,172 @@ fields = [
t.Fatalf("unxpected error: %v", err)
}
spec, err := NewSpecFromSchema(&out)
got, err := NewSpecFromSchema(&out)
if err != nil {
t.Error(err)
}
t.Log(spec)
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) {
in := `
title = "example schema"
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 = [
{ name = "tag0", source = [ "host1", "host2" ] },
{ name = "tag1", source = { type = "sequence", format = "value%s", start = 0, count = 100 } },
]
fields = [
{ name = "f0", count = 5000, source = 0.5 },
]
tags = [ { source = [ "host1", "host2" ] } ]
fields = [ { name = "f0", count = 5000, source = 0.5 } ]
`,
decodeErr: "tag: missing or invalid value for name",
},
{
in: `
[[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)
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"`,
},
}
spec, err := NewSpecFromSchema(&out)
if err != nil {
t.Error(err)
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)
}
})
}
t.Log(spec)
}