2016-03-19 06:37:57 +08:00
|
|
|
package couchbase
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
2021-03-30 23:17:58 +08:00
|
|
|
"net/http"
|
|
|
|
|
"net/http/httptest"
|
2022-11-09 01:41:17 +08:00
|
|
|
"os"
|
2016-03-19 06:37:57 +08:00
|
|
|
"testing"
|
2016-09-09 22:46:31 +08:00
|
|
|
|
2022-11-09 01:41:17 +08:00
|
|
|
"github.com/stretchr/testify/require"
|
2022-06-28 03:03:55 +08:00
|
|
|
|
2022-11-09 01:41:17 +08:00
|
|
|
"github.com/influxdata/telegraf/plugins/common/tls"
|
2016-09-09 22:46:31 +08:00
|
|
|
"github.com/influxdata/telegraf/testutil"
|
2016-03-19 06:37:57 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestGatherServer(t *testing.T) {
|
2021-03-30 23:17:58 +08:00
|
|
|
bucket := "blastro-df"
|
|
|
|
|
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2021-09-08 05:25:30 +08:00
|
|
|
if r.URL.Path == "/pools" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(readJSON(t, "testdata/pools_response.json"))
|
2021-09-08 05:25:30 +08:00
|
|
|
} else if r.URL.Path == "/pools/default" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(readJSON(t, "testdata/pools_default_response.json"))
|
2021-09-08 05:25:30 +08:00
|
|
|
} else if r.URL.Path == "/pools/default/buckets" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(readJSON(t, "testdata/bucket_response.json"))
|
2021-09-08 05:25:30 +08:00
|
|
|
} else if r.URL.Path == "/pools/default/buckets/"+bucket+"/stats" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(readJSON(t, "testdata/bucket_stats_response.json"))
|
2021-03-30 23:17:58 +08:00
|
|
|
} else {
|
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
|
2021-09-30 05:39:46 +08:00
|
|
|
cb := Couchbase{
|
2022-06-28 03:03:55 +08:00
|
|
|
ClusterBucketStats: true,
|
2021-09-30 05:39:46 +08:00
|
|
|
BucketStatsIncluded: []string{"quota_percent_used", "ops_per_sec", "disk_fetches", "item_count", "disk_used", "data_used", "mem_used"},
|
|
|
|
|
}
|
2022-06-28 03:03:55 +08:00
|
|
|
require.NoError(t, cb.Init())
|
2021-03-30 23:17:58 +08:00
|
|
|
|
2016-03-19 06:37:57 +08:00
|
|
|
var acc testutil.Accumulator
|
2022-06-28 03:03:55 +08:00
|
|
|
require.NoError(t, cb.gatherServer(&acc, fakeServer.URL))
|
|
|
|
|
|
2016-03-22 05:59:31 +08:00
|
|
|
acc.AssertContainsTaggedFields(t, "couchbase_node",
|
|
|
|
|
map[string]interface{}{"memory_free": 23181365248.0, "memory_total": 64424656896.0},
|
2021-03-30 23:17:58 +08:00
|
|
|
map[string]string{"cluster": fakeServer.URL, "hostname": "172.16.10.187:8091"})
|
2016-03-22 05:59:31 +08:00
|
|
|
acc.AssertContainsTaggedFields(t, "couchbase_node",
|
|
|
|
|
map[string]interface{}{"memory_free": 23665811456.0, "memory_total": 64424656896.0},
|
2021-03-30 23:17:58 +08:00
|
|
|
map[string]string{"cluster": fakeServer.URL, "hostname": "172.16.10.65:8091"})
|
2016-03-22 05:59:31 +08:00
|
|
|
acc.AssertContainsTaggedFields(t, "couchbase_bucket",
|
|
|
|
|
map[string]interface{}{
|
|
|
|
|
"quota_percent_used": 68.85424936294555,
|
|
|
|
|
"ops_per_sec": 5686.789686789687,
|
|
|
|
|
"disk_fetches": 0.0,
|
|
|
|
|
"item_count": 943239752.0,
|
|
|
|
|
"disk_used": 409178772321.0,
|
|
|
|
|
"data_used": 212179309111.0,
|
|
|
|
|
"mem_used": 202156957464.0,
|
|
|
|
|
},
|
2021-03-30 23:17:58 +08:00
|
|
|
map[string]string{"cluster": fakeServer.URL, "bucket": "blastro-df"})
|
2016-03-19 06:37:57 +08:00
|
|
|
}
|
|
|
|
|
|
2017-08-01 02:29:14 +08:00
|
|
|
func TestSanitizeURI(t *testing.T) {
|
|
|
|
|
var sanitizeTest = []struct {
|
|
|
|
|
input string
|
|
|
|
|
expected string
|
|
|
|
|
}{
|
|
|
|
|
{"http://user:password@localhost:121", "http://localhost:121"},
|
|
|
|
|
{"user:password@localhost:12/endpoint", "localhost:12/endpoint"},
|
|
|
|
|
{"https://mail@address.com:password@localhost", "https://localhost"},
|
|
|
|
|
{"localhost", "localhost"},
|
|
|
|
|
{"user:password@localhost:2321", "localhost:2321"},
|
|
|
|
|
{"http://user:password@couchbase-0.example.com:8091/endpoint", "http://couchbase-0.example.com:8091/endpoint"},
|
|
|
|
|
{" ", " "},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, test := range sanitizeTest {
|
|
|
|
|
result := regexpURI.ReplaceAllString(test.input, "${1}")
|
|
|
|
|
|
|
|
|
|
if result != test.expected {
|
|
|
|
|
t.Errorf("TestSanitizeAddress: input %s, expected %s, actual %s", test.input, test.expected, result)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-30 23:17:58 +08:00
|
|
|
func TestGatherDetailedBucketMetrics(t *testing.T) {
|
|
|
|
|
bucket := "Ducks"
|
2022-06-28 03:03:55 +08:00
|
|
|
node := "172.94.77.2:8091"
|
|
|
|
|
|
2022-11-09 01:41:17 +08:00
|
|
|
bucketStatsResponse := readJSON(t, "testdata/bucket_stats_response.json")
|
|
|
|
|
bucketStatsResponseWithMissing := readJSON(t, "testdata/bucket_stats_response_with_missing.json")
|
|
|
|
|
nodeBucketStatsResponse := readJSON(t, "testdata/node_bucket_stats_response.json")
|
|
|
|
|
|
2021-07-02 04:50:35 +08:00
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
2023-08-29 21:07:41 +08:00
|
|
|
node string
|
2022-11-09 01:41:17 +08:00
|
|
|
response []byte
|
2021-07-02 04:50:35 +08:00
|
|
|
}{
|
|
|
|
|
{
|
2022-06-28 03:03:55 +08:00
|
|
|
name: "cluster-level with all fields",
|
2021-07-02 04:50:35 +08:00
|
|
|
response: bucketStatsResponse,
|
|
|
|
|
},
|
|
|
|
|
{
|
2022-06-28 03:03:55 +08:00
|
|
|
name: "cluster-level with missing fields",
|
2021-07-02 04:50:35 +08:00
|
|
|
response: bucketStatsResponseWithMissing,
|
|
|
|
|
},
|
2022-06-28 03:03:55 +08:00
|
|
|
{
|
|
|
|
|
name: "node-level with all fields",
|
|
|
|
|
response: nodeBucketStatsResponse,
|
2023-08-29 21:07:41 +08:00
|
|
|
node: node,
|
2022-06-28 03:03:55 +08:00
|
|
|
},
|
2021-03-30 23:17:58 +08:00
|
|
|
}
|
|
|
|
|
|
2021-07-02 04:50:35 +08:00
|
|
|
for _, test := range tests {
|
|
|
|
|
t.Run(test.name, func(t *testing.T) {
|
|
|
|
|
fakeServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
2022-06-28 03:03:55 +08:00
|
|
|
if r.URL.Path == "/pools/default/buckets/"+bucket+"/stats" || r.URL.Path == "/pools/default/buckets/"+bucket+"/nodes/"+node+"/stats" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(test.response)
|
2021-07-02 04:50:35 +08:00
|
|
|
} else {
|
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
var cb Couchbase
|
|
|
|
|
cb.BucketStatsIncluded = []string{"couch_total_disk_size"}
|
2021-09-30 05:39:46 +08:00
|
|
|
cb.ClientConfig = tls.ClientConfig{
|
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
|
}
|
2021-07-02 04:50:35 +08:00
|
|
|
err = cb.Init()
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
bucketStats := &BucketStats{}
|
2022-11-09 01:41:17 +08:00
|
|
|
if err := json.Unmarshal(test.response, bucketStats); err != nil {
|
2021-07-02 04:50:35 +08:00
|
|
|
t.Fatal("parse bucketResponse", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fields := make(map[string]interface{})
|
2022-06-28 03:03:55 +08:00
|
|
|
err = cb.gatherDetailedBucketStats(fakeServer.URL, bucket, test.node, fields)
|
2021-07-02 04:50:35 +08:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
acc.AddFields("couchbase_bucket", fields, nil)
|
|
|
|
|
|
|
|
|
|
// Ensure we gathered only one metric (the one that we configured).
|
|
|
|
|
require.Equal(t, len(acc.Metrics), 1)
|
|
|
|
|
require.Equal(t, len(acc.Metrics[0].Fields), 1)
|
|
|
|
|
})
|
|
|
|
|
}
|
2021-03-30 23:17:58 +08:00
|
|
|
}
|
|
|
|
|
|
2022-06-28 03:03:55 +08:00
|
|
|
func TestGatherNodeOnly(t *testing.T) {
|
|
|
|
|
faker := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
if r.URL.Path == "/pools" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(readJSON(t, "testdata/pools_response.json"))
|
2022-06-28 03:03:55 +08:00
|
|
|
} else if r.URL.Path == "/pools/default" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(readJSON(t, "testdata/pools_default_response.json"))
|
2022-06-28 03:03:55 +08:00
|
|
|
} else if r.URL.Path == "/pools/default/buckets" {
|
2022-11-09 01:41:17 +08:00
|
|
|
_, _ = w.Write(readJSON(t, "testdata/bucket_response.json"))
|
2022-06-28 03:03:55 +08:00
|
|
|
} else {
|
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
|
}
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
cb := Couchbase{
|
|
|
|
|
Servers: []string{faker.URL},
|
|
|
|
|
}
|
|
|
|
|
require.NoError(t, cb.Init())
|
|
|
|
|
|
|
|
|
|
var acc testutil.Accumulator
|
|
|
|
|
require.NoError(t, cb.gatherServer(&acc, faker.URL))
|
|
|
|
|
|
|
|
|
|
require.Equal(t, 0, len(acc.Errors))
|
|
|
|
|
require.Equal(t, 7, len(acc.Metrics))
|
|
|
|
|
acc.AssertDoesNotContainMeasurement(t, "couchbase_bucket")
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-09 01:41:17 +08:00
|
|
|
func readJSON(t *testing.T, jsonFilePath string) []byte {
|
|
|
|
|
data, err := os.ReadFile(jsonFilePath)
|
|
|
|
|
require.NoErrorf(t, err, "could not read from data file %s", jsonFilePath)
|
2021-09-08 05:25:30 +08:00
|
|
|
|
2022-11-09 01:41:17 +08:00
|
|
|
return data
|
|
|
|
|
}
|