diff options
-rw-r--r-- | src/k8splugin/krd/plugins.go | 14 | ||||
-rw-r--r-- | src/k8splugin/krd/plugins_test.go | 95 | ||||
-rw-r--r-- | src/k8splugin/plugins/deployment/plugin_test.go | 139 | ||||
-rw-r--r-- | src/k8splugin/plugins/namespace/plugin.go | 18 | ||||
-rw-r--r-- | src/k8splugin/plugins/namespace/plugin_test.go | 80 | ||||
-rw-r--r-- | src/k8splugin/plugins/service/plugin_test.go | 137 |
6 files changed, 380 insertions, 103 deletions
diff --git a/src/k8splugin/krd/plugins.go b/src/k8splugin/krd/plugins.go index 41b83226..9ccb04fa 100644 --- a/src/k8splugin/krd/plugins.go +++ b/src/k8splugin/krd/plugins.go @@ -38,21 +38,25 @@ type ResourceData struct { // DecodeYAML reads a YAMl file to extract the Kubernetes object definition var DecodeYAML = func(path string) (runtime.Object, error) { - if _, err := os.Stat(path); os.IsNotExist(err) { - return nil, pkgerrors.New("File " + path + " not found") + if _, err := os.Stat(path); err != nil { + if os.IsNotExist(err) { + return nil, pkgerrors.New("File " + path + " not found") + } else { + return nil, pkgerrors.Wrap(err, "Stat file error") + } } - log.Println("Reading deployment YAML") + log.Println("Reading YAML file") rawBytes, err := ioutil.ReadFile(path) if err != nil { - return nil, pkgerrors.Wrap(err, "Deployment YAML file read error") + return nil, pkgerrors.Wrap(err, "Read YAML file error") } log.Println("Decoding deployment YAML") decode := scheme.Codecs.UniversalDeserializer().Decode obj, _, err := decode(rawBytes, nil, nil) if err != nil { - return nil, pkgerrors.Wrap(err, "Deserialize deployment error") + return nil, pkgerrors.Wrap(err, "Deserialize YAML error") } return obj, nil diff --git a/src/k8splugin/krd/plugins_test.go b/src/k8splugin/krd/plugins_test.go new file mode 100644 index 00000000..81d2784e --- /dev/null +++ b/src/k8splugin/krd/plugins_test.go @@ -0,0 +1,95 @@ +// +build unit + +/* +Copyright 2018 Intel Corporation. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package krd + +import ( + "strings" + "testing" + + appsV1 "k8s.io/api/apps/v1" + coreV1 "k8s.io/api/core/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +func TestDecodeYAML(t *testing.T) { + testCases := []struct { + label string + input string + expectedResult runtime.Object + expectedError string + }{ + { + label: "Fail to read non-existing YAML file", + input: "unexisting-file.yaml", + expectedError: "not found", + }, + { + label: "Fail to read invalid YAML format", + input: "./plugins_test.go", + expectedError: "mapping values are not allowed in this contex", + }, + { + label: "Successfully read YAML file", + input: "../mock_files/mock_yamls/deployment.yaml", + expectedResult: &appsV1.Deployment{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "mock-deployment", + }, + Spec: appsV1.DeploymentSpec{ + Template: coreV1.PodTemplateSpec{ + ObjectMeta: metaV1.ObjectMeta{ + Labels: map[string]string{"app": "sise"}, + }, + Spec: coreV1.PodSpec{ + Containers: []coreV1.Container{ + coreV1.Container{ + Name: "sise", + Image: "mhausenblas/simpleservice:0.5.0", + }, + }, + }, + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + result, err := DecodeYAML(testCase.input) + if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Decode YAML method return an un-expected (%s)", err) + } + if !strings.Contains(string(err.Error()), testCase.expectedError) { + t.Fatalf("Decode YAML method returned an error (%s)", err) + } + } else { + if testCase.expectedError != "" && testCase.expectedResult == nil { + t.Fatalf("Decode YAML method was expecting \"%s\" error message", testCase.expectedError) + } + if result == nil { + t.Fatal("Decode YAML method returned nil result") + } + // if !reflect.DeepEqual(testCase.expectedResult, result) { + + // t.Fatalf("Decode YAML method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + // } + } + }) + } +} diff --git a/src/k8splugin/plugins/deployment/plugin_test.go b/src/k8splugin/plugins/deployment/plugin_test.go index 636629a9..c8dcb29e 100644 --- a/src/k8splugin/plugins/deployment/plugin_test.go +++ b/src/k8splugin/plugins/deployment/plugin_test.go @@ -39,14 +39,6 @@ func TestCreateDeployment(t *testing.T) { expectedError string }{ { - label: "Fail to create a deployment with non-existing file", - input: &krd.ResourceData{ - YamlFilePath: "non-existing_test_file.yaml", - }, - clientOutput: &appsV1.Deployment{}, - expectedError: "not found", - }, - { label: "Fail to create a deployment with invalid type", input: &krd.ResourceData{ YamlFilePath: "../../mock_files/mock_yamls/service.yaml", @@ -75,19 +67,30 @@ func TestCreateDeployment(t *testing.T) { t.Run(testCase.label, func(t *testing.T) { result, err := Create(testCase.input, client) if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Create method return an un-expected (%s)", err) + } if !strings.Contains(string(err.Error()), testCase.expectedError) { t.Fatalf("Create method returned an error (%s)", err) } - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("Create method returned %v and it was expected (%v)", result, testCase.expectedResult) + } else { + if testCase.expectedError != "" && testCase.expectedResult == "" { + t.Fatalf("Create method was expecting \"%s\" error message", testCase.expectedError) + } + if result == "" { + t.Fatal("Create method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("Create method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } } func TestListDeployment(t *testing.T) { - namespace := "test1" + namespace := "test" testCases := []struct { label string input string @@ -115,6 +118,27 @@ func TestListDeployment(t *testing.T) { }, expectedResult: []string{"test"}, }, + { + label: "Sucessfully display a list of existing deployments in default namespace", + input: "", + clientOutput: &appsV1.DeploymentList{ + Items: []appsV1.Deployment{ + appsV1.Deployment{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + appsV1.Deployment{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test2", + Namespace: namespace, + }, + }, + }, + }, + expectedResult: []string{"test"}, + }, } for _, testCase := range testCases { @@ -123,29 +147,42 @@ func TestListDeployment(t *testing.T) { result, err := List(testCase.input, client) if err != nil { t.Fatalf("List method returned an error (%s)", err) - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("List method returned %v and it was expected (%v)", result, testCase.expectedResult) + } else { + if result == nil { + t.Fatal("List method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("List method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } } func TestDeleteDeployment(t *testing.T) { - namespace := "test1" - name := "mock-deployment" testCases := []struct { label string - input string + input map[string]string clientOutput *appsV1.Deployment }{ { label: "Sucessfully delete an existing deployment", - input: name, + input: map[string]string{"name": "test-deployment", "namespace": "test-namespace"}, clientOutput: &appsV1.Deployment{ ObjectMeta: metaV1.ObjectMeta{ - Name: name, - Namespace: namespace, + Name: "test-deployment", + Namespace: "test-namespace", + }, + }, + }, + { + label: "Sucessfully delete an existing deployment in default namespace", + input: map[string]string{"name": "test-deployment", "namespace": ""}, + clientOutput: &appsV1.Deployment{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test-deployment", + Namespace: "default", }, }, }, @@ -154,7 +191,7 @@ func TestDeleteDeployment(t *testing.T) { for _, testCase := range testCases { client := testclient.NewSimpleClientset(testCase.clientOutput) t.Run(testCase.label, func(t *testing.T) { - err := Delete(testCase.input, namespace, client) + err := Delete(testCase.input["name"], testCase.input["namespace"], client) if err != nil { t.Fatalf("Delete method returned an error (%s)", err) } @@ -163,36 +200,70 @@ func TestDeleteDeployment(t *testing.T) { } func TestGetDeployment(t *testing.T) { - namespace := "test1" - name := "mock-deployment" testCases := []struct { label string - input string + input map[string]string clientOutput *appsV1.Deployment expectedResult string + expectedError string }{ { label: "Sucessfully get an existing deployment", - input: name, + input: map[string]string{"name": "test-deployment", "namespace": "test-namespace"}, clientOutput: &appsV1.Deployment{ ObjectMeta: metaV1.ObjectMeta{ - Name: name, - Namespace: namespace, + Name: "test-deployment", + Namespace: "test-namespace", }, }, - expectedResult: name, + expectedResult: "test-deployment", + }, + { + label: "Sucessfully get an existing deployment from default namespaces", + input: map[string]string{"name": "test-deployment", "namespace": ""}, + clientOutput: &appsV1.Deployment{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test-deployment", + Namespace: "default", + }, + }, + expectedResult: "test-deployment", + }, + { + label: "Fail to get an non-existing namespace", + input: map[string]string{"name": "test-name", "namespace": "test-namespace"}, + clientOutput: &appsV1.Deployment{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test-deployment", + Namespace: "default", + }, + }, + expectedError: "not found", }, } for _, testCase := range testCases { client := testclient.NewSimpleClientset(testCase.clientOutput) t.Run(testCase.label, func(t *testing.T) { - result, err := Get(testCase.input, namespace, client) + result, err := Get(testCase.input["name"], testCase.input["namespace"], client) if err != nil { - t.Fatalf("Get method returned an error (%s)", err) - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("Get method returned %v and it was expected (%v)", result, testCase.expectedResult) + if testCase.expectedError == "" { + t.Fatalf("Get method return an un-expected (%s)", err) + } + if !strings.Contains(string(err.Error()), testCase.expectedError) { + t.Fatalf("Get method returned an error (%s)", err) + } + } else { + if testCase.expectedError != "" && testCase.expectedResult == "" { + t.Fatalf("Get method was expecting \"%s\" error message", testCase.expectedError) + } + if result == "" { + t.Fatal("Get method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("Get method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } diff --git a/src/k8splugin/plugins/namespace/plugin.go b/src/k8splugin/plugins/namespace/plugin.go index e29ff43d..de2f4f8b 100644 --- a/src/k8splugin/plugins/namespace/plugin.go +++ b/src/k8splugin/plugins/namespace/plugin.go @@ -37,25 +37,23 @@ func Create(data *krd.ResourceData, client kubernetes.Interface) (string, error) if err != nil { return "", pkgerrors.Wrap(err, "Create Namespace error") } + log.Printf("Namespace (%s) created", data.Namespace) + return data.Namespace, nil } // Get an existing namespace hosted in a specific Kubernetes cluster func Get(name string, namespace string, client kubernetes.Interface) (string, error) { - opts := metaV1.ListOptions{} + opts := metaV1.GetOptions{} + opts.APIVersion = "apps/v1" + opts.Kind = "Deployment" - list, err := client.CoreV1().Namespaces().List(opts) + ns, err := client.CoreV1().Namespaces().Get(name, opts) if err != nil { - return "", pkgerrors.Wrap(err, "Get Namespace list error") - } - - for _, ns := range list.Items { - if namespace == ns.Name { - return ns.Name, nil - } + return "", pkgerrors.Wrap(err, "Get Namespace error") } - return "", nil + return ns.Name, nil } // Delete an existing namespace hosted in a specific Kubernetes cluster diff --git a/src/k8splugin/plugins/namespace/plugin_test.go b/src/k8splugin/plugins/namespace/plugin_test.go index fe60404d..8a9fc5ac 100644 --- a/src/k8splugin/plugins/namespace/plugin_test.go +++ b/src/k8splugin/plugins/namespace/plugin_test.go @@ -51,12 +51,23 @@ func TestCreateNamespace(t *testing.T) { t.Run(testCase.label, func(t *testing.T) { result, err := Create(testCase.input, client) if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Create method return an un-expected (%s)", err) + } if !strings.Contains(string(err.Error()), testCase.expectedError) { t.Fatalf("Create method returned an error (%s)", err) } - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("Create method returned %v and it was expected (%v)", result, testCase.expectedResult) + } else { + if testCase.expectedError != "" && testCase.expectedResult == "" { + t.Fatalf("Create method was expecting \"%s\" error message", testCase.expectedError) + } + if result == "" { + t.Fatal("Create method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("Create method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } @@ -98,27 +109,31 @@ func TestListNamespace(t *testing.T) { result, err := List(testCase.input, client) if err != nil { t.Fatalf("List method returned an error (%s)", err) - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("List method returned %v and it was expected (%v)", result, testCase.expectedResult) + } else { + if result == nil { + t.Fatal("List method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("List method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } } func TestDeleteNamespace(t *testing.T) { - namespace := "test1" testCases := []struct { label string - input string + input map[string]string clientOutput *coreV1.Namespace }{ { label: "Sucessfully to delete an existing namespace", - input: namespace, + input: map[string]string{"name": "test-name", "namespace": "test-namespace"}, clientOutput: &coreV1.Namespace{ ObjectMeta: metaV1.ObjectMeta{ - Name: namespace, + Name: "test-name", }, }, }, @@ -127,7 +142,7 @@ func TestDeleteNamespace(t *testing.T) { for _, testCase := range testCases { client := testclient.NewSimpleClientset(testCase.clientOutput) t.Run(testCase.label, func(t *testing.T) { - err := Delete(testCase.input, namespace, client) + err := Delete(testCase.input["name"], testCase.input["namespace"], client) if err != nil { t.Fatalf("Delete method returned an error (%s)", err) } @@ -136,34 +151,57 @@ func TestDeleteNamespace(t *testing.T) { } func TestGetNamespace(t *testing.T) { - namespace := "test1" testCases := []struct { label string - input string + input map[string]string clientOutput *coreV1.Namespace expectedResult string + expectedError string }{ { label: "Sucessfully to get an existing namespace", - input: namespace, + input: map[string]string{"name": "test-name", "namespace": "test-namespace"}, clientOutput: &coreV1.Namespace{ ObjectMeta: metaV1.ObjectMeta{ - Name: namespace, + Name: "test-name", }, }, - expectedResult: namespace, + expectedResult: "test-name", + }, + { + label: "Fail to get an non-existing namespace", + input: map[string]string{"name": "test-name", "namespace": "test-namespace"}, + clientOutput: &coreV1.Namespace{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test-name2", + }, + }, + expectedError: "not found", }, } for _, testCase := range testCases { client := testclient.NewSimpleClientset(testCase.clientOutput) t.Run(testCase.label, func(t *testing.T) { - result, err := Get(testCase.input, namespace, client) + result, err := Get(testCase.input["name"], testCase.input["namespace"], client) if err != nil { - t.Fatalf("Get method returned an error (%s)", err) - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("Get method returned %v and it was expected (%v)", result, testCase.expectedResult) + if testCase.expectedError == "" { + t.Fatalf("Get method return an un-expected (%s)", err) + } + if !strings.Contains(string(err.Error()), testCase.expectedError) { + t.Fatalf("Get method returned an error (%s)", err) + } + } else { + if testCase.expectedError != "" && testCase.expectedResult == "" { + t.Fatalf("Get method was expecting \"%s\" error message", testCase.expectedError) + } + if result == "" { + t.Fatal("Get method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("Get method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } diff --git a/src/k8splugin/plugins/service/plugin_test.go b/src/k8splugin/plugins/service/plugin_test.go index 001467df..25eeb730 100644 --- a/src/k8splugin/plugins/service/plugin_test.go +++ b/src/k8splugin/plugins/service/plugin_test.go @@ -39,14 +39,6 @@ func TestCreateService(t *testing.T) { expectedError string }{ { - label: "Fail to create a service with non-existing file", - input: &krd.ResourceData{ - YamlFilePath: "non-existing_test_file.yaml", - }, - clientOutput: &coreV1.Service{}, - expectedError: "not found", - }, - { label: "Fail to create a service with invalid type", input: &krd.ResourceData{ YamlFilePath: "../../mock_files/mock_yamls/deployment.yaml", @@ -75,12 +67,23 @@ func TestCreateService(t *testing.T) { t.Run(testCase.label, func(t *testing.T) { result, err := Create(testCase.input, client) if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Create method return an un-expected (%s)", err) + } if !strings.Contains(string(err.Error()), testCase.expectedError) { t.Fatalf("Create method returned an error (%s)", err) } - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("Create method returned %v and it was expected (%v)", result, testCase.expectedResult) + } else { + if testCase.expectedError != "" && testCase.expectedResult == "" { + t.Fatalf("Create method was expecting \"%s\" error message", testCase.expectedError) + } + if result == "" { + t.Fatal("Create method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("Create method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } @@ -115,6 +118,27 @@ func TestListService(t *testing.T) { }, expectedResult: []string{"test"}, }, + { + label: "Sucessfully display a list of existing services in default namespace", + input: "", + clientOutput: &coreV1.ServiceList{ + Items: []coreV1.Service{ + coreV1.Service{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + }, + coreV1.Service{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test2", + Namespace: namespace, + }, + }, + }, + }, + expectedResult: []string{"test"}, + }, } for _, testCase := range testCases { @@ -123,29 +147,42 @@ func TestListService(t *testing.T) { result, err := List(testCase.input, client) if err != nil { t.Fatalf("List method returned an error (%s)", err) - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("List method returned %v and it was expected (%v)", result, testCase.expectedResult) + } else { + if result == nil { + t.Fatal("List method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("List method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } } func TestDeleteService(t *testing.T) { - namespace := "test1" - name := "mock-service" testCases := []struct { label string - input string + input map[string]string clientOutput *coreV1.Service }{ { label: "Sucessfully to delete an existing service", - input: name, + input: map[string]string{"name": "test-service", "namespace": "test-namespace"}, clientOutput: &coreV1.Service{ ObjectMeta: metaV1.ObjectMeta{ - Name: name, - Namespace: namespace, + Name: "test-service", + Namespace: "test-namespace", + }, + }, + }, + { + label: "Sucessfully delete an existing service in default namespace", + input: map[string]string{"name": "test-service", "namespace": ""}, + clientOutput: &coreV1.Service{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test-service", + Namespace: "default", }, }, }, @@ -154,7 +191,7 @@ func TestDeleteService(t *testing.T) { for _, testCase := range testCases { client := testclient.NewSimpleClientset(testCase.clientOutput) t.Run(testCase.label, func(t *testing.T) { - err := Delete(testCase.input, namespace, client) + err := Delete(testCase.input["name"], testCase.input["namespace"], client) if err != nil { t.Fatalf("Delete method returned an error (%s)", err) } @@ -163,36 +200,70 @@ func TestDeleteService(t *testing.T) { } func TestGetService(t *testing.T) { - namespace := "test1" - name := "mock-service" testCases := []struct { label string - input string + input map[string]string clientOutput *coreV1.Service expectedResult string + expectedError string }{ { label: "Sucessfully to get an existing service", - input: name, + input: map[string]string{"name": "test-service", "namespace": "test-namespace"}, clientOutput: &coreV1.Service{ ObjectMeta: metaV1.ObjectMeta{ - Name: name, - Namespace: namespace, + Name: "test-service", + Namespace: "test-namespace", }, }, - expectedResult: name, + expectedResult: "test-service", + }, + { + label: "Sucessfully get an existing service from default namespaces", + input: map[string]string{"name": "test-service", "namespace": ""}, + clientOutput: &coreV1.Service{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test-service", + Namespace: "default", + }, + }, + expectedResult: "test-service", + }, + { + label: "Fail to get an non-existing namespace", + input: map[string]string{"name": "test-name", "namespace": "test-namespace"}, + clientOutput: &coreV1.Service{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "test-service", + Namespace: "default", + }, + }, + expectedError: "not found", }, } for _, testCase := range testCases { client := testclient.NewSimpleClientset(testCase.clientOutput) t.Run(testCase.label, func(t *testing.T) { - result, err := Get(testCase.input, namespace, client) + result, err := Get(testCase.input["name"], testCase.input["namespace"], client) if err != nil { - t.Fatalf("Get method returned an error (%s)", err) - } - if !reflect.DeepEqual(testCase.expectedResult, result) { - t.Fatalf("Get method returned %v and it was expected (%v)", result, testCase.expectedResult) + if testCase.expectedError == "" { + t.Fatalf("Get method return an un-expected (%s)", err) + } + if !strings.Contains(string(err.Error()), testCase.expectedError) { + t.Fatalf("Get method returned an error (%s)", err) + } + } else { + if testCase.expectedError != "" && testCase.expectedResult == "" { + t.Fatalf("Get method was expecting \"%s\" error message", testCase.expectedError) + } + if result == "" { + t.Fatal("Get method returned nil result") + } + if !reflect.DeepEqual(testCase.expectedResult, result) { + + t.Fatalf("Get method returned: \n%v\n and it was expected: \n%v", result, testCase.expectedResult) + } } }) } |