2015-06-22 20:53:51 +00:00
|
|
|
package graphite_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/influxdb/influxdb/services/graphite"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestDecodeNameAndTags(t *testing.T) {
|
|
|
|
var tests = []struct {
|
|
|
|
test string
|
|
|
|
str string
|
|
|
|
measurement string
|
|
|
|
tags map[string]string
|
2015-06-22 22:47:03 +00:00
|
|
|
template string
|
2015-06-22 20:53:51 +00:00
|
|
|
err string
|
|
|
|
}{
|
|
|
|
{test: "metric only",
|
|
|
|
str: "cpu",
|
|
|
|
measurement: "cpu",
|
2015-06-22 22:47:03 +00:00
|
|
|
template: "measurement",
|
2015-06-22 20:53:51 +00:00
|
|
|
},
|
|
|
|
{test: "metric with single series",
|
|
|
|
str: "cpu.server01",
|
|
|
|
measurement: "cpu",
|
2015-06-22 22:47:03 +00:00
|
|
|
template: "measurement.hostname",
|
2015-06-22 20:53:51 +00:00
|
|
|
tags: map[string]string{"hostname": "server01"},
|
|
|
|
},
|
|
|
|
{test: "metric with multiple series",
|
|
|
|
str: "cpu.us-west.server01",
|
|
|
|
measurement: "cpu",
|
2015-06-22 22:47:03 +00:00
|
|
|
template: "measurement.region.hostname",
|
2015-06-22 20:53:51 +00:00
|
|
|
tags: map[string]string{"hostname": "server01", "region": "us-west"},
|
|
|
|
},
|
|
|
|
{test: "no metric",
|
2015-06-22 22:47:03 +00:00
|
|
|
tags: make(map[string]string),
|
|
|
|
err: `no measurement specified for template. ""`,
|
2015-06-22 20:53:51 +00:00
|
|
|
},
|
|
|
|
{test: "ignore unnamed",
|
|
|
|
str: "foo.cpu",
|
2015-06-22 22:47:03 +00:00
|
|
|
template: "measurement",
|
2015-06-22 20:53:51 +00:00
|
|
|
tags: make(map[string]string),
|
|
|
|
measurement: "foo"},
|
2015-06-22 22:47:03 +00:00
|
|
|
{test: "name shorter than template",
|
2015-06-22 20:53:51 +00:00
|
|
|
str: "foo",
|
2015-06-22 22:47:03 +00:00
|
|
|
template: "measurement.A.B.C",
|
2015-06-22 20:53:51 +00:00
|
|
|
tags: make(map[string]string),
|
|
|
|
measurement: "foo",
|
|
|
|
},
|
2015-06-22 21:39:28 +00:00
|
|
|
{test: "wildcard measurement at end",
|
|
|
|
str: "prod.us-west.server01.cpu.load",
|
2015-06-22 22:47:03 +00:00
|
|
|
template: "env.zone.host.measurement*",
|
2015-06-22 21:39:28 +00:00
|
|
|
tags: map[string]string{"env": "prod", "zone": "us-west", "host": "server01"},
|
|
|
|
measurement: "cpu.load",
|
|
|
|
},
|
2015-06-22 23:11:27 +00:00
|
|
|
{test: "skip fields",
|
|
|
|
str: "ignore.us-west.ignore-this-too.cpu.load",
|
|
|
|
template: ".zone..measurement*",
|
|
|
|
tags: map[string]string{"zone": "us-west"},
|
|
|
|
measurement: "cpu.load",
|
|
|
|
},
|
2015-06-22 20:53:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
2015-06-23 05:28:52 +00:00
|
|
|
p, err := graphite.NewParser([]string{test.template})
|
2015-06-22 20:53:51 +00:00
|
|
|
if errstr(err) != test.err {
|
|
|
|
t.Fatalf("err does not match. expected %v, got %v", test.err, err)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
// If we erred out,it was intended and the following tests won't work
|
|
|
|
continue
|
|
|
|
}
|
2015-06-22 22:47:03 +00:00
|
|
|
|
|
|
|
measurement, tags := p.DecodeNameAndTags(test.str)
|
2015-06-22 20:53:51 +00:00
|
|
|
if measurement != test.measurement {
|
|
|
|
t.Fatalf("name parse failer. expected %v, got %v", test.measurement, measurement)
|
|
|
|
}
|
|
|
|
if len(tags) != len(test.tags) {
|
2015-06-22 23:11:27 +00:00
|
|
|
t.Fatalf("unexpected number of tags. expected %v, got %v", test.tags, tags)
|
2015-06-22 20:53:51 +00:00
|
|
|
}
|
|
|
|
for k, v := range test.tags {
|
|
|
|
if tags[k] != v {
|
|
|
|
t.Fatalf("unexpected tag value for tags[%s]. expected %q, got %q", k, v, tags[k])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-22 22:47:03 +00:00
|
|
|
func TestParseMissingMeasurement(t *testing.T) {
|
2015-06-23 05:28:52 +00:00
|
|
|
_, err := graphite.NewParser([]string{"a.b.c"})
|
2015-06-22 22:47:03 +00:00
|
|
|
if err == nil {
|
|
|
|
t.Fatalf("expected error creating parser, got nil")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-22 20:53:51 +00:00
|
|
|
func TestParse(t *testing.T) {
|
|
|
|
testTime := time.Now().Round(time.Second)
|
|
|
|
epochTime := testTime.Unix()
|
|
|
|
strTime := strconv.FormatInt(epochTime, 10)
|
|
|
|
|
|
|
|
var tests = []struct {
|
2015-06-22 22:47:03 +00:00
|
|
|
test string
|
|
|
|
line string
|
|
|
|
measurement string
|
|
|
|
tags map[string]string
|
|
|
|
value float64
|
|
|
|
time time.Time
|
|
|
|
template string
|
|
|
|
err string
|
2015-06-22 20:53:51 +00:00
|
|
|
}{
|
|
|
|
{
|
2015-06-22 22:47:03 +00:00
|
|
|
test: "normal case",
|
|
|
|
line: `cpu.foo.bar 50 ` + strTime,
|
|
|
|
template: "measurement.foo.bar",
|
|
|
|
measurement: "cpu",
|
2015-06-22 20:53:51 +00:00
|
|
|
tags: map[string]string{
|
|
|
|
"foo": "foo",
|
|
|
|
"bar": "bar",
|
|
|
|
},
|
|
|
|
value: 50,
|
|
|
|
time: testTime,
|
|
|
|
},
|
|
|
|
{
|
2015-06-22 22:47:03 +00:00
|
|
|
test: "metric only with float value",
|
|
|
|
line: `cpu 50.554 ` + strTime,
|
|
|
|
measurement: "cpu",
|
|
|
|
template: "measurement",
|
|
|
|
value: 50.554,
|
|
|
|
time: testTime,
|
2015-06-22 20:53:51 +00:00
|
|
|
},
|
|
|
|
{
|
2015-06-22 22:47:03 +00:00
|
|
|
test: "missing metric",
|
|
|
|
line: `50.554 1419972457825`,
|
|
|
|
template: "measurement",
|
|
|
|
err: `received "50.554 1419972457825" which doesn't have three fields`,
|
2015-06-22 20:53:51 +00:00
|
|
|
},
|
|
|
|
{
|
2015-06-22 22:47:03 +00:00
|
|
|
test: "should error parsing invalid float",
|
|
|
|
line: `cpu 50.554z 1419972457825`,
|
|
|
|
template: "measurement",
|
|
|
|
err: `field "cpu" value: strconv.ParseFloat: parsing "50.554z": invalid syntax`,
|
2015-06-22 20:53:51 +00:00
|
|
|
},
|
|
|
|
{
|
2015-06-22 22:47:03 +00:00
|
|
|
test: "should error parsing invalid int",
|
|
|
|
line: `cpu 50z 1419972457825`,
|
|
|
|
template: "measurement",
|
|
|
|
err: `field "cpu" value: strconv.ParseFloat: parsing "50z": invalid syntax`,
|
2015-06-22 20:53:51 +00:00
|
|
|
},
|
|
|
|
{
|
2015-06-22 22:47:03 +00:00
|
|
|
test: "should error parsing invalid time",
|
|
|
|
line: `cpu 50.554 14199724z57825`,
|
|
|
|
template: "measurement",
|
|
|
|
err: `field "cpu" time: strconv.ParseFloat: parsing "14199724z57825": invalid syntax`,
|
2015-06-22 20:53:51 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range tests {
|
2015-06-23 05:28:52 +00:00
|
|
|
p, err := graphite.NewParser([]string{test.template})
|
2015-06-22 22:47:03 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unexpected error creating graphite parser: %v", err)
|
2015-06-22 20:53:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
point, err := p.Parse(test.line)
|
|
|
|
if errstr(err) != test.err {
|
|
|
|
t.Fatalf("err does not match. expected %v, got %v", test.err, err)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
// If we erred out,it was intended and the following tests won't work
|
|
|
|
continue
|
|
|
|
}
|
2015-06-22 22:47:03 +00:00
|
|
|
if point.Name() != test.measurement {
|
|
|
|
t.Fatalf("name parse failer. expected %v, got %v", test.measurement, point.Name())
|
2015-06-22 20:53:51 +00:00
|
|
|
}
|
|
|
|
if len(point.Tags()) != len(test.tags) {
|
|
|
|
t.Fatalf("tags len mismatch. expected %d, got %d", len(test.tags), len(point.Tags()))
|
|
|
|
}
|
|
|
|
f := point.Fields()["value"].(float64)
|
|
|
|
if point.Fields()["value"] != f {
|
|
|
|
t.Fatalf("floatValue value mismatch. expected %v, got %v", test.value, f)
|
|
|
|
}
|
|
|
|
if point.Time().UnixNano()/1000000 != test.time.UnixNano()/1000000 {
|
|
|
|
t.Fatalf("time value mismatch. expected %v, got %v", test.time.UnixNano(), point.Time().UnixNano())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|