package helm
import (
+ "errors"
+ "github.com/spf13/viper"
"os"
"reflect"
"strconv"
+ "strings"
"testing"
"gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/appmgr"
"gerrit.o-ran-sc.org/r/ric-plt/appmgr/pkg/util"
)
+var caughtKubeExecArgs string
+var kubeExecRetOut string
+var kubeExecRetErr error
+var caughtHelmExecArgs string
+var helmExecRetOut string
+var helmExecRetErr error
var helmStatusOutput = `
LAST DEPLOYED: Sat Mar 9 06:50:45 2019
NAMESPACE: default
dummy-xapp 3/3 3 3 55m
`
-var helListOutput = `Next: ""
+var helListAllOutput = `Next: ""
Releases:
- AppVersion: "1.0"
Chart: dummy-xapp-chart-0.1.0
Updated: Sun Mar 24 07:17:00 2019
`
-var helmServiceOutput = `{
+var helListOutput = `Next: ""
+Releases:
+- AppVersion: "1.0"
+ Chart: dummy-xapp-chart-0.1.0
+ Name: dummy-xapp
+ Namespace: default
+ Revision: 1
+ Status: DEPLOYED
+ Updated: Mon Mar 11 06:55:05 2019
+ `
+
+var kubeServiceOutput = `{
"apiVersion": "v1",
"kind": "Service",
"metadata": {
os.Exit(code)
}
-func TestHelmStatus(t *testing.T) {
- util.KubectlExec = func(args string) (out []byte, err error) {
- return []byte(helmServiceOutput), nil
+func TestInit(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+
+ NewHelm().Init()
+
+ expectedHelmCommand := "init -c --skip-refresh"
+ if caughtHelmExecArgs != expectedHelmCommand {
+ t.Errorf("Init failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
+ }
+}
+
+func TestAddRepoSuccess(t *testing.T) {
+ defer func() {
+ resetHelmExecMock()
+ removeTestUsernameFile()
+ removeTestPasswordFile()
+ }()
+ helmExec = mockedHelmExec
+
+ if err := writeTestUsernameFile(); err != nil {
+ t.Errorf("AddRepo username file create failed: %s", err)
+ return
+ }
+ if err := writeTestPasswordFile(); err != nil {
+ t.Errorf("AddRepo password file create failed: %s", err)
+ return
+ }
+
+ if _, err := NewHelm().AddRepo(); err != nil {
+ t.Errorf("AddRepo failed: %v", err)
+ }
+
+ if !strings.Contains(caughtHelmExecArgs, "repo add") {
+ t.Errorf("AddRepo failed: expected %v, got %v", "repo add", caughtHelmExecArgs)
+ }
+}
+
+func TestAddRepoReturnsErrorIfNoUsernameFile(t *testing.T) {
+ if _, err := NewHelm().AddRepo(); err == nil {
+ t.Errorf("AddRepo expected to fail but it didn't")
}
+}
+
+func TestAddRepoReturnsErrorIfNoPasswordFile(t *testing.T) {
+ defer func() { resetHelmExecMock(); removeTestUsernameFile() }()
+ helmExec = mockedHelmExec
+
+ if err := writeTestUsernameFile(); err != nil {
+ t.Errorf("AddRepo username file create failed: %s", err)
+ return
+ }
+ if _, err := NewHelm().AddRepo(); err == nil {
+ t.Errorf("AddRepo expected to fail but it didn't")
+ }
+}
+
+func TestInstallSuccess(t *testing.T) {
+ name := "dummy-xapp"
+ xappDesc := models.XappDescriptor{XappName: &name, Namespace: "ricxapp"}
+
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetOut = helmStatusOutput
+
+ defer func() { resetKubeExecMock() }()
+ kubeExec = mockedKubeExec
+ kubeExecRetOut = kubeServiceOutput
+
+ xapp, err := NewHelm().Install(xappDesc)
+ if err != nil {
+ t.Errorf("Install failed: %v", err)
+ }
+ validateXappModel(t, xapp)
+}
+
+func TestInstallReturnsErrorIfHelmRepoUpdateFails(t *testing.T) {
+ name := "dummy-xapp"
+ xappDesc := models.XappDescriptor{XappName: &name, Namespace: "ricxapp"}
+
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetErr = errors.New("some helm command error")
+
+ if _, err := NewHelm().Install(xappDesc); err == nil {
+ t.Errorf("Install expected to fail but it didn't")
+ }
+}
+
+func TestStatusSuccess(t *testing.T) {
+ name := "dummy-xapp"
+
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetOut = helmStatusOutput
+
+ xapp, err := NewHelm().Status(name)
+ if err != nil {
+ t.Errorf("Status failed: %v", err)
+ }
+ validateXappModel(t, xapp)
+}
+
+func TestStatusReturnsErrorIfHelmStatusFails(t *testing.T) {
+ name := "dummy-xapp"
+
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetErr = errors.New("some helm command error")
+
+ if _, err := NewHelm().Status(name); err == nil {
+ t.Errorf("Status expected to fail but it didn't")
+ }
+}
+
+func TestParseStatusSuccess(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetOut = helListOutput
+
+ defer func() { resetKubeExecMock() }()
+ kubeExec = mockedKubeExec
+ kubeExecRetOut = kubeServiceOutput
+
xapp, err := NewHelm().ParseStatus("dummy-xapp", helmStatusOutput)
if err != nil {
- t.Errorf("Helm install failed: %v", err)
+ t.Errorf("ParseStatus failed: %v", err)
}
- x := getXappData()
- xapp.Version = "1.0"
- if *x.Name != *xapp.Name || x.Status != xapp.Status || x.Version != xapp.Version {
- t.Errorf("\n%v \n%v", *xapp.Name, *x.Name)
+ validateXappModel(t, xapp)
+
+ expectedHelmCommand := "list --deployed --output yaml --namespace=ricxapp dummy-xapp"
+ if caughtHelmExecArgs != expectedHelmCommand {
+ t.Errorf("ParseStatus failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
+ }
+}
+
+func TestListSuccess(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetOut = helListAllOutput
+
+ names, err := NewHelm().List()
+ if err != nil {
+ t.Errorf("List failed: %v", err)
}
- if *x.Instances[0].Name != *xapp.Instances[0].Name || x.Instances[0].Status != xapp.Instances[0].Status {
- t.Errorf("\n1:%v 2:%v", *x.Instances[0].Name, *xapp.Instances[0].Name)
+ if !reflect.DeepEqual(names, []string{"dummy-xapp", "dummy-xapp2"}) {
+ t.Errorf("List failed: %v", err)
+ }
+ expectedHelmCommand := "list --all --deployed --output yaml --namespace=ricxapp"
+ if caughtHelmExecArgs != expectedHelmCommand {
+ t.Errorf("List: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
}
+}
+
+func TestListReturnsErrorIfHelmListFails(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetErr = errors.New("some helm command error")
- if x.Instances[0].IP != xapp.Instances[0].IP || x.Instances[0].Port != xapp.Instances[0].Port {
- t.Errorf("\n%v - %v, %v - %v", x.Instances[0].IP, xapp.Instances[0].IP, x.Instances[0].Port, xapp.Instances[0].Port)
+ if _, err := NewHelm().List(); err == nil {
+ t.Errorf("List expected to fail but it didn't")
}
}
-func TestHelmLists(t *testing.T) {
- names, err := NewHelm().GetNames(helListOutput)
+func TestDeleteSuccess(t *testing.T) {
+ name := "dummy-xapp"
+
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetOut = helmStatusOutput
+
+ defer func() { resetKubeExecMock() }()
+ kubeExec = mockedKubeExec
+ kubeExecRetOut = kubeServiceOutput
+
+ xapp, err := NewHelm().Delete(name)
if err != nil {
- t.Errorf("Helm status failed: %v", err)
+ t.Errorf("Delete failed: %v", err)
+ }
+
+ validateXappModel(t, xapp)
+
+ expectedHelmCommand := "del --purge dummy-xapp"
+ if caughtHelmExecArgs != expectedHelmCommand {
+ t.Errorf("Delete failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
}
+}
+
+func TestDeleteReturnsErrorIfHelmStatusFails(t *testing.T) {
+ name := "dummy-xapp"
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetErr = errors.New("some helm command error")
+
+ if _, err := NewHelm().Delete(name); err == nil {
+ t.Errorf("Delete expected to fail but it didn't")
+ }
+}
+
+func TestFetchSuccessIfCmdArgHasTestSuffix(t *testing.T) {
+ if err := NewHelm().Fetch("kissa", "koira"); err != nil {
+ t.Errorf("Fetch failed: %v", err)
+ }
+}
+
+func TestGetVersionSuccess(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetOut = helListOutput
+
+ if version := NewHelm().GetVersion("dummy-xapp"); version != "1.0" {
+ t.Errorf("GetVersion failed: expected 1.0, got %v", version)
+ }
+
+ expectedHelmCommand := "list --deployed --output yaml --namespace=ricxapp dummy-xapp"
+ if caughtHelmExecArgs != expectedHelmCommand {
+ t.Errorf("GetVersion failed: expected %v, got %v", expectedHelmCommand, caughtHelmExecArgs)
+ }
+}
+
+func TestGetVersionReturnsEmptyStringIfHelmListFails(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetErr = errors.New("some helm command error")
+
+ if version := NewHelm().GetVersion("dummy-xapp"); version != "" {
+ t.Errorf("GetVersion expected to return empty string, got %v", version)
+ }
+}
+
+func TestGetAddressSuccess(t *testing.T) {
+ ip, port := NewHelm().GetAddress(helmStatusOutput)
+ if ip != "10.102.184.212" {
+ t.Errorf("GetAddress failed: expected 10.102.184.212, got %v", ip)
+ }
+ if port != "80/TCP" {
+ t.Errorf("GetAddress failed: expected 80/TCP, got %v", port)
+ }
+}
+
+func TestGetEndpointInfoSuccess(t *testing.T) {
+ defer func() { resetKubeExecMock() }()
+ kubeExec = mockedKubeExec
+ kubeExecRetOut = kubeServiceOutput
+
+ svc, port := NewHelm().GetEndpointInfo("dummy-xapp")
+ expectedSvc := "service-ricxapp-dummy-xapp-rmr.ricxapp"
+ if svc != expectedSvc {
+ t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedSvc, svc)
+ }
+ if port != 4560 {
+ t.Errorf("GetEndpointInfo failed: expected port 4560, got %v", port)
+ }
+ expectedKubeCommand := " get service -n ricxapp service-ricxapp-dummy-xapp-rmr -o json"
+ if caughtKubeExecArgs != expectedKubeCommand {
+ t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedKubeCommand, caughtKubeExecArgs)
+ }
+}
+
+func TestGetEndpointInfoReturnsDefaultPortIfJsonParseFails(t *testing.T) {
+ defer func() { resetKubeExecMock() }()
+ kubeExec = mockedKubeExec
+ kubeExecRetOut = "not-json-syntax"
+
+ svc, port := NewHelm().GetEndpointInfo("dummy-xapp")
+ expectedSvc := "service-ricxapp-dummy-xapp-rmr.ricxapp"
+ if svc != expectedSvc {
+ t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedSvc, svc)
+ }
+ if port != 4560 {
+ t.Errorf("GetEndpointInfo failed: expected port 4560, got %v", port)
+ }
+}
+
+func TestGetEndpointInfoReturnsDefaultPortIfKubeGetServiceFails(t *testing.T) {
+ defer func() { resetKubeExecMock() }()
+ kubeExec = mockedKubeExec
+ kubeExecRetErr = errors.New("some helm command error")
+
+ svc, port := NewHelm().GetEndpointInfo("dummy-xapp")
+ expectedSvc := "service-ricxapp-dummy-xapp-rmr.ricxapp"
+ if svc != expectedSvc {
+ t.Errorf("GetEndpointInfo failed: expected %v, got %v", expectedSvc, svc)
+ }
+ if port != 4560 {
+ t.Errorf("GetEndpointInfo failed: expected port 4560, got %v", port)
+ }
+}
+
+func TestHelmStatusAllSuccess(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetOut = helListAllOutput
+
+ if _, err := NewHelm().StatusAll(); err != nil {
+ t.Errorf("StatusAll failed: %v", err)
+ }
+ // Todo: check StatusAll response content
+}
+
+func TestStatusAllReturnsErrorIfHelmListFails(t *testing.T) {
+ defer func() { resetHelmExecMock() }()
+ helmExec = mockedHelmExec
+ helmExecRetErr = errors.New("some helm command error")
+
+ if _, err := NewHelm().StatusAll(); err == nil {
+ t.Errorf("StatusAll expected to fail but it didn't")
+ }
+}
+
+func TestGetNamesSuccess(t *testing.T) {
+ names, err := NewHelm().GetNames(helListAllOutput)
+ if err != nil {
+ t.Errorf("GetNames failed: %v", err)
+ }
if !reflect.DeepEqual(names, []string{"dummy-xapp", "dummy-xapp2"}) {
- t.Errorf("Helm status failed: %v", err)
+ t.Errorf("GetNames failed: %v", err)
}
}
func TestAddTillerEnv(t *testing.T) {
if NewHelm().AddTillerEnv() != nil {
- t.Errorf("TestAddTillerEnv failed!")
+ t.Errorf("AddTillerEnv failed!")
}
}
expectedArgs := "install helm-repo/dummy-xapp --namespace=ricxapp --name=dummy-xapp"
if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
- t.Errorf("TestGetInstallArgs failed: expected %v, got %v", expectedArgs, args)
+ t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
+ }
+
+ expectedArgs += " --set ricapp.appconfig.override=dummy-xapp-appconfig"
+ if args := NewHelm().GetInstallArgs(x, true); args != expectedArgs {
+ t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
}
x.HelmVersion = "1.2.3"
expectedArgs = "install helm-repo/dummy-xapp --namespace=ricxapp --version=1.2.3 --name=dummy-xapp"
if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
- t.Errorf("TestGetInstallArgs failed: expected %v, got %v", expectedArgs, args)
+ t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
}
x.ReleaseName = "ueec-xapp"
expectedArgs = "install helm-repo/dummy-xapp --namespace=ricxapp --version=1.2.3 --name=ueec-xapp"
if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
- t.Errorf("TestGetInstallArgs failed: expected %v, got %v", expectedArgs, args)
+ t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
+ }
+
+ x.OverrideFile = "../../test/dummy-xapp_values.json"
+ expectedArgs += " -f=/tmp/appmgr_override.yaml"
+ if args := NewHelm().GetInstallArgs(x, false); args != expectedArgs {
+ t.Errorf("GetInstallArgs failed: expected %v, got %v", expectedArgs, args)
}
}
+func writeTestUsernameFile() error {
+ f, err := os.Create(viper.GetString("helm.helm-username-file"))
+ if err != nil {
+ return err
+ }
+ _, err = f.WriteString("some-username")
+ f.Close()
+ return err
+}
+
+func removeTestUsernameFile() error {
+ return os.Remove(viper.GetString("helm.helm-username-file"))
+}
+
+func writeTestPasswordFile() (err error) {
+ f, err := os.Create(viper.GetString("helm.helm-password-file"))
+ if err != nil {
+ return err
+ }
+
+ _, err = f.WriteString("some-password")
+ f.Close()
+ return err
+}
+
+func removeTestPasswordFile() error {
+ return os.Remove(viper.GetString("helm.helm-password-file"))
+}
+
func getXappData() (x models.Xapp) {
//name1 := "dummy-xapp-8984fc9fd-l6xch"
//name2 := "dummy-xapp-8984fc9fd-pp4hg"
return
}
+
+func mockedKubeExec(args string) (out []byte, err error) {
+ caughtKubeExecArgs = args
+ return []byte(kubeExecRetOut), kubeExecRetErr
+}
+
+func resetKubeExecMock() {
+ kubeExec = util.KubectlExec
+ caughtKubeExecArgs = ""
+ 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
+}
+
+func validateXappModel(t *testing.T, xapp models.Xapp) {
+ expXapp := getXappData()
+ xapp.Version = "1.0"
+
+ if *expXapp.Name != *xapp.Name || expXapp.Status != xapp.Status || expXapp.Version != xapp.Version {
+ t.Errorf("\n%v \n%v", *xapp.Name, *expXapp.Name)
+ }
+
+ if *expXapp.Instances[0].Name != *xapp.Instances[0].Name || expXapp.Instances[0].Status != xapp.Instances[0].Status {
+ t.Errorf("\n1:%v 2:%v", *expXapp.Instances[0].Name, *xapp.Instances[0].Name)
+ }
+
+ if expXapp.Instances[0].IP != xapp.Instances[0].IP || expXapp.Instances[0].Port != xapp.Instances[0].Port {
+ t.Errorf("\n%v - %v, %v - %v", expXapp.Instances[0].IP, xapp.Instances[0].IP, expXapp.Instances[0].Port, xapp.Instances[0].Port)
+ }
+}