200 lines
4.7 KiB
Go
200 lines
4.7 KiB
Go
|
package graylog
|
||
|
|
||
|
import (
|
||
|
"io/ioutil"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/influxdata/telegraf/testutil"
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
const validJSON = `
|
||
|
{
|
||
|
"total": 3,
|
||
|
"metrics": [
|
||
|
{
|
||
|
"full_name": "jvm.cl.loaded",
|
||
|
"metric": {
|
||
|
"value": 18910
|
||
|
},
|
||
|
"name": "loaded",
|
||
|
"type": "gauge"
|
||
|
},
|
||
|
{
|
||
|
"full_name": "jvm.memory.pools.Metaspace.committed",
|
||
|
"metric": {
|
||
|
"value": 108040192
|
||
|
},
|
||
|
"name": "committed",
|
||
|
"type": "gauge"
|
||
|
},
|
||
|
{
|
||
|
"full_name": "org.graylog2.shared.journal.KafkaJournal.writeTime",
|
||
|
"metric": {
|
||
|
"time": {
|
||
|
"min": 99
|
||
|
},
|
||
|
"rate": {
|
||
|
"total": 10,
|
||
|
"mean": 2
|
||
|
},
|
||
|
"duration_unit": "microseconds",
|
||
|
"rate_unit": "events/second"
|
||
|
},
|
||
|
"name": "writeTime",
|
||
|
"type": "hdrtimer"
|
||
|
}
|
||
|
]
|
||
|
}`
|
||
|
|
||
|
var validTags = map[string]map[string]string{
|
||
|
"jvm.cl.loaded": {
|
||
|
"name": "loaded",
|
||
|
"type": "gauge",
|
||
|
"port": "12900",
|
||
|
"server": "localhost",
|
||
|
},
|
||
|
"jvm.memory.pools.Metaspace.committed": {
|
||
|
"name": "committed",
|
||
|
"type": "gauge",
|
||
|
"port": "12900",
|
||
|
"server": "localhost",
|
||
|
},
|
||
|
"org.graylog2.shared.journal.KafkaJournal.writeTime": {
|
||
|
"name": "writeTime",
|
||
|
"type": "hdrtimer",
|
||
|
"port": "12900",
|
||
|
"server": "localhost",
|
||
|
},
|
||
|
}
|
||
|
|
||
|
var expectedFields = map[string]map[string]interface{}{
|
||
|
"jvm.cl.loaded": {
|
||
|
"value": float64(18910),
|
||
|
},
|
||
|
"jvm.memory.pools.Metaspace.committed": {
|
||
|
"value": float64(108040192),
|
||
|
},
|
||
|
"org.graylog2.shared.journal.KafkaJournal.writeTime": {
|
||
|
"time_min": float64(99),
|
||
|
"rate_total": float64(10),
|
||
|
"rate_mean": float64(2),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
const invalidJSON = "I don't think this is JSON"
|
||
|
|
||
|
const empty = ""
|
||
|
|
||
|
type mockHTTPClient struct {
|
||
|
responseBody string
|
||
|
statusCode int
|
||
|
}
|
||
|
|
||
|
// Mock implementation of MakeRequest. Usually returns an http.Response with
|
||
|
// hard-coded responseBody and statusCode. However, if the request uses a
|
||
|
// nonstandard method, it uses status code 405 (method not allowed)
|
||
|
func (c *mockHTTPClient) MakeRequest(req *http.Request) (*http.Response, error) {
|
||
|
resp := http.Response{}
|
||
|
resp.StatusCode = c.statusCode
|
||
|
|
||
|
// basic error checking on request method
|
||
|
allowedMethods := []string{"GET", "HEAD", "POST", "PUT", "DELETE", "TRACE", "CONNECT"}
|
||
|
methodValid := false
|
||
|
for _, method := range allowedMethods {
|
||
|
if req.Method == method {
|
||
|
methodValid = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if !methodValid {
|
||
|
resp.StatusCode = 405 // Method not allowed
|
||
|
}
|
||
|
|
||
|
resp.Body = ioutil.NopCloser(strings.NewReader(c.responseBody))
|
||
|
return &resp, nil
|
||
|
}
|
||
|
|
||
|
func (c *mockHTTPClient) SetHTTPClient(_ *http.Client) {
|
||
|
}
|
||
|
|
||
|
func (c *mockHTTPClient) HTTPClient() *http.Client {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Generates a pointer to an HttpJson object that uses a mock HTTP client.
|
||
|
// Parameters:
|
||
|
// response : Body of the response that the mock HTTP client should return
|
||
|
// statusCode: HTTP status code the mock HTTP client should return
|
||
|
//
|
||
|
// Returns:
|
||
|
// *HttpJson: Pointer to an HttpJson object that uses the generated mock HTTP client
|
||
|
func genMockGrayLog(response string, statusCode int) []*GrayLog {
|
||
|
return []*GrayLog{
|
||
|
&GrayLog{
|
||
|
client: &mockHTTPClient{responseBody: response, statusCode: statusCode},
|
||
|
Servers: []string{
|
||
|
"http://localhost:12900/system/metrics/multiple",
|
||
|
},
|
||
|
Metrics: []string{
|
||
|
"jvm.memory.pools.Metaspace.committed",
|
||
|
"jvm.cl.loaded",
|
||
|
"org.graylog2.shared.journal.KafkaJournal.writeTime",
|
||
|
},
|
||
|
Username: "test",
|
||
|
Password: "test",
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test that the proper values are ignored or collected
|
||
|
func TestNormalResponse(t *testing.T) {
|
||
|
graylog := genMockGrayLog(validJSON, 200)
|
||
|
|
||
|
for _, service := range graylog {
|
||
|
var acc testutil.Accumulator
|
||
|
err := service.Gather(&acc)
|
||
|
require.NoError(t, err)
|
||
|
for k, v := range expectedFields {
|
||
|
acc.AssertContainsTaggedFields(t, k, v, validTags[k])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test response to HTTP 500
|
||
|
func TestHttpJson500(t *testing.T) {
|
||
|
graylog := genMockGrayLog(validJSON, 500)
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := graylog[0].Gather(&acc)
|
||
|
|
||
|
assert.NotNil(t, err)
|
||
|
assert.Equal(t, 0, acc.NFields())
|
||
|
}
|
||
|
|
||
|
// Test response to malformed JSON
|
||
|
func TestHttpJsonBadJson(t *testing.T) {
|
||
|
graylog := genMockGrayLog(invalidJSON, 200)
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := graylog[0].Gather(&acc)
|
||
|
|
||
|
assert.NotNil(t, err)
|
||
|
assert.Equal(t, 0, acc.NFields())
|
||
|
}
|
||
|
|
||
|
// Test response to empty string as response objectgT
|
||
|
func TestHttpJsonEmptyResponse(t *testing.T) {
|
||
|
graylog := genMockGrayLog(empty, 200)
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := graylog[0].Gather(&acc)
|
||
|
|
||
|
assert.NotNil(t, err)
|
||
|
assert.Equal(t, 0, acc.NFields())
|
||
|
}
|