github.com/netdata/go.d.plugin@v0.58.1/modules/logstash/logstash_test.go (about) 1 // SPDX-License-Identifier: GPL-3.0-or-later 2 3 package logstash 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 nodeStataData, _ = os.ReadFile("testdata/stats.json") 19 ) 20 21 func Test_testDataIsValid(t *testing.T) { 22 for name, data := range map[string][]byte{ 23 "nodeStataData": nodeStataData, 24 } { 25 require.NotNilf(t, data, name) 26 27 } 28 } 29 30 func TestLogstash_Init(t *testing.T) { 31 tests := map[string]struct { 32 wantFail bool 33 config Config 34 }{ 35 "success with default": { 36 wantFail: false, 37 config: New().Config, 38 }, 39 "fail when URL not set": { 40 wantFail: true, 41 config: Config{ 42 HTTP: web.HTTP{ 43 Request: web.Request{URL: ""}, 44 }, 45 }, 46 }, 47 } 48 49 for name, test := range tests { 50 t.Run(name, func(t *testing.T) { 51 ls := New() 52 ls.Config = test.config 53 54 if test.wantFail { 55 assert.False(t, ls.Init()) 56 } else { 57 assert.True(t, ls.Init()) 58 } 59 }) 60 } 61 } 62 63 func TestLogstash_Charts(t *testing.T) { 64 assert.NotNil(t, New().Charts()) 65 } 66 67 func TestLogstash_Cleanup(t *testing.T) { 68 assert.NotPanics(t, New().Cleanup) 69 } 70 71 func TestLogstash_Check(t *testing.T) { 72 tests := map[string]struct { 73 wantFail bool 74 prepare func(t *testing.T) (ls *Logstash, cleanup func()) 75 }{ 76 "success on valid response": { 77 wantFail: false, 78 prepare: caseValidResponse, 79 }, 80 "fail on invalid data response": { 81 wantFail: true, 82 prepare: caseInvalidDataResponse, 83 }, 84 "fail on connection refused": { 85 wantFail: true, 86 prepare: caseConnectionRefused, 87 }, 88 "fail on 404 response": { 89 wantFail: true, 90 prepare: case404, 91 }, 92 } 93 94 for name, test := range tests { 95 t.Run(name, func(t *testing.T) { 96 ls, cleanup := test.prepare(t) 97 defer cleanup() 98 99 if test.wantFail { 100 assert.False(t, ls.Check()) 101 } else { 102 assert.True(t, ls.Check()) 103 } 104 }) 105 } 106 } 107 108 func TestLogstash_Collect(t *testing.T) { 109 tests := map[string]struct { 110 prepare func(t *testing.T) (ls *Logstash, cleanup func()) 111 wantNumOfCharts int 112 wantMetrics map[string]int64 113 }{ 114 "success on valid response": { 115 prepare: caseValidResponse, 116 wantNumOfCharts: len(charts) + len(pipelineChartsTmpl), 117 wantMetrics: map[string]int64{ 118 "event_duration_in_millis": 0, 119 "event_filtered": 0, 120 "event_in": 0, 121 "event_out": 0, 122 "event_queue_push_duration_in_millis": 0, 123 "jvm_gc_collectors_eden_collection_count": 5796, 124 "jvm_gc_collectors_eden_collection_time_in_millis": 45008, 125 "jvm_gc_collectors_old_collection_count": 7, 126 "jvm_gc_collectors_old_collection_time_in_millis": 3263, 127 "jvm_mem_heap_committed_in_bytes": 528154624, 128 "jvm_mem_heap_used_in_bytes": 189973480, 129 "jvm_mem_heap_used_percent": 35, 130 "jvm_mem_pools_eden_committed_in_bytes": 69795840, 131 "jvm_mem_pools_eden_used_in_bytes": 2600120, 132 "jvm_mem_pools_old_committed_in_bytes": 449642496, 133 "jvm_mem_pools_old_used_in_bytes": 185944824, 134 "jvm_mem_pools_survivor_committed_in_bytes": 8716288, 135 "jvm_mem_pools_survivor_used_in_bytes": 1428536, 136 "jvm_threads_count": 28, 137 "jvm_uptime_in_millis": 699809475, 138 "pipelines_pipeline-1_event_duration_in_millis": 5027018, 139 "pipelines_pipeline-1_event_filtered": 567639, 140 "pipelines_pipeline-1_event_in": 567639, 141 "pipelines_pipeline-1_event_out": 567639, 142 "pipelines_pipeline-1_event_queue_push_duration_in_millis": 84241, 143 "process_open_file_descriptors": 101, 144 }, 145 }, 146 "fail on invalid data response": { 147 prepare: caseInvalidDataResponse, 148 wantNumOfCharts: 0, 149 wantMetrics: nil, 150 }, 151 "fail on connection refused": { 152 prepare: caseConnectionRefused, 153 wantNumOfCharts: 0, 154 wantMetrics: nil, 155 }, 156 "fail on 404 response": { 157 prepare: case404, 158 wantNumOfCharts: 0, 159 wantMetrics: nil, 160 }, 161 } 162 163 for name, test := range tests { 164 t.Run(name, func(t *testing.T) { 165 ls, cleanup := test.prepare(t) 166 defer cleanup() 167 168 mx := ls.Collect() 169 170 require.Equal(t, test.wantMetrics, mx) 171 if len(test.wantMetrics) > 0 { 172 assert.Equal(t, test.wantNumOfCharts, len(*ls.Charts())) 173 ensureCollectedHasAllChartsDimsVarsIDs(t, ls, mx) 174 } 175 }) 176 } 177 } 178 179 func ensureCollectedHasAllChartsDimsVarsIDs(t *testing.T, ls *Logstash, mx map[string]int64) { 180 for _, chart := range *ls.Charts() { 181 for _, dim := range chart.Dims { 182 _, ok := mx[dim.ID] 183 assert.Truef(t, ok, "collected metrics has no data for dim '%s' chart '%s'", dim.ID, chart.ID) 184 } 185 for _, v := range chart.Vars { 186 _, ok := mx[v.ID] 187 assert.Truef(t, ok, "collected metrics has no data for var '%s' chart '%s'", v.ID, chart.ID) 188 } 189 } 190 } 191 192 func caseValidResponse(t *testing.T) (*Logstash, func()) { 193 t.Helper() 194 srv := httptest.NewServer(http.HandlerFunc( 195 func(w http.ResponseWriter, r *http.Request) { 196 switch r.URL.Path { 197 case urlPathNodeStatsAPI: 198 _, _ = w.Write(nodeStataData) 199 default: 200 w.WriteHeader(http.StatusNotFound) 201 } 202 })) 203 ls := New() 204 ls.URL = srv.URL 205 require.True(t, ls.Init()) 206 207 return ls, srv.Close 208 } 209 210 func caseInvalidDataResponse(t *testing.T) (*Logstash, func()) { 211 t.Helper() 212 srv := httptest.NewServer(http.HandlerFunc( 213 func(w http.ResponseWriter, r *http.Request) { 214 _, _ = w.Write([]byte("hello and\n goodbye")) 215 })) 216 ls := New() 217 ls.URL = srv.URL 218 require.True(t, ls.Init()) 219 220 return ls, srv.Close 221 } 222 223 func caseConnectionRefused(t *testing.T) (*Logstash, func()) { 224 t.Helper() 225 ls := New() 226 ls.URL = "http://127.0.0.1:65001" 227 require.True(t, ls.Init()) 228 229 return ls, func() {} 230 } 231 232 func case404(t *testing.T) (*Logstash, func()) { 233 t.Helper() 234 srv := httptest.NewServer(http.HandlerFunc( 235 func(w http.ResponseWriter, r *http.Request) { 236 w.WriteHeader(http.StatusNotFound) 237 })) 238 ls := New() 239 ls.URL = srv.URL 240 require.True(t, ls.Init()) 241 242 return ls, srv.Close 243 }