X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=pkg%2Fcm%2Fcm_test.go;h=b180fc98cfdeb846600f8c1d33efe292364fdbfa;hb=d3aa5b98789c65107e5ac41fc5be11f08acf11d8;hp=01f5bc57521f9cb475c6440daff09017024e4c92;hpb=2a4099785bcc1dda74d5192f93f69b33533585b3;p=ric-plt%2Fappmgr.git diff --git a/pkg/cm/cm_test.go b/pkg/cm/cm_test.go index 01f5bc5..b180fc9 100755 --- a/pkg/cm/cm_test.go +++ b/pkg/cm/cm_test.go @@ -24,6 +24,7 @@ import ( "errors" "os" "reflect" + "strings" "testing" "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/appmgr" @@ -31,6 +32,26 @@ import ( "gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/util" ) +const ( + expectedHelmSearchCmd = "search helm-repo" + expectedHelmFetchCmd = `fetch --untar --untardir /tmp helm-repo/dummy-xapp` +) + +var caughtKubeExecArgs []string +var kubeExecRetOut string +var kubeExecRetErr error +var caughtHelmExecArgs string +var helmExecRetOut string +var helmExecRetErr error + +var expectedKubectlGetCmd []string = []string{ + `get configmap -o jsonpath='{.data.config-file\.json}' -n ricxapp configmap-ricxapp-anr-appconfig`, + `get configmap -o jsonpath='{.data.config-file\.json}' -n ricxapp configmap-ricxapp-appmgr-appconfig`, + `get configmap -o jsonpath='{.data.config-file\.json}' -n ricxapp configmap-ricxapp-dualco-appconfig`, + `get configmap -o jsonpath='{.data.config-file\.json}' -n ricxapp configmap-ricxapp-reporter-appconfig`, + `get configmap -o jsonpath='{.data.config-file\.json}' -n ricxapp configmap-ricxapp-uemgr-appconfig`, +} + var helmSearchOutput = ` helm-repo/anr 0.0.1 1.0 Helm Chart for Nokia ANR (Automatic Neighbour Relation) xAPP helm-repo/appmgr 0.0.2 1.0 Helm Chart for xAppManager @@ -62,6 +83,15 @@ var kubectlConfigmapOutput = ` } } ` +var cfgData = `{ + "active":true, + "interfaceId": { + "globalENBId":{ + "plmnId": "1234", + "eNBId":"55" + } + } +}` type ConfigSample struct { Level int @@ -112,20 +142,181 @@ func TestMain(m *testing.M) { os.Exit(code) } -func TestGetRtmData(t *testing.T) { +func TestUploadConfigAllSuccess(t *testing.T) { + var cfg interface{} + var expectedResult models.AllXappConfig + ns := "ricxapp" + xapps := []string{"anr", "appmgr", "dualco", "reporter", "uemgr"} + + if ret := json.Unmarshal([]byte(cfgData), &cfg); ret != nil { + t.Errorf("UploadConfigAll Json unmarshal failed: %v", ret) + } + + for i, _ := range xapps { + expectedResult = append(expectedResult, + &models.XAppConfig{ + Config: cfg, + Metadata: &models.ConfigMetadata{ + Namespace: &ns, + XappName: &xapps[i], + }, + }, + ) + } + + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + //Fake helm search success + helmExecRetOut = helmSearchOutput + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' success + kubeExecRetOut = strings.ReplaceAll(cfgData, "\\", "") + + result := NewCM().UploadConfigAll() + if !reflect.DeepEqual(result, expectedResult) { + t.Errorf("UploadConfigAll failed: expected: %v, got: %v", expectedResult, result) + } + if caughtHelmExecArgs != expectedHelmSearchCmd { + t.Errorf("UploadConfigAll failed: expected: %v, got: %v", expectedHelmSearchCmd, caughtHelmExecArgs) + } + if !reflect.DeepEqual(caughtKubeExecArgs, expectedKubectlGetCmd) { + t.Errorf("UploadConfigAll failed: expected: %v, got: %v", expectedKubectlGetCmd, caughtKubeExecArgs) + } +} + +func TestUploadConfigAllReturnsEmptyMapIfAllConfigMapReadsFail(t *testing.T) { + var expectedResult models.AllXappConfig + + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + //Fake helm search success + helmExecRetOut = helmSearchOutput + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' failure + kubeExecRetErr = errors.New("some error") + + result := NewCM().UploadConfigAll() + if !reflect.DeepEqual(result, expectedResult) { + t.Errorf("UploadConfigAll failed: expected: %v, got: %v", expectedResult, result) + } +} + +func TestUploadConfigElementSuccess(t *testing.T) { + var cfg interface{} + var expectedResult models.AllXappConfig + ns := "ricxapp" + xapps := []string{"anr", "appmgr", "dualco", "reporter", "uemgr"} + + if ret := json.Unmarshal([]byte(cfgData), &cfg); ret != nil { + t.Errorf("UploadConfigElement Json unmarshal failed: %v", ret) + } + + for i, _ := range xapps { + expectedResult = append(expectedResult, + &models.XAppConfig{ + Config: cfg.(map[string]interface{})["active"], + Metadata: &models.ConfigMetadata{ + Namespace: &ns, + XappName: &xapps[i], + }, + }, + ) + } + + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + //Fake helm search success + helmExecRetOut = helmSearchOutput + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' success + kubeExecRetOut = strings.ReplaceAll(cfgData, "\\", "") + + result := NewCM().UploadConfigElement("active") + if !reflect.DeepEqual(result, expectedResult) { + t.Errorf("UploadConfigElement failed: expected: %v, got: %v", expectedResult, result) + } + if caughtHelmExecArgs != expectedHelmSearchCmd { + t.Errorf("UploadConfigElement failed: expected: %v, got: %v", expectedHelmSearchCmd, caughtHelmExecArgs) + } + if !reflect.DeepEqual(caughtKubeExecArgs, expectedKubectlGetCmd) { + t.Errorf("UploadConfigElement failed: expected: %v, got: %v", expectedKubectlGetCmd, caughtKubeExecArgs) + } +} + +func TestUploadConfigElementReturnsEmptyMapIfElementMissingFromConfigMap(t *testing.T) { + var expectedResult models.AllXappConfig + + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + //Fake helm search success + helmExecRetOut = helmSearchOutput + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' success + kubeExecRetOut = strings.ReplaceAll(cfgData, "\\", "") + + //Try to upload non-existing configuration element + result := NewCM().UploadConfigElement("some-not-existing-element") + if !reflect.DeepEqual(result, expectedResult) { + t.Errorf("UploadConfigElement failed: expected: %v, got: %v", expectedResult, result) + } +} + +func TestGetRtmDataSuccess(t *testing.T) { + expectedKubeCmd := []string{ + `get configmap -o jsonpath='{.data.config-file\.json}' -n ricxapp configmap-ricxapp-dummy-xapp-appconfig`, + } expectedMsgs := appmgr.RtmData{ TxMessages: []string{"RIC_X2_LOAD_INFORMATION"}, RxMessages: []string{"RIC_X2_LOAD_INFORMATION"}, Policies: []int64{11, 22, 33}, } - util.KubectlExec = func(args string) (out []byte, err error) { - return []byte(kubectlConfigmapOutput), nil + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' success + kubeExecRetOut = kubectlConfigmapOutput + + result := NewCM().GetRtmData("dummy-xapp") + if !reflect.DeepEqual(result, expectedMsgs) { + t.Errorf("GetRtmData failed: expected: %v, got: %v", expectedMsgs, result) + } + if !reflect.DeepEqual(caughtKubeExecArgs, expectedKubeCmd) { + t.Errorf("GetRtmData failed: expected: '%v', got: '%v'", expectedKubeCmd, caughtKubeExecArgs) + } +} + +func TestGetRtmDataReturnsNoDataIfConfigmapGetFails(t *testing.T) { + var expectedMsgs appmgr.RtmData + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' failure + kubeExecRetErr = errors.New("some error") + + result := NewCM().GetRtmData("dummy-xapp") + if !reflect.DeepEqual(result, expectedMsgs) { + t.Errorf("GetRtmData failed: expected: %v, got: %v", expectedMsgs, result) } +} + +func TestGetRtmDataReturnsNoDataIfJsonParseFails(t *testing.T) { + var expectedMsgs appmgr.RtmData + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' to return nothing what will cause JSON parse failure result := NewCM().GetRtmData("dummy-xapp") if !reflect.DeepEqual(result, expectedMsgs) { - t.Errorf("TestGetRtmData failed: expected: %v, got: %v", expectedMsgs, result) + t.Errorf("GetRtmData failed: expected: %v, got: %v", expectedMsgs, result) } } @@ -146,32 +337,50 @@ func TestFetchChartFails(t *testing.T) { } func TestFetchChartSuccess(t *testing.T) { - util.HelmExec = func(args string) (out []byte, err error) { - return - } + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec if NewCM().FetchChart("dummy-xapp") != nil { t.Errorf("TestFetchChart failed!") } } +func TestGetNamespaceSuccess(t *testing.T) { + if ns := NewCM().GetNamespace("my-ns"); ns != "my-ns" { + t.Errorf("GetNamespace failed: expected: my-ns, got: %s", ns) + } +} + +func TestGetNamespaceReturnsConfiguredNamespaceName(t *testing.T) { + if ns := NewCM().GetNamespace(""); ns != "ricxapp" { + t.Errorf("GetNamespace failed: expected: ricxapp, got: %s", ns) + } +} + func TestGetNamesFromHelmRepoSuccess(t *testing.T) { expectedResult := []string{"anr", "appmgr", "dualco", "reporter", "uemgr"} - util.HelmExec = func(args string) (out []byte, err error) { - return []byte(helmSearchOutput), nil - } + + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + //Fake helm search success + helmExecRetOut = helmSearchOutput names := NewCM().GetNamesFromHelmRepo() if !reflect.DeepEqual(names, expectedResult) { t.Errorf("GetNamesFromHelmRepo failed: expected %v, got %v", expectedResult, names) } + if caughtHelmExecArgs != expectedHelmSearchCmd { + t.Errorf("GetNamesFromHelmRepo failed: expected: %v, got: %v", expectedHelmSearchCmd, caughtHelmExecArgs) + } } func TestGetNamesFromHelmRepoFailure(t *testing.T) { expectedResult := []string{} - util.HelmExec = func(args string) (out []byte, err error) { - return []byte(helmSearchOutput), errors.New("Command failed!") - } + + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + helmExecRetOut = helmSearchOutput + helmExecRetErr = errors.New("Command failed!") names := NewCM().GetNamesFromHelmRepo() if names != nil { @@ -180,26 +389,128 @@ func TestGetNamesFromHelmRepoFailure(t *testing.T) { } func TestBuildConfigMapSuccess(t *testing.T) { + expectedKubeCmd := []string{ + `get configmap -o jsonpath='{.data.config-file\.json}' -n ricxapp configmap-ricxapp-dummy-xapp-appconfig`, + } name := "dummy-xapp" namespace := "ricxapp" m := models.ConfigMetadata{XappName: &name, Namespace: &namespace} - s := `{"Metadata": {"XappName": "ueec", "Namespace": "ricxapp"}, "Config": {"active": true, "interfaceId":{"globalENBId": {"eNBId": 77, "plmnId": "6666"}}}}` + s := `{"Metadata": {"XappName": "ueec", "Namespace": "ricxapp"}, ` + + `"Config": {"active": true, "interfaceId":{"globalENBId": {"eNBId": 77, "plmnId": "6666"}}}}` - util.KubectlExec = func(args string) (out []byte, err error) { - return []byte(`{"logger": {"level": 2}}`), nil - } + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' success + kubeExecRetOut = `{"logger": {"level": 2}}` cmString, err := NewCM().BuildConfigMap(models.XAppConfig{Metadata: &m, Config: s}) if err != nil { t.Errorf("BuildConfigMap failed: %v -> %v", err, cmString) } + if !reflect.DeepEqual(caughtKubeExecArgs, expectedKubeCmd) { + t.Errorf("BuildConfigMap failed: expected: %v, got: %v", expectedKubeCmd, caughtKubeExecArgs) + } } -func TestUpdateConfigMapFails(t *testing.T) { +func TestBuildConfigMapReturnErrorIfJsonMarshalFails(t *testing.T) { + name := "dummy-xapp" + namespace := "ricxapp" + m := models.ConfigMetadata{XappName: &name, Namespace: &namespace} + //Give channel as a configuration input, this will fail JSON marshal + cmString, err := NewCM().BuildConfigMap(models.XAppConfig{Metadata: &m, Config: make(chan int)}) + if err == nil { + t.Errorf("BuildConfigMap failed: %v -> %v", err, cmString) + } +} + +func TestBuildConfigMapReturnErrorIfKubectlGetConfigmapFails(t *testing.T) { + name := "dummy-xapp" + namespace := "ricxapp" + m := models.ConfigMetadata{XappName: &name, Namespace: &namespace} + s := `{"Metadata": {"XappName": "ueec", "Namespace": "ricxapp"}, ` + + `"Config": {"active": true, "interfaceId":{"globalENBId": {"eNBId": 77, "plmnId": "6666"}}}}` + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl get configmap' failure + kubeExecRetErr = errors.New("some error") + + cmString, err := NewCM().BuildConfigMap(models.XAppConfig{Metadata: &m, Config: s}) + if err == nil { + t.Errorf("BuildConfigMap failed: %v -> %v", err, cmString) + } else if err.Error() != "some error" { + t.Errorf("BuildConfigMap failed: expected: 'some error', got: '%s'", err.Error()) + } +} + +func TestBuildConfigMapReturnErrorIfJsonParserFails(t *testing.T) { + name := "dummy-xapp" + namespace := "ricxapp" + m := models.ConfigMetadata{XappName: &name, Namespace: &namespace} + s := `{"Metadata": {"XappName": "ueec", "Namespace": "ricxapp"}, ` + + `"Config": {"active": true, "interfaceId":{"globalENBId": {"eNBId": 77, "plmnId": "6666"}}}}` + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Return empty json that causes JSON parser to fail + kubeExecRetOut = `` + + cmString, err := NewCM().BuildConfigMap(models.XAppConfig{Metadata: &m, Config: s}) + if err == nil { + t.Errorf("BuildConfigMap failed: %v -> %v", err, cmString) + } +} + +func TestGenerateJSONFileSuccess(t *testing.T) { + err := NewCM().GenerateJSONFile("{}") + if err != nil { + t.Errorf("GenerateJSONFile failed: %v", err) + } +} + +func TestReplaceConfigMapSuccess(t *testing.T) { + name := "dummy-xapp" + namespace := "ricxapp" + + defer func() { resetKubeExecMock() }() + kubeExec = mockedKubeExec + //Fake 'kubectl create configmap' success + kubeExecRetOut = "" + + err := NewCM().ReplaceConfigMap(name, namespace) + if err != nil { + t.Errorf("ReplaceConfigMap failed: %v", err) + } +} + +func TestUpdateConfigMapReturnsErrorIfSchemaFileIsMissing(t *testing.T) { + name := "dummy-xapp" + namespace := "ricxapp" + config := models.XAppConfig{Metadata: &models.ConfigMetadata{XappName: &name, Namespace: &namespace}} + + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + helmExecRetOut = `{}` + + //Will fail at schema reading, because schema file is mission + validationErrors, err := NewCM().UpdateConfigMap(config) + if err == nil { + t.Errorf("UpdateConfigMap failed: %v -> %v", err, validationErrors) + } + if caughtHelmExecArgs != expectedHelmFetchCmd { + t.Errorf("UpdateConfigMap failed: expected: %v, got: %v", expectedHelmFetchCmd, caughtHelmExecArgs) + } +} + +func TestUpdateConfigMapReturnsErrorIfHelmFetchChartFails(t *testing.T) { name := "dummy-xapp" namespace := "ricxapp" config := models.XAppConfig{Metadata: &models.ConfigMetadata{XappName: &name, Namespace: &namespace}} + defer func() { resetHelmExecMock() }() + helmExec = mockedHelmExec + helmExecRetErr = errors.New("some error") + validationErrors, err := NewCM().UpdateConfigMap(config) if err == nil { t.Errorf("UpdateConfigMap failed: %v -> %v", err, validationErrors) @@ -225,6 +536,7 @@ func TestValidationSuccess(t *testing.T) { func TestValidationFails(t *testing.T) { var d interface{} var cfg map[string]interface{} + err := json.Unmarshal([]byte(`{"active": "INVALID", "interfaceId":{"globalENBId": {"eNBId": 77, "plmnId": "6666"}}}`), &cfg) err = NewCM().ReadFile("../../test/schema.json", &d) @@ -234,7 +546,47 @@ func TestValidationFails(t *testing.T) { feedback, err := NewCM().doValidate(d, cfg) if err == nil { - t.Errorf("doValidate should faile but didn't: %v -> %v", err, feedback) + t.Errorf("doValidate should fail but didn't: %v -> %v", err, feedback) } appmgr.Logger.Debug("Feedbacks: %v", feedback) } + +func TestReadFileReturnsErrorIfFileReadFails(t *testing.T) { + var d interface{} + + if err := NewCM().ReadFile("not/existing/test/schema.json", &d); err == nil { + t.Errorf("ReadFile should fail but it didn't") + } +} + +func TestReadFileReturnsErrorIfJsonUnmarshalFails(t *testing.T) { + var d interface{} + + if err := NewCM().ReadFile("../../test/faulty_schema.json", &d); err == nil { + t.Errorf("ReadFile should fail but it didn't") + } +} + +func mockedKubeExec(args string) (out []byte, err error) { + caughtKubeExecArgs = append(caughtKubeExecArgs, args) + return []byte(kubeExecRetOut), kubeExecRetErr +} + +func resetKubeExecMock() { + kubeExec = util.KubectlExec + caughtKubeExecArgs = nil + kubeExecRetOut = "" + kubeExecRetErr = nil +} + +func mockedHelmExec(args string) (out []byte, err error) { + caughtHelmExecArgs = args + return []byte(helmExecRetOut), helmExecRetErr +} + +func resetHelmExecMock() { + helmExec = util.HelmExec + caughtHelmExecArgs = "" + helmExecRetOut = "" + helmExecRetErr = nil +}