2019-02-05 21:31:54 +00:00
|
|
|
package gen
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2019-02-26 22:55:50 +00:00
|
|
|
"time"
|
2019-02-05 21:31:54 +00:00
|
|
|
|
|
|
|
"github.com/BurntSushi/toml"
|
2019-02-26 22:55:50 +00:00
|
|
|
"github.com/google/go-cmp/cmp"
|
|
|
|
"github.com/influxdata/influxdb/models"
|
2019-02-05 21:31:54 +00:00
|
|
|
)
|
|
|
|
|
2019-02-26 22:55:50 +00:00
|
|
|
func countableSequenceFnCmp(a, b NewCountableSequenceFn) bool {
|
|
|
|
// these aren't comparable
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
func timeValuesSequenceFnCmp(a, b NewTimeValuesSequenceFn) bool {
|
|
|
|
// these aren't comparable
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2019-02-05 21:31:54 +00:00
|
|
|
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 },
|
2019-02-26 22:55:50 +00:00
|
|
|
{ name = "f1", count = 5000, source = 2 },
|
2019-02-05 21:31:54 +00:00
|
|
|
]
|
|
|
|
[[measurements]]
|
|
|
|
name = "m1"
|
2019-02-26 22:55:50 +00:00
|
|
|
|
2019-02-05 21:31:54 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2019-02-26 22:55:50 +00:00
|
|
|
got, err := NewSpecFromSchema(&out)
|
2019-02-05 21:31:54 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
2019-02-26 22:55:50 +00:00
|
|
|
|
|
|
|
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)))
|
|
|
|
}
|
2019-02-05 21:31:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestSpecFromSchemaError(t *testing.T) {
|
2019-02-26 22:55:50 +00:00
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
in string
|
2019-02-05 21:31:54 +00:00
|
|
|
|
2019-02-26 22:55:50 +00:00
|
|
|
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: `
|
2019-02-05 21:31:54 +00:00
|
|
|
[[measurements]]
|
|
|
|
name = "m0"
|
2019-02-26 22:55:50 +00:00
|
|
|
tags = [ { source = [ "host1", "host2" ] } ]
|
|
|
|
fields = [ { name = "f0", count = 5000, source = 0.5 } ]
|
|
|
|
`,
|
|
|
|
decodeErr: "tag: missing or invalid value for name",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
in: `
|
2019-02-05 21:31:54 +00:00
|
|
|
[[measurements]]
|
2019-02-26 22:55:50 +00:00
|
|
|
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"`,
|
|
|
|
},
|
|
|
|
}
|
2019-02-05 21:31:54 +00:00
|
|
|
|
2019-02-26 22:55:50 +00:00
|
|
|
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))
|
|
|
|
}
|
2019-02-05 21:31:54 +00:00
|
|
|
}
|
|
|
|
|
2019-02-26 22:55:50 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
})
|
2019-02-05 21:31:54 +00:00
|
|
|
}
|
|
|
|
}
|