f98e48f66e85ceb7c81328fb2294e141325dd7e9
[icn/sdwan.git] /
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright (c) 2020 Intel Corporation
3
4 package rtcontext
5
6 import (
7         "github.com/open-ness/EMCO/src/orchestrator/pkg/infra/contextdb"
8         pkgerrors "github.com/pkg/errors"
9         "strings"
10         "testing"
11 )
12
13 // MockContextDb for mocking contextdb
14 type MockContextDb struct {
15         Items map[string]interface{}
16         Err   error
17 }
18
19 // Put function
20 func (c *MockContextDb) Put(key string, val interface{}) error {
21         if c.Items == nil {
22                 c.Items = make(map[string]interface{})
23         }
24         c.Items[key] = val
25         return c.Err
26 }
27
28 // Get function
29 func (c *MockContextDb) Get(key string, val interface{}) error {
30         var s *string
31         s = val.(*string)
32         for kvKey, kvValue := range c.Items {
33                 if kvKey == key {
34                         *s = kvValue.(string)
35                         return c.Err
36                 }
37         }
38         return c.Err
39 }
40
41 // Delete function
42 func (c *MockContextDb) Delete(key string) error {
43         delete(c.Items, key)
44         return c.Err
45 }
46
47 // Delete all function
48 func (c *MockContextDb) DeleteAll(key string) error {
49         for kvKey := range c.Items {
50                 delete(c.Items, kvKey)
51         }
52         return c.Err
53 }
54
55 // GetAllKeys function
56 func (c *MockContextDb) GetAllKeys(path string) ([]string, error) {
57         var keys []string
58
59         for k := range c.Items {
60                 keys = append(keys, string(k))
61         }
62         return keys, c.Err
63 }
64
65 func (c *MockContextDb) HealthCheck() error {
66         return nil
67 }
68
69 func TestRtcInit(t *testing.T) {
70         var rtc = RunTimeContext{}
71         testCases := []struct {
72                 label         string
73                 mockContextDb *MockContextDb
74                 expectedError string
75         }{
76                 {
77                         label:         "Success case",
78                         mockContextDb: &MockContextDb{},
79                 },
80                 {
81                         label:         "Init returns error case",
82                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
83                         expectedError: "Error, context already initialized",
84                 },
85         }
86
87         for _, testCase := range testCases {
88                 t.Run(testCase.label, func(t *testing.T) {
89                         contextdb.Db = testCase.mockContextDb
90                         _, err := rtc.RtcInit()
91                         if err != nil {
92                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
93                                         t.Fatalf("Method returned an error (%s)", err)
94                                 }
95                         }
96
97                 })
98         }
99 }
100
101 func TestRtcLoad(t *testing.T) {
102         var rtc = RunTimeContext{"", ""}
103         testCases := []struct {
104                 label         string
105                 mockContextDb *MockContextDb
106                 id            string
107                 expectedError string
108         }{
109                 {
110                         label:         "Success case",
111                         id:            "5345674458787728",
112                         mockContextDb: &MockContextDb{},
113                 },
114                 {
115                         label:         "reinit returns error case",
116                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
117                         id:            "8885674458787728",
118                         expectedError: "Error finding the context id:",
119                 },
120         }
121
122         for _, testCase := range testCases {
123                 t.Run(testCase.label, func(t *testing.T) {
124                         contextdb.Db = testCase.mockContextDb
125                         _, err := rtc.RtcLoad("5345674458787728")
126                         if err != nil {
127                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
128                                         t.Fatalf("Method returned an error (%s)", err)
129                                 }
130                         }
131
132                 })
133         }
134 }
135
136 func TestRtcCreate(t *testing.T) {
137         var rtc = RunTimeContext{"/context/5345674458787728/", ""}
138         testCases := []struct {
139                 label         string
140                 mockContextDb *MockContextDb
141                 expectedError string
142         }{
143                 {
144                         label:         "Success case",
145                         mockContextDb: &MockContextDb{},
146                 },
147                 {
148                         label:         "Create returns error case",
149                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
150                         expectedError: "Error creating run time context:",
151                 },
152         }
153
154         for _, testCase := range testCases {
155                 t.Run(testCase.label, func(t *testing.T) {
156                         contextdb.Db = testCase.mockContextDb
157                         _, err := rtc.RtcCreate()
158                         if err != nil {
159                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
160                                         t.Fatalf("Method returned an error (%s)", err)
161                                 }
162                         }
163
164                 })
165         }
166 }
167
168 func TestRtcGet(t *testing.T) {
169         var rtc = RunTimeContext{"/context/5345674458787728/", ""}
170         testCases := []struct {
171                 label         string
172                 mockContextDb *MockContextDb
173                 expectedError string
174         }{
175                 {
176                         label:         "Success case",
177                         mockContextDb: &MockContextDb{},
178                 },
179                 {
180                         label:         "Get returns error case",
181                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
182                         expectedError: "Error getting run time context metadata:",
183                 },
184                 {
185                         label:         "Context handle does not match",
186                         mockContextDb: &MockContextDb{Err: nil},
187                         expectedError: "Error matching run time context metadata",
188                 },
189         }
190
191         for _, testCase := range testCases {
192                 t.Run(testCase.label, func(t *testing.T) {
193                         switch testCase.label {
194                         case "Success case":
195                                 contextdb.Db = testCase.mockContextDb
196                                 chandle, err := rtc.RtcCreate()
197                                 if err != nil {
198                                         t.Fatalf("Create returned an error (%s)", err)
199                                 }
200                                 ghandle, err := rtc.RtcGet()
201                                 if err != nil {
202                                         t.Fatalf("Get returned an error (%s)", err)
203                                 }
204                                 if chandle != ghandle {
205                                         t.Fatalf("Create and Get does not match")
206                                 }
207                         case "Get returns error case":
208                                 contextdb.Db = testCase.mockContextDb
209                                 _, err := rtc.RtcGet()
210                                 if err != nil {
211                                         if !strings.Contains(string(err.Error()), testCase.expectedError) {
212                                                 t.Fatalf("Method returned an error (%s)", err)
213                                         }
214                                 }
215                         case "Context handle does not match":
216                                 contextdb.Db = testCase.mockContextDb
217                                 contextdb.Db.Put("/context/5345674458787728/", "6345674458787728")
218                                 _, err := rtc.RtcGet()
219                                 if err != nil {
220                                         if !strings.Contains(string(err.Error()), testCase.expectedError) {
221                                                 t.Fatalf("Method returned an error (%s)", err)
222                                         }
223                                 }
224                         }
225                 })
226         }
227 }
228
229 func TestRtcAddLevel(t *testing.T) {
230         var rtc = RunTimeContext{"/context/3528435435454354/", ""}
231         testCases := []struct {
232                 label         string
233                 mockContextDb *MockContextDb
234                 handle        interface{}
235                 level         string
236                 value         string
237                 expectedError string
238         }{
239                 {
240                         label:         "Success case",
241                         mockContextDb: &MockContextDb{},
242                         handle:        "/context/3528435435454354/",
243                         level:         "app",
244                         value:         "testapp1",
245                 },
246                 {
247                         label:         "Not a valid rtc handle",
248                         mockContextDb: &MockContextDb{},
249                         handle:        "/context/9528435435454354/",
250                         level:         "app",
251                         value:         "testapp1",
252                         expectedError: "Not a valid run time context handle",
253                 },
254                 {
255                         label:         "Not a valid rtc level",
256                         mockContextDb: &MockContextDb{},
257                         handle:        "/context/3528435435454354/",
258                         level:         "",
259                         value:         "testapp1",
260                         expectedError: "Not a valid run time context level",
261                 },
262                 {
263                         label:         "Not a valid rtc value",
264                         mockContextDb: &MockContextDb{},
265                         handle:        "/context/3528435435454354/",
266                         level:         "app",
267                         value:         "",
268                         expectedError: "Not a valid run time context level value",
269                 },
270                 {
271                         label:         "Put returns error",
272                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
273                         handle:        "/context/3528435435454354/",
274                         level:         "app",
275                         value:         "testapp1",
276                         expectedError: "Error adding run time context level:",
277                 },
278         }
279
280         for _, testCase := range testCases {
281                 t.Run(testCase.label, func(t *testing.T) {
282                         contextdb.Db = testCase.mockContextDb
283                         _, err := rtc.RtcAddLevel(testCase.handle, testCase.level, testCase.value)
284                         if err != nil {
285                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
286                                         t.Fatalf("Method returned an error (%s)", err)
287                                 }
288                         }
289                 })
290         }
291 }
292
293 func TestRtcAddResource(t *testing.T) {
294         var rtc = RunTimeContext{"/context/3528435435454354/", ""}
295         testCases := []struct {
296                 label         string
297                 mockContextDb *MockContextDb
298                 handle        interface{}
299                 resname       string
300                 value         interface{}
301                 expectedError string
302         }{
303                 {
304                         label:         "Success case",
305                         mockContextDb: &MockContextDb{},
306                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
307                         resname:       "R1",
308                         value:         "res1",
309                 },
310                 {
311                         label:         "Not a valid rtc handle",
312                         mockContextDb: &MockContextDb{},
313                         handle:        "/context/9528435435454354/app/apptest1/cluster/cluster1/",
314                         resname:       "R1",
315                         value:         "res1",
316                         expectedError: "Not a valid run time context handle",
317                 },
318                 {
319                         label:         "Not a valid rtc resource name",
320                         mockContextDb: &MockContextDb{},
321                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
322                         resname:       "",
323                         value:         "res1",
324                         expectedError: "Not a valid run time context resource name",
325                 },
326                 {
327                         label:         "Not a valid rtc value",
328                         mockContextDb: &MockContextDb{},
329                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
330                         resname:       "R1",
331                         value:         nil,
332                         expectedError: "Not a valid run time context resource value",
333                 },
334                 {
335                         label:         "Put returns error",
336                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
337                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
338                         resname:       "R1",
339                         value:         "res1",
340                         expectedError: "Error adding run time context resource:",
341                 },
342         }
343
344         for _, testCase := range testCases {
345                 t.Run(testCase.label, func(t *testing.T) {
346                         contextdb.Db = testCase.mockContextDb
347                         _, err := rtc.RtcAddResource(testCase.handle, testCase.resname, testCase.value)
348                         if err != nil {
349                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
350                                         t.Fatalf("Method returned an error (%s)", err)
351                                 }
352                         }
353                 })
354         }
355 }
356
357 func TestRtcAddInstruction(t *testing.T) {
358         var rtc = RunTimeContext{"/context/3528435435454354/", ""}
359         testCases := []struct {
360                 label         string
361                 mockContextDb *MockContextDb
362                 handle        interface{}
363                 level         string
364                 insttype      string
365                 value         interface{}
366                 expectedError string
367         }{
368                 {
369                         label:         "Success case",
370                         mockContextDb: &MockContextDb{},
371                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
372                         level:         "resource",
373                         insttype:      "order",
374                         value:         "{resorder: [R3, R1, R2]}",
375                 },
376                 {
377                         label:         "Not a valid rtc handle",
378                         mockContextDb: &MockContextDb{},
379                         handle:        "/context/9528435435454354/app/apptest1/cluster/cluster1/",
380                         level:         "resource",
381                         insttype:      "order",
382                         value:         "{resorder: [R3, R1, R2]}",
383                         expectedError: "Not a valid run time context handle",
384                 },
385                 {
386                         label:         "Not a valid rtc level name",
387                         mockContextDb: &MockContextDb{},
388                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
389                         level:         "",
390                         insttype:      "order",
391                         value:         "{resorder: [R3, R1, R2]}",
392                         expectedError: "Not a valid run time context level",
393                 },
394                 {
395                         label:         "Not a valid rtc instruction type",
396                         mockContextDb: &MockContextDb{},
397                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
398                         level:         "resource",
399                         insttype:      "",
400                         value:         "{resorder: [R3, R1, R2]}",
401                         expectedError: "Not a valid run time context instruction type",
402                 },
403                 {
404                         label:         "Not a valid rtc value",
405                         mockContextDb: &MockContextDb{},
406                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
407                         level:         "resource",
408                         insttype:      "order",
409                         value:         nil,
410                         expectedError: "Not a valid run time context instruction value",
411                 },
412                 {
413                         label:         "Put returns error",
414                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Client not intialized")},
415                         handle:        "/context/3528435435454354/app/apptest1/cluster/cluster1/",
416                         level:         "resource",
417                         insttype:      "order",
418                         value:         "{resorder: [R3, R1, R2]}",
419                         expectedError: "Error adding run time context instruction:",
420                 },
421         }
422
423         for _, testCase := range testCases {
424                 t.Run(testCase.label, func(t *testing.T) {
425                         contextdb.Db = testCase.mockContextDb
426                         _, err := rtc.RtcAddInstruction(testCase.handle, testCase.level, testCase.insttype, testCase.value)
427                         if err != nil {
428                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
429                                         t.Fatalf("Method returned an error (%s)", err)
430                                 }
431                         }
432                 })
433         }
434 }
435
436 func TestRtcGetHandles(t *testing.T) {
437         var rtc = RunTimeContext{"/context/5345674458787728/", ""}
438         testCases := []struct {
439                 label         string
440                 mockContextDb *MockContextDb
441                 key           interface{}
442                 expectedError string
443         }{
444                 {
445                         label:         "Not valid input handle case",
446                         mockContextDb: &MockContextDb{},
447                         key:           "/context/3528435435454354/",
448                         expectedError: "Not a valid run time context handle",
449                 },
450                 {
451                         label:         "Contextdb call returns error case",
452                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
453                         key:           "/context/5345674458787728/",
454                         expectedError: "Error getting run time context handles:",
455                 },
456                 {
457                         label:         "Success case",
458                         mockContextDb: &MockContextDb{},
459                         key:           "/context/5345674458787728/",
460                 },
461         }
462
463         for _, testCase := range testCases {
464                 t.Run(testCase.label, func(t *testing.T) {
465                         contextdb.Db = testCase.mockContextDb
466                         if testCase.label == "Success case" {
467                                 contextdb.Db.Put("/context/5345674458787728/", 5345674458787728)
468                         }
469                         _, err := rtc.RtcGetHandles(testCase.key)
470                         if err != nil {
471                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
472                                         t.Fatalf("Method returned an error (%s)", err)
473                                 }
474                         }
475                 })
476         }
477 }
478
479 func TestRtcGetValue(t *testing.T) {
480         var rtc = RunTimeContext{"/context/5345674458787728/", ""}
481         testCases := []struct {
482                 label         string
483                 mockContextDb *MockContextDb
484                 key           interface{}
485                 expectedError string
486         }{
487                 {
488                         label:         "Not valid input handle case",
489                         mockContextDb: &MockContextDb{},
490                         key:           "/context/3528435435454354/",
491                         expectedError: "Not a valid run time context handle",
492                 },
493                 {
494                         label:         "Contextdb call returns error case",
495                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
496                         key:           "/context/5345674458787728/",
497                         expectedError: "Error getting run time context value:",
498                 },
499                 {
500                         label:         "Success case",
501                         mockContextDb: &MockContextDb{},
502                         key:           "/context/5345674458787728/",
503                 },
504         }
505
506         for _, testCase := range testCases {
507                 t.Run(testCase.label, func(t *testing.T) {
508                         contextdb.Db = testCase.mockContextDb
509                         if testCase.label == "Success case" {
510                                 contextdb.Db.Put("/context/5345674458787728/", "5345674458787728")
511                         }
512                         var val string
513                         err := rtc.RtcGetValue(testCase.key, &val)
514                         if err != nil {
515                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
516                                         t.Fatalf("Method returned an error (%s)", err)
517                                 }
518                         }
519                 })
520         }
521 }
522
523 func TestRtcUpdateValue(t *testing.T) {
524         var rtc = RunTimeContext{"/context/5345674458787728/", ""}
525         testCases := []struct {
526                 label         string
527                 mockContextDb *MockContextDb
528                 key           interface{}
529                 value         interface{}
530                 expectedError string
531         }{
532                 {
533                         label:         "Not valid input handle case",
534                         mockContextDb: &MockContextDb{},
535                         key:           "/context/3528435435454354/",
536                         value:         "{apporder: [app1, app2, app3]}",
537                         expectedError: "Not a valid run time context handle",
538                 },
539                 {
540                         label:         "Contextdb call returns error case",
541                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
542                         key:           "/context/5345674458787728/",
543                         value:         "{apporder: [app1, app2, app3]}",
544                         expectedError: "Error updating run time context value:",
545                 },
546                 {
547                         label:         "Success case",
548                         mockContextDb: &MockContextDb{},
549                         key:           "/context/5345674458787728/",
550                         value:         "{apporder: [app2, app3, app1]}",
551                 },
552         }
553
554         for _, testCase := range testCases {
555                 t.Run(testCase.label, func(t *testing.T) {
556                         contextdb.Db = testCase.mockContextDb
557                         if testCase.label == "Success case" {
558                                 contextdb.Db.Put("/context/5345674458787728/", "5345674458787728")
559                         }
560                         err := rtc.RtcUpdateValue(testCase.key, testCase.value)
561                         if err != nil {
562                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
563                                         t.Fatalf("Method returned an error (%s)", err)
564                                 }
565                         }
566                 })
567         }
568 }
569
570 func TestRtcDeletePair(t *testing.T) {
571         var rtc = RunTimeContext{"/context/5345674458787728/", ""}
572         testCases := []struct {
573                 label         string
574                 mockContextDb *MockContextDb
575                 key           interface{}
576                 expectedError string
577         }{
578                 {
579                         label:         "Not valid input handle case",
580                         mockContextDb: &MockContextDb{},
581                         key:           "/context/3528435435454354/",
582                         expectedError: "Not a valid run time context handle",
583                 },
584                 {
585                         label:         "Contextdb call returns error case",
586                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
587                         key:           "/context/5345674458787728/",
588                         expectedError: "Error deleting run time context pair:",
589                 },
590                 {
591                         label:         "Success case",
592                         mockContextDb: &MockContextDb{},
593                         key:           "/context/5345674458787728/",
594                 },
595         }
596
597         for _, testCase := range testCases {
598                 t.Run(testCase.label, func(t *testing.T) {
599                         contextdb.Db = testCase.mockContextDb
600                         err := rtc.RtcDeletePair(testCase.key)
601                         if err != nil {
602                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
603                                         t.Fatalf("Method returned an error (%s)", err)
604                                 }
605                         }
606                 })
607         }
608 }
609
610 func TestRtcDeletePrefix(t *testing.T) {
611         var rtc = RunTimeContext{"/context/5345674458787728/", ""}
612         testCases := []struct {
613                 label         string
614                 mockContextDb *MockContextDb
615                 key           interface{}
616                 expectedError string
617         }{
618                 {
619                         label:         "Not valid input handle case",
620                         mockContextDb: &MockContextDb{},
621                         key:           "/context/3528435435454354/",
622                         expectedError: "Not a valid run time context handle",
623                 },
624                 {
625                         label:         "Contextdb call returns error case",
626                         mockContextDb: &MockContextDb{Err: pkgerrors.Errorf("Key does not exist")},
627                         key:           "/context/5345674458787728/",
628                         expectedError: "Error deleting run time context with prefix:",
629                 },
630                 {
631                         label:         "Success case",
632                         mockContextDb: &MockContextDb{},
633                         key:           "/context/5345674458787728/",
634                 },
635         }
636
637         for _, testCase := range testCases {
638                 t.Run(testCase.label, func(t *testing.T) {
639                         contextdb.Db = testCase.mockContextDb
640                         err := rtc.RtcDeletePrefix(testCase.key)
641                         if err != nil {
642                                 if !strings.Contains(string(err.Error()), testCase.expectedError) {
643                                         t.Fatalf("Method returned an error (%s)", err)
644                                 }
645                         }
646                 })
647         }
648 }