master
go 320 lines 11.8 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package cockroachdb
4
5 import (
6 "context"
7 "net/http"
8 "net/http/httptest"
9 "os"
10 "testing"
11
12 "github.com/netdata/netdata/go/plugins/plugin/framework/collectorapi"
13 "github.com/netdata/netdata/go/plugins/plugin/go.d/pkg/collecttest"
14
15 "github.com/stretchr/testify/assert"
16 "github.com/stretchr/testify/require"
17 )
18
19 var (
20 dataConfigJSON, _ = os.ReadFile("testdata/config.json")
21 dataConfigYAML, _ = os.ReadFile("testdata/config.yaml")
22
23 dataExpectedMetrics, _ = os.ReadFile("testdata/metrics.txt")
24 dataUnexpectedMetrics, _ = os.ReadFile("testdata/non_cockroachdb.txt")
25 )
26
27 func Test_testDataIsValid(t *testing.T) {
28 for name, data := range map[string][]byte{
29 "dataConfigJSON": dataConfigJSON,
30 "dataConfigYAML": dataConfigYAML,
31 "dataExpectedMetrics": dataExpectedMetrics,
32 "dataUnexpectedMetrics": dataUnexpectedMetrics,
33 } {
34 assert.NotNil(t, data, name)
35 }
36 }
37
38 func TestCollector_ConfigurationSerialize(t *testing.T) {
39 collecttest.TestConfigurationSerialize(t, &Collector{}, dataConfigJSON, dataConfigYAML)
40 }
41
42 func TestNew(t *testing.T) {
43 assert.Implements(t, (*collectorapi.CollectorV1)(nil), New())
44 }
45
46 func TestCollector_Init(t *testing.T) {
47 collr := prepareCockroachDB()
48
49 assert.NoError(t, collr.Init(context.Background()))
50 }
51
52 func TestCollector_Init_ReturnsFalseIfConfigURLIsNotSet(t *testing.T) {
53 collr := prepareCockroachDB()
54 collr.URL = ""
55
56 assert.Error(t, collr.Init(context.Background()))
57 }
58
59 func TestCollector_Init_ReturnsFalseIfClientWrongTLSCA(t *testing.T) {
60 collr := prepareCockroachDB()
61 collr.ClientConfig.TLSConfig.TLSCA = "testdata/tls"
62
63 assert.Error(t, collr.Init(context.Background()))
64 }
65
66 func TestCollector_Check(t *testing.T) {
67 collr, srv := prepareClientServer(t)
68 defer srv.Close()
69
70 assert.NoError(t, collr.Check(context.Background()))
71 }
72
73 func TestCollector_Check_ReturnsFalseIfConnectionRefused(t *testing.T) {
74 collr := New()
75 collr.URL = "http://127.0.0.1:38001/metrics"
76 require.NoError(t, collr.Init(context.Background()))
77
78 assert.Error(t, collr.Check(context.Background()))
79 }
80
81 func TestCollector_Charts(t *testing.T) {
82 assert.NotNil(t, New().Charts())
83 }
84
85 func TestCollector_Cleanup(t *testing.T) {
86 assert.NotPanics(t, func() { New().Cleanup(context.Background()) })
87 }
88
89 func TestCollector_Collect(t *testing.T) {
90 collr, srv := prepareClientServer(t)
91 defer srv.Close()
92
93 expected := map[string]int64{
94 "capacity": 64202351837184,
95 "capacity_available": 40402062147584,
96 "capacity_unusable": 23800157791684,
97 "capacity_usable": 40402194045500,
98 "capacity_usable_used_percent": 0,
99 "capacity_used": 131897916,
100 "capacity_used_percent": 37070,
101 "keybytes": 6730852,
102 "keycount": 119307,
103 "livebytes": 81979227,
104 "liveness_heartbeatfailures": 2,
105 "liveness_heartbeatsuccesses": 2720,
106 "liveness_livenodes": 3,
107 "queue_consistency_process_failure": 0,
108 "queue_gc_process_failure": 0,
109 "queue_raftlog_process_failure": 0,
110 "queue_raftsnapshot_process_failure": 0,
111 "queue_replicagc_process_failure": 0,
112 "queue_replicate_process_failure": 0,
113 "queue_split_process_failure": 0,
114 "queue_tsmaintenance_process_failure": 0,
115 "range_adds": 0,
116 "range_merges": 0,
117 "range_removes": 0,
118 "range_snapshots_generated": 0,
119 "range_snapshots_learner_applied": 0,
120 "range_snapshots_normal_applied": 0,
121 "range_snapshots_preemptive_applied": 0,
122 "range_splits": 0,
123 "ranges": 34,
124 "ranges_overreplicated": 0,
125 "ranges_unavailable": 0,
126 "ranges_underreplicated": 0,
127 "rebalancing_queriespersecond": 801,
128 "rebalancing_writespersecond": 213023,
129 "replicas": 34,
130 "replicas_active": 0,
131 "replicas_leaders": 7,
132 "replicas_leaders_not_leaseholders": 0,
133 "replicas_leaseholders": 7,
134 "replicas_quiescent": 34,
135 "requests_slow_latch": 0,
136 "requests_slow_lease": 0,
137 "requests_slow_raft": 0,
138 "rocksdb_block_cache_hit_rate": 92104,
139 "rocksdb_block_cache_hits": 94825,
140 "rocksdb_block_cache_misses": 8129,
141 "rocksdb_block_cache_usage": 39397184,
142 "rocksdb_compactions": 7,
143 "rocksdb_flushes": 13,
144 "rocksdb_num_sstables": 8,
145 "rocksdb_read_amplification": 1,
146 "sql_bytesin": 0,
147 "sql_bytesout": 0,
148 "sql_conns": 0,
149 "sql_ddl_count": 0,
150 "sql_ddl_started_count": 0,
151 "sql_delete_count": 0,
152 "sql_delete_started_count": 0,
153 "sql_distsql_flows_active": 0,
154 "sql_distsql_flows_queued": 0,
155 "sql_distsql_queries_active": 0,
156 "sql_failure_count": 0,
157 "sql_insert_count": 0,
158 "sql_insert_started_count": 0,
159 "sql_misc_count": 0,
160 "sql_misc_started_count": 0,
161 "sql_query_count": 0,
162 "sql_query_started_count": 0,
163 "sql_restart_savepoint_count": 0,
164 "sql_restart_savepoint_release_count": 0,
165 "sql_restart_savepoint_release_started_count": 0,
166 "sql_restart_savepoint_rollback_count": 0,
167 "sql_restart_savepoint_rollback_started_count": 0,
168 "sql_restart_savepoint_started_count": 0,
169 "sql_savepoint_count": 0,
170 "sql_savepoint_started_count": 0,
171 "sql_select_count": 0,
172 "sql_select_started_count": 0,
173 "sql_txn_abort_count": 0,
174 "sql_txn_begin_count": 0,
175 "sql_txn_begin_started_count": 0,
176 "sql_txn_commit_count": 0,
177 "sql_txn_commit_started_count": 0,
178 "sql_txn_rollback_count": 0,
179 "sql_txn_rollback_started_count": 0,
180 "sql_update_count": 0,
181 "sql_update_started_count": 0,
182 "sys_cgo_allocbytes": 63363512,
183 "sys_cgocalls": 577778,
184 "sys_cpu_combined_percent_normalized": 851,
185 "sys_cpu_sys_ns": 154420000000,
186 "sys_cpu_sys_percent": 1403,
187 "sys_cpu_user_ns": 227620000000,
188 "sys_cpu_user_percent": 2004,
189 "sys_fd_open": 47,
190 "sys_fd_softlimit": 1048576,
191 "sys_gc_count": 279,
192 "sys_gc_pause_ns": 60700450,
193 "sys_go_allocbytes": 106576224,
194 "sys_goroutines": 235,
195 "sys_host_disk_iopsinprogress": 0,
196 "sys_host_disk_read_bytes": 43319296,
197 "sys_host_disk_read_count": 1176,
198 "sys_host_disk_write_bytes": 942080,
199 "sys_host_disk_write_count": 106,
200 "sys_host_net_recv_bytes": 234392325,
201 "sys_host_net_recv_packets": 593876,
202 "sys_host_net_send_bytes": 461746036,
203 "sys_host_net_send_packets": 644128,
204 "sys_rss": 314691584,
205 "sys_uptime": 12224,
206 "sysbytes": 13327,
207 "timeseries_write_bytes": 82810041,
208 "timeseries_write_errors": 0,
209 "timeseries_write_samples": 845784,
210 "txn_aborts": 1,
211 "txn_commits": 7472,
212 "txn_commits1PC": 3206,
213 "txn_restarts_asyncwritefailure": 0,
214 "txn_restarts_possiblereplay": 0,
215 "txn_restarts_readwithinuncertainty": 0,
216 "txn_restarts_serializable": 0,
217 "txn_restarts_txnaborted": 0,
218 "txn_restarts_txnpush": 0,
219 "txn_restarts_unknown": 0,
220 "txn_restarts_writetooold": 0,
221 "txn_restarts_writetoooldmulti": 0,
222 "valbytes": 75527718,
223 "valcount": 124081,
224 }
225
226 mx := collr.Collect(context.Background())
227
228 assert.Equal(t, expected, mx)
229
230 collecttest.TestMetricsHasAllChartsDims(t, collr.Charts(), mx)
231 }
232
233 func TestCollector_Collect_ReturnsNilIfNotCockroachDBMetrics(t *testing.T) {
234 collr, srv := prepareClientServerNotCockroachDBMetricResponse(t)
235 defer srv.Close()
236
237 assert.Nil(t, collr.Collect(context.Background()))
238 }
239
240 func TestCollector_Collect_ReturnsNilIfConnectionRefused(t *testing.T) {
241 collr := prepareCockroachDB()
242 require.NoError(t, collr.Init(context.Background()))
243
244 assert.Nil(t, collr.Collect(context.Background()))
245 }
246
247 func TestCollector_Collect_ReturnsNilIfReceiveInvalidResponse(t *testing.T) {
248 collr, ts := prepareClientServerInvalidDataResponse(t)
249 defer ts.Close()
250
251 assert.Nil(t, collr.Collect(context.Background()))
252 }
253
254 func TestCollector_Collect_ReturnsNilIfReceiveResponse404(t *testing.T) {
255 collr, ts := prepareClientServerResponse404(t)
256 defer ts.Close()
257
258 assert.Nil(t, collr.Collect(context.Background()))
259 }
260
261 func prepareCockroachDB() *Collector {
262 collr := New()
263 collr.URL = "http://127.0.0.1:38001/metrics"
264 return collr
265 }
266
267 func prepareClientServer(t *testing.T) (*Collector, *httptest.Server) {
268 t.Helper()
269 ts := httptest.NewServer(http.HandlerFunc(
270 func(w http.ResponseWriter, r *http.Request) {
271 _, _ = w.Write(dataExpectedMetrics)
272 }))
273
274 collr := New()
275 collr.URL = ts.URL
276 require.NoError(t, collr.Init(context.Background()))
277
278 return collr, ts
279 }
280
281 func prepareClientServerNotCockroachDBMetricResponse(t *testing.T) (*Collector, *httptest.Server) {
282 t.Helper()
283 ts := httptest.NewServer(http.HandlerFunc(
284 func(w http.ResponseWriter, r *http.Request) {
285 _, _ = w.Write(dataUnexpectedMetrics)
286 }))
287
288 collr := New()
289 collr.URL = ts.URL
290 require.NoError(t, collr.Init(context.Background()))
291
292 return collr, ts
293 }
294
295 func prepareClientServerInvalidDataResponse(t *testing.T) (*Collector, *httptest.Server) {
296 t.Helper()
297 ts := httptest.NewServer(http.HandlerFunc(
298 func(w http.ResponseWriter, r *http.Request) {
299 _, _ = w.Write([]byte("hello and\n goodbye"))
300 }))
301
302 collr := New()
303 collr.URL = ts.URL
304 require.NoError(t, collr.Init(context.Background()))
305
306 return collr, ts
307 }
308
309 func prepareClientServerResponse404(t *testing.T) (*Collector, *httptest.Server) {
310 t.Helper()
311 ts := httptest.NewServer(http.HandlerFunc(
312 func(w http.ResponseWriter, r *http.Request) {
313 w.WriteHeader(http.StatusNotFound)
314 }))
315
316 collr := New()
317 collr.URL = ts.URL
318 require.NoError(t, collr.Init(context.Background()))
319 return collr, ts
320 }