0.3.0 unit tests: exec, httpjson, and haproxy

This commit is contained in:
Cameron Sparr 2016-01-06 16:11:16 -07:00
parent c4a7711e02
commit 524fddedb4
8 changed files with 221 additions and 377 deletions

View File

@ -51,7 +51,7 @@ func (f *JSONFlattener) FlattenJSON(
} }
case float64: case float64:
f.Fields[fieldname] = t f.Fields[fieldname] = t
case bool, string, []interface{}: case bool, string, []interface{}, nil:
// ignored types // ignored types
return nil return nil
default: default:

View File

@ -1,10 +1,12 @@
package aerospike package aerospike
import ( import (
"reflect"
"testing"
"github.com/influxdb/telegraf/testutil" "github.com/influxdb/telegraf/testutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"testing"
) )
func TestAerospikeStatistics(t *testing.T) { func TestAerospikeStatistics(t *testing.T) {
@ -60,55 +62,57 @@ func TestReadAerospikeStatsNoNamespace(t *testing.T) {
acc.AssertContainsTaggedFields(t, "aerospike", fields, tags) acc.AssertContainsTaggedFields(t, "aerospike", fields, tags)
} }
// func TestReadAerospikeStatsNamespace(t *testing.T) { func TestReadAerospikeStatsNamespace(t *testing.T) {
// var acc testutil.Accumulator var acc testutil.Accumulator
// stats := map[string]string{ stats := map[string]string{
// "stat_write_errs": "12345", "stat_write_errs": "12345",
// "stat_read_reqs": "12345", "stat_read_reqs": "12345",
// } }
// readAerospikeStats(stats, &acc, "host1", "test") readAerospikeStats(stats, &acc, "host1", "test")
// tags := map[string]string{ fields := map[string]interface{}{
// "aerospike_host": "host1", "stat_write_errs": int64(12345),
// "namespace": "test", "stat_read_reqs": int64(12345),
// } }
// for k := range stats { tags := map[string]string{
// assert.True(t, acc.ValidateTaggedValue(k, int64(12345), tags) == nil) "aerospike_host": "host1",
// } "namespace": "test",
// } }
acc.AssertContainsTaggedFields(t, "aerospike", fields, tags)
}
// func TestAerospikeUnmarshalList(t *testing.T) { func TestAerospikeUnmarshalList(t *testing.T) {
// i := map[string]string{ i := map[string]string{
// "test": "one;two;three", "test": "one;two;three",
// } }
// expected := []string{"one", "two", "three"} expected := []string{"one", "two", "three"}
// list, err := unmarshalListInfo(i, "test2") list, err := unmarshalListInfo(i, "test2")
// assert.True(t, err != nil) assert.True(t, err != nil)
// list, err = unmarshalListInfo(i, "test") list, err = unmarshalListInfo(i, "test")
// assert.True(t, err == nil) assert.True(t, err == nil)
// equal := true equal := true
// for ix := range expected { for ix := range expected {
// if list[ix] != expected[ix] { if list[ix] != expected[ix] {
// equal = false equal = false
// break break
// } }
// } }
// assert.True(t, equal) assert.True(t, equal)
// } }
// func TestAerospikeUnmarshalMap(t *testing.T) { func TestAerospikeUnmarshalMap(t *testing.T) {
// i := map[string]string{ i := map[string]string{
// "test": "key1=value1;key2=value2", "test": "key1=value1;key2=value2",
// } }
// expected := map[string]string{ expected := map[string]string{
// "key1": "value1", "key1": "value1",
// "key2": "value2", "key2": "value2",
// } }
// m, err := unmarshalMapInfo(i, "test") m, err := unmarshalMapInfo(i, "test")
// assert.True(t, err == nil) assert.True(t, err == nil)
// assert.True(t, reflect.DeepEqual(m, expected)) assert.True(t, reflect.DeepEqual(m, expected))
// } }

View File

@ -2,12 +2,11 @@ package exec
import ( import (
"fmt" "fmt"
"testing"
"github.com/influxdb/telegraf/testutil" "github.com/influxdb/telegraf/testutil"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"math"
"testing"
"time"
) )
// Midnight 9/22/2015 // Midnight 9/22/2015
@ -37,10 +36,6 @@ type runnerMock struct {
err error err error
} }
type clockMock struct {
now time.Time
}
func newRunnerMock(out []byte, err error) Runner { func newRunnerMock(out []byte, err error) Runner {
return &runnerMock{ return &runnerMock{
out: out, out: out,
@ -48,215 +43,56 @@ func newRunnerMock(out []byte, err error) Runner {
} }
} }
func (r runnerMock) Run(command *Command) ([]byte, error) { func (r runnerMock) Run(e *Exec) ([]byte, error) {
if r.err != nil { if r.err != nil {
return nil, r.err return nil, r.err
} }
return r.out, nil return r.out, nil
} }
func newClockMock(now time.Time) Clock {
return &clockMock{now: now}
}
func (c clockMock) Now() time.Time {
return c.now
}
func TestExec(t *testing.T) { func TestExec(t *testing.T) {
runner := newRunnerMock([]byte(validJson), nil)
clock := newClockMock(time.Unix(baseTimeSeconds+20, 0))
command := Command{
Command: "testcommand arg1",
Name: "mycollector",
Interval: 10,
lastRunAt: time.Unix(baseTimeSeconds, 0),
}
e := &Exec{ e := &Exec{
runner: runner, runner: newRunnerMock([]byte(validJson), nil),
clock: clock, Command: "testcommand arg1",
Commands: []*Command{&command}, Name: "mycollector",
} }
var acc testutil.Accumulator var acc testutil.Accumulator
initialPoints := len(acc.Points)
err := e.Gather(&acc) err := e.Gather(&acc)
deltaPoints := len(acc.Points) - initialPoints
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, acc.NFields(), 4, "non-numeric measurements should be ignored")
checkFloat := []struct { fields := map[string]interface{}{
name string "num_processes": float64(82),
value float64 "cpu_used": float64(8234),
}{ "cpu_free": float64(32),
{"mycollector_num_processes", 82}, "percent": float64(0.81),
{"mycollector_cpu_used", 8234},
{"mycollector_cpu_free", 32},
{"mycollector_percent", 0.81},
} }
acc.AssertContainsFields(t, "exec_mycollector", fields)
for _, c := range checkFloat {
assert.True(t, acc.CheckValue(c.name, c.value))
}
assert.Equal(t, deltaPoints, 4, "non-numeric measurements should be ignored")
} }
func TestExecMalformed(t *testing.T) { func TestExecMalformed(t *testing.T) {
runner := newRunnerMock([]byte(malformedJson), nil)
clock := newClockMock(time.Unix(baseTimeSeconds+20, 0))
command := Command{
Command: "badcommand arg1",
Name: "mycollector",
Interval: 10,
lastRunAt: time.Unix(baseTimeSeconds, 0),
}
e := &Exec{ e := &Exec{
runner: runner, runner: newRunnerMock([]byte(malformedJson), nil),
clock: clock, Command: "badcommand arg1",
Commands: []*Command{&command}, Name: "mycollector",
} }
var acc testutil.Accumulator var acc testutil.Accumulator
initialPoints := len(acc.Points)
err := e.Gather(&acc) err := e.Gather(&acc)
deltaPoints := len(acc.Points) - initialPoints
require.Error(t, err) require.Error(t, err)
assert.Equal(t, acc.NFields(), 0, "No new points should have been added")
assert.Equal(t, deltaPoints, 0, "No new points should have been added")
} }
func TestCommandError(t *testing.T) { func TestCommandError(t *testing.T) {
runner := newRunnerMock(nil, fmt.Errorf("exit status code 1"))
clock := newClockMock(time.Unix(baseTimeSeconds+20, 0))
command := Command{
Command: "badcommand",
Name: "mycollector",
Interval: 10,
lastRunAt: time.Unix(baseTimeSeconds, 0),
}
e := &Exec{ e := &Exec{
runner: runner, runner: newRunnerMock(nil, fmt.Errorf("exit status code 1")),
clock: clock, Command: "badcommand",
Commands: []*Command{&command}, Name: "mycollector",
} }
var acc testutil.Accumulator var acc testutil.Accumulator
initialPoints := len(acc.Points)
err := e.Gather(&acc) err := e.Gather(&acc)
deltaPoints := len(acc.Points) - initialPoints
require.Error(t, err) require.Error(t, err)
assert.Equal(t, acc.NFields(), 0, "No new points should have been added")
assert.Equal(t, deltaPoints, 0, "No new points should have been added")
}
func TestExecNotEnoughTime(t *testing.T) {
runner := newRunnerMock([]byte(validJson), nil)
clock := newClockMock(time.Unix(baseTimeSeconds+5, 0))
command := Command{
Command: "testcommand arg1",
Name: "mycollector",
Interval: 10,
lastRunAt: time.Unix(baseTimeSeconds, 0),
}
e := &Exec{
runner: runner,
clock: clock,
Commands: []*Command{&command},
}
var acc testutil.Accumulator
initialPoints := len(acc.Points)
err := e.Gather(&acc)
deltaPoints := len(acc.Points) - initialPoints
require.NoError(t, err)
assert.Equal(t, deltaPoints, 0, "No new points should have been added")
}
func TestExecUninitializedLastRunAt(t *testing.T) {
runner := newRunnerMock([]byte(validJson), nil)
clock := newClockMock(time.Unix(baseTimeSeconds, 0))
command := Command{
Command: "testcommand arg1",
Name: "mycollector",
Interval: math.MaxInt32,
// Uninitialized lastRunAt should default to time.Unix(0, 0), so this should
// run no matter what the interval is
}
e := &Exec{
runner: runner,
clock: clock,
Commands: []*Command{&command},
}
var acc testutil.Accumulator
initialPoints := len(acc.Points)
err := e.Gather(&acc)
deltaPoints := len(acc.Points) - initialPoints
require.NoError(t, err)
checkFloat := []struct {
name string
value float64
}{
{"mycollector_num_processes", 82},
{"mycollector_cpu_used", 8234},
{"mycollector_cpu_free", 32},
{"mycollector_percent", 0.81},
}
for _, c := range checkFloat {
assert.True(t, acc.CheckValue(c.name, c.value))
}
assert.Equal(t, deltaPoints, 4, "non-numeric measurements should be ignored")
}
func TestExecOneNotEnoughTimeAndOneEnoughTime(t *testing.T) {
runner := newRunnerMock([]byte(validJson), nil)
clock := newClockMock(time.Unix(baseTimeSeconds+5, 0))
notEnoughTimeCommand := Command{
Command: "testcommand arg1",
Name: "mycollector",
Interval: 10,
lastRunAt: time.Unix(baseTimeSeconds, 0),
}
enoughTimeCommand := Command{
Command: "testcommand arg1",
Name: "mycollector",
Interval: 3,
lastRunAt: time.Unix(baseTimeSeconds, 0),
}
e := &Exec{
runner: runner,
clock: clock,
Commands: []*Command{&notEnoughTimeCommand, &enoughTimeCommand},
}
var acc testutil.Accumulator
initialPoints := len(acc.Points)
err := e.Gather(&acc)
deltaPoints := len(acc.Points) - initialPoints
require.NoError(t, err)
checkFloat := []struct {
name string
value float64
}{
{"mycollector_num_processes", 82},
{"mycollector_cpu_used", 8234},
{"mycollector_cpu_free", 32},
{"mycollector_percent", 0.81},
}
for _, c := range checkFloat {
assert.True(t, acc.CheckValue(c.name, c.value))
}
assert.Equal(t, deltaPoints, 4, "Only one command should have been run")
} }

View File

@ -91,7 +91,7 @@ var sampleConfig = `
# If no servers are specified, then default to 127.0.0.1:1936 # If no servers are specified, then default to 127.0.0.1:1936
servers = ["http://myhaproxy.com:1936", "http://anotherhaproxy.com:1936"] servers = ["http://myhaproxy.com:1936", "http://anotherhaproxy.com:1936"]
# Or you can also use local socket(not work yet) # Or you can also use local socket(not work yet)
# servers = ["socket:/run/haproxy/admin.sock"] # servers = ["socket://run/haproxy/admin.sock"]
` `
func (r *haproxy) SampleConfig() string { func (r *haproxy) SampleConfig() string {

View File

@ -47,52 +47,39 @@ func TestHaproxyGeneratesMetricsWithAuthentication(t *testing.T) {
"sv": "host0", "sv": "host0",
} }
assert.NoError(t, acc.ValidateTaggedValue("stot", uint64(171014), tags)) fields := map[string]interface{}{
"active_servers": uint64(1),
checkInt := []struct { "backup_servers": uint64(0),
name string "bin": uint64(510913516),
value uint64 "bout": uint64(2193856571),
}{ "check_duration": uint64(10),
"cli_abort": uint64(73),
{"qmax", 81}, "ctime": uint64(2),
{"scur", 288}, "downtime": uint64(0),
{"smax", 713}, "dresp": uint64(0),
{"bin", 5557055817}, "econ": uint64(0),
{"bout", 24096715169}, "eresp": uint64(1),
{"dreq", 1102}, "http_response.1xx": uint64(0),
{"dresp", 80}, "http_response.2xx": uint64(119534),
{"ereq", 95740}, "http_response.3xx": uint64(48051),
{"econ", 0}, "http_response.4xx": uint64(2345),
{"eresp", 0}, "http_response.5xx": uint64(1056),
{"wretr", 17}, "lbtot": uint64(171013),
{"wredis", 19}, "qcur": uint64(0),
{"active_servers", 1}, "qmax": uint64(0),
{"backup_servers", 0}, "qtime": uint64(0),
{"downtime", 0}, "rate": uint64(3),
{"throttle", 13}, "rate_max": uint64(12),
{"lbtot", 114}, "rtime": uint64(312),
{"rate", 18}, "scur": uint64(1),
{"rate_max", 102}, "smax": uint64(32),
{"check_duration", 1}, "srv_abort": uint64(1),
{"http_response.1xx", 0}, "stot": uint64(171014),
{"http_response.2xx", 1314093}, "ttime": uint64(2341),
{"http_response.3xx", 537036}, "wredis": uint64(0),
{"http_response.4xx", 123452}, "wretr": uint64(1),
{"http_response.5xx", 11966},
{"req_rate", 35},
{"req_rate_max", 140},
{"req_tot", 1987928},
{"cli_abort", 0},
{"srv_abort", 0},
{"qtime", 0},
{"ctime", 2},
{"rtime", 23},
{"ttime", 545},
}
for _, c := range checkInt {
assert.Equal(t, true, acc.CheckValue(c.name, c.value))
} }
acc.AssertContainsTaggedFields(t, "haproxy", fields, tags)
//Here, we should get error because we don't pass authentication data //Here, we should get error because we don't pass authentication data
r = &haproxy{ r = &haproxy{
@ -124,10 +111,39 @@ func TestHaproxyGeneratesMetricsWithoutAuthentication(t *testing.T) {
"sv": "host0", "sv": "host0",
} }
assert.NoError(t, acc.ValidateTaggedValue("stot", uint64(171014), tags)) fields := map[string]interface{}{
assert.NoError(t, acc.ValidateTaggedValue("scur", uint64(1), tags)) "active_servers": uint64(1),
assert.NoError(t, acc.ValidateTaggedValue("rate", uint64(3), tags)) "backup_servers": uint64(0),
assert.Equal(t, true, acc.CheckValue("bin", uint64(5557055817))) "bin": uint64(510913516),
"bout": uint64(2193856571),
"check_duration": uint64(10),
"cli_abort": uint64(73),
"ctime": uint64(2),
"downtime": uint64(0),
"dresp": uint64(0),
"econ": uint64(0),
"eresp": uint64(1),
"http_response.1xx": uint64(0),
"http_response.2xx": uint64(119534),
"http_response.3xx": uint64(48051),
"http_response.4xx": uint64(2345),
"http_response.5xx": uint64(1056),
"lbtot": uint64(171013),
"qcur": uint64(0),
"qmax": uint64(0),
"qtime": uint64(0),
"rate": uint64(3),
"rate_max": uint64(12),
"rtime": uint64(312),
"scur": uint64(1),
"smax": uint64(32),
"srv_abort": uint64(1),
"stot": uint64(171014),
"ttime": uint64(2341),
"wredis": uint64(0),
"wretr": uint64(1),
}
acc.AssertContainsTaggedFields(t, "haproxy", fields, tags)
} }
//When not passing server config, we default to localhost //When not passing server config, we default to localhost

View File

@ -153,7 +153,7 @@ func (h *HttpJson) gatherServer(
} else { } else {
msrmnt_name = "httpjson_" + h.Name msrmnt_name = "httpjson_" + h.Name
} }
acc.AddFields(msrmnt_name, f.Fields, nil) acc.AddFields(msrmnt_name, f.Fields, tags)
return nil return nil
} }

View File

@ -1,7 +1,6 @@
package httpjson package httpjson
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strings" "strings"
@ -35,6 +34,11 @@ const validJSONTags = `
"build": "123" "build": "123"
}` }`
var expectedFields = map[string]interface{}{
"parent_child": float64(3),
"integer": float64(4),
}
const invalidJSON = "I don't think this is JSON" const invalidJSON = "I don't think this is JSON"
const empty = "" const empty = ""
@ -76,37 +80,36 @@ func (c mockHTTPClient) MakeRequest(req *http.Request) (*http.Response, error) {
// //
// Returns: // Returns:
// *HttpJson: Pointer to an HttpJson object that uses the generated mock HTTP client // *HttpJson: Pointer to an HttpJson object that uses the generated mock HTTP client
func genMockHttpJson(response string, statusCode int) *HttpJson { func genMockHttpJson(response string, statusCode int) []*HttpJson {
return &HttpJson{ return []*HttpJson{
client: mockHTTPClient{responseBody: response, statusCode: statusCode}, &HttpJson{
Services: []Service{ client: mockHTTPClient{responseBody: response, statusCode: statusCode},
Service{ Servers: []string{
Servers: []string{ "http://server1.example.com/metrics/",
"http://server1.example.com/metrics/", "http://server2.example.com/metrics/",
"http://server2.example.com/metrics/",
},
Name: "my_webapp",
Method: "GET",
Parameters: map[string]string{
"httpParam1": "12",
"httpParam2": "the second parameter",
},
}, },
Service{ Name: "my_webapp",
Servers: []string{ Method: "GET",
"http://server3.example.com/metrics/", Parameters: map[string]string{
"http://server4.example.com/metrics/", "httpParam1": "12",
}, "httpParam2": "the second parameter",
Name: "other_webapp", },
Method: "POST", },
Parameters: map[string]string{ &HttpJson{
"httpParam1": "12", client: mockHTTPClient{responseBody: response, statusCode: statusCode},
"httpParam2": "the second parameter", Servers: []string{
}, "http://server3.example.com/metrics/",
TagKeys: []string{ "http://server4.example.com/metrics/",
"role", },
"build", Name: "other_webapp",
}, Method: "POST",
Parameters: map[string]string{
"httpParam1": "12",
"httpParam2": "the second parameter",
},
TagKeys: []string{
"role",
"build",
}, },
}, },
} }
@ -116,28 +119,15 @@ func genMockHttpJson(response string, statusCode int) *HttpJson {
func TestHttpJson200(t *testing.T) { func TestHttpJson200(t *testing.T) {
httpjson := genMockHttpJson(validJSON, 200) httpjson := genMockHttpJson(validJSON, 200)
var acc testutil.Accumulator for _, service := range httpjson {
err := httpjson.Gather(&acc) var acc testutil.Accumulator
require.NoError(t, err) err := service.Gather(&acc)
require.NoError(t, err)
assert.Equal(t, 8, len(acc.Points)) assert.Equal(t, 4, acc.NFields())
for _, service := range httpjson.Services {
for _, srv := range service.Servers { for _, srv := range service.Servers {
require.NoError(t, tags := map[string]string{"server": srv}
acc.ValidateTaggedValue( mname := "httpjson_" + service.Name
fmt.Sprintf("%s_parent_child", service.Name), acc.AssertContainsTaggedFields(t, mname, expectedFields, tags)
3.0,
map[string]string{"server": srv},
),
)
require.NoError(t,
acc.ValidateTaggedValue(
fmt.Sprintf("%s_integer", service.Name),
4.0,
map[string]string{"server": srv},
),
)
} }
} }
} }
@ -147,28 +137,22 @@ func TestHttpJson500(t *testing.T) {
httpjson := genMockHttpJson(validJSON, 500) httpjson := genMockHttpJson(validJSON, 500)
var acc testutil.Accumulator var acc testutil.Accumulator
err := httpjson.Gather(&acc) err := httpjson[0].Gather(&acc)
assert.NotNil(t, err) assert.NotNil(t, err)
// 4 error lines for (2 urls) * (2 services) assert.Equal(t, 0, acc.NFields())
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
assert.Equal(t, 0, len(acc.Points))
} }
// Test response to HTTP 405 // Test response to HTTP 405
func TestHttpJsonBadMethod(t *testing.T) { func TestHttpJsonBadMethod(t *testing.T) {
httpjson := genMockHttpJson(validJSON, 200) httpjson := genMockHttpJson(validJSON, 200)
httpjson.Services[0].Method = "NOT_A_REAL_METHOD" httpjson[0].Method = "NOT_A_REAL_METHOD"
var acc testutil.Accumulator var acc testutil.Accumulator
err := httpjson.Gather(&acc) err := httpjson[0].Gather(&acc)
assert.NotNil(t, err) assert.NotNil(t, err)
// 2 error lines for (2 urls) * (1 falied service) assert.Equal(t, 0, acc.NFields())
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 2)
// (2 measurements) * (2 servers) * (1 successful service)
assert.Equal(t, 4, len(acc.Points))
} }
// Test response to malformed JSON // Test response to malformed JSON
@ -176,12 +160,10 @@ func TestHttpJsonBadJson(t *testing.T) {
httpjson := genMockHttpJson(invalidJSON, 200) httpjson := genMockHttpJson(invalidJSON, 200)
var acc testutil.Accumulator var acc testutil.Accumulator
err := httpjson.Gather(&acc) err := httpjson[0].Gather(&acc)
assert.NotNil(t, err) assert.NotNil(t, err)
// 4 error lines for (2 urls) * (2 services) assert.Equal(t, 0, acc.NFields())
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
assert.Equal(t, 0, len(acc.Points))
} }
// Test response to empty string as response objectgT // Test response to empty string as response objectgT
@ -189,34 +171,27 @@ func TestHttpJsonEmptyResponse(t *testing.T) {
httpjson := genMockHttpJson(empty, 200) httpjson := genMockHttpJson(empty, 200)
var acc testutil.Accumulator var acc testutil.Accumulator
err := httpjson.Gather(&acc) err := httpjson[0].Gather(&acc)
assert.NotNil(t, err) assert.NotNil(t, err)
// 4 error lines for (2 urls) * (2 services) assert.Equal(t, 0, acc.NFields())
assert.Equal(t, len(strings.Split(err.Error(), "\n")), 4)
assert.Equal(t, 0, len(acc.Points))
} }
// Test that the proper values are ignored or collected // Test that the proper values are ignored or collected
func TestHttpJson200Tags(t *testing.T) { func TestHttpJson200Tags(t *testing.T) {
httpjson := genMockHttpJson(validJSONTags, 200) httpjson := genMockHttpJson(validJSONTags, 200)
var acc testutil.Accumulator for _, service := range httpjson {
err := httpjson.Gather(&acc)
require.NoError(t, err)
assert.Equal(t, 4, len(acc.Points))
for _, service := range httpjson.Services {
if service.Name == "other_webapp" { if service.Name == "other_webapp" {
var acc testutil.Accumulator
err := service.Gather(&acc)
require.NoError(t, err)
assert.Equal(t, 2, acc.NFields())
for _, srv := range service.Servers { for _, srv := range service.Servers {
require.NoError(t, tags := map[string]string{"server": srv, "role": "master", "build": "123"}
acc.ValidateTaggedValue( fields := map[string]interface{}{"value": float64(15)}
fmt.Sprintf("%s_value", service.Name), mname := "httpjson_" + service.Name
15.0, acc.AssertContainsTaggedFields(t, mname, fields, tags)
map[string]string{"server": srv, "role": "master", "build": "123"},
),
)
} }
} }
} }

View File

@ -1,6 +1,7 @@
package testutil package testutil
import ( import (
"encoding/json"
"fmt" "fmt"
"reflect" "reflect"
"sync" "sync"
@ -25,7 +26,9 @@ func (p *Point) String() string {
// Accumulator defines a mocked out accumulator // Accumulator defines a mocked out accumulator
type Accumulator struct { type Accumulator struct {
sync.Mutex sync.Mutex
Points []*Point Points []*Point
debug bool
} }
// Add adds a measurement point to the accumulator // Add adds a measurement point to the accumulator
@ -59,6 +62,14 @@ func (a *Accumulator) AddFields(
t = time.Now() t = time.Now()
} }
if a.debug {
pretty, _ := json.MarshalIndent(fields, "", " ")
prettyTags, _ := json.MarshalIndent(tags, "", " ")
msg := fmt.Sprintf("Adding Measurement [%s]\nFields:%s\nTags:%s\n",
measurement, string(pretty), string(prettyTags))
fmt.Print(msg)
}
p := &Point{ p := &Point{
Measurement: measurement, Measurement: measurement,
Fields: fields, Fields: fields,
@ -66,10 +77,7 @@ func (a *Accumulator) AddFields(
Time: t, Time: t,
} }
a.Points = append( a.Points = append(a.Points, p)
a.Points,
p,
)
} }
func (a *Accumulator) SetDefaultTags(tags map[string]string) { func (a *Accumulator) SetDefaultTags(tags map[string]string) {
@ -91,11 +99,12 @@ func (a *Accumulator) SetPrefix(prefix string) {
func (a *Accumulator) Debug() bool { func (a *Accumulator) Debug() bool {
// stub for implementing Accumulator interface. // stub for implementing Accumulator interface.
return true return a.debug
} }
func (a *Accumulator) SetDebug(debug bool) { func (a *Accumulator) SetDebug(debug bool) {
// stub for implementing Accumulator interface. // stub for implementing Accumulator interface.
a.debug = debug
} }
// Get gets the specified measurement point from the accumulator // Get gets the specified measurement point from the accumulator
@ -134,8 +143,10 @@ func (a *Accumulator) AssertContainsTaggedFields(
if p.Measurement == measurement { if p.Measurement == measurement {
if !reflect.DeepEqual(fields, p.Fields) { if !reflect.DeepEqual(fields, p.Fields) {
msg := fmt.Sprintf("Actual:\n %v (%T) \nExpected:\n %v (%T)", pActual, _ := json.MarshalIndent(p.Fields, "", " ")
p.Fields, p.Fields, fields, fields) pExp, _ := json.MarshalIndent(fields, "", " ")
msg := fmt.Sprintf("Actual:\n%s\n(%T) \nExpected:\n%s\n(%T)",
string(pActual), p.Fields, string(pExp), fields)
assert.Fail(t, msg) assert.Fail(t, msg)
} }
return return
@ -153,8 +164,10 @@ func (a *Accumulator) AssertContainsFields(
for _, p := range a.Points { for _, p := range a.Points {
if p.Measurement == measurement { if p.Measurement == measurement {
if !reflect.DeepEqual(fields, p.Fields) { if !reflect.DeepEqual(fields, p.Fields) {
msg := fmt.Sprintf("Actual:\n %v (%T) \nExpected:\n %v (%T)", pActual, _ := json.MarshalIndent(p.Fields, "", " ")
p.Fields, p.Fields, fields, fields) pExp, _ := json.MarshalIndent(fields, "", " ")
msg := fmt.Sprintf("Actual:\n%s\n(%T) \nExpected:\n%s\n(%T)",
string(pActual), p.Fields, string(pExp), fields)
assert.Fail(t, msg) assert.Fail(t, msg)
} }
return return