github.com/netdata/go.d.plugin@v0.58.1/modules/couchbase/couchbase_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package couchbase 4 5 import ( 6 "net/http" 7 "net/http/httptest" 8 "os" 9 "testing" 10 11 "github.com/netdata/go.d.plugin/agent/module" 12 "github.com/netdata/go.d.plugin/pkg/web" 13 14 "github.com/stretchr/testify/assert" 15 "github.com/stretchr/testify/require" 16 ) 17 18 var ( 19 v660BucketsBasicStats, _ = os.ReadFile("testdata/6.6.0/buckets_basic_stats.json") 20 ) 21 22 func TestNew(t *testing.T) { 23 assert.Implements(t, (*module.Module)(nil), New()) 24 } 25 26 func Test_testDataIsCorrectlyReadAndValid(t *testing.T) { 27 for name, data := range map[string][]byte{ 28 "v660BucketsBasicStats": v660BucketsBasicStats, 29 } { 30 require.NotNilf(t, data, name) 31 } 32 } 33 34 func TestCouchbase_Init(t *testing.T) { 35 tests := map[string]struct { 36 config Config 37 wantFail bool 38 }{ 39 "success on default config": { 40 config: New().Config, 41 }, 42 "fails on unset 'URL'": { 43 wantFail: true, 44 config: Config{ 45 HTTP: web.HTTP{ 46 Request: web.Request{ 47 URL: "", 48 }, 49 }, 50 }, 51 }, 52 "fails on invalid URL": { 53 wantFail: true, 54 config: Config{ 55 HTTP: web.HTTP{ 56 Request: web.Request{ 57 URL: "127.0.0.1:9090", 58 }, 59 }, 60 }, 61 }, 62 } 63 64 for name, test := range tests { 65 t.Run(name, func(t *testing.T) { 66 cb := New() 67 cb.Config = test.config 68 69 if test.wantFail { 70 assert.False(t, cb.Init()) 71 } else { 72 assert.True(t, cb.Init()) 73 } 74 }) 75 } 76 } 77 78 func TestCouchbase_Check(t *testing.T) { 79 tests := map[string]struct { 80 prepare func(*testing.T) (cb *Couchbase, cleanup func()) 81 wantFail bool 82 }{ 83 "success on valid response v6.6.0": { 84 prepare: prepareCouchbaseV660, 85 }, 86 "fails on response with invalid data": { 87 wantFail: true, 88 prepare: prepareCouchbaseInvalidData, 89 }, 90 "fails on 404 response": { 91 wantFail: true, 92 prepare: prepareCouchbase404, 93 }, 94 "fails on connection refused": { 95 wantFail: true, 96 prepare: prepareCouchbaseConnectionRefused, 97 }, 98 } 99 100 for name, test := range tests { 101 t.Run(name, func(t *testing.T) { 102 cb, cleanup := test.prepare(t) 103 defer cleanup() 104 105 if test.wantFail { 106 assert.False(t, cb.Check()) 107 } else { 108 assert.True(t, cb.Check()) 109 } 110 }) 111 } 112 } 113 114 func TestCouchbase_Collect(t *testing.T) { 115 tests := map[string]struct { 116 prepare func(t *testing.T) (cb *Couchbase, cleanup func()) 117 wantCollected map[string]int64 118 }{ 119 "success on valid response v6.6.0": { 120 prepare: prepareCouchbaseV660, 121 wantCollected: map[string]int64{ 122 "bucket_beer-sample_data_used": 13990431, 123 "bucket_beer-sample_disk_fetches": 1, 124 "bucket_beer-sample_disk_used": 27690472, 125 "bucket_beer-sample_item_count": 7303, 126 "bucket_beer-sample_mem_used": 34294872, 127 "bucket_beer-sample_ops_per_sec": 1100, 128 "bucket_beer-sample_quota_percent_used": 32706, 129 "bucket_beer-sample_vb_active_num_non_resident": 1, 130 "bucket_gamesim-sample_data_used": 5371804, 131 "bucket_gamesim-sample_disk_fetches": 1, 132 "bucket_gamesim-sample_disk_used": 13821793, 133 "bucket_gamesim-sample_item_count": 586, 134 "bucket_gamesim-sample_mem_used": 29586696, 135 "bucket_gamesim-sample_ops_per_sec": 1100, 136 "bucket_gamesim-sample_quota_percent_used": 28216, 137 "bucket_gamesim-sample_vb_active_num_non_resident": 1, 138 "bucket_travel-sample_data_used": 53865472, 139 "bucket_travel-sample_disk_fetches": 1, 140 "bucket_travel-sample_disk_used": 62244260, 141 "bucket_travel-sample_item_count": 31591, 142 "bucket_travel-sample_mem_used": 54318184, 143 "bucket_travel-sample_ops_per_sec": 1100, 144 "bucket_travel-sample_quota_percent_used": 51801, 145 "bucket_travel-sample_vb_active_num_non_resident": 1, 146 }, 147 }, 148 "fails on response with invalid data": { 149 prepare: prepareCouchbaseInvalidData, 150 }, 151 "fails on 404 response": { 152 prepare: prepareCouchbase404, 153 }, 154 "fails on connection refused": { 155 prepare: prepareCouchbaseConnectionRefused, 156 }, 157 } 158 159 for name, test := range tests { 160 t.Run(name, func(t *testing.T) { 161 cb, cleanup := test.prepare(t) 162 defer cleanup() 163 164 collected := cb.Collect() 165 166 assert.Equal(t, test.wantCollected, collected) 167 ensureCollectedHasAllChartsDimsVarsIDs(t, cb, collected) 168 }) 169 } 170 } 171 172 func prepareCouchbaseV660(t *testing.T) (cb *Couchbase, cleanup func()) { 173 t.Helper() 174 srv := httptest.NewServer(http.HandlerFunc( 175 func(w http.ResponseWriter, r *http.Request) { 176 _, _ = w.Write(v660BucketsBasicStats) 177 })) 178 179 cb = New() 180 cb.URL = srv.URL 181 require.True(t, cb.Init()) 182 183 return cb, srv.Close 184 } 185 186 func prepareCouchbaseInvalidData(t *testing.T) (*Couchbase, func()) { 187 t.Helper() 188 srv := httptest.NewServer(http.HandlerFunc( 189 func(w http.ResponseWriter, r *http.Request) { 190 _, _ = w.Write([]byte("hello and\n goodbye")) 191 })) 192 cb := New() 193 cb.URL = srv.URL 194 require.True(t, cb.Init()) 195 196 return cb, srv.Close 197 } 198 199 func prepareCouchbase404(t *testing.T) (*Couchbase, func()) { 200 t.Helper() 201 srv := httptest.NewServer(http.HandlerFunc( 202 func(w http.ResponseWriter, r *http.Request) { 203 w.WriteHeader(http.StatusNotFound) 204 })) 205 cb := New() 206 cb.URL = srv.URL 207 require.True(t, cb.Init()) 208 209 return cb, srv.Close 210 } 211 212 func prepareCouchbaseConnectionRefused(t *testing.T) (*Couchbase, func()) { 213 t.Helper() 214 cb := New() 215 cb.URL = "http://127.0.0.1:38001" 216 require.True(t, cb.Init()) 217 218 return cb, func() {} 219 } 220 221 func ensureCollectedHasAllChartsDimsVarsIDs(t *testing.T, cb *Couchbase, collected map[string]int64) { 222 for _, chart := range *cb.Charts() { 223 if chart.Obsolete { 224 continue 225 } 226 for _, dim := range chart.Dims { 227 _, ok := collected[dim.ID] 228 assert.Truef(t, ok, "chart '%s' dim '%s': no dim in collected", dim.ID, chart.ID) 229 } 230 for _, v := range chart.Vars { 231 _, ok := collected[v.ID] 232 assert.Truef(t, ok, "chart '%s' dim '%s': no dim in collected", v.ID, chart.ID) 233 } 234 } 235 }