2014-12-31 21:37:58 +00:00
package graphite_test
2014-12-30 22:46:33 +00:00
import (
"strconv"
"testing"
"time"
2014-12-31 21:37:58 +00:00
"github.com/influxdb/influxdb/graphite"
2014-12-30 22:46:33 +00:00
)
2014-12-31 21:37:58 +00:00
func Test_DecodeNameAndTags ( t * testing . T ) {
2014-12-30 22:46:33 +00:00
var tests = [ ] struct {
2015-01-06 03:14:43 +00:00
test string
str string
name string
tags map [ string ] string
position string
2015-01-06 16:57:44 +00:00
separator string
2015-01-06 03:14:43 +00:00
err string
2014-12-30 22:46:33 +00:00
} {
{ test : "metric only" , str : "cpu" , name : "cpu" } ,
2015-01-06 03:14:43 +00:00
{ test : "metric with single series" , str : "cpu.hostname.server01" , name : "cpu" , tags : map [ string ] string { "hostname" : "server01" } } ,
{ test : "metric with multiple series" , str : "cpu.region.us-west.hostname.server01" , name : "cpu" , tags : map [ string ] string { "hostname" : "server01" , "region" : "us-west" } } ,
2014-12-30 22:46:33 +00:00
{ test : "no metric" , tags : make ( map [ string ] string ) , err : ` no name specified for metric. "" ` } ,
2015-01-13 23:00:41 +00:00
{ test : "wrong metric format" , str : "foo.cpu" , tags : make ( map [ string ] string ) , err : ` received "foo.cpu" which doesn't conform to format of key.value.key.value.name or name ` } ,
2014-12-30 22:46:33 +00:00
}
for _ , test := range tests {
t . Logf ( "testing %q..." , test . test )
2015-01-07 07:36:56 +00:00
p := graphite . NewParser ( )
if test . separator != "" {
p . Separator = test . separator
}
name , tags , err := p . DecodeNameAndTags ( test . str )
2014-12-31 21:37:58 +00:00
if errstr ( err ) != test . err {
t . Fatalf ( "err does not match. expected %v, got %v" , test . err , err )
2014-12-30 22:46:33 +00:00
}
if name != test . name {
t . Fatalf ( "name parse failer. expected %v, got %v" , test . name , name )
}
if len ( tags ) != len ( test . tags ) {
t . Fatalf ( "unexpected number of tags. expected %d, got %d" , len ( test . tags ) , len ( tags ) )
}
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 ] )
}
}
}
}
2014-12-31 21:37:58 +00:00
func Test_DecodeMetric ( t * testing . T ) {
2015-03-25 23:04:00 +00:00
testTime := time . Now ( ) . Round ( time . Second )
epochTime := testTime . Unix ( )
2014-12-30 22:46:33 +00:00
strTime := strconv . FormatInt ( epochTime , 10 )
var tests = [ ] struct {
2015-01-06 03:14:43 +00:00
test string
2015-01-07 07:36:56 +00:00
line string
2015-01-06 03:14:43 +00:00
name string
tags map [ string ] string
2015-03-14 15:59:33 +00:00
value float64
2015-01-06 03:14:43 +00:00
timestamp time . Time
2015-01-06 16:57:44 +00:00
position , separator string
2015-01-06 03:14:43 +00:00
err string
2014-12-30 22:46:33 +00:00
} {
{
2015-01-06 03:14:43 +00:00
test : "position first by default" ,
2015-01-07 07:51:59 +00:00
line : ` cpu.foo.bar 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "position first if unable to determine" ,
position : "foo" ,
2015-01-07 07:51:59 +00:00
line : ` cpu.foo.bar 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "position last if specified" ,
position : "last" ,
2015-01-07 07:51:59 +00:00
line : ` foo.bar.cpu 50 ` + strTime ,
2014-12-30 22:46:33 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2014-12-30 22:46:33 +00:00
timestamp : testTime ,
} ,
2015-01-06 03:14:43 +00:00
{
test : "position first if specified with no series" ,
position : "first" ,
2015-01-07 07:51:59 +00:00
line : ` cpu 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "position last if specified with no series" ,
position : "last" ,
2015-01-07 07:51:59 +00:00
line : ` cpu 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "sepeartor is . by default" ,
2015-01-07 07:51:59 +00:00
line : ` cpu.foo.bar 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "sepeartor is . if specified" ,
2015-01-06 16:57:44 +00:00
separator : "." ,
2015-01-07 07:51:59 +00:00
line : ` cpu.foo.bar 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "sepeartor is - if specified" ,
2015-01-06 16:57:44 +00:00
separator : "-" ,
2015-01-07 07:51:59 +00:00
line : ` cpu-foo-bar 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "sepeartor is boo if specified" ,
2015-01-06 16:57:44 +00:00
separator : "boo" ,
2015-01-07 07:51:59 +00:00
line : ` cpuboofooboobar 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
{
test : "series + metric + integer value" ,
2015-01-07 07:51:59 +00:00
line : ` cpu.foo.bar 50 ` + strTime ,
2015-01-06 03:14:43 +00:00
name : "cpu" ,
tags : map [ string ] string { "foo" : "bar" } ,
2015-03-14 15:59:33 +00:00
value : 50 ,
2015-01-06 03:14:43 +00:00
timestamp : testTime ,
} ,
2014-12-30 22:46:33 +00:00
{
test : "metric only with float value" ,
2015-01-07 07:51:59 +00:00
line : ` cpu 50.554 ` + strTime ,
2014-12-30 22:46:33 +00:00
name : "cpu" ,
2015-03-14 15:59:33 +00:00
value : 50.554 ,
2014-12-30 22:46:33 +00:00
timestamp : testTime ,
} ,
{
2015-01-07 07:36:56 +00:00
test : "missing metric" ,
2015-01-07 07:51:59 +00:00
line : ` 50.554 1419972457825 ` ,
2015-01-07 07:36:56 +00:00
err : ` received "50.554 1419972457825" which doesn't have three fields ` ,
2014-12-30 22:46:33 +00:00
} ,
{
2015-01-07 07:36:56 +00:00
test : "should fail on invalid key" ,
2015-01-07 07:51:59 +00:00
line : ` foo.cpu 50.554 1419972457825 ` ,
2015-01-13 23:00:41 +00:00
err : ` received "foo.cpu" which doesn't conform to format of key.value.key.value.name or name ` ,
2014-12-30 22:46:33 +00:00
} ,
{
2015-01-07 07:36:56 +00:00
test : "should fail parsing invalid float" ,
2015-01-07 07:51:59 +00:00
line : ` cpu 50.554z 1419972457825 ` ,
2015-04-19 14:17:35 +00:00
err : ` field "cpu" value: strconv.ParseFloat: parsing "50.554z": invalid syntax ` ,
2014-12-30 22:46:33 +00:00
} ,
{
2015-01-07 07:36:56 +00:00
test : "should fail parsing invalid int" ,
2015-01-07 07:51:59 +00:00
line : ` cpu 50z 1419972457825 ` ,
2015-04-19 14:17:35 +00:00
err : ` field "cpu" value: strconv.ParseFloat: parsing "50z": invalid syntax ` ,
2014-12-30 22:46:33 +00:00
} ,
{
2015-01-07 07:36:56 +00:00
test : "should fail parsing invalid time" ,
2015-01-07 07:51:59 +00:00
line : ` cpu 50.554 14199724z57825 ` ,
2015-04-19 14:17:35 +00:00
err : ` field "cpu" timestamp: strconv.ParseFloat: parsing "14199724z57825": invalid syntax ` ,
2014-12-30 22:46:33 +00:00
} ,
}
for _ , test := range tests {
t . Logf ( "testing %q..." , test . test )
2015-01-07 07:36:56 +00:00
p := graphite . NewParser ( )
if test . separator != "" {
p . Separator = test . separator
}
p . LastEnabled = ( test . position == "last" )
2015-01-13 23:00:41 +00:00
point , err := p . Parse ( test . line )
2014-12-31 21:37:58 +00:00
if errstr ( err ) != test . err {
t . Fatalf ( "err does not match. expected %v, got %v" , test . err , err )
2014-12-30 22:46:33 +00:00
}
if err != nil {
// If we erred out,it was intended and the following tests won't work
continue
}
2015-01-13 23:00:41 +00:00
if point . Name != test . name {
t . Fatalf ( "name parse failer. expected %v, got %v" , test . name , point . Name )
2014-12-30 22:46:33 +00:00
}
2015-01-13 23:00:41 +00:00
if len ( point . Tags ) != len ( test . tags ) {
t . Fatalf ( "tags len mismatch. expected %d, got %d" , len ( test . tags ) , len ( point . Tags ) )
2014-12-30 22:46:33 +00:00
}
2015-03-14 15:59:33 +00:00
f := point . Fields [ point . Name ] . ( float64 )
if point . Fields [ point . Name ] != f {
t . Fatalf ( "floatValue value mismatch. expected %v, got %v" , test . value , f )
2014-12-30 22:46:33 +00:00
}
2015-01-13 23:00:41 +00:00
if point . Timestamp . UnixNano ( ) / 1000000 != test . timestamp . UnixNano ( ) / 1000000 {
t . Fatalf ( "timestamp value mismatch. expected %v, got %v" , test . timestamp . UnixNano ( ) , point . Timestamp . UnixNano ( ) )
2014-12-30 22:46:33 +00:00
}
}
}
2014-12-31 21:37:58 +00:00
// Test Helpers
func errstr ( err error ) string {
if err != nil {
return err . Error ( )
}
return ""
}