github.com/netdata/go.d.plugin@v0.58.1/modules/cassandra/cassandra_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package cassandra 4 5 import ( 6 "net/http" 7 "net/http/httptest" 8 "os" 9 "testing" 10 11 "github.com/netdata/go.d.plugin/pkg/web" 12 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 var ( 18 dataMetrics, _ = os.ReadFile("testdata/metrics.txt") 19 ) 20 21 func Test_TestData(t *testing.T) { 22 for name, data := range map[string][]byte{ 23 "dataMetrics": dataMetrics, 24 } { 25 assert.NotNilf(t, data, name) 26 } 27 } 28 29 func TestNew(t *testing.T) { 30 assert.IsType(t, (*Cassandra)(nil), New()) 31 } 32 33 func TestCassandra_Init(t *testing.T) { 34 tests := map[string]struct { 35 config Config 36 wantFail bool 37 }{ 38 "success if 'url' is set": { 39 config: Config{ 40 HTTP: web.HTTP{Request: web.Request{URL: "http://127.0.0.1:7072"}}}, 41 }, 42 "success on default config": { 43 wantFail: false, 44 config: New().Config, 45 }, 46 "fails if 'url' is unset": { 47 wantFail: true, 48 config: Config{HTTP: web.HTTP{Request: web.Request{URL: ""}}}, 49 }, 50 } 51 52 for name, test := range tests { 53 t.Run(name, func(t *testing.T) { 54 c := New() 55 c.Config = test.config 56 57 if test.wantFail { 58 assert.False(t, c.Init()) 59 } else { 60 assert.True(t, c.Init()) 61 } 62 }) 63 } 64 } 65 66 func TestCassandra_Check(t *testing.T) { 67 tests := map[string]struct { 68 prepare func() (c *Cassandra, cleanup func()) 69 wantFail bool 70 }{ 71 "success on valid response": { 72 prepare: prepareCassandra, 73 }, 74 "fails if endpoint returns invalid data": { 75 wantFail: true, 76 prepare: prepareCassandraInvalidData, 77 }, 78 "fails on connection refused": { 79 wantFail: true, 80 prepare: prepareCassandraConnectionRefused, 81 }, 82 "fails on 404 response": { 83 wantFail: true, 84 prepare: prepareCassandraResponse404, 85 }, 86 } 87 88 for name, test := range tests { 89 t.Run(name, func(t *testing.T) { 90 c, cleanup := test.prepare() 91 defer cleanup() 92 93 require.True(t, c.Init()) 94 95 if test.wantFail { 96 assert.False(t, c.Check()) 97 } else { 98 assert.True(t, c.Check()) 99 } 100 }) 101 } 102 } 103 104 func TestCassandra_Charts(t *testing.T) { 105 assert.NotNil(t, New().Charts()) 106 } 107 108 func TestCassandra_Collect(t *testing.T) { 109 tests := map[string]struct { 110 prepare func() (c *Cassandra, cleanup func()) 111 wantCollected map[string]int64 112 }{ 113 "success on valid response": { 114 prepare: prepareCassandra, 115 wantCollected: map[string]int64{ 116 "client_request_failures_reads": 0, 117 "client_request_failures_writes": 0, 118 "client_request_latency_reads": 333316, 119 "client_request_latency_writes": 331841, 120 "client_request_read_latency_p50": 61, 121 "client_request_read_latency_p75": 88, 122 "client_request_read_latency_p95": 126, 123 "client_request_read_latency_p98": 182, 124 "client_request_read_latency_p99": 219, 125 "client_request_read_latency_p999": 454, 126 "client_request_timeouts_reads": 0, 127 "client_request_timeouts_writes": 0, 128 "client_request_total_latency_reads": 23688998, 129 "client_request_total_latency_writes": 14253267, 130 "client_request_unavailables_reads": 0, 131 "client_request_unavailables_writes": 0, 132 "client_request_write_latency_p50": 35, 133 "client_request_write_latency_p75": 61, 134 "client_request_write_latency_p95": 105, 135 "client_request_write_latency_p98": 126, 136 "client_request_write_latency_p99": 152, 137 "client_request_write_latency_p999": 315, 138 "compaction_bytes_compacted": 2532, 139 "compaction_completed_tasks": 1078, 140 "compaction_pending_tasks": 0, 141 "dropped_messages": 0, 142 "jvm_gc_cms_count": 1, 143 "jvm_gc_cms_time": 59, 144 "jvm_gc_parnew_count": 218, 145 "jvm_gc_parnew_time": 1617, 146 "jvm_memory_heap_used": 1134866288, 147 "jvm_memory_nonheap_used": 96565696, 148 "key_cache_hit_ratio": 87273, 149 "key_cache_hits": 1336427, 150 "key_cache_misses": 194890, 151 "key_cache_size": 196559936, 152 "key_cache_utilization": 20828, 153 "row_cache_hit_ratio": 0, 154 "row_cache_hits": 0, 155 "row_cache_misses": 0, 156 "row_cache_size": 0, 157 "row_cache_utilization": 0, 158 "storage_exceptions": 0, 159 "storage_load": 858272986, 160 "thread_pool_CacheCleanupExecutor_active_tasks": 0, 161 "thread_pool_CacheCleanupExecutor_blocked_tasks": 0, 162 "thread_pool_CacheCleanupExecutor_pending_tasks": 0, 163 "thread_pool_CacheCleanupExecutor_total_blocked_tasks": 0, 164 "thread_pool_CompactionExecutor_active_tasks": 0, 165 "thread_pool_CompactionExecutor_blocked_tasks": 0, 166 "thread_pool_CompactionExecutor_pending_tasks": 0, 167 "thread_pool_CompactionExecutor_total_blocked_tasks": 0, 168 "thread_pool_GossipStage_active_tasks": 0, 169 "thread_pool_GossipStage_blocked_tasks": 0, 170 "thread_pool_GossipStage_pending_tasks": 0, 171 "thread_pool_GossipStage_total_blocked_tasks": 0, 172 "thread_pool_HintsDispatcher_active_tasks": 0, 173 "thread_pool_HintsDispatcher_blocked_tasks": 0, 174 "thread_pool_HintsDispatcher_pending_tasks": 0, 175 "thread_pool_HintsDispatcher_total_blocked_tasks": 0, 176 "thread_pool_MemtableFlushWriter_active_tasks": 0, 177 "thread_pool_MemtableFlushWriter_blocked_tasks": 0, 178 "thread_pool_MemtableFlushWriter_pending_tasks": 0, 179 "thread_pool_MemtableFlushWriter_total_blocked_tasks": 0, 180 "thread_pool_MemtablePostFlush_active_tasks": 0, 181 "thread_pool_MemtablePostFlush_blocked_tasks": 0, 182 "thread_pool_MemtablePostFlush_pending_tasks": 0, 183 "thread_pool_MemtablePostFlush_total_blocked_tasks": 0, 184 "thread_pool_MemtableReclaimMemory_active_tasks": 0, 185 "thread_pool_MemtableReclaimMemory_blocked_tasks": 0, 186 "thread_pool_MemtableReclaimMemory_pending_tasks": 0, 187 "thread_pool_MemtableReclaimMemory_total_blocked_tasks": 0, 188 "thread_pool_MutationStage_active_tasks": 0, 189 "thread_pool_MutationStage_blocked_tasks": 0, 190 "thread_pool_MutationStage_pending_tasks": 0, 191 "thread_pool_MutationStage_total_blocked_tasks": 0, 192 "thread_pool_Native-Transport-Requests_active_tasks": 0, 193 "thread_pool_Native-Transport-Requests_blocked_tasks": 0, 194 "thread_pool_Native-Transport-Requests_pending_tasks": 0, 195 "thread_pool_Native-Transport-Requests_total_blocked_tasks": 0, 196 "thread_pool_PendingRangeCalculator_active_tasks": 0, 197 "thread_pool_PendingRangeCalculator_blocked_tasks": 0, 198 "thread_pool_PendingRangeCalculator_pending_tasks": 0, 199 "thread_pool_PendingRangeCalculator_total_blocked_tasks": 0, 200 "thread_pool_PerDiskMemtableFlushWriter_0_active_tasks": 0, 201 "thread_pool_PerDiskMemtableFlushWriter_0_blocked_tasks": 0, 202 "thread_pool_PerDiskMemtableFlushWriter_0_pending_tasks": 0, 203 "thread_pool_PerDiskMemtableFlushWriter_0_total_blocked_tasks": 0, 204 "thread_pool_ReadStage_active_tasks": 0, 205 "thread_pool_ReadStage_blocked_tasks": 0, 206 "thread_pool_ReadStage_pending_tasks": 0, 207 "thread_pool_ReadStage_total_blocked_tasks": 0, 208 "thread_pool_Sampler_active_tasks": 0, 209 "thread_pool_Sampler_blocked_tasks": 0, 210 "thread_pool_Sampler_pending_tasks": 0, 211 "thread_pool_Sampler_total_blocked_tasks": 0, 212 "thread_pool_SecondaryIndexManagement_active_tasks": 0, 213 "thread_pool_SecondaryIndexManagement_blocked_tasks": 0, 214 "thread_pool_SecondaryIndexManagement_pending_tasks": 0, 215 "thread_pool_SecondaryIndexManagement_total_blocked_tasks": 0, 216 "thread_pool_ValidationExecutor_active_tasks": 0, 217 "thread_pool_ValidationExecutor_blocked_tasks": 0, 218 "thread_pool_ValidationExecutor_pending_tasks": 0, 219 "thread_pool_ValidationExecutor_total_blocked_tasks": 0, 220 "thread_pool_ViewBuildExecutor_active_tasks": 0, 221 "thread_pool_ViewBuildExecutor_blocked_tasks": 0, 222 "thread_pool_ViewBuildExecutor_pending_tasks": 0, 223 "thread_pool_ViewBuildExecutor_total_blocked_tasks": 0, 224 }, 225 }, 226 "fails if endpoint returns invalid data": { 227 prepare: prepareCassandraInvalidData, 228 }, 229 "fails on connection refused": { 230 prepare: prepareCassandraConnectionRefused, 231 }, 232 "fails on 404 response": { 233 prepare: prepareCassandraResponse404, 234 }, 235 } 236 237 for name, test := range tests { 238 t.Run(name, func(t *testing.T) { 239 c, cleanup := test.prepare() 240 defer cleanup() 241 242 require.True(t, c.Init()) 243 244 mx := c.Collect() 245 246 assert.Equal(t, test.wantCollected, mx) 247 }) 248 } 249 } 250 251 func prepareCassandra() (c *Cassandra, cleanup func()) { 252 ts := httptest.NewServer(http.HandlerFunc( 253 func(w http.ResponseWriter, r *http.Request) { 254 _, _ = w.Write(dataMetrics) 255 })) 256 257 c = New() 258 c.URL = ts.URL 259 return c, ts.Close 260 } 261 262 func prepareCassandraInvalidData() (c *Cassandra, cleanup func()) { 263 ts := httptest.NewServer(http.HandlerFunc( 264 func(w http.ResponseWriter, r *http.Request) { 265 _, _ = w.Write([]byte("hello and\n goodbye")) 266 })) 267 268 c = New() 269 c.URL = ts.URL 270 return c, ts.Close 271 } 272 273 func prepareCassandraConnectionRefused() (c *Cassandra, cleanup func()) { 274 c = New() 275 c.URL = "http://127.0.0.1:38001" 276 return c, func() {} 277 } 278 279 func prepareCassandraResponse404() (c *Cassandra, cleanup func()) { 280 ts := httptest.NewServer(http.HandlerFunc( 281 func(w http.ResponseWriter, r *http.Request) { 282 w.WriteHeader(http.StatusNotFound) 283 })) 284 285 c = New() 286 c.URL = ts.URL 287 return c, ts.Close 288 }