2016-04-01 23:13:21 +00:00
|
|
|
package cassandra
|
|
|
|
|
|
|
|
import (
|
|
|
|
_ "fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/influxdata/telegraf/testutil"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
_ "github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
const validJavaMultiValueJSON = `
|
|
|
|
{
|
|
|
|
"request":{
|
|
|
|
"mbean":"java.lang:type=Memory",
|
|
|
|
"attribute":"HeapMemoryUsage",
|
|
|
|
"type":"read"
|
|
|
|
},
|
|
|
|
"value":{
|
|
|
|
"init":67108864,
|
|
|
|
"committed":456130560,
|
|
|
|
"max":477626368,
|
|
|
|
"used":203288528
|
|
|
|
},
|
|
|
|
"timestamp":1446129191,
|
|
|
|
"status":200
|
|
|
|
}`
|
|
|
|
|
|
|
|
const validCassandraMultiValueJSON = `
|
|
|
|
{
|
|
|
|
"request": {
|
|
|
|
"mbean": "org.apache.cassandra.metrics:keyspace=test_keyspace1,name=ReadLatency,scope=test_table,type=Table",
|
|
|
|
"type": "read"},
|
|
|
|
"status": 200,
|
|
|
|
"timestamp": 1458089229,
|
|
|
|
"value": {
|
|
|
|
"999thPercentile": 20.0,
|
|
|
|
"99thPercentile": 10.0,
|
|
|
|
"Count": 400,
|
|
|
|
"DurationUnit": "microseconds",
|
|
|
|
"Max": 30.0,
|
|
|
|
"Mean": null,
|
|
|
|
"MeanRate": 3.0,
|
|
|
|
"Min": 1.0,
|
|
|
|
"RateUnit": "events/second",
|
|
|
|
"StdDev": null
|
|
|
|
}
|
|
|
|
}`
|
|
|
|
|
|
|
|
const validCassandraNestedMultiValueJSON = `
|
|
|
|
{
|
|
|
|
"request": {
|
|
|
|
"mbean": "org.apache.cassandra.metrics:keyspace=test_keyspace1,name=ReadLatency,scope=*,type=Table",
|
|
|
|
"type": "read"},
|
|
|
|
"status": 200,
|
|
|
|
"timestamp": 1458089184,
|
|
|
|
"value": {
|
2016-04-19 00:12:58 +00:00
|
|
|
"org.apache.cassandra.metrics:keyspace=test_keyspace1,name=ReadLatency,scope=test_table1,type=Table":
|
2016-04-01 23:13:21 +00:00
|
|
|
{ "999thPercentile": 1.0,
|
|
|
|
"Count": 100,
|
|
|
|
"DurationUnit": "microseconds",
|
|
|
|
"OneMinuteRate": 1.0,
|
|
|
|
"RateUnit": "events/second",
|
|
|
|
"StdDev": null
|
|
|
|
},
|
2016-04-19 00:12:58 +00:00
|
|
|
"org.apache.cassandra.metrics:keyspace=test_keyspace2,name=ReadLatency,scope=test_table2,type=Table":
|
2016-04-01 23:13:21 +00:00
|
|
|
{ "999thPercentile": 2.0,
|
|
|
|
"Count": 200,
|
|
|
|
"DurationUnit": "microseconds",
|
|
|
|
"OneMinuteRate": 2.0,
|
|
|
|
"RateUnit": "events/second",
|
|
|
|
"StdDev": null
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`
|
|
|
|
|
|
|
|
const validSingleValueJSON = `
|
|
|
|
{
|
|
|
|
"request":{
|
|
|
|
"path":"used",
|
|
|
|
"mbean":"java.lang:type=Memory",
|
|
|
|
"attribute":"HeapMemoryUsage",
|
|
|
|
"type":"read"
|
|
|
|
},
|
|
|
|
"value":209274376,
|
|
|
|
"timestamp":1446129256,
|
|
|
|
"status":200
|
|
|
|
}`
|
|
|
|
|
|
|
|
const validJavaMultiTypeJSON = `
|
|
|
|
{
|
|
|
|
"request":{
|
|
|
|
"mbean":"java.lang:name=ConcurrentMarkSweep,type=GarbageCollector",
|
|
|
|
"attribute":"CollectionCount",
|
|
|
|
"type":"read"
|
|
|
|
},
|
|
|
|
"value":1,
|
|
|
|
"timestamp":1459316570,
|
|
|
|
"status":200
|
|
|
|
}`
|
|
|
|
|
|
|
|
const invalidJSON = "I don't think this is JSON"
|
|
|
|
|
|
|
|
const empty = ""
|
|
|
|
|
|
|
|
var Servers = []string{"10.10.10.10:8778"}
|
|
|
|
var AuthServers = []string{"user:passwd@10.10.10.10:8778"}
|
|
|
|
var MultipleServers = []string{"10.10.10.10:8778", "10.10.10.11:8778"}
|
|
|
|
var HeapMetric = "/java.lang:type=Memory/HeapMemoryUsage"
|
|
|
|
var ReadLatencyMetric = "/org.apache.cassandra.metrics:type=Table,keyspace=test_keyspace1,scope=test_table,name=ReadLatency"
|
|
|
|
var NestedReadLatencyMetric = "/org.apache.cassandra.metrics:type=Table,keyspace=test_keyspace1,scope=*,name=ReadLatency"
|
|
|
|
var GarbageCollectorMetric1 = "/java.lang:type=GarbageCollector,name=ConcurrentMarkSweep/CollectionCount"
|
|
|
|
var GarbageCollectorMetric2 = "/java.lang:type=GarbageCollector,name=ConcurrentMarkSweep/CollectionTime"
|
|
|
|
var Context = "/jolokia/read"
|
|
|
|
|
|
|
|
type jolokiaClientStub struct {
|
|
|
|
responseBody string
|
|
|
|
statusCode int
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c jolokiaClientStub) MakeRequest(req *http.Request) (*http.Response, error) {
|
|
|
|
resp := http.Response{}
|
|
|
|
resp.StatusCode = c.statusCode
|
|
|
|
resp.Body = ioutil.NopCloser(strings.NewReader(c.responseBody))
|
|
|
|
return &resp, 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 genJolokiaClientStub(response string, statusCode int, servers []string, metrics []string) *Cassandra {
|
|
|
|
return &Cassandra{
|
|
|
|
jClient: jolokiaClientStub{responseBody: response, statusCode: statusCode},
|
|
|
|
Context: Context,
|
|
|
|
Servers: servers,
|
|
|
|
Metrics: metrics,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that the proper values are ignored or collected for class=Java
|
|
|
|
func TestHttpJsonJavaMultiValue(t *testing.T) {
|
|
|
|
cassandra := genJolokiaClientStub(validJavaMultiValueJSON, 200,
|
|
|
|
MultipleServers, []string{HeapMetric})
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
acc.SetDebug(true)
|
|
|
|
err := cassandra.Gather(&acc)
|
|
|
|
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 2, len(acc.Metrics))
|
|
|
|
|
|
|
|
fields := map[string]interface{}{
|
|
|
|
"HeapMemoryUsage_init": 67108864.0,
|
|
|
|
"HeapMemoryUsage_committed": 456130560.0,
|
|
|
|
"HeapMemoryUsage_max": 477626368.0,
|
|
|
|
"HeapMemoryUsage_used": 203288528.0,
|
|
|
|
}
|
|
|
|
tags1 := map[string]string{
|
2016-04-19 00:12:58 +00:00
|
|
|
"cassandra_host": "10.10.10.10",
|
|
|
|
"mname": "HeapMemoryUsage",
|
2016-04-01 23:13:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tags2 := map[string]string{
|
2016-04-19 00:12:58 +00:00
|
|
|
"cassandra_host": "10.10.10.11",
|
|
|
|
"mname": "HeapMemoryUsage",
|
2016-04-01 23:13:21 +00:00
|
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "javaMemory", fields, tags1)
|
|
|
|
acc.AssertContainsTaggedFields(t, "javaMemory", fields, tags2)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHttpJsonJavaMultiType(t *testing.T) {
|
|
|
|
cassandra := genJolokiaClientStub(validJavaMultiTypeJSON, 200, AuthServers, []string{GarbageCollectorMetric1, GarbageCollectorMetric2})
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
acc.SetDebug(true)
|
|
|
|
err := cassandra.Gather(&acc)
|
|
|
|
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 2, len(acc.Metrics))
|
|
|
|
|
|
|
|
fields := map[string]interface{}{
|
|
|
|
"CollectionCount": 1.0,
|
|
|
|
}
|
|
|
|
|
|
|
|
tags := map[string]string{
|
2016-04-19 00:12:58 +00:00
|
|
|
"cassandra_host": "10.10.10.10",
|
|
|
|
"mname": "ConcurrentMarkSweep",
|
2016-04-01 23:13:21 +00:00
|
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "javaGarbageCollector", fields, tags)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that the proper values are ignored or collected
|
|
|
|
func TestHttpJsonOn404(t *testing.T) {
|
|
|
|
|
|
|
|
jolokia := genJolokiaClientStub(validJavaMultiValueJSON, 404, Servers,
|
|
|
|
[]string{HeapMetric})
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := jolokia.Gather(&acc)
|
|
|
|
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 0, len(acc.Metrics))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that the proper values are ignored or collected for class=Cassandra
|
|
|
|
func TestHttpJsonCassandraMultiValue(t *testing.T) {
|
|
|
|
cassandra := genJolokiaClientStub(validCassandraMultiValueJSON, 200, Servers, []string{ReadLatencyMetric})
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
err := cassandra.Gather(&acc)
|
|
|
|
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 1, len(acc.Metrics))
|
|
|
|
|
|
|
|
fields := map[string]interface{}{
|
|
|
|
"ReadLatency_999thPercentile": 20.0,
|
|
|
|
"ReadLatency_99thPercentile": 10.0,
|
|
|
|
"ReadLatency_Count": 400.0,
|
|
|
|
"ReadLatency_DurationUnit": "microseconds",
|
|
|
|
"ReadLatency_Max": 30.0,
|
|
|
|
"ReadLatency_MeanRate": 3.0,
|
|
|
|
"ReadLatency_Min": 1.0,
|
|
|
|
"ReadLatency_RateUnit": "events/second",
|
|
|
|
}
|
|
|
|
|
|
|
|
tags := map[string]string{
|
2016-04-19 00:12:58 +00:00
|
|
|
"cassandra_host": "10.10.10.10",
|
|
|
|
"mname": "ReadLatency",
|
|
|
|
"keyspace": "test_keyspace1",
|
|
|
|
"scope": "test_table",
|
2016-04-01 23:13:21 +00:00
|
|
|
}
|
|
|
|
acc.AssertContainsTaggedFields(t, "cassandraTable", fields, tags)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test that the proper values are ignored or collected for class=Cassandra with
|
|
|
|
// nested values
|
|
|
|
func TestHttpJsonCassandraNestedMultiValue(t *testing.T) {
|
|
|
|
cassandra := genJolokiaClientStub(validCassandraNestedMultiValueJSON, 200, Servers, []string{NestedReadLatencyMetric})
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
acc.SetDebug(true)
|
|
|
|
err := cassandra.Gather(&acc)
|
|
|
|
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, 2, len(acc.Metrics))
|
|
|
|
|
|
|
|
fields1 := map[string]interface{}{
|
|
|
|
"ReadLatency_999thPercentile": 1.0,
|
|
|
|
"ReadLatency_Count": 100.0,
|
|
|
|
"ReadLatency_DurationUnit": "microseconds",
|
|
|
|
"ReadLatency_OneMinuteRate": 1.0,
|
|
|
|
"ReadLatency_RateUnit": "events/second",
|
|
|
|
}
|
|
|
|
|
|
|
|
fields2 := map[string]interface{}{
|
|
|
|
"ReadLatency_999thPercentile": 2.0,
|
|
|
|
"ReadLatency_Count": 200.0,
|
|
|
|
"ReadLatency_DurationUnit": "microseconds",
|
|
|
|
"ReadLatency_OneMinuteRate": 2.0,
|
|
|
|
"ReadLatency_RateUnit": "events/second",
|
|
|
|
}
|
|
|
|
|
|
|
|
tags1 := map[string]string{
|
2016-04-19 00:12:58 +00:00
|
|
|
"cassandra_host": "10.10.10.10",
|
|
|
|
"mname": "ReadLatency",
|
|
|
|
"keyspace": "test_keyspace1",
|
|
|
|
"scope": "test_table1",
|
2016-04-01 23:13:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tags2 := map[string]string{
|
2016-04-19 00:12:58 +00:00
|
|
|
"cassandra_host": "10.10.10.10",
|
|
|
|
"mname": "ReadLatency",
|
|
|
|
"keyspace": "test_keyspace2",
|
|
|
|
"scope": "test_table2",
|
2016-04-01 23:13:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
acc.AssertContainsTaggedFields(t, "cassandraTable", fields1, tags1)
|
|
|
|
acc.AssertContainsTaggedFields(t, "cassandraTable", fields2, tags2)
|
|
|
|
}
|