feedback(influx_tools): Add +ve and -ve test cases for processing schema
parent
9b7ffd36ad
commit
4ff74ff971
|
@ -81,3 +81,4 @@ man/*.1.gz
|
|||
|
||||
# vendored files
|
||||
/vendor
|
||||
/gen
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue