github.com/verrazzano/verrazzano@v1.7.1/tools/psr/backend/workers/opensearch/postlogs/postlogs_test.go (about) 1 // Copyright (c) 2022, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package postlogs 5 6 import ( 7 "errors" 8 "github.com/stretchr/testify/assert" 9 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 10 "github.com/verrazzano/verrazzano/tools/psr/backend/config" 11 "io" 12 "net/http" 13 "strings" 14 "testing" 15 ) 16 17 type fakeHTTP struct { 18 resp *http.Response 19 httpDoError error 20 } 21 22 type fakeBody struct { 23 bodyData string 24 httpReadError error 25 } 26 27 var _ httpClientI = &fakeHTTP{} 28 29 // TestGetters tests the worker getters 30 // GIVEN a worker 31 // 32 // WHEN the getter methods are calls 33 // THEN ensure that the correct results are returned 34 func TestGetters(t *testing.T) { 35 w, err := NewPostLogsWorker() 36 assert.NoError(t, err) 37 38 wd := w.GetWorkerDesc() 39 assert.Equal(t, config.WorkerTypeOpsPostLogs, wd.WorkerType) 40 assert.Equal(t, "The postlogs worker performs POST requests on the OpenSearch endpoint", wd.Description) 41 assert.Equal(t, metricsPrefix, wd.MetricsPrefix) 42 43 logged := w.WantLoopInfoLogged() 44 assert.False(t, logged) 45 } 46 47 // TestGetEnvDescList tests the GetEnvDescList method 48 // GIVEN a worker 49 // 50 // WHEN the GetEnvDescList methods is called 51 // THEN ensure that the correct results are returned 52 func TestGetEnvDescList(t *testing.T) { 53 tests := []struct { 54 name string 55 key string 56 defval string 57 required bool 58 }{ 59 {name: "1", 60 key: LogEntries, 61 defval: "1", 62 required: false, 63 }, 64 {name: "2", 65 key: LogLength, 66 defval: "1", 67 required: false, 68 }, 69 } 70 71 for _, test := range tests { 72 t.Run(test.name, func(t *testing.T) { 73 w, err := NewPostLogsWorker() 74 assert.NoError(t, err) 75 el := w.GetEnvDescList() 76 for _, e := range el { 77 if e.Key == test.key { 78 assert.Equal(t, test.defval, e.DefaultVal) 79 assert.Equal(t, test.required, e.Required) 80 } 81 } 82 }) 83 } 84 } 85 86 func TestGetMetricDescList(t *testing.T) { 87 tests := []struct { 88 name string 89 fqName string 90 help string 91 }{ 92 {name: "1", fqName: "opensearch_postlogs_success_count_total", help: "The total number of successful OpenSearch POST requests"}, 93 {name: "2", fqName: "opensearch_postlogs_failure_count_total", help: "The total number of successful OpenSearch POST requests"}, 94 {name: "3", fqName: "opensearch_postlogs_success_latency_nanoseconds", help: "The latency of successful OpenSearch POST requests in nanoseconds"}, 95 {name: "4", fqName: "opensearch_postlogs_failure_latency_nanoseconds", help: "The latency of failed OpenSearch POST requests in nanoseconds"}, 96 {name: "5", fqName: "opensearch_postlogs_data_chars_total", help: "The total number of characters posted to OpenSearch"}, 97 } 98 for _, test := range tests { 99 t.Run(test.name, func(t *testing.T) { 100 wi, err := NewPostLogsWorker() 101 assert.NoError(t, err) 102 w := wi.(worker) 103 assert.NoError(t, err) 104 dl := w.GetMetricDescList() 105 var found int 106 for _, d := range dl { 107 s := d.String() 108 if strings.Contains(s, test.fqName) && strings.Contains(s, test.help) { 109 found++ 110 } 111 } 112 assert.Equal(t, 1, found) 113 }) 114 } 115 } 116 117 func TestGetMetricList(t *testing.T) { 118 tests := []struct { 119 name string 120 fqName string 121 help string 122 }{ 123 {name: "1", fqName: metricsPrefix + "_success_count_total", help: "The total number of successful OpenSearch POST requests"}, 124 {name: "2", fqName: metricsPrefix + "_failure_count_total", help: "The total number of successful OpenSearch POST requests"}, 125 {name: "3", fqName: metricsPrefix + "_success_latency_nanoseconds", help: "The latency of successful OpenSearch POST requests in nanoseconds"}, 126 {name: "4", fqName: metricsPrefix + "_failure_latency_nanoseconds", help: "The latency of failed OpenSearch POST requests in nanoseconds"}, 127 {name: "5", fqName: metricsPrefix + "_data_chars_total", help: "The total number of characters posted to OpenSearch"}, 128 } 129 for _, test := range tests { 130 t.Run(test.name, func(t *testing.T) { 131 wi, err := NewPostLogsWorker() 132 w := wi.(worker) 133 assert.NoError(t, err) 134 ml := w.GetMetricList() 135 var found int 136 for _, m := range ml { 137 s := m.Desc().String() 138 if strings.Contains(s, test.fqName) && strings.Contains(s, test.help) { 139 found++ 140 } 141 } 142 assert.Equal(t, 1, found) 143 }) 144 } 145 } 146 147 // TestDoWork tests the DoWork method 148 // GIVEN a worker 149 // 150 // WHEN the DoWork methods is called 151 // THEN ensure that the correct results are returned 152 func TestDoWork(t *testing.T) { 153 tests := []struct { 154 name string 155 doworkError error 156 httpDoError error 157 nilResp bool 158 statusCode int 159 reqCount int 160 successCount int 161 failureCount int 162 fakeBody 163 }{ 164 { 165 name: "1", 166 statusCode: 201, 167 reqCount: 1, 168 successCount: 1, 169 failureCount: 0, 170 fakeBody: fakeBody{ 171 bodyData: "bodydata", 172 }, 173 }, 174 { 175 name: "2", 176 reqCount: 1, 177 successCount: 0, 178 failureCount: 1, 179 doworkError: errors.New("error"), 180 httpDoError: errors.New("error"), 181 fakeBody: fakeBody{ 182 bodyData: "bodydata", 183 }, 184 }, 185 { 186 name: "3", 187 statusCode: 500, 188 doworkError: errors.New("error"), 189 reqCount: 1, 190 successCount: 0, 191 failureCount: 1, 192 fakeBody: fakeBody{ 193 bodyData: "bodydata", 194 httpReadError: errors.New("error"), 195 }, 196 }, 197 { 198 name: "4", 199 doworkError: errors.New("GET request to endpoint received a nil response"), 200 nilResp: true, 201 reqCount: 1, 202 successCount: 0, 203 failureCount: 1, 204 fakeBody: fakeBody{ 205 bodyData: "bodydata", 206 httpReadError: errors.New("error"), 207 }, 208 }, 209 } 210 for _, test := range tests { 211 t.Run(test.name, func(t *testing.T) { 212 var resp *http.Response 213 if !test.nilResp { 214 resp = &http.Response{ 215 StatusCode: test.statusCode, 216 Body: &test.fakeBody, 217 ContentLength: int64(len(test.bodyData)), 218 } 219 } 220 221 c := httpClient 222 defer func() { 223 httpClient = c 224 }() 225 httpClient = &fakeHTTP{ 226 httpDoError: test.doworkError, 227 resp: resp, 228 } 229 230 wi, err := NewPostLogsWorker() 231 assert.NoError(t, err) 232 233 w := wi.(worker) 234 235 err = config.PsrEnv.LoadFromEnv(w.GetEnvDescList()) 236 assert.NoError(t, err) 237 238 err = w.DoWork(config.CommonConfig{ 239 WorkerType: "Fake", 240 }, vzlog.DefaultLogger()) 241 if test.doworkError == nil && test.httpDoError == nil && test.httpReadError == nil { 242 assert.NoError(t, err) 243 } else { 244 assert.Error(t, err) 245 } 246 247 assert.Equal(t, int64(test.successCount), w.openSearchPostSuccessCountTotal.Val) 248 assert.Equal(t, int64(test.failureCount), w.openSearchPostFailureCountTotal.Val) 249 }) 250 } 251 } 252 253 func (f *fakeHTTP) Do(_ *http.Request) (resp *http.Response, err error) { 254 return f.resp, f.httpDoError 255 } 256 257 func (f fakeBody) ReadAll(d []byte) (n int, err error) { 258 if f.httpReadError != nil { 259 return 0, f.httpReadError 260 } 261 copy(d, f.bodyData) 262 return len(f.bodyData), nil 263 } 264 265 func (f fakeBody) Read(d []byte) (n int, err error) { 266 if f.httpReadError != nil { 267 return 0, f.httpReadError 268 } 269 copy(d, f.bodyData) 270 return len(f.bodyData), io.EOF 271 } 272 273 func (f fakeBody) Close() error { 274 return nil 275 }