From 3f780f7973081903f1ab6ea01a855fb6c5512a48 Mon Sep 17 00:00:00 2001 From: Kiran Kamineni Date: Thu, 15 Nov 2018 17:09:54 -0800 Subject: Reconcile names in code and Jira items k8splugin manages deployment of resource bundles and these are not restricted to vnfs. This names' change is to reflect that functionality. P2: using rb instead of resource bundle Issue-ID: MULTICLOUD-410 Change-Id: I09e0b92a8fc13562e1c6bb17dc8bc13de97264d7 Signed-off-by: Kiran Kamineni --- src/k8splugin/api/api.go | 16 +- src/k8splugin/api/defhandler.go | 128 +++++++++++++ src/k8splugin/api/defhandler_test.go | 336 ++++++++++++++++++++++++++++++++++ src/k8splugin/api/vnfdhandler.go | 128 ------------- src/k8splugin/api/vnfdhandler_test.go | 336 ---------------------------------- src/k8splugin/rb/definition.go | 135 ++++++++++++++ src/k8splugin/rb/definition_test.go | 262 ++++++++++++++++++++++++++ src/k8splugin/vnfd/vnfd.go | 134 -------------- src/k8splugin/vnfd/vnfd_test.go | 262 -------------------------- 9 files changed, 869 insertions(+), 868 deletions(-) create mode 100644 src/k8splugin/api/defhandler.go create mode 100644 src/k8splugin/api/defhandler_test.go delete mode 100644 src/k8splugin/api/vnfdhandler.go delete mode 100644 src/k8splugin/api/vnfdhandler_test.go create mode 100644 src/k8splugin/rb/definition.go create mode 100644 src/k8splugin/rb/definition_test.go delete mode 100644 src/k8splugin/vnfd/vnfd.go delete mode 100644 src/k8splugin/vnfd/vnfd_test.go (limited to 'src') diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go index f05fbb0b..571a9576 100644 --- a/src/k8splugin/api/api.go +++ b/src/k8splugin/api/api.go @@ -14,7 +14,7 @@ limitations under the License. package api import ( - "k8splugin/vnfd" + "k8splugin/rb" "os" "path/filepath" "plugin" @@ -106,13 +106,13 @@ func NewRouter(kubeconfig string) *mux.Router { vnfInstanceHandler.HandleFunc("/{cloudRegionID}/{namespace}/{externalVNFID}", DeleteHandler).Methods("DELETE") vnfInstanceHandler.HandleFunc("/{cloudRegionID}/{namespace}/{externalVNFID}", GetHandler).Methods("GET") - vnfdRouter := router.PathPrefix("/v1/vnfd").Subrouter() - vh := vnfdHandler{vnfdClient: vnfd.GetVNFDClient()} - vnfdRouter.HandleFunc("", vh.vnfdCreateHandler).Methods("POST") - vnfdRouter.HandleFunc("/{vnfdID}/upload", vh.vnfdUploadHandler).Methods("POST") - vnfdRouter.HandleFunc("", vh.vnfdListHandler).Methods("GET") - vnfdRouter.HandleFunc("/{vnfdID}", vh.vnfdGetHandler).Methods("GET") - vnfdRouter.HandleFunc("/{vnfdID}", vh.vnfdDeleteHandler).Methods("DELETE") + resRouter := router.PathPrefix("/v1/rb").Subrouter() + rbdef := rbDefinitionHandler{client: rb.NewDefinitionClient()} + resRouter.HandleFunc("/definition", rbdef.createHandler).Methods("POST") + resRouter.HandleFunc("/definition/{rbdID}/upload", rbdef.uploadHandler).Methods("POST") + resRouter.HandleFunc("/definition", rbdef.listHandler).Methods("GET") + resRouter.HandleFunc("/definition/{rbdID}", rbdef.getHandler).Methods("GET") + resRouter.HandleFunc("/definition/{rbdID}", rbdef.deleteHandler).Methods("DELETE") // (TODO): Fix update method // vnfInstanceHandler.HandleFunc("/{vnfInstanceId}", UpdateHandler).Methods("PUT") diff --git a/src/k8splugin/api/defhandler.go b/src/k8splugin/api/defhandler.go new file mode 100644 index 00000000..c8c03496 --- /dev/null +++ b/src/k8splugin/api/defhandler.go @@ -0,0 +1,128 @@ +/* + * Copyright 2018 Intel Corporation, Inc + * + * 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 api + +import ( + "encoding/json" + "net/http" + + "k8splugin/rb" + + "github.com/gorilla/mux" +) + +// Used to store backend implementations objects +// Also simplifies mocking for unit testing purposes +type rbDefinitionHandler struct { + // Interface that implements bundle Definition operations + // We will set this variable with a mock interface for testing + client rb.DefinitionManager +} + +// createHandler handles creation of the definition entry in the database +func (h rbDefinitionHandler) createHandler(w http.ResponseWriter, r *http.Request) { + var v rb.Definition + + if r.Body == nil { + http.Error(w, "Empty body", http.StatusBadRequest) + return + } + + err := json.NewDecoder(r.Body).Decode(&v) + if err != nil { + http.Error(w, err.Error(), http.StatusUnprocessableEntity) + return + } + + // Name is required. + if v.Name == "" { + http.Error(w, "Missing name in POST request", http.StatusBadRequest) + return + } + + ret, err := h.client.Create(v) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusCreated) + err = json.NewEncoder(w).Encode(ret) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +// uploadHandler handles upload of the bundle tar file into the database +// Note: This will be implemented in a different patch +func (h rbDefinitionHandler) uploadHandler(w http.ResponseWriter, r *http.Request) { +} + +// listHandler handles GET (list) operations on the endpoint +// Returns a list of rb.Definitions +func (h rbDefinitionHandler) listHandler(w http.ResponseWriter, r *http.Request) { + ret, err := h.client.List() + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + err = json.NewEncoder(w).Encode(ret) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +// getHandler handles GET operations on a particular ids +// Returns a rb.Definition +func (h rbDefinitionHandler) getHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + id := vars["rbdID"] + + ret, err := h.client.Get(id) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + err = json.NewEncoder(w).Encode(ret) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + +// deleteHandler handles DELETE operations on a particular bundle definition id +func (h rbDefinitionHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + id := vars["rbdID"] + + err := h.client.Delete(id) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusNoContent) +} diff --git a/src/k8splugin/api/defhandler_test.go b/src/k8splugin/api/defhandler_test.go new file mode 100644 index 00000000..b83f0b7a --- /dev/null +++ b/src/k8splugin/api/defhandler_test.go @@ -0,0 +1,336 @@ +/* + * Copyright 2018 Intel Corporation, Inc + * + * 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 api + +import ( + "bytes" + "encoding/json" + "io" + "k8splugin/rb" + "net/http" + "net/http/httptest" + "reflect" + "testing" + + pkgerrors "github.com/pkg/errors" +) + +//Creating an embedded interface via anonymous variable +//This allows us to make mockDB satisfy the DatabaseConnection +//interface even if we are not implementing all the methods in it +type mockRBDefinition struct { + rb.DefinitionManager + // Items and err will be used to customize each test + // via a localized instantiation of mockRBDefinition + Items []rb.Definition + Err error +} + +func (m *mockRBDefinition) Create(inp rb.Definition) (rb.Definition, error) { + if m.Err != nil { + return rb.Definition{}, m.Err + } + + return m.Items[0], nil +} + +func (m *mockRBDefinition) List() ([]rb.Definition, error) { + if m.Err != nil { + return []rb.Definition{}, m.Err + } + + return m.Items, nil +} + +func (m *mockRBDefinition) Get(id string) (rb.Definition, error) { + if m.Err != nil { + return rb.Definition{}, m.Err + } + + return m.Items[0], nil +} + +func (m *mockRBDefinition) Delete(id string) error { + return m.Err +} + +func TestRBDefCreateHandler(t *testing.T) { + testCases := []struct { + label string + reader io.Reader + expected rb.Definition + expectedCode int + rbDefClient *mockRBDefinition + }{ + { + label: "Missing Body Failure", + expectedCode: http.StatusBadRequest, + rbDefClient: &mockRBDefinition{}, + }, + { + label: "Create without UUID", + expectedCode: http.StatusCreated, + reader: bytes.NewBuffer([]byte(`{ + "name":"testdomain", + "description":"test description", + "service-type":"firewall" + }`)), + expected: rb.Definition{ + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "test description", + ServiceType: "firewall", + }, + rbDefClient: &mockRBDefinition{ + //Items that will be returned by the mocked Client + Items: []rb.Definition{ + { + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "test description", + ServiceType: "firewall", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + vh := rbDefinitionHandler{client: testCase.rbDefClient} + req, err := http.NewRequest("POST", "/v1/resource/definition", testCase.reader) + + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + hr := http.HandlerFunc(vh.createHandler) + hr.ServeHTTP(rr, req) + + //Check returned code + if rr.Code != testCase.expectedCode { + t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) + } + + //Check returned body only if statusCreated + if rr.Code == http.StatusCreated { + got := rb.Definition{} + json.NewDecoder(rr.Body).Decode(&got) + + if reflect.DeepEqual(testCase.expected, got) == false { + t.Errorf("createHandler returned unexpected body: got %v;"+ + " expected %v", got, testCase.expected) + } + } + }) + } +} + +func TestRBDefListHandler(t *testing.T) { + + testCases := []struct { + label string + expected []rb.Definition + expectedCode int + rbDefClient *mockRBDefinition + }{ + { + label: "List Bundle Definitions", + expectedCode: http.StatusOK, + expected: []rb.Definition{ + { + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "test description", + ServiceType: "firewall", + }, + { + UUID: "123e4567-e89b-12d3-a456-426655441111", + Name: "testresourcebundle2", + Description: "test description", + ServiceType: "dns", + }, + }, + rbDefClient: &mockRBDefinition{ + // list of definitions that will be returned by the mockclient + Items: []rb.Definition{ + { + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "test description", + ServiceType: "firewall", + }, + { + UUID: "123e4567-e89b-12d3-a456-426655441111", + Name: "testresourcebundle2", + Description: "test description", + ServiceType: "dns", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + vh := rbDefinitionHandler{client: testCase.rbDefClient} + req, err := http.NewRequest("GET", "/v1/resource/definition", nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + hr := http.HandlerFunc(vh.listHandler) + + hr.ServeHTTP(rr, req) + //Check returned code + if rr.Code != testCase.expectedCode { + t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) + } + + //Check returned body only if statusOK + if rr.Code == http.StatusOK { + got := []rb.Definition{} + json.NewDecoder(rr.Body).Decode(&got) + + if reflect.DeepEqual(testCase.expected, got) == false { + t.Errorf("listHandler returned unexpected body: got %v;"+ + " expected %v", got, testCase.expected) + } + } + }) + } +} + +func TestRBDefGetHandler(t *testing.T) { + + testCases := []struct { + label string + expected rb.Definition + inpUUID string + expectedCode int + rbDefClient *mockRBDefinition + }{ + { + label: "Get Bundle Definition", + expectedCode: http.StatusOK, + expected: rb.Definition{ + UUID: "123e4567-e89b-12d3-a456-426655441111", + Name: "testresourcebundle2", + Description: "test description", + ServiceType: "dns", + }, + inpUUID: "123e4567-e89b-12d3-a456-426655441111", + rbDefClient: &mockRBDefinition{ + // list of definitions that will be returned by the mockclient + Items: []rb.Definition{ + { + UUID: "123e4567-e89b-12d3-a456-426655441111", + Name: "testresourcebundle2", + Description: "test description", + ServiceType: "dns", + }, + }, + }, + }, + { + label: "Get Non-Exiting Bundle Definition", + expectedCode: http.StatusInternalServerError, + inpUUID: "123e4567-e89b-12d3-a456-426655440000", + rbDefClient: &mockRBDefinition{ + // list of definitions that will be returned by the mockclient + Items: []rb.Definition{}, + Err: pkgerrors.New("Internal Error"), + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + vh := rbDefinitionHandler{client: testCase.rbDefClient} + req, err := http.NewRequest("GET", "/v1/resource/definition/"+testCase.inpUUID, nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + hr := http.HandlerFunc(vh.getHandler) + + hr.ServeHTTP(rr, req) + //Check returned code + if rr.Code != testCase.expectedCode { + t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) + } + + //Check returned body only if statusOK + if rr.Code == http.StatusOK { + got := rb.Definition{} + json.NewDecoder(rr.Body).Decode(&got) + + if reflect.DeepEqual(testCase.expected, got) == false { + t.Errorf("listHandler returned unexpected body: got %v;"+ + " expected %v", got, testCase.expected) + } + } + }) + } +} + +func TestRBDefDeleteHandler(t *testing.T) { + + testCases := []struct { + label string + inpUUID string + expectedCode int + rbDefClient *mockRBDefinition + }{ + { + label: "Delete Bundle Definition", + expectedCode: http.StatusNoContent, + inpUUID: "123e4567-e89b-12d3-a456-426655441111", + rbDefClient: &mockRBDefinition{}, + }, + { + label: "Delete Non-Exiting Bundle Definition", + expectedCode: http.StatusInternalServerError, + inpUUID: "123e4567-e89b-12d3-a456-426655440000", + rbDefClient: &mockRBDefinition{ + Err: pkgerrors.New("Internal Error"), + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + vh := rbDefinitionHandler{client: testCase.rbDefClient} + req, err := http.NewRequest("GET", "/v1/resource/definition/"+testCase.inpUUID, nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + hr := http.HandlerFunc(vh.deleteHandler) + + hr.ServeHTTP(rr, req) + //Check returned code + if rr.Code != testCase.expectedCode { + t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) + } + }) + } +} diff --git a/src/k8splugin/api/vnfdhandler.go b/src/k8splugin/api/vnfdhandler.go deleted file mode 100644 index ff777826..00000000 --- a/src/k8splugin/api/vnfdhandler.go +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2018 Intel Corporation, Inc - * - * 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 api - -import ( - "encoding/json" - "net/http" - - "k8splugin/vnfd" - - "github.com/gorilla/mux" -) - -// Used to store backend implementations objects -// Also simplifies mocking for unit testing purposes -type vnfdHandler struct { - // Interface that implements vnfDefinition operations - // We will set this variable with a mock interface for testing - vnfdClient vnfd.VNFDefinitionInterface -} - -// vnfdCreateHandler handles creation of the vnfd entry in the database -func (h vnfdHandler) vnfdCreateHandler(w http.ResponseWriter, r *http.Request) { - var v vnfd.VNFDefinition - - if r.Body == nil { - http.Error(w, "Empty body", http.StatusBadRequest) - return - } - - err := json.NewDecoder(r.Body).Decode(&v) - if err != nil { - http.Error(w, err.Error(), http.StatusUnprocessableEntity) - return - } - - // Name is required. - if v.Name == "" { - http.Error(w, "Missing name in POST request", http.StatusBadRequest) - return - } - - ret, err := h.vnfdClient.Create(v) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusCreated) - err = json.NewEncoder(w).Encode(ret) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} - -// vnfdUploadHandler handles upload of the vnf tar file into the database -// Note: This will be implemented in a different patch -func (h vnfdHandler) vnfdUploadHandler(w http.ResponseWriter, r *http.Request) { -} - -// vnfdListHandler handles GET (list) operations on the /v1/vnfd endpoint -// Returns a list of vnfd.VNFDefinitions -func (h vnfdHandler) vnfdListHandler(w http.ResponseWriter, r *http.Request) { - ret, err := h.vnfdClient.List() - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - err = json.NewEncoder(w).Encode(ret) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} - -// vnfdGetHandler handles GET operations on a particular VNFID -// Returns a vnfd.VNFDefinition -func (h vnfdHandler) vnfdGetHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - vnfdID := vars["vnfdID"] - - ret, err := h.vnfdClient.Get(vnfdID) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - err = json.NewEncoder(w).Encode(ret) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} - -// vnfdDeleteHandler handles DELETE operations on a particular VNFID -func (h vnfdHandler) vnfdDeleteHandler(w http.ResponseWriter, r *http.Request) { - vars := mux.Vars(r) - vnfdID := vars["vnfdID"] - - err := h.vnfdClient.Delete(vnfdID) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - w.WriteHeader(http.StatusNoContent) -} diff --git a/src/k8splugin/api/vnfdhandler_test.go b/src/k8splugin/api/vnfdhandler_test.go deleted file mode 100644 index e393be6f..00000000 --- a/src/k8splugin/api/vnfdhandler_test.go +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2018 Intel Corporation, Inc - * - * 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 api - -import ( - "bytes" - "encoding/json" - "io" - "k8splugin/vnfd" - "net/http" - "net/http/httptest" - "reflect" - "testing" - - pkgerrors "github.com/pkg/errors" -) - -//Creating an embedded interface via anonymous variable -//This allows us to make mockDB satisfy the DatabaseConnection -//interface even if we are not implementing all the methods in it -type mockVNFDefinition struct { - vnfd.VNFDefinitionInterface - // Items and err will be used to customize each test - // via a localized instantiation of mockVNFDefinition - Items []vnfd.VNFDefinition - Err error -} - -func (m *mockVNFDefinition) Create(inp vnfd.VNFDefinition) (vnfd.VNFDefinition, error) { - if m.Err != nil { - return vnfd.VNFDefinition{}, m.Err - } - - return m.Items[0], nil -} - -func (m *mockVNFDefinition) List() ([]vnfd.VNFDefinition, error) { - if m.Err != nil { - return []vnfd.VNFDefinition{}, m.Err - } - - return m.Items, nil -} - -func (m *mockVNFDefinition) Get(vnfID string) (vnfd.VNFDefinition, error) { - if m.Err != nil { - return vnfd.VNFDefinition{}, m.Err - } - - return m.Items[0], nil -} - -func (m *mockVNFDefinition) Delete(vnfID string) error { - return m.Err -} - -func TestVnfdCreateHandler(t *testing.T) { - testCases := []struct { - label string - reader io.Reader - expected vnfd.VNFDefinition - expectedCode int - vnfdClient *mockVNFDefinition - }{ - { - label: "Missing Body Failure", - expectedCode: http.StatusBadRequest, - vnfdClient: &mockVNFDefinition{}, - }, - { - label: "Create without UUID", - expectedCode: http.StatusCreated, - reader: bytes.NewBuffer([]byte(`{ - "name":"testdomain", - "description":"test description", - "service-type":"firewall" - }`)), - expected: vnfd.VNFDefinition{ - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "test description", - ServiceType: "firewall", - }, - vnfdClient: &mockVNFDefinition{ - //Items that will be returned by the mocked Client - Items: []vnfd.VNFDefinition{ - { - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "test description", - ServiceType: "firewall", - }, - }, - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - vh := vnfdHandler{vnfdClient: testCase.vnfdClient} - req, err := http.NewRequest("POST", "/v1/vnfd", testCase.reader) - - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - hr := http.HandlerFunc(vh.vnfdCreateHandler) - hr.ServeHTTP(rr, req) - - //Check returned code - if rr.Code != testCase.expectedCode { - t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) - } - - //Check returned body only if statusCreated - if rr.Code == http.StatusCreated { - got := vnfd.VNFDefinition{} - json.NewDecoder(rr.Body).Decode(&got) - - if reflect.DeepEqual(testCase.expected, got) == false { - t.Errorf("vnfdCreateHandler returned unexpected body: got %v;"+ - " expected %v", got, testCase.expected) - } - } - }) - } -} - -func TestVnfdListHandler(t *testing.T) { - - testCases := []struct { - label string - expected []vnfd.VNFDefinition - expectedCode int - vnfdClient *mockVNFDefinition - }{ - { - label: "List VNF Definitions", - expectedCode: http.StatusOK, - expected: []vnfd.VNFDefinition{ - { - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "test description", - ServiceType: "firewall", - }, - { - UUID: "123e4567-e89b-12d3-a456-426655441111", - Name: "testvnf2", - Description: "test description", - ServiceType: "dns", - }, - }, - vnfdClient: &mockVNFDefinition{ - // list of definitions that will be returned by the mockclient - Items: []vnfd.VNFDefinition{ - { - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "test description", - ServiceType: "firewall", - }, - { - UUID: "123e4567-e89b-12d3-a456-426655441111", - Name: "testvnf2", - Description: "test description", - ServiceType: "dns", - }, - }, - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - vh := vnfdHandler{vnfdClient: testCase.vnfdClient} - req, err := http.NewRequest("GET", "/v1/vnfd", nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - hr := http.HandlerFunc(vh.vnfdListHandler) - - hr.ServeHTTP(rr, req) - //Check returned code - if rr.Code != testCase.expectedCode { - t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) - } - - //Check returned body only if statusOK - if rr.Code == http.StatusOK { - got := []vnfd.VNFDefinition{} - json.NewDecoder(rr.Body).Decode(&got) - - if reflect.DeepEqual(testCase.expected, got) == false { - t.Errorf("vnfdListHandler returned unexpected body: got %v;"+ - " expected %v", got, testCase.expected) - } - } - }) - } -} - -func TestVnfdGetHandler(t *testing.T) { - - testCases := []struct { - label string - expected vnfd.VNFDefinition - inpUUID string - expectedCode int - vnfdClient *mockVNFDefinition - }{ - { - label: "Get VNF Definition", - expectedCode: http.StatusOK, - expected: vnfd.VNFDefinition{ - UUID: "123e4567-e89b-12d3-a456-426655441111", - Name: "testvnf2", - Description: "test description", - ServiceType: "dns", - }, - inpUUID: "123e4567-e89b-12d3-a456-426655441111", - vnfdClient: &mockVNFDefinition{ - // list of definitions that will be returned by the mockclient - Items: []vnfd.VNFDefinition{ - { - UUID: "123e4567-e89b-12d3-a456-426655441111", - Name: "testvnf2", - Description: "test description", - ServiceType: "dns", - }, - }, - }, - }, - { - label: "Get Non-Exiting VNF Definition", - expectedCode: http.StatusInternalServerError, - inpUUID: "123e4567-e89b-12d3-a456-426655440000", - vnfdClient: &mockVNFDefinition{ - // list of definitions that will be returned by the mockclient - Items: []vnfd.VNFDefinition{}, - Err: pkgerrors.New("Internal Error"), - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - vh := vnfdHandler{vnfdClient: testCase.vnfdClient} - req, err := http.NewRequest("GET", "/v1/vnfd/"+testCase.inpUUID, nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - hr := http.HandlerFunc(vh.vnfdGetHandler) - - hr.ServeHTTP(rr, req) - //Check returned code - if rr.Code != testCase.expectedCode { - t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) - } - - //Check returned body only if statusOK - if rr.Code == http.StatusOK { - got := vnfd.VNFDefinition{} - json.NewDecoder(rr.Body).Decode(&got) - - if reflect.DeepEqual(testCase.expected, got) == false { - t.Errorf("vnfdListHandler returned unexpected body: got %v;"+ - " expected %v", got, testCase.expected) - } - } - }) - } -} - -func TestVnfdDeleteHandler(t *testing.T) { - - testCases := []struct { - label string - inpUUID string - expectedCode int - vnfdClient *mockVNFDefinition - }{ - { - label: "Delete VNF Definition", - expectedCode: http.StatusNoContent, - inpUUID: "123e4567-e89b-12d3-a456-426655441111", - vnfdClient: &mockVNFDefinition{}, - }, - { - label: "Delete Non-Exiting VNF Definition", - expectedCode: http.StatusInternalServerError, - inpUUID: "123e4567-e89b-12d3-a456-426655440000", - vnfdClient: &mockVNFDefinition{ - Err: pkgerrors.New("Internal Error"), - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - vh := vnfdHandler{vnfdClient: testCase.vnfdClient} - req, err := http.NewRequest("GET", "/v1/vnfd/"+testCase.inpUUID, nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - hr := http.HandlerFunc(vh.vnfdDeleteHandler) - - hr.ServeHTTP(rr, req) - //Check returned code - if rr.Code != testCase.expectedCode { - t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code) - } - }) - } -} diff --git a/src/k8splugin/rb/definition.go b/src/k8splugin/rb/definition.go new file mode 100644 index 00000000..03fffdda --- /dev/null +++ b/src/k8splugin/rb/definition.go @@ -0,0 +1,135 @@ +/* + * Copyright 2018 Intel Corporation, Inc + * + * 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 rb + +import ( + "k8splugin/db" + "log" + + uuid "github.com/hashicorp/go-uuid" + pkgerrors "github.com/pkg/errors" +) + +// Definition contains the parameters needed for resource bundle (rb) definitions +// It implements the interface for managing the definitions +type Definition struct { + Name string `json:"name"` + Description string `json:"description"` + UUID string `json:"uuid,omitempty"` + ServiceType string `json:"service-type"` +} + +// DefinitionManager is an interface exposes the resource bundle definition functionality +type DefinitionManager interface { + Create(def Definition) (Definition, error) + List() ([]Definition, error) + Get(resID string) (Definition, error) + Delete(resID string) error +} + +// DefinitionClient implements the DefinitionManager +// It will also be used to maintain some localized state +type DefinitionClient struct { + keyPrefix string +} + +// NewDefinitionClient returns an instance of the DefinitionClient +// which implements the DefinitionManager +// Uses rb/def prefix +func NewDefinitionClient() *DefinitionClient { + return &DefinitionClient{ + keyPrefix: "rb/def/"} +} + +// Create an entry for the resource in the database +func (v *DefinitionClient) Create(def Definition) (Definition, error) { + // If UUID is empty, we will generate one + if def.UUID == "" { + def.UUID, _ = uuid.GenerateUUID() + } + key := v.keyPrefix + def.UUID + + serData, err := db.Serialize(v) + if err != nil { + return Definition{}, pkgerrors.Wrap(err, "Serialize Resource Bundle Definition") + } + + err = db.DBconn.Create(key, serData) + if err != nil { + return Definition{}, pkgerrors.Wrap(err, "Creating DB Entry") + } + + return def, nil +} + +// List all resource entries in the database +func (v *DefinitionClient) List() ([]Definition, error) { + strArray, err := db.DBconn.ReadAll(v.keyPrefix) + if err != nil { + return []Definition{}, pkgerrors.Wrap(err, "Listing Resource Bundle Definitions") + } + + var retData []Definition + + for _, key := range strArray { + value, err := db.DBconn.Read(key) + if err != nil { + log.Printf("Error Reading Key: %s", key) + continue + } + if value != "" { + def := Definition{} + err = db.DeSerialize(value, &def) + if err != nil { + log.Printf("Error Deserializing Value: %s", value) + continue + } + retData = append(retData, def) + } + } + + return retData, nil +} + +// Get returns the Resource Bundle Definition for corresponding ID +func (v *DefinitionClient) Get(id string) (Definition, error) { + value, err := db.DBconn.Read(v.keyPrefix + id) + if err != nil { + return Definition{}, pkgerrors.Wrap(err, "Get Resource Bundle definition") + } + + if value != "" { + def := Definition{} + err = db.DeSerialize(value, &def) + if err != nil { + return Definition{}, pkgerrors.Wrap(err, "Deserializing Value") + } + return def, nil + } + + return Definition{}, pkgerrors.New("Error getting Resource Bundle Definition") +} + +// Delete the Resource Bundle definition from database +func (v *DefinitionClient) Delete(id string) error { + err := db.DBconn.Delete(v.keyPrefix + id) + if err != nil { + return pkgerrors.Wrap(err, "Delete Resource Bundle Definitions") + } + + return nil +} diff --git a/src/k8splugin/rb/definition_test.go b/src/k8splugin/rb/definition_test.go new file mode 100644 index 00000000..a3993c8c --- /dev/null +++ b/src/k8splugin/rb/definition_test.go @@ -0,0 +1,262 @@ +// +build unit + +/* + * Copyright 2018 Intel Corporation, Inc + * + * 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 rb + +import ( + "k8splugin/db" + "reflect" + "strings" + "testing" + + "github.com/hashicorp/consul/api" + pkgerrors "github.com/pkg/errors" +) + +func TestCreate(t *testing.T) { + testCases := []struct { + label string + inp Definition + expectedError string + mockdb *db.MockDB + expected Definition + }{ + { + label: "Create Resource Bundle Definition", + inp: Definition{ + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "testresourcebundle", + ServiceType: "firewall", + }, + expected: Definition{ + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "testresourcebundle", + ServiceType: "firewall", + }, + expectedError: "", + mockdb: &db.MockDB{}, + }, + { + label: "Failed Create Resource Bundle Definition", + expectedError: "Error Creating Definition", + mockdb: &db.MockDB{ + Err: pkgerrors.New("Error Creating Definition"), + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + db.DBconn = testCase.mockdb + impl := NewDefinitionClient() + got, err := impl.Create(testCase.inp) + if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Create returned an unexpected error %s", err) + } + if strings.Contains(err.Error(), testCase.expectedError) == false { + t.Fatalf("Create returned an unexpected error %s", err) + } + } else { + if reflect.DeepEqual(testCase.expected, got) == false { + t.Errorf("Create Resource Bundle returned unexpected body: got %v;"+ + " expected %v", got, testCase.expected) + } + } + }) + } +} + +func TestList(t *testing.T) { + + testCases := []struct { + label string + expectedError string + mockdb *db.MockDB + expected []Definition + }{ + { + label: "List Resource Bundle Definition", + expected: []Definition{ + { + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "testresourcebundle", + ServiceType: "firewall", + }, + { + UUID: "123e4567-e89b-12d3-a456-426655441111", + Name: "testresourcebundle2", + Description: "testresourcebundle2", + ServiceType: "dns", + }, + }, + expectedError: "", + mockdb: &db.MockDB{ + Items: api.KVPairs{ + &api.KVPair{ + Key: "rb/def/123e4567-e89b-12d3-a456-426655440000", + Value: []byte("{\"name\":\"testresourcebundle\"," + + "\"description\":\"testresourcebundle\"," + + "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," + + "\"service-type\":\"firewall\"}"), + }, + &api.KVPair{ + Key: "rb/def/123e4567-e89b-12d3-a456-426655441111", + Value: []byte("{\"name\":\"testresourcebundle2\"," + + "\"description\":\"testresourcebundle2\"," + + "\"uuid\":\"123e4567-e89b-12d3-a456-426655441111\"," + + "\"service-type\":\"dns\"}"), + }, + }, + }, + }, + { + label: "List Error", + expectedError: "DB Error", + mockdb: &db.MockDB{ + Err: pkgerrors.New("DB Error"), + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + db.DBconn = testCase.mockdb + impl := NewDefinitionClient() + got, err := impl.List() + if err != nil { + if testCase.expectedError == "" { + t.Fatalf("List returned an unexpected error %s", err) + } + if strings.Contains(err.Error(), testCase.expectedError) == false { + t.Fatalf("List returned an unexpected error %s", err) + } + } else { + if reflect.DeepEqual(testCase.expected, got) == false { + t.Errorf("List Resource Bundle returned unexpected body: got %v;"+ + " expected %v", got, testCase.expected) + } + } + }) + } +} + +func TestGet(t *testing.T) { + + testCases := []struct { + label string + expectedError string + mockdb *db.MockDB + inp string + expected Definition + }{ + { + label: "Get Resource Bundle Definition", + inp: "123e4567-e89b-12d3-a456-426655440000", + expected: Definition{ + UUID: "123e4567-e89b-12d3-a456-426655440000", + Name: "testresourcebundle", + Description: "testresourcebundle", + ServiceType: "firewall", + }, + expectedError: "", + mockdb: &db.MockDB{ + Items: api.KVPairs{ + &api.KVPair{ + Key: "rb/def/123e4567-e89b-12d3-a456-426655440000", + Value: []byte("{\"name\":\"testresourcebundle\"," + + "\"description\":\"testresourcebundle\"," + + "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," + + "\"service-type\":\"firewall\"}"), + }, + }, + }, + }, + { + label: "Get Error", + expectedError: "DB Error", + mockdb: &db.MockDB{ + Err: pkgerrors.New("DB Error"), + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + db.DBconn = testCase.mockdb + impl := NewDefinitionClient() + got, err := impl.Get(testCase.inp) + if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Get returned an unexpected error %s", err) + } + if strings.Contains(err.Error(), testCase.expectedError) == false { + t.Fatalf("Get returned an unexpected error %s", err) + } + } else { + if reflect.DeepEqual(testCase.expected, got) == false { + t.Errorf("Get Resource Bundle returned unexpected body: got %v;"+ + " expected %v", got, testCase.expected) + } + } + }) + } +} + +func TestDelete(t *testing.T) { + + testCases := []struct { + label string + inp string + expectedError string + mockdb *db.MockDB + expected []Definition + }{ + { + label: "Delete Resource Bundle Definition", + inp: "123e4567-e89b-12d3-a456-426655440000", + mockdb: &db.MockDB{}, + }, + { + label: "Delete Error", + expectedError: "DB Error", + mockdb: &db.MockDB{ + Err: pkgerrors.New("DB Error"), + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + db.DBconn = testCase.mockdb + impl := NewDefinitionClient() + err := impl.Delete(testCase.inp) + if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Delete returned an unexpected error %s", err) + } + if strings.Contains(err.Error(), testCase.expectedError) == false { + t.Fatalf("Delete returned an unexpected error %s", err) + } + } + }) + } +} diff --git a/src/k8splugin/vnfd/vnfd.go b/src/k8splugin/vnfd/vnfd.go deleted file mode 100644 index 0fb81dbd..00000000 --- a/src/k8splugin/vnfd/vnfd.go +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2018 Intel Corporation, Inc - * - * 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 vnfd - -import ( - "k8splugin/db" - "log" - - uuid "github.com/hashicorp/go-uuid" - pkgerrors "github.com/pkg/errors" -) - -// VNFDefinition contains the parameters needed for VNF Definitions -// It implements the interface for managing the definitions -type VNFDefinition struct { - Name string `json:"name"` - Description string `json:"description"` - UUID string `json:"uuid,omitempty"` - ServiceType string `json:"service-type"` -} - -// VNFDefinitionInterface is an interface exposes the VNFDefinition functionality -type VNFDefinitionInterface interface { - Create(vnfd VNFDefinition) (VNFDefinition, error) - List() ([]VNFDefinition, error) - Get(vnfID string) (VNFDefinition, error) - Delete(vnfID string) error -} - -// VNFDefinitionClient implements the VNFDefinitionInterface -// It will also be used to maintain some localized state -type VNFDefinitionClient struct { - keyPrefix string -} - -// GetVNFDClient Returns an instance of the VNFDefinitionClient -// which implements the VNFDefinitionInterface interface -func GetVNFDClient() *VNFDefinitionClient { - return &VNFDefinitionClient{ - keyPrefix: "vnfd/"} -} - -// Create creates an entry for the VNF in the database -func (v *VNFDefinitionClient) Create(vnfd VNFDefinition) (VNFDefinition, error) { - // If UUID is empty, we will generate one - if vnfd.UUID == "" { - vnfd.UUID, _ = uuid.GenerateUUID() - } - key := v.keyPrefix + vnfd.UUID - - serData, err := db.Serialize(v) - if err != nil { - return VNFDefinition{}, pkgerrors.Wrap(err, "Serialize VNF Definition") - } - - err = db.DBconn.Create(key, serData) - if err != nil { - return VNFDefinition{}, pkgerrors.Wrap(err, "Creating DB Entry") - } - - return vnfd, nil -} - -// List lists all vnf entries in the database -func (v *VNFDefinitionClient) List() ([]VNFDefinition, error) { - strArray, err := db.DBconn.ReadAll(v.keyPrefix) - if err != nil { - return []VNFDefinition{}, pkgerrors.Wrap(err, "Listing VNF Definitions") - } - - var retData []VNFDefinition - - for _, key := range strArray { - value, err := db.DBconn.Read(key) - if err != nil { - log.Printf("Error Reading Key: %s", key) - continue - } - if value != "" { - vnfd := VNFDefinition{} - err = db.DeSerialize(value, &vnfd) - if err != nil { - log.Printf("Error Deserializing Value: %s", value) - continue - } - retData = append(retData, vnfd) - } - } - - return retData, nil -} - -// Get returns the VNF Definition for corresponding ID -func (v *VNFDefinitionClient) Get(vnfID string) (VNFDefinition, error) { - value, err := db.DBconn.Read(v.keyPrefix + vnfID) - if err != nil { - return VNFDefinition{}, pkgerrors.Wrap(err, "Get VNF Definitions") - } - - if value != "" { - vnfd := VNFDefinition{} - err = db.DeSerialize(value, &vnfd) - if err != nil { - return VNFDefinition{}, pkgerrors.Wrap(err, "Deserializing Value") - } - return vnfd, nil - } - - return VNFDefinition{}, pkgerrors.New("Error getting VNF Definition") -} - -// Delete deletes the VNF Definition from database -func (v *VNFDefinitionClient) Delete(vnfID string) error { - err := db.DBconn.Delete(v.keyPrefix + vnfID) - if err != nil { - return pkgerrors.Wrap(err, "Delete VNF Definitions") - } - - return nil -} diff --git a/src/k8splugin/vnfd/vnfd_test.go b/src/k8splugin/vnfd/vnfd_test.go deleted file mode 100644 index 3230d3ef..00000000 --- a/src/k8splugin/vnfd/vnfd_test.go +++ /dev/null @@ -1,262 +0,0 @@ -// +build unit - -/* - * Copyright 2018 Intel Corporation, Inc - * - * 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 vnfd - -import ( - "k8splugin/db" - "reflect" - "strings" - "testing" - - "github.com/hashicorp/consul/api" - pkgerrors "github.com/pkg/errors" -) - -func TestCreate(t *testing.T) { - testCases := []struct { - label string - inp VNFDefinition - expectedError string - mockdb *db.MockDB - expected VNFDefinition - }{ - { - label: "Create VNF Definition", - inp: VNFDefinition{ - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "testvnf", - ServiceType: "firewall", - }, - expected: VNFDefinition{ - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "testvnf", - ServiceType: "firewall", - }, - expectedError: "", - mockdb: &db.MockDB{}, - }, - { - label: "Failed Create VNF Definition", - expectedError: "Error Creating Definition", - mockdb: &db.MockDB{ - Err: pkgerrors.New("Error Creating Definition"), - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - db.DBconn = testCase.mockdb - vimpl := GetVNFDClient() - got, err := vimpl.Create(testCase.inp) - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("Create returned an unexpected error %s", err) - } - if strings.Contains(err.Error(), testCase.expectedError) == false { - t.Fatalf("Create returned an unexpected error %s", err) - } - } else { - if reflect.DeepEqual(testCase.expected, got) == false { - t.Errorf("Create VNF returned unexpected body: got %v;"+ - " expected %v", got, testCase.expected) - } - } - }) - } -} - -func TestList(t *testing.T) { - - testCases := []struct { - label string - expectedError string - mockdb *db.MockDB - expected []VNFDefinition - }{ - { - label: "List VNF Definition", - expected: []VNFDefinition{ - { - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "testvnf", - ServiceType: "firewall", - }, - { - UUID: "123e4567-e89b-12d3-a456-426655441111", - Name: "testvnf2", - Description: "testvnf2", - ServiceType: "dns", - }, - }, - expectedError: "", - mockdb: &db.MockDB{ - Items: api.KVPairs{ - &api.KVPair{ - Key: "vnfd/123e4567-e89b-12d3-a456-426655440000", - Value: []byte("{\"name\":\"testvnf\"," + - "\"description\":\"testvnf\"," + - "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," + - "\"service-type\":\"firewall\"}"), - }, - &api.KVPair{ - Key: "vnfd/123e4567-e89b-12d3-a456-426655441111", - Value: []byte("{\"name\":\"testvnf2\"," + - "\"description\":\"testvnf2\"," + - "\"uuid\":\"123e4567-e89b-12d3-a456-426655441111\"," + - "\"service-type\":\"dns\"}"), - }, - }, - }, - }, - { - label: "List Error", - expectedError: "DB Error", - mockdb: &db.MockDB{ - Err: pkgerrors.New("DB Error"), - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - db.DBconn = testCase.mockdb - vimpl := GetVNFDClient() - got, err := vimpl.List() - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("List returned an unexpected error %s", err) - } - if strings.Contains(err.Error(), testCase.expectedError) == false { - t.Fatalf("List returned an unexpected error %s", err) - } - } else { - if reflect.DeepEqual(testCase.expected, got) == false { - t.Errorf("List VNF returned unexpected body: got %v;"+ - " expected %v", got, testCase.expected) - } - } - }) - } -} - -func TestGet(t *testing.T) { - - testCases := []struct { - label string - expectedError string - mockdb *db.MockDB - inp string - expected VNFDefinition - }{ - { - label: "Get VNF Definition", - inp: "123e4567-e89b-12d3-a456-426655440000", - expected: VNFDefinition{ - UUID: "123e4567-e89b-12d3-a456-426655440000", - Name: "testvnf", - Description: "testvnf", - ServiceType: "firewall", - }, - expectedError: "", - mockdb: &db.MockDB{ - Items: api.KVPairs{ - &api.KVPair{ - Key: "vnfd/123e4567-e89b-12d3-a456-426655440000", - Value: []byte("{\"name\":\"testvnf\"," + - "\"description\":\"testvnf\"," + - "\"uuid\":\"123e4567-e89b-12d3-a456-426655440000\"," + - "\"service-type\":\"firewall\"}"), - }, - }, - }, - }, - { - label: "Get Error", - expectedError: "DB Error", - mockdb: &db.MockDB{ - Err: pkgerrors.New("DB Error"), - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - db.DBconn = testCase.mockdb - vimpl := GetVNFDClient() - got, err := vimpl.Get(testCase.inp) - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("Get returned an unexpected error %s", err) - } - if strings.Contains(err.Error(), testCase.expectedError) == false { - t.Fatalf("Get returned an unexpected error %s", err) - } - } else { - if reflect.DeepEqual(testCase.expected, got) == false { - t.Errorf("Get VNF returned unexpected body: got %v;"+ - " expected %v", got, testCase.expected) - } - } - }) - } -} - -func TestDelete(t *testing.T) { - - testCases := []struct { - label string - inp string - expectedError string - mockdb *db.MockDB - expected []VNFDefinition - }{ - { - label: "Delete VNF Definition", - inp: "123e4567-e89b-12d3-a456-426655440000", - mockdb: &db.MockDB{}, - }, - { - label: "Delete Error", - expectedError: "DB Error", - mockdb: &db.MockDB{ - Err: pkgerrors.New("DB Error"), - }, - }, - } - - for _, testCase := range testCases { - t.Run(testCase.label, func(t *testing.T) { - db.DBconn = testCase.mockdb - vimpl := GetVNFDClient() - err := vimpl.Delete(testCase.inp) - if err != nil { - if testCase.expectedError == "" { - t.Fatalf("Delete returned an unexpected error %s", err) - } - if strings.Contains(err.Error(), testCase.expectedError) == false { - t.Fatalf("Delete returned an unexpected error %s", err) - } - } - }) - } -} -- cgit 1.2.3-korg