Enabling helm3 Support for appmgr.
[ric-plt/appmgr.git] / pkg / helm / helm_test.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package helm
21
22 import (
23         "errors"
24         "github.com/spf13/viper"
25         "os"
26         "reflect"
27         "strconv"
28         "strings"
29         "testing"
30         "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/cm"
31         "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/appmgr"
32         "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/models"
33         "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/util"
34 )
35
36 var caughtKubeExecArgs string
37 var kubeExecRetOut string
38 var kubeExecRetErr error
39 var caughtHelmExecArgs string
40 var helmExecRetOut string
41 var helmExecRetErr error
42 var helmStatusOutput = `
43 LAST DEPLOYED: Sat Mar  9 06:50:45 2019
44 NAMESPACE: default
45 STATUS: DEPLOYED
46
47 RESOURCES:
48 ==> v1/Pod(related)
49 NAME                        READY  STATUS   RESTARTS  AGE
50 dummy-xapp-8984fc9fd-bkcbp  1/1    Running  0         55m
51 dummy-xapp-8984fc9fd-l6xch  1/1    Running  0         55m
52 dummy-xapp-8984fc9fd-pp4hg  1/1    Running  0         55m
53
54 ==> v1/Service
55 NAME                         TYPE       CLUSTER-IP      EXTERNAL-IP  PORT(S)  AGE
56 dummy-xapp-dummy-xapp-chart  ClusterIP  10.102.184.212  <none>       80/TCP   55m
57
58 ==> v1beta1/Deployment
59 NAME        READY  UP-TO-DATE  AVAILABLE  AGE
60 dummy-xapp  3/3    3           3          55m
61 `
62
63 var helListAllOutput = `Next: ""
64 Releases:
65 - AppVersion: "1.0"
66   Chart: dummy-xapp-chart-0.1.0
67   Name: dummy-xapp
68   Namespace: default
69   Revision: 1
70   Status: DEPLOYED
71   Updated: Mon Mar 11 06:55:05 2019
72 - AppVersion: "2.0"
73   Chart: dummy-xapp-chart-0.1.0
74   Name: dummy-xapp2
75   Namespace: default
76   Revision: 1
77   Status: DEPLOYED
78   Updated: Mon Mar 11 06:55:05 2019
79 - AppVersion: "1.0"
80   Chart: appmgr-0.0.1
81   Name: appmgr
82   Namespace: default
83   Revision: 1
84   Status: DEPLOYED
85   Updated: Sun Mar 24 07:17:00 2019
86   `
87
88 var helListOutput = `Next: ""
89 Releases:
90 - AppVersion: "1.0"
91   Chart: dummy-xapp-chart-0.1.0
92   Name: dummy-xapp
93   Namespace: default
94   Revision: 1
95   Status: DEPLOYED
96   Updated: Mon Mar 11 06:55:05 2019
97   `
98
99 var kubeServiceOutput = `{
100     "apiVersion": "v1",
101     "kind": "Service",
102     "metadata": {
103         "creationTimestamp": "2020-03-31T12:27:12Z",
104         "labels": {
105             "app": "ricxapp-dummy-xapp",
106             "chart": "dummy-xapp-0.0.4",
107             "heritage": "Tiller",
108             "release": "dummy-xapp"
109         },
110         "name": "service-ricxapp-dummy-xapp-rmr",
111         "namespace": "ricxapp",
112         "resourceVersion": "4423380",
113         "selfLink": "/api/v1/namespaces/ricxapp/services/service-ricxapp-dummy-xapp-rmr",
114         "uid": "2254b77d-7dd6-43e0-beff-3e2a7b24c89a"
115     },
116     "spec": {
117         "clusterIP": "10.98.239.107",
118         "ports": [
119             {
120                 "name": "rmrdata",
121                 "port": 4560,
122                 "protocol": "TCP",
123                 "targetPort": "rmrdata"
124             },
125             {
126                 "name": "rmrroute",
127                 "port": 4561,
128                 "protocol": "TCP",
129                 "targetPort": "rmrroute"
130             }
131         ],
132         "selector": {
133             "app": "ricxapp-dummy-xapp",
134             "release": "dummy-xapp"
135         },
136         "sessionAffinity": "None",
137         "type": "ClusterIP"
138     },
139     "status": {
140         "loadBalancer": {}
141     }
142 }`
143
144 // Test cases
145 func TestMain(m *testing.M) {
146         appmgr.Init()
147         appmgr.Logger.SetLevel(0)
148
149         code := m.Run()
150         os.Exit(code)
151 }
152
153 func TestInit(t *testing.T) {
154         defer func() { resetHelmExecMock() }()
155         var expectedHelmCommand string = ""
156         helmExec = mockedHelmExec
157
158         NewHelm().Init()
159
160         if cm.EnvHelmVersion == cm.HELM_VERSION_2{
161                 expectedHelmCommand = "init -c --skip-refresh"
162                 if caughtHelmExecArgs != expectedHelmCommand {
163                         t.Errorf("Init failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
164                 }
165         }
166 }
167
168 func TestAddRepoSuccess(t *testing.T) {
169         defer func() {
170                 resetHelmExecMock()
171                 removeTestUsernameFile()
172                 removeTestPasswordFile()
173         }()
174         helmExec = mockedHelmExec
175
176         if err := writeTestUsernameFile(); err != nil {
177                 t.Errorf("AddRepo username file create failed: %s", err)
178                 return
179         }
180         if err := writeTestPasswordFile(); err != nil {
181                 t.Errorf("AddRepo password file create failed: %s", err)
182                 return
183         }
184
185         if _, err := NewHelm().AddRepo(); err != nil {
186                 t.Errorf("AddRepo failed: %v", err)
187         }
188
189         if !strings.Contains(caughtHelmExecArgs, "repo add") {
190                 t.Errorf("AddRepo failed: expected %v, got %v", "repo add", caughtHelmExecArgs)
191         }
192 }
193
194 func TestAddRepoReturnsErrorIfNoUsernameFile(t *testing.T) {
195         if _, err := NewHelm().AddRepo(); err == nil {
196                 t.Errorf("AddRepo expected to fail but it didn't")
197         }
198 }
199
200 func TestAddRepoReturnsErrorIfNoPasswordFile(t *testing.T) {
201         defer func() { resetHelmExecMock(); removeTestUsernameFile() }()
202         helmExec = mockedHelmExec
203
204         if err := writeTestUsernameFile(); err != nil {
205                 t.Errorf("AddRepo username file create failed: %s", err)
206                 return
207         }
208         if _, err := NewHelm().AddRepo(); err == nil {
209                 t.Errorf("AddRepo expected to fail but it didn't")
210         }
211 }
212
213 func TestInstallSuccess(t *testing.T) {
214         name := "dummy-xapp"
215         xappDesc := models.XappDescriptor{XappName: &name, Namespace: "ricxapp"}
216
217         defer func() { resetHelmExecMock() }()
218         helmExec = mockedHelmExec
219         helmExecRetOut = helmStatusOutput
220
221         defer func() { resetKubeExecMock() }()
222         kubeExec = mockedKubeExec
223         kubeExecRetOut = kubeServiceOutput
224
225         xapp, err := NewHelm().Install(xappDesc)
226         if err != nil {
227                 t.Errorf("Install failed: %v", err)
228         }
229         validateXappModel(t, xapp)
230 }
231
232 func TestInstallReturnsErrorIfHelmRepoUpdateFails(t *testing.T) {
233         name := "dummy-xapp"
234         xappDesc := models.XappDescriptor{XappName: &name, Namespace: "ricxapp"}
235
236         defer func() { resetHelmExecMock() }()
237         helmExec = mockedHelmExec
238         helmExecRetErr = errors.New("some helm command error")
239
240         if _, err := NewHelm().Install(xappDesc); err == nil {
241                 t.Errorf("Install expected to fail but it didn't")
242         }
243 }
244
245 func TestStatusSuccess(t *testing.T) {
246         name := "dummy-xapp"
247
248         defer func() { resetHelmExecMock() }()
249         helmExec = mockedHelmExec
250         helmExecRetOut = helmStatusOutput
251
252         xapp, err := NewHelm().Status(name)
253         if err != nil {
254                 t.Errorf("Status failed: %v", err)
255         }
256         validateXappModel(t, xapp)
257 }
258
259 func TestStatusReturnsErrorIfHelmStatusFails(t *testing.T) {
260         name := "dummy-xapp"
261
262         defer func() { resetHelmExecMock() }()
263         helmExec = mockedHelmExec
264         helmExecRetErr = errors.New("some helm command error")
265
266         if _, err := NewHelm().Status(name); err == nil {
267                 t.Errorf("Status expected to fail but it didn't")
268         }
269 }
270
271 func TestParseStatusSuccess(t *testing.T) {
272         defer func() { resetHelmExecMock() }()
273         var expectedHelmCommand string = ""
274         helmExec = mockedHelmExec
275         helmExecRetOut = helListOutput
276
277         defer func() { resetKubeExecMock() }()
278         kubeExec = mockedKubeExec
279         kubeExecRetOut = kubeServiceOutput
280
281         xapp, err := NewHelm().ParseStatus("dummy-xapp", helmStatusOutput)
282         if err != nil {
283                 t.Errorf("ParseStatus failed: %v", err)
284         }
285
286         validateXappModel(t, xapp)
287
288         if cm.EnvHelmVersion == cm.HELM_VERSION_2 {
289                 expectedHelmCommand = "list --deployed --output yaml --namespace=ricxapp dummy-xapp"
290         }else {
291                 expectedHelmCommand = "list --deployed --output yaml --namespace=ricxapp -f dummy-xapp"
292         }
293         if caughtHelmExecArgs != expectedHelmCommand {
294                 t.Errorf("ParseStatus failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
295         }
296 }
297
298 func TestListSuccess(t *testing.T) {
299         defer func() { resetHelmExecMock() }()
300         helmExec = mockedHelmExec
301         helmExecRetOut = helListAllOutput
302
303         names, err := NewHelm().List()
304         if err != nil {
305                 t.Errorf("List failed: %v", err)
306         }
307
308         if !reflect.DeepEqual(names, []string{"dummy-xapp", "dummy-xapp2"}) {
309                 t.Errorf("List failed: %v", err)
310         }
311         expectedHelmCommand := "list --all --deployed --output yaml --namespace=ricxapp"
312         if caughtHelmExecArgs != expectedHelmCommand {
313                 t.Errorf("List: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
314         }
315 }
316
317 func TestListReturnsErrorIfHelmListFails(t *testing.T) {
318         defer func() { resetHelmExecMock() }()
319         helmExec = mockedHelmExec
320         helmExecRetErr = errors.New("some helm command error")
321
322         if _, err := NewHelm().List(); err == nil {
323                 t.Errorf("List expected to fail but it didn't")
324         }
325 }
326
327 func TestDeleteSuccess(t *testing.T) {
328         name := "dummy-xapp"
329
330         var expectedHelmCommand string = ""
331         defer func() { resetHelmExecMock() }()
332         helmExec = mockedHelmExec
333         helmExecRetOut = helmStatusOutput
334
335         defer func() { resetKubeExecMock() }()
336         kubeExec = mockedKubeExec
337         kubeExecRetOut = kubeServiceOutput
338
339         xapp, err := NewHelm().Delete(name)
340         if err != nil {
341                 t.Errorf("Delete failed: %v", err)
342         }
343
344         validateXappModel(t, xapp)
345
346         if cm.EnvHelmVersion == cm.HELM_VERSION_2 {
347                 expectedHelmCommand = "del --purge dummy-xapp"
348         } else {
349                 expectedHelmCommand =   "uninstall dummy-xapp -n ricxapp"
350         }
351         if caughtHelmExecArgs != expectedHelmCommand {
352                 t.Errorf("Delete failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
353         }
354 }
355
356 func TestDeleteReturnsErrorIfHelmStatusFails(t *testing.T) {
357         name := "dummy-xapp"
358
359         defer func() { resetHelmExecMock() }()
360         helmExec = mockedHelmExec
361         helmExecRetErr = errors.New("some helm command error")
362
363         if _, err := NewHelm().Delete(name); err == nil {
364                 t.Errorf("Delete expected to fail but it didn't")
365         }
366 }
367
368 func TestFetchSuccessIfCmdArgHasTestSuffix(t *testing.T) {
369         if err := NewHelm().Fetch("kissa", "koira"); err != nil {
370                 t.Errorf("Fetch failed: %v", err)
371         }
372 }
373
374 func TestGetVersionSuccess(t *testing.T) {
375         defer func() { resetHelmExecMock() }()
376         var expectedHelmCommand string = ""
377         helmExec = mockedHelmExec
378         helmExecRetOut = helListOutput
379
380         if version := NewHelm().GetVersion("dummy-xapp"); version != "1.0" {
381                 t.Errorf("GetVersion failed: expected 1.0, got %v", version)
382         }
383
384         if cm.EnvHelmVersion == cm.HELM_VERSION_2{
385                 expectedHelmCommand = "list --deployed --output yaml --namespace=ricxapp dummy-xapp"
386         }else {
387                 expectedHelmCommand = "list --deployed --output yaml --namespace=ricxapp -f dummy-xapp"
388         }
389         if caughtHelmExecArgs != expectedHelmCommand {
390                 t.Errorf("GetVersion failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
391         }
392 }
393
394 func TestGetVersionReturnsEmptyStringIfHelmListFails(t *testing.T) {
395         defer func() { resetHelmExecMock() }()
396         helmExec = mockedHelmExec
397         helmExecRetErr = errors.New("some helm command error")
398
399         if version := NewHelm().GetVersion("dummy-xapp"); version != "" {
400                 t.Errorf("GetVersion expected to return empty string, got %v", version)
401         }
402 }
403
404 func TestGetAddressSuccess(t *testing.T) {
405         ip, port := NewHelm().GetAddress(helmStatusOutput)
406         if ip != "10.102.184.212" {
407                 t.Errorf("GetAddress failed: expected 10.102.184.212, got %v", ip)
408         }
409         if port != "80/TCP" {
410                 t.Errorf("GetAddress failed: expected 80/TCP, got %v", port)
411         }
412 }
413
414 func TestGetEndpointInfoSuccess(t *testing.T) {
415         defer func() { resetKubeExecMock() }()
416         kubeExec = mockedKubeExec
417         kubeExecRetOut = kubeServiceOutput
418
419         svc, port := NewHelm().GetEndpointInfo("dummy-xapp")
420         expectedSvc := "service-ricxapp-dummy-xapp-rmr.ricxapp"
421         if svc != expectedSvc {
422                 t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedSvc, svc)
423         }
424         if port != 4560 {
425                 t.Errorf("GetEndpointInfo failed: expected port 4560, got %v", port)
426         }
427         expectedKubeCommand := " get service -n ricxapp service-ricxapp-dummy-xapp-rmr -o json"
428         if caughtKubeExecArgs != expectedKubeCommand {
429                 t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedKubeCommand, caughtKubeExecArgs)
430         }
431 }
432
433 func TestGetEndpointInfoReturnsDefaultPortIfJsonParseFails(t *testing.T) {
434         defer func() { resetKubeExecMock() }()
435         kubeExec = mockedKubeExec
436         kubeExecRetOut = "not-json-syntax"
437
438         svc, port := NewHelm().GetEndpointInfo("dummy-xapp")
439         expectedSvc := "service-ricxapp-dummy-xapp-rmr.ricxapp"
440         if svc != expectedSvc {
441                 t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedSvc, svc)
442         }
443         if port != 4560 {
444                 t.Errorf("GetEndpointInfo failed: expected port 4560, got %v", port)
445         }
446 }
447
448 func TestGetEndpointInfoReturnsDefaultPortIfKubeGetServiceFails(t *testing.T) {
449         defer func() { resetKubeExecMock() }()
450         kubeExec = mockedKubeExec
451         kubeExecRetErr = errors.New("some helm command error")
452
453         svc, port := NewHelm().GetEndpointInfo("dummy-xapp")
454         expectedSvc := "service-ricxapp-dummy-xapp-rmr.ricxapp"
455         if svc != expectedSvc {
456                 t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedSvc, svc)
457         }
458         if port != 4560 {
459                 t.Errorf("GetEndpointInfo failed: expected port 4560, got %v", port)
460         }
461 }
462
463 func TestHelmStatusAllSuccess(t *testing.T) {
464         defer func() { resetHelmExecMock() }()
465         helmExec = mockedHelmExec
466         helmExecRetOut = helListAllOutput
467
468         if _, err := NewHelm().StatusAll(); err != nil {
469                 t.Errorf("StatusAll failed: %v", err)
470         }
471         // Todo: check StatusAll response content
472 }
473
474 func TestStatusAllReturnsErrorIfHelmListFails(t *testing.T) {
475         defer func() { resetHelmExecMock() }()
476         helmExec = mockedHelmExec
477         helmExecRetErr = errors.New("some helm command error")
478
479         if _, err := NewHelm().StatusAll(); err == nil {
480                 t.Errorf("StatusAll expected to fail but it didn't")
481         }
482 }
483
484 func TestGetNamesSuccess(t *testing.T) {
485         names, err := NewHelm().GetNames(helListAllOutput)
486         if err != nil {
487                 t.Errorf("GetNames failed: %v", err)
488         }
489         if !reflect.DeepEqual(names, []string{"dummy-xapp", "dummy-xapp2"}) {
490                 t.Errorf("GetNames failed: %v", err)
491         }
492 }
493
494 func TestAddTillerEnv(t *testing.T) {
495         if NewHelm().AddTillerEnv() != nil {
496                 t.Errorf("AddTillerEnv failed!")
497         }
498 }
499
500 func TestGetInstallArgs(t *testing.T) {
501         name := "dummy-xapp"
502         var expectedArgs string = ""
503
504         x := models.XappDescriptor{XappName: &name, Namespace: "ricxapp"}
505
506         if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
507                 expectedArgs = "install dummy-xapp helm-repo/dummy-xapp --namespace=ricxapp"
508         }else {
509                 expectedArgs = "install helm-repo/dummy-xapp --namespace=ricxapp --name=dummy-xapp"
510         }
511
512         if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
513                 t.Errorf("GetInstallArgs failed: expected '%v', got '%v'", expectedArgs, args)
514         }
515
516         expectedArgs += " --set ricapp.appconfig.override=dummy-xapp-appconfig"
517         if args := NewHelm().GetInstallArgs(x, true); args != expectedArgs {
518                 t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
519         }
520
521         x.HelmVersion = "1.2.3"
522         if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
523                 expectedArgs = "install dummy-xapp helm-repo/dummy-xapp --namespace=ricxapp --version=1.2.3"
524         } else {
525                 expectedArgs = "install helm-repo/dummy-xapp --namespace=ricxapp --version=1.2.3 --name=dummy-xapp"
526         }
527         if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
528                 t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
529         }
530
531
532         x.ReleaseName = "ueec-xapp"
533         if cm.EnvHelmVersion == cm.HELM_VERSION_3 {
534                 expectedArgs = "install dummy-xapp helm-repo/dummy-xapp --namespace=ricxapp --version=1.2.3"
535         } else {
536                 expectedArgs = "install helm-repo/dummy-xapp --namespace=ricxapp --version=1.2.3 --name=ueec-xapp"
537         }
538         if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
539                 t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
540         }
541
542         x.OverrideFile = "../../test/dummy-xapp_values.json"
543         expectedArgs += " -f=/tmp/appmgr_override.yaml"
544         if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
545                 t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
546         }
547 }
548
549 func writeTestUsernameFile() error {
550         f, err := os.Create(viper.GetString("helm.helm-username-file"))
551         if err != nil {
552                 return err
553         }
554         _, err = f.WriteString("some-username")
555         f.Close()
556         return err
557 }
558
559 func removeTestUsernameFile() error {
560         return os.Remove(viper.GetString("helm.helm-username-file"))
561 }
562
563 func writeTestPasswordFile() (err error) {
564         f, err := os.Create(viper.GetString("helm.helm-password-file"))
565         if err != nil {
566                 return err
567         }
568
569         _, err = f.WriteString("some-password")
570         f.Close()
571         return err
572 }
573
574 func removeTestPasswordFile() error {
575         return os.Remove(viper.GetString("helm.helm-password-file"))
576 }
577
578 func getXappData() (x models.Xapp) {
579         //name1 := "dummy-xapp-8984fc9fd-l6xch"
580         //name2 := "dummy-xapp-8984fc9fd-pp4hg"
581         x = generateXapp("dummy-xapp", "deployed", "1.0", "dummy-xapp-8984fc9fd-bkcbp", "running", "service-ricxapp-dummy-xapp-rmr.ricxapp", "4560")
582         //x.Instances = append(x.Instances, x.Instances[0])
583         //x.Instances = append(x.Instances, x.Instances[0])
584         //x.Instances[1].Name = &name1
585         //x.Instances[2].Name = &name2
586
587         return x
588 }
589
590 func generateXapp(name, status, ver, iname, istatus, ip, port string) (x models.Xapp) {
591         x.Name = &name
592         x.Status = status
593         x.Version = ver
594         p, _ := strconv.Atoi(port)
595         var msgs appmgr.RtmData
596
597         instance := &models.XappInstance{
598                 Name:       &iname,
599                 Status:     istatus,
600                 IP:         ip,
601                 Port:       int64(p),
602                 TxMessages: msgs.TxMessages,
603                 RxMessages: msgs.RxMessages,
604         }
605         x.Instances = append(x.Instances, instance)
606
607         return
608 }
609
610 func mockedKubeExec(args string) (out []byte, err error) {
611         caughtKubeExecArgs = args
612         return []byte(kubeExecRetOut), kubeExecRetErr
613 }
614
615 func resetKubeExecMock() {
616         kubeExec = util.KubectlExec
617         caughtKubeExecArgs = ""
618         kubeExecRetOut = ""
619         kubeExecRetErr = nil
620 }
621
622 func mockedHelmExec(args string) (out []byte, err error) {
623         caughtHelmExecArgs = args
624         return []byte(helmExecRetOut), helmExecRetErr
625 }
626
627 func resetHelmExecMock() {
628         helmExec = util.HelmExec
629         caughtHelmExecArgs = ""
630         helmExecRetOut = ""
631         helmExecRetErr = nil
632 }
633
634 func validateXappModel(t *testing.T, xapp models.Xapp) {
635         expXapp := getXappData()
636         xapp.Version = "1.0"
637
638         if *expXapp.Name != *xapp.Name || expXapp.Status != xapp.Status || expXapp.Version != xapp.Version {
639                 t.Errorf("\n%v \n%v", *xapp.Name, *expXapp.Name)
640         }
641
642         if *expXapp.Instances[0].Name != *xapp.Instances[0].Name || expXapp.Instances[0].Status != xapp.Instances[0].Status {
643                 t.Errorf("\n1:%v 2:%v", *expXapp.Instances[0].Name, *xapp.Instances[0].Name)
644         }
645
646         if expXapp.Instances[0].IP != xapp.Instances[0].IP || expXapp.Instances[0].Port != xapp.Instances[0].Port {
647                 t.Errorf("\n%v - %v, %v - %v", expXapp.Instances[0].IP, xapp.Instances[0].IP, expXapp.Instances[0].Port, xapp.Instances[0].Port)
648         }
649 }