220 lines
6.4 KiB
Go
220 lines
6.4 KiB
Go
|
package kubernetes
|
||
|
|
||
|
import (
|
||
|
"io/ioutil"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/influxdata/telegraf/testutil"
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
const validData = `# HELP cadvisor_version_info A metric with a constant '1' value labeled by kernel version, OS version, docker version, cadvisor version & cadvisor revision.
|
||
|
# TYPE cadvisor_version_info gauge
|
||
|
cadvisor_version_info{cadvisorRevision="",cadvisorVersion="",dockerVersion="1.8.2",kernelVersion="3.10.0-229.20.1.el7.x86_64",osVersion="CentOS Linux 7 (Core)"} 1
|
||
|
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
|
||
|
# TYPE go_gc_duration_seconds summary
|
||
|
go_gc_duration_seconds{quantile="0"} 0.013534896000000001
|
||
|
go_gc_duration_seconds{quantile="0.25"} 0.02469263
|
||
|
go_gc_duration_seconds{quantile="0.5"} 0.033727822000000005
|
||
|
go_gc_duration_seconds{quantile="0.75"} 0.03840335
|
||
|
go_gc_duration_seconds{quantile="1"} 0.049956604
|
||
|
go_gc_duration_seconds_sum 1970.341293002
|
||
|
go_gc_duration_seconds_count 65952
|
||
|
# HELP http_request_duration_microseconds The HTTP request latencies in microseconds.
|
||
|
# TYPE http_request_duration_microseconds summary
|
||
|
http_request_duration_microseconds{handler="prometheus",quantile="0.5"} 552048.506
|
||
|
http_request_duration_microseconds{handler="prometheus",quantile="0.9"} 5.876804288e+06
|
||
|
http_request_duration_microseconds{handler="prometheus",quantile="0.99"} 5.876804288e+06
|
||
|
http_request_duration_microseconds_sum{handler="prometheus"} 1.8909097205e+07
|
||
|
http_request_duration_microseconds_count{handler="prometheus"} 9
|
||
|
# HELP get_token_fail_count Counter of failed Token() requests to the alternate token source
|
||
|
# TYPE get_token_fail_count counter
|
||
|
get_token_fail_count 0
|
||
|
`
|
||
|
|
||
|
const invalidData = "I don't think this is valid data"
|
||
|
|
||
|
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, timeout float64) (*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
|
||
|
}
|
||
|
|
||
|
// Generates a pointer to an Kubernetes 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:
|
||
|
// *Kubernetes: Pointer to an Kubernetes object that uses the generated mock HTTP client
|
||
|
func genMockKubernetes(response string, statusCode int) Kubernetes {
|
||
|
return Kubernetes{
|
||
|
client: mockHTTPClient{responseBody: response, statusCode: statusCode},
|
||
|
Apiserver: []Apiserver{
|
||
|
Apiserver{
|
||
|
KubeService{
|
||
|
Url: "http://127.0.0.1:8080",
|
||
|
Endpoint: "/metrics",
|
||
|
Timeout: 1.0,
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Scheduler: []Scheduler{
|
||
|
Scheduler{
|
||
|
KubeService{
|
||
|
Url: "http://127.0.0.1:10251",
|
||
|
Excludes: []string{"http_request_duration_.*"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Controllermanager: []Controllermanager{
|
||
|
Controllermanager{
|
||
|
KubeService{
|
||
|
Url: "http://127.0.0.1:10252",
|
||
|
Endpoint: "metrics",
|
||
|
Includes: []string{"http_request_duration_microseconds"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
Kubelet: []Kubelet{
|
||
|
Kubelet{
|
||
|
KubeService{
|
||
|
Url: "http://127.0.0.1:4194",
|
||
|
Endpoint: "metrics",
|
||
|
Includes: []string{"http_request_duration_microseconds"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Generates a pointer to an Kubernetes 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:
|
||
|
// *Kubernetes: Pointer to an Kubernetes object that uses the generated mock HTTP client
|
||
|
func genMockKubernetes2(response string, statusCode int) Kubernetes {
|
||
|
return Kubernetes{
|
||
|
client: mockHTTPClient{responseBody: response, statusCode: statusCode},
|
||
|
Apiserver: []Apiserver{
|
||
|
Apiserver{
|
||
|
KubeService{
|
||
|
Url: "http://127.0.0.1:8080",
|
||
|
Endpoint: "/metrics",
|
||
|
Timeout: 1.0,
|
||
|
Includes: []string{"http_request_duration_microseconds"},
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Test that the proper values are ignored or collected
|
||
|
func TestOK(t *testing.T) {
|
||
|
kubernetes := genMockKubernetes(validData, 200)
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := kubernetes.Gather(&acc)
|
||
|
require.NoError(t, err)
|
||
|
assert.Equal(t, 33, acc.NFields())
|
||
|
|
||
|
}
|
||
|
|
||
|
// Test that the proper values are ignored or collected
|
||
|
func TestOK2(t *testing.T) {
|
||
|
kubernetes := genMockKubernetes2(validData, 200)
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := kubernetes.Gather(&acc)
|
||
|
require.NoError(t, err)
|
||
|
assert.Equal(t, 5, acc.NFields())
|
||
|
|
||
|
tags := map[string]string{
|
||
|
"kubeservice": "apiserver",
|
||
|
"serverURL": "http://127.0.0.1:8080/metrics",
|
||
|
"handler": "prometheus",
|
||
|
}
|
||
|
mname := "http_request_duration_microseconds"
|
||
|
expectedFields := map[string]interface{}{
|
||
|
"0.5": 552048.506,
|
||
|
"0.9": 5.876804288e+06,
|
||
|
"0.99": 5.876804288e+06,
|
||
|
"count": 0.0,
|
||
|
"sum": 1.8909097205e+07}
|
||
|
acc.AssertContainsTaggedFields(t, mname, expectedFields, tags)
|
||
|
|
||
|
}
|
||
|
|
||
|
// Test response to HTTP 500
|
||
|
func TestKubernetes500(t *testing.T) {
|
||
|
kubernetes := genMockKubernetes(validData, 500)
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := kubernetes.Gather(&acc)
|
||
|
|
||
|
assert.NotNil(t, err)
|
||
|
assert.Equal(t, 0, acc.NFields())
|
||
|
}
|
||
|
|
||
|
// Test response to malformed Data
|
||
|
func TestKubernetesBadData(t *testing.T) {
|
||
|
kubernetes := genMockKubernetes(invalidData, 200)
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := kubernetes.Gather(&acc)
|
||
|
|
||
|
assert.NotNil(t, err)
|
||
|
assert.Equal(t, 0, acc.NFields())
|
||
|
}
|
||
|
|
||
|
// Test response to empty string as response objectgT
|
||
|
func TestKubernetesEmptyResponse(t *testing.T) {
|
||
|
kubernetes := Kubernetes{client: RealHTTPClient{client: &http.Client{}}}
|
||
|
kubernetes.Apiserver = []Apiserver{
|
||
|
Apiserver{
|
||
|
KubeService{
|
||
|
Url: "http://127.0.0.1:59999",
|
||
|
Endpoint: "/metrics",
|
||
|
Timeout: 1.0,
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
|
||
|
var acc testutil.Accumulator
|
||
|
err := kubernetes.Gather(&acc)
|
||
|
|
||
|
require.NotNil(t, err)
|
||
|
assert.Equal(t, 0, acc.NFields())
|
||
|
}
|