1 package services
2
3 import (
4 "context"
5 "testing"
6
7 "github.com/DATA-DOG/go-sqlmock"
8 "github.com/lib/pq"
9 "github.com/stretchr/testify/assert"
10 "github.com/stretchr/testify/require"
11
12 "edge-infra.dev/pkg/edge/api/graph/model"
13 sqlquery "edge-infra.dev/pkg/edge/api/sql"
14 )
15
16 var (
17 clusterEdgeIDs = []string{"e4a10c8e-74b2-4b5e-b489-4019afe12b80", "e4a10c8e-74b2-4b5e-b489-4019afe12b81"}
18 logReplayIDs = []string{"6b8bd6f2-f6f8-41d8-ba3e-32aab9e61550", "6b8bd6f2-f6f8-41d8-ba3e-32aab9e61551"}
19
20 testFormattedStartTime = "2024-04-25T19:34:12Z"
21 testFormattedEndTime = "2024-04-25T23:34:12Z"
22 testFormattedUpdateTime = "2024-04-25T23:34:12Z"
23
24 testStartTime = "2024-04-25T15:34:12-04:00"
25 testEndTime = "2024-04-25T19:34:12-04:00"
26 testUpdateTime = "2024-04-25T23:34:12Z"
27
28 namespacesList = []string{"test-1", "test-2"}
29 longerNamespacesList = []string{"test-1", "test-2", "test-3"}
30 logLevels = []string{"DEBUG", "INFO", "NOTICE", "WARNING", "ERROR", "CRITICAL", "ALERT", "EMERGENCY"}
31 lrStatuses = []string{"NOT_STARTED", "PENDING", "SUCCEEDED", "FAILED", "TIMEOUT"}
32 lrjJSONPaths = []string{"$.status.active", "$.status.ready", "$.status.succeeded", "$.status.failed"}
33 lrjNames = []string{"lr-6b8bd6f2-f6f8-41d8-ba3e-32aab9e61550", "lr-6b8bd6f2-f6f8-41d8-ba3e-32aab9e61551"}
34
35 emptyString = ""
36 zeroValue = "0"
37 oneValue = "0"
38 defaultQueued = false
39 defaultExecuted = false
40
41 logReplayRowsUpdated = []string{"log_replay_id", "cluster_edge_id", "namespaces", "log_level", "start_time", "end_time", "queued", "executed", "status", "updated_at"}
42 logReplayJobs = []string{"jsonpath", "value", "missing", "name", "queued", "executed", "status", "updated_at", "log_replay_id"}
43 )
44
45 func TestGetLogReplay(t *testing.T) {
46 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
47 require.NoError(t, err)
48 defer db.Close()
49
50
51
52 mock.ExpectQuery(sqlquery.GetLogReplay).
53 WithArgs(logReplayIDs[0]).
54 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
55 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime))
56
57 service := NewLogReplayService(db)
58
59 logReplay, err := service.GetLogReplay(context.Background(), logReplayIDs[0])
60
61 assert.NoError(t, err)
62 assert.NotEmpty(t, logReplay)
63
64 assert.Equal(t, logReplayIDs[0], logReplay.LogReplayID)
65 assert.Equal(t, clusterEdgeIDs[0], logReplay.ClusterEdgeID)
66 assert.ElementsMatch(t, namespacesList, logReplay.Namespaces)
67 assert.Equal(t, logLevels[0], logReplay.LogLevel)
68 assert.Equal(t, testFormattedStartTime, logReplay.StartTime)
69 assert.Equal(t, testFormattedEndTime, logReplay.EndTime)
70 assert.False(t, logReplay.Queued)
71 assert.False(t, logReplay.Executed)
72 assert.Equal(t, lrStatuses[0], logReplay.Status)
73 }
74
75 func TestGetLogReplays(t *testing.T) {
76 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
77 require.NoError(t, err)
78 defer db.Close()
79
80 mock.ExpectQuery(sqlquery.GetLogReplays).
81 WithArgs(clusterEdgeIDs[0]).
82 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
83 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(&namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime).
84 AddRow(logReplayIDs[1], clusterEdgeIDs[0], pq.Array(&namespacesList), logLevels[1], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime))
85
86 service := NewLogReplayService(db)
87
88 logReplays, err := service.GetLogReplays(context.Background(), clusterEdgeIDs[0], nil)
89
90 assert.NoError(t, err)
91 assert.NotEmpty(t, logReplays)
92
93 for i := range logReplays {
94 assert.Equal(t, logReplayIDs[i], logReplays[i].LogReplayID)
95 assert.Equal(t, clusterEdgeIDs[0], logReplays[i].ClusterEdgeID)
96 assert.ElementsMatch(t, namespacesList, logReplays[i].Namespaces)
97 assert.Equal(t, logLevels[i], logReplays[i].LogLevel)
98 assert.Equal(t, testFormattedStartTime, logReplays[i].StartTime)
99 assert.Equal(t, testFormattedEndTime, logReplays[i].EndTime)
100 assert.False(t, logReplays[i].Queued)
101 assert.False(t, logReplays[i].Executed)
102 assert.Equal(t, lrStatuses[i], logReplays[i].Status)
103 }
104 }
105
106 func TestGetLogReplaysNotExecuted(t *testing.T) {
107 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
108 require.NoError(t, err)
109 defer db.Close()
110
111 mock.ExpectQuery(sqlquery.GetLogReplaysNotExecuted).
112 WithArgs(clusterEdgeIDs[0]).
113 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
114 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(&namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime).
115 AddRow(logReplayIDs[1], clusterEdgeIDs[0], pq.Array(&namespacesList), logLevels[1], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime))
116
117 service := NewLogReplayService(db)
118
119 logReplays, err := service.GetLogReplays(context.Background(), clusterEdgeIDs[0], &trueValue)
120
121 assert.NoError(t, err)
122 assert.NotEmpty(t, logReplays)
123
124 for i := range logReplays {
125 assert.Equal(t, logReplayIDs[i], logReplays[i].LogReplayID)
126 assert.Equal(t, clusterEdgeIDs[0], logReplays[i].ClusterEdgeID)
127 assert.ElementsMatch(t, namespacesList, logReplays[i].Namespaces)
128 assert.Equal(t, logLevels[i], logReplays[i].LogLevel)
129 assert.Equal(t, testFormattedStartTime, logReplays[i].StartTime)
130 assert.Equal(t, testFormattedEndTime, logReplays[i].EndTime)
131 assert.False(t, logReplays[i].Queued)
132 assert.False(t, logReplays[i].Executed)
133 assert.Equal(t, lrStatuses[i], logReplays[i].Status)
134 assert.Equal(t, testFormattedUpdateTime, logReplays[i].UpdatedAt)
135 }
136 }
137 func TestGetLogReplayJobs(t *testing.T) {
138 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
139 require.NoError(t, err)
140 defer db.Close()
141
142 testCases := []struct {
143 name string
144 clusterEdgeID string
145 mocksQuery func() []*sqlmock.ExpectedQuery
146 expectedLogReplayJobs []*model.LogReplayJob
147 expectedErr string
148 }{
149 {
150 name: "Test 1 - 1 LogReplayJob",
151 clusterEdgeID: clusterEdgeIDs[0],
152 mocksQuery: func() []*sqlmock.ExpectedQuery {
153 return []*sqlmock.ExpectedQuery{
154 mock.ExpectQuery(sqlquery.GetLogReplayJobs).
155 WithArgs(clusterEdgeIDs[0]).
156 WillReturnRows(mock.NewRows(logReplayJobs).
157 AddRow(lrjJSONPaths[0], emptyString, true, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0]).
158 AddRow(lrjJSONPaths[1], oneValue, false, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0]).
159 AddRow(lrjJSONPaths[2], zeroValue, false, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0]).
160 AddRow(lrjJSONPaths[3], emptyString, true, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0])),
161 }
162 },
163 expectedLogReplayJobs: []*model.LogReplayJob{
164 {
165 Jsonpath: lrjJSONPaths[0],
166 Value: emptyString,
167 Missing: true,
168 Name: lrjNames[0],
169 Queued: defaultQueued,
170 Executed: defaultExecuted,
171 Status: lrStatuses[1],
172 UpdatedAt: testFormattedUpdateTime,
173 LogReplayID: logReplayIDs[0],
174 },
175 {
176 Jsonpath: lrjJSONPaths[1],
177 Value: oneValue,
178 Missing: false,
179 Name: lrjNames[0],
180 Queued: defaultQueued,
181 Executed: defaultExecuted,
182 Status: lrStatuses[1],
183 UpdatedAt: testFormattedUpdateTime,
184 LogReplayID: logReplayIDs[0],
185 },
186 {
187 Jsonpath: lrjJSONPaths[2],
188 Value: zeroValue,
189 Missing: false,
190 Name: lrjNames[0],
191 Queued: defaultQueued,
192 Executed: defaultExecuted,
193 Status: lrStatuses[1],
194 UpdatedAt: testFormattedUpdateTime,
195 LogReplayID: logReplayIDs[0],
196 },
197 {
198 Jsonpath: lrjJSONPaths[3],
199 Value: emptyString,
200 Missing: true,
201 Name: lrjNames[0],
202 Queued: defaultQueued,
203 Executed: defaultExecuted,
204 Status: lrStatuses[1],
205 UpdatedAt: testFormattedUpdateTime,
206 LogReplayID: logReplayIDs[0],
207 },
208 },
209 expectedErr: "",
210 },
211 {
212 name: "Test 2 - 2 LogReplayJob",
213 clusterEdgeID: clusterEdgeIDs[0],
214 mocksQuery: func() []*sqlmock.ExpectedQuery {
215 return []*sqlmock.ExpectedQuery{
216 mock.ExpectQuery(sqlquery.GetLogReplayJobs).
217 WithArgs(clusterEdgeIDs[0]).
218 WillReturnRows(mock.NewRows(logReplayJobs).
219 AddRow(lrjJSONPaths[0], emptyString, true, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0]).
220 AddRow(lrjJSONPaths[1], oneValue, false, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0]).
221 AddRow(lrjJSONPaths[2], zeroValue, false, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0]).
222 AddRow(lrjJSONPaths[3], emptyString, true, lrjNames[0], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[0]).
223 AddRow(lrjJSONPaths[0], emptyString, true, lrjNames[1], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[1]).
224 AddRow(lrjJSONPaths[1], emptyString, true, lrjNames[1], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[1]).
225 AddRow(lrjJSONPaths[2], emptyString, true, lrjNames[1], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[1]).
226 AddRow(lrjJSONPaths[3], oneValue, false, lrjNames[1], defaultQueued, defaultExecuted, lrStatuses[1], testUpdateTime, logReplayIDs[1])),
227 }
228 },
229 expectedLogReplayJobs: []*model.LogReplayJob{
230 {
231 Jsonpath: lrjJSONPaths[0],
232 Value: emptyString,
233 Missing: true,
234 Name: lrjNames[0],
235 Queued: defaultQueued,
236 Executed: defaultExecuted,
237 Status: lrStatuses[1],
238 UpdatedAt: testFormattedUpdateTime,
239 LogReplayID: logReplayIDs[0],
240 },
241 {
242 Jsonpath: lrjJSONPaths[1],
243 Value: oneValue,
244 Missing: false,
245 Name: lrjNames[0],
246 Queued: defaultQueued,
247 Executed: defaultExecuted,
248 Status: lrStatuses[1],
249 UpdatedAt: testFormattedUpdateTime,
250 LogReplayID: logReplayIDs[0],
251 },
252 {
253 Jsonpath: lrjJSONPaths[2],
254 Value: zeroValue,
255 Missing: false,
256 Name: lrjNames[0],
257 Queued: defaultQueued,
258 Executed: defaultExecuted,
259 Status: lrStatuses[1],
260 UpdatedAt: testFormattedUpdateTime,
261 LogReplayID: logReplayIDs[0],
262 },
263 {
264 Jsonpath: lrjJSONPaths[3],
265 Value: emptyString,
266 Missing: true,
267 Name: lrjNames[0],
268 Queued: defaultQueued,
269 Executed: defaultExecuted,
270 Status: lrStatuses[1],
271 UpdatedAt: testFormattedUpdateTime,
272 LogReplayID: logReplayIDs[0],
273 },
274 {
275 Jsonpath: lrjJSONPaths[0],
276 Value: emptyString,
277 Missing: true,
278 Name: lrjNames[1],
279 Queued: defaultQueued,
280 Executed: defaultExecuted,
281 Status: lrStatuses[1],
282 UpdatedAt: testFormattedUpdateTime,
283 LogReplayID: logReplayIDs[1],
284 },
285 {
286 Jsonpath: lrjJSONPaths[1],
287 Value: emptyString,
288 Missing: true,
289 Name: lrjNames[1],
290 Queued: defaultQueued,
291 Executed: defaultExecuted,
292 Status: lrStatuses[1],
293 UpdatedAt: testFormattedUpdateTime,
294 LogReplayID: logReplayIDs[1],
295 },
296 {
297 Jsonpath: lrjJSONPaths[2],
298 Value: emptyString,
299 Missing: true,
300 Name: lrjNames[1],
301 Queued: defaultQueued,
302 Executed: defaultExecuted,
303 Status: lrStatuses[1],
304 UpdatedAt: testFormattedUpdateTime,
305 LogReplayID: logReplayIDs[1],
306 },
307 {
308 Jsonpath: lrjJSONPaths[3],
309 Value: oneValue,
310 Missing: false,
311 Name: lrjNames[1],
312 Queued: defaultQueued,
313 Executed: defaultExecuted,
314 Status: lrStatuses[1],
315 UpdatedAt: testFormattedUpdateTime,
316 LogReplayID: logReplayIDs[1],
317 },
318 },
319 expectedErr: "",
320 },
321 }
322
323 service := NewLogReplayService(db)
324
325 for _, test := range testCases {
326 test.mocksQuery()
327
328 t.Run(test.name, func(t *testing.T) {
329 logReplayJobs, err := service.GetLogReplayJobs(context.Background(), clusterEdgeIDs[0])
330
331 assert.NoError(t, err)
332 assert.NotEmpty(t, logReplayJobs)
333
334 for index, item := range logReplayJobs {
335 assert.Equal(t, test.expectedLogReplayJobs[index].Jsonpath, item.Jsonpath)
336 assert.Equal(t, test.expectedLogReplayJobs[index].Value, item.Value)
337 assert.Equal(t, test.expectedLogReplayJobs[index].Name, item.Name)
338 assert.Equal(t, test.expectedLogReplayJobs[index].Status, item.Status)
339 assert.Equal(t, test.expectedLogReplayJobs[index].UpdatedAt, item.UpdatedAt)
340 assert.Equal(t, test.expectedLogReplayJobs[index].LogReplayID, item.LogReplayID)
341 }
342 })
343 }
344 }
345
346 func TestDeleteLogReplay(t *testing.T) {
347 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
348 require.NoError(t, err)
349 defer db.Close()
350
351 mock.ExpectExec(sqlquery.DeleteLogReplay).WithArgs(logReplayIDs[0]).
352 WillReturnResult(sqlmock.NewResult(1, 1))
353
354 service := NewLogReplayService(db)
355
356 if deleted, err := service.DeleteLogReplay(context.Background(), logReplayIDs[0]); !deleted && err != nil {
357 t.Errorf("error was not expected while deleting log replay: %s", err)
358 }
359 }
360
361 func TestCreateLogReplay(t *testing.T) {
362 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
363 require.NoError(t, err)
364 defer db.Close()
365
366 testCases := []struct {
367 name string
368 clusterEdgeID string
369 payload *model.CreateLogReplayPayload
370 mocksExec func() []*sqlmock.ExpectedExec
371 expectedErr string
372 }{
373 {
374 name: "Test 1 - Log Level DEBUG Passed In",
375 clusterEdgeID: clusterEdgeIDs[0],
376 payload: &model.CreateLogReplayPayload{
377 Namespaces: namespacesList,
378 StartTime: testFormattedStartTime,
379 EndTime: testFormattedEndTime,
380 LogLevel: model.AllLogLevels[0],
381 },
382 mocksExec: func() []*sqlmock.ExpectedExec {
383 return []*sqlmock.ExpectedExec{
384 mock.ExpectExec(sqlquery.CreateLogReplay).
385 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
386 WillReturnResult(sqlmock.NewResult(1, 1))}
387 },
388 expectedErr: "",
389 },
390 {
391 name: "Test 2 - Log Level INFO Passed In",
392 clusterEdgeID: clusterEdgeIDs[0],
393 payload: &model.CreateLogReplayPayload{
394 Namespaces: namespacesList,
395 StartTime: testFormattedStartTime,
396 EndTime: testFormattedEndTime,
397 LogLevel: model.AllLogLevels[1],
398 },
399 mocksExec: func() []*sqlmock.ExpectedExec {
400 return []*sqlmock.ExpectedExec{
401 mock.ExpectExec(sqlquery.CreateLogReplay).
402 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[1], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
403 WillReturnResult(sqlmock.NewResult(1, 1))}
404 },
405 expectedErr: "",
406 },
407 {
408 name: "Test 3 - Log Level NOTICE Passed In",
409 clusterEdgeID: clusterEdgeIDs[0],
410 payload: &model.CreateLogReplayPayload{
411 Namespaces: namespacesList,
412 StartTime: testFormattedStartTime,
413 EndTime: testFormattedEndTime,
414 LogLevel: model.AllLogLevels[2],
415 },
416 mocksExec: func() []*sqlmock.ExpectedExec {
417 return []*sqlmock.ExpectedExec{
418 mock.ExpectExec(sqlquery.CreateLogReplay).
419 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[2], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
420 WillReturnResult(sqlmock.NewResult(1, 1))}
421 },
422 expectedErr: "",
423 },
424 {
425 name: "Test 4 - Log Level WARNING Passed In",
426 clusterEdgeID: clusterEdgeIDs[0],
427 payload: &model.CreateLogReplayPayload{
428 Namespaces: namespacesList,
429 StartTime: testFormattedStartTime,
430 EndTime: testFormattedEndTime,
431 LogLevel: model.AllLogLevels[3],
432 },
433 mocksExec: func() []*sqlmock.ExpectedExec {
434 return []*sqlmock.ExpectedExec{
435 mock.ExpectExec(sqlquery.CreateLogReplay).
436 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[3], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
437 WillReturnResult(sqlmock.NewResult(1, 1))}
438 },
439 expectedErr: "",
440 },
441 {
442 name: "Test 5 - Log Level ERROR Passed In",
443 clusterEdgeID: clusterEdgeIDs[0],
444 payload: &model.CreateLogReplayPayload{
445 Namespaces: namespacesList,
446 StartTime: testFormattedStartTime,
447 EndTime: testFormattedEndTime,
448 LogLevel: model.AllLogLevels[4],
449 },
450 mocksExec: func() []*sqlmock.ExpectedExec {
451 return []*sqlmock.ExpectedExec{
452 mock.ExpectExec(sqlquery.CreateLogReplay).
453 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[4], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
454 WillReturnResult(sqlmock.NewResult(1, 1))}
455 },
456 expectedErr: "",
457 },
458 {
459 name: "Test 6 - Log Level CRITICAL Passed In",
460 clusterEdgeID: clusterEdgeIDs[0],
461 payload: &model.CreateLogReplayPayload{
462 Namespaces: namespacesList,
463 StartTime: testFormattedStartTime,
464 EndTime: testFormattedEndTime,
465 LogLevel: model.AllLogLevels[5],
466 },
467 mocksExec: func() []*sqlmock.ExpectedExec {
468 return []*sqlmock.ExpectedExec{
469 mock.ExpectExec(sqlquery.CreateLogReplay).
470 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[5], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
471 WillReturnResult(sqlmock.NewResult(1, 1))}
472 },
473 expectedErr: "",
474 },
475 {
476 name: "Test 7 - Log Level ALERT Passed In",
477 clusterEdgeID: clusterEdgeIDs[0],
478 payload: &model.CreateLogReplayPayload{
479 Namespaces: namespacesList,
480 StartTime: testFormattedStartTime,
481 EndTime: testFormattedEndTime,
482 LogLevel: model.AllLogLevels[6],
483 },
484 mocksExec: func() []*sqlmock.ExpectedExec {
485 return []*sqlmock.ExpectedExec{
486 mock.ExpectExec(sqlquery.CreateLogReplay).
487 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[6], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
488 WillReturnResult(sqlmock.NewResult(1, 1))}
489 },
490 expectedErr: "",
491 },
492 {
493 name: "Test 8 - Log Level EMERGENCY Passed In",
494 clusterEdgeID: clusterEdgeIDs[0],
495 payload: &model.CreateLogReplayPayload{
496 Namespaces: namespacesList,
497 StartTime: testFormattedStartTime,
498 EndTime: testFormattedEndTime,
499 LogLevel: model.AllLogLevels[7],
500 },
501 mocksExec: func() []*sqlmock.ExpectedExec {
502 return []*sqlmock.ExpectedExec{
503 mock.ExpectExec(sqlquery.CreateLogReplay).
504 WithArgs(clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[7], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
505 WillReturnResult(sqlmock.NewResult(1, 1))}
506 },
507 expectedErr: "",
508 },
509 {
510 name: "Test 9 - Incorrect Start Time Format",
511 clusterEdgeID: clusterEdgeIDs[0],
512 payload: &model.CreateLogReplayPayload{
513 Namespaces: namespacesList,
514 StartTime: "2024-04-25T15:34:12.101Z",
515 EndTime: testFormattedEndTime,
516 LogLevel: model.AllLogLevels[0],
517 },
518 expectedErr: "error validating ",
519 },
520 {
521 name: "Test 10 - Incorrect End Time Format",
522 clusterEdgeID: clusterEdgeIDs[0],
523 payload: &model.CreateLogReplayPayload{
524 Namespaces: namespacesList,
525 StartTime: testFormattedStartTime,
526 EndTime: "2024-04-25T15:34:12.101Z",
527 LogLevel: model.AllLogLevels[0],
528 },
529 expectedErr: "error validating ",
530 },
531 {
532 name: "Test 11 - Longer Namespaces List Passed In",
533 clusterEdgeID: clusterEdgeIDs[0],
534 payload: &model.CreateLogReplayPayload{
535 Namespaces: longerNamespacesList,
536 StartTime: testFormattedStartTime,
537 EndTime: testFormattedEndTime,
538 LogLevel: model.AllLogLevels[0],
539 },
540 mocksExec: func() []*sqlmock.ExpectedExec {
541 return []*sqlmock.ExpectedExec{
542 mock.ExpectExec(sqlquery.CreateLogReplay).
543 WithArgs(clusterEdgeIDs[0], pq.Array(longerNamespacesList), logLevels[0], testFormattedStartTime, testFormattedEndTime, defaultQueued, defaultExecuted, lrStatuses[0]).
544 WillReturnResult(sqlmock.NewResult(1, 1))}
545 },
546 expectedErr: "",
547 },
548 }
549
550 service := NewLogReplayService(db)
551
552 for _, test := range testCases {
553 if test.expectedErr == "" {
554 test.mocksExec()
555
556 t.Run(test.name, func(t *testing.T) {
557 result, err := service.CreateLogReplay(context.Background(), test.clusterEdgeID, *test.payload)
558 assert.NoError(t, err)
559 assert.True(t, result)
560 })
561 } else {
562 t.Run(test.name, func(t *testing.T) {
563 result, err := service.CreateLogReplay(context.Background(), test.clusterEdgeID, *test.payload)
564 assert.ErrorContains(t, err, test.expectedErr)
565 assert.False(t, result)
566 })
567 }
568 }
569 }
570
571 func TestUpdateLogReplay(t *testing.T) {
572 db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))
573 require.NoError(t, err)
574 defer db.Close()
575
576 testCases := []struct {
577 name string
578 logReplayID string
579 clusterEdgeID string
580 payload *model.UpdateLogReplayPayload
581 mocksQuery func() []*sqlmock.ExpectedQuery
582 mocksExec func() []*sqlmock.ExpectedExec
583 expectedErr string
584 }{
585 {
586 name: "Test 1 - Only Queued Passed IN",
587 logReplayID: logReplayIDs[0],
588 clusterEdgeID: clusterEdgeIDs[0],
589 payload: &model.UpdateLogReplayPayload{
590 Queued: &trueValue,
591 },
592 mocksQuery: func() []*sqlmock.ExpectedQuery {
593 return []*sqlmock.ExpectedQuery{
594 mock.ExpectQuery(sqlquery.GetLogReplay).
595 WithArgs(logReplayIDs[0]).
596 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
597 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
598 }
599 },
600 mocksExec: func() []*sqlmock.ExpectedExec {
601 return []*sqlmock.ExpectedExec{
602 mock.ExpectExec(sqlquery.UpdateLogReplay).
603 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], true, false, lrStatuses[0]).
604 WillReturnResult(sqlmock.NewResult(1, 1))}
605 },
606 expectedErr: "",
607 },
608 {
609 name: "Test 2 - Only executed Passed IN",
610 logReplayID: logReplayIDs[0],
611 clusterEdgeID: clusterEdgeIDs[0],
612 payload: &model.UpdateLogReplayPayload{
613 Executed: &trueValue,
614 },
615 mocksQuery: func() []*sqlmock.ExpectedQuery {
616 return []*sqlmock.ExpectedQuery{
617 mock.ExpectQuery(sqlquery.GetLogReplay).
618 WithArgs(logReplayIDs[0]).
619 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
620 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
621 }
622 },
623 mocksExec: func() []*sqlmock.ExpectedExec {
624 return []*sqlmock.ExpectedExec{
625 mock.ExpectExec(sqlquery.UpdateLogReplay).
626 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], false, true, lrStatuses[0]).
627 WillReturnResult(sqlmock.NewResult(1, 1))}
628 },
629 expectedErr: "",
630 },
631 {
632 name: "Test 3 - Only Status Passed IN: PENDING",
633 logReplayID: logReplayIDs[0],
634 clusterEdgeID: clusterEdgeIDs[0],
635 payload: &model.UpdateLogReplayPayload{
636 Status: &model.AllLogReplayStatus[1],
637 },
638 mocksQuery: func() []*sqlmock.ExpectedQuery {
639 return []*sqlmock.ExpectedQuery{
640 mock.ExpectQuery(sqlquery.GetLogReplay).
641 WithArgs(logReplayIDs[0]).
642 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
643 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
644 }
645 },
646 mocksExec: func() []*sqlmock.ExpectedExec {
647 return []*sqlmock.ExpectedExec{
648 mock.ExpectExec(sqlquery.UpdateLogReplay).
649 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], false, false, lrStatuses[1]).
650 WillReturnResult(sqlmock.NewResult(1, 1))}
651 },
652 expectedErr: "",
653 },
654 {
655 name: "Test 4 - Only Status Passed IN: SUCCEEDED",
656 logReplayID: logReplayIDs[0],
657 clusterEdgeID: clusterEdgeIDs[0],
658 payload: &model.UpdateLogReplayPayload{
659 Status: &model.AllLogReplayStatus[2],
660 },
661 mocksQuery: func() []*sqlmock.ExpectedQuery {
662 return []*sqlmock.ExpectedQuery{
663 mock.ExpectQuery(sqlquery.GetLogReplay).
664 WithArgs(logReplayIDs[0]).
665 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
666 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
667 }
668 },
669 mocksExec: func() []*sqlmock.ExpectedExec {
670 return []*sqlmock.ExpectedExec{
671 mock.ExpectExec(sqlquery.UpdateLogReplay).
672 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], false, false, lrStatuses[2]).
673 WillReturnResult(sqlmock.NewResult(1, 1))}
674 },
675 expectedErr: "",
676 },
677 {
678 name: "Test 5 - Only Status Passed IN: SUCCEEDED",
679 logReplayID: logReplayIDs[0],
680 clusterEdgeID: clusterEdgeIDs[0],
681 payload: &model.UpdateLogReplayPayload{
682 Status: &model.AllLogReplayStatus[2],
683 },
684 mocksQuery: func() []*sqlmock.ExpectedQuery {
685 return []*sqlmock.ExpectedQuery{
686 mock.ExpectQuery(sqlquery.GetLogReplay).
687 WithArgs(logReplayIDs[0]).
688 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
689 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
690 }
691 },
692 mocksExec: func() []*sqlmock.ExpectedExec {
693 return []*sqlmock.ExpectedExec{
694 mock.ExpectExec(sqlquery.UpdateLogReplay).
695 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], false, false, lrStatuses[2]).
696 WillReturnResult(sqlmock.NewResult(1, 1))}
697 },
698 expectedErr: "",
699 },
700 {
701 name: "Test 6 - Only Status Passed IN: FAILED",
702 logReplayID: logReplayIDs[0],
703 clusterEdgeID: clusterEdgeIDs[0],
704 payload: &model.UpdateLogReplayPayload{
705 Status: &model.AllLogReplayStatus[3],
706 },
707 mocksQuery: func() []*sqlmock.ExpectedQuery {
708 return []*sqlmock.ExpectedQuery{
709 mock.ExpectQuery(sqlquery.GetLogReplay).
710 WithArgs(logReplayIDs[0]).
711 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
712 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
713 }
714 },
715 mocksExec: func() []*sqlmock.ExpectedExec {
716 return []*sqlmock.ExpectedExec{
717 mock.ExpectExec(sqlquery.UpdateLogReplay).
718 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], false, false, lrStatuses[3]).
719 WillReturnResult(sqlmock.NewResult(1, 1))}
720 },
721 expectedErr: "",
722 },
723 {
724 name: "Test 7 - Only Status Passed IN: TIMEOUT",
725 logReplayID: logReplayIDs[0],
726 clusterEdgeID: clusterEdgeIDs[0],
727 payload: &model.UpdateLogReplayPayload{
728 Status: &model.AllLogReplayStatus[4],
729 },
730 mocksQuery: func() []*sqlmock.ExpectedQuery {
731 return []*sqlmock.ExpectedQuery{
732 mock.ExpectQuery(sqlquery.GetLogReplay).
733 WithArgs(logReplayIDs[0]).
734 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
735 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
736 }
737 },
738 mocksExec: func() []*sqlmock.ExpectedExec {
739 return []*sqlmock.ExpectedExec{
740 mock.ExpectExec(sqlquery.UpdateLogReplay).
741 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], false, false, lrStatuses[4]).
742 WillReturnResult(sqlmock.NewResult(1, 1))}
743 },
744 expectedErr: "",
745 },
746
747 {
748 name: "Test 8 - Only Executed and Status (SUCCEEDED)",
749 logReplayID: logReplayIDs[0],
750 clusterEdgeID: clusterEdgeIDs[0],
751 payload: &model.UpdateLogReplayPayload{
752 Executed: &trueValue,
753 Status: &model.AllLogReplayStatus[2],
754 },
755 mocksQuery: func() []*sqlmock.ExpectedQuery {
756 return []*sqlmock.ExpectedQuery{
757 mock.ExpectQuery(sqlquery.GetLogReplay).
758 WithArgs(logReplayIDs[0]).
759 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
760 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
761 }
762 },
763 mocksExec: func() []*sqlmock.ExpectedExec {
764 return []*sqlmock.ExpectedExec{
765 mock.ExpectExec(sqlquery.UpdateLogReplay).
766 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], false, true, lrStatuses[2]).
767 WillReturnResult(sqlmock.NewResult(1, 1))}
768 },
769 expectedErr: "",
770 },
771
772 {
773 name: "Test 9 - Only QUEUED and Status (PENDING)",
774 logReplayID: logReplayIDs[0],
775 clusterEdgeID: clusterEdgeIDs[0],
776 payload: &model.UpdateLogReplayPayload{
777 Queued: &trueValue,
778 Status: &model.AllLogReplayStatus[1],
779 },
780 mocksQuery: func() []*sqlmock.ExpectedQuery {
781 return []*sqlmock.ExpectedQuery{
782 mock.ExpectQuery(sqlquery.GetLogReplay).
783 WithArgs(logReplayIDs[0]).
784 WillReturnRows(mock.NewRows(logReplayRowsUpdated).
785 AddRow(logReplayIDs[0], clusterEdgeIDs[0], pq.Array(namespacesList), logLevels[0], testStartTime, testEndTime, defaultQueued, defaultExecuted, lrStatuses[0], testUpdateTime)),
786 }
787 },
788 mocksExec: func() []*sqlmock.ExpectedExec {
789 return []*sqlmock.ExpectedExec{
790 mock.ExpectExec(sqlquery.UpdateLogReplay).
791 WithArgs(logReplayIDs[0], clusterEdgeIDs[0], true, false, lrStatuses[1]).
792 WillReturnResult(sqlmock.NewResult(1, 1))}
793 },
794 expectedErr: "",
795 },
796 }
797
798 service := NewLogReplayService(db)
799
800 for _, test := range testCases {
801 t.Run(test.name, func(t *testing.T) {
802 test.mocksQuery()
803 test.mocksExec()
804 result, err := service.UpdateLogReplay(context.Background(), logReplayIDs[0], test.clusterEdgeID, *test.payload)
805 assert.NoError(t, err)
806 assert.True(t, result)
807 })
808 }
809 }
810
View as plain text