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()) }