diff options
Diffstat (limited to 'src/k8splugin/api')
-rw-r--r-- | src/k8splugin/api/api.go | 2 | ||||
-rw-r--r-- | src/k8splugin/api/instancehandler.go | 18 | ||||
-rw-r--r-- | src/k8splugin/api/instancehandler_test.go | 118 | ||||
-rw-r--r-- | src/k8splugin/api/profilehandler.go | 25 | ||||
-rw-r--r-- | src/k8splugin/api/profilehandler_test.go | 101 |
5 files changed, 261 insertions, 3 deletions
diff --git a/src/k8splugin/api/api.go b/src/k8splugin/api/api.go index 353972a1..ea7b5b26 100644 --- a/src/k8splugin/api/api.go +++ b/src/k8splugin/api/api.go @@ -38,6 +38,7 @@ func NewRouter(defClient rb.DefinitionManager, instHandler := instanceHandler{client: instClient} instRouter := router.PathPrefix("/v1").Subrouter() instRouter.HandleFunc("/instance", instHandler.createHandler).Methods("POST") + instRouter.HandleFunc("/instance", instHandler.listHandler).Methods("GET") instRouter.HandleFunc("/instance/{instID}", instHandler.getHandler).Methods("GET") instRouter.HandleFunc("/instance/{instID}", instHandler.deleteHandler).Methods("DELETE") // (TODO): Fix update method @@ -78,6 +79,7 @@ func NewRouter(defClient rb.DefinitionManager, } profileHandler := rbProfileHandler{client: profileClient} resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile", profileHandler.createHandler).Methods("POST") + resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile", profileHandler.listHandler).Methods("GET") resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}/content", profileHandler.uploadHandler).Methods("POST") resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.getHandler).Methods("GET") resRouter.HandleFunc("/definition/{rbname}/{rbversion}/profile/{prname}", profileHandler.deleteHandler).Methods("DELETE") diff --git a/src/k8splugin/api/instancehandler.go b/src/k8splugin/api/instancehandler.go index 42f3b212..3ec055bc 100644 --- a/src/k8splugin/api/instancehandler.go +++ b/src/k8splugin/api/instancehandler.go @@ -106,6 +106,24 @@ func (i instanceHandler) getHandler(w http.ResponseWriter, r *http.Request) { } } +// getHandler retrieves information about an instance via the ID +func (i instanceHandler) listHandler(w http.ResponseWriter, r *http.Request) { + + resp, err := i.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(resp) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } +} + // deleteHandler method terminates an instance via the ID func (i instanceHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) diff --git a/src/k8splugin/api/instancehandler_test.go b/src/k8splugin/api/instancehandler_test.go index 35cef531..83fa3d2b 100644 --- a/src/k8splugin/api/instancehandler_test.go +++ b/src/k8splugin/api/instancehandler_test.go @@ -21,6 +21,7 @@ import ( "net/http" "net/http/httptest" "reflect" + "sort" "testing" "github.com/onap/multicloud-k8s/src/k8splugin/internal/app" @@ -38,8 +39,9 @@ type mockInstanceClient struct { app.InstanceManager // Items and err will be used to customize each test // via a localized instantiation of mockInstanceClient - items []app.InstanceResponse - err error + items []app.InstanceResponse + miniitems []app.InstanceMiniResponse + err error } func (m *mockInstanceClient) Create(inp app.InstanceRequest) (app.InstanceResponse, error) { @@ -58,6 +60,14 @@ func (m *mockInstanceClient) Get(id string) (app.InstanceResponse, error) { return m.items[0], nil } +func (m *mockInstanceClient) List() ([]app.InstanceMiniResponse, error) { + if m.err != nil { + return []app.InstanceMiniResponse{}, m.err + } + + return m.miniitems, nil +} + func (m *mockInstanceClient) Find(rbName string, ver string, profile string, labelKeys map[string]string) ([]app.InstanceResponse, error) { if m.err != nil { return nil, m.err @@ -297,6 +307,110 @@ func TestInstanceGetHandler(t *testing.T) { } } +func TestInstanceListHandler(t *testing.T) { + testCases := []struct { + label string + input string + expectedCode int + expectedResponse []app.InstanceMiniResponse + instClient *mockInstanceClient + }{ + { + label: "Fail to List Instance", + input: "HaKpys8e", + expectedCode: http.StatusInternalServerError, + instClient: &mockInstanceClient{ + err: pkgerrors.New("Internal error"), + }, + }, + { + label: "Succesful List Instances", + expectedCode: http.StatusOK, + expectedResponse: []app.InstanceMiniResponse{ + { + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", + }, + { + ID: "HaKpys8f", + Request: app.InstanceRequest{ + RBName: "test-rbdef-two", + RBVersion: "versionsomething", + ProfileName: "profile3", + CloudRegion: "region1", + }, + Namespace: "testnamespace-two", + }, + }, + instClient: &mockInstanceClient{ + miniitems: []app.InstanceMiniResponse{ + { + ID: "HaKpys8e", + Request: app.InstanceRequest{ + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + CloudRegion: "region1", + }, + Namespace: "testnamespace", + }, + { + ID: "HaKpys8f", + Request: app.InstanceRequest{ + RBName: "test-rbdef-two", + RBVersion: "versionsomething", + ProfileName: "profile3", + CloudRegion: "region1", + }, + Namespace: "testnamespace-two", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + request := httptest.NewRequest("GET", "/v1/instance", nil) + resp := executeRequest(request, NewRouter(nil, nil, testCase.instClient, nil, nil, nil)) + + if testCase.expectedCode != resp.StatusCode { + t.Fatalf("Request method returned: %v and it was expected: %v", + resp.StatusCode, testCase.expectedCode) + } + if resp.StatusCode == http.StatusOK { + var response []app.InstanceMiniResponse + err := json.NewDecoder(resp.Body).Decode(&response) + if err != nil { + t.Fatalf("Parsing the returned response got an error (%s)", err) + } + + // Since the order of returned slice is not guaranteed + // Sort them first and then do deepequal + // Check both and return error if both don't match + sort.Slice(response, func(i, j int) bool { + return response[i].ID < response[j].ID + }) + + sort.Slice(testCase.expectedResponse, func(i, j int) bool { + return testCase.expectedResponse[i].ID < testCase.expectedResponse[j].ID + }) + + if reflect.DeepEqual(testCase.expectedResponse, response) == false { + t.Fatalf("TestGetHandler returned:\n result=%v\n expected=%v", + &response, testCase.expectedResponse) + } + } + }) + } +} + func TestDeleteHandler(t *testing.T) { testCases := []struct { label string diff --git a/src/k8splugin/api/profilehandler.go b/src/k8splugin/api/profilehandler.go index adb9249b..68ab77a4 100644 --- a/src/k8splugin/api/profilehandler.go +++ b/src/k8splugin/api/profilehandler.go @@ -20,9 +20,10 @@ import ( "encoding/json" "io" "io/ioutil" - "github.com/onap/multicloud-k8s/src/k8splugin/internal/rb" "net/http" + "github.com/onap/multicloud-k8s/src/k8splugin/internal/rb" + "github.com/gorilla/mux" ) @@ -119,6 +120,28 @@ func (h rbProfileHandler) getHandler(w http.ResponseWriter, r *http.Request) { } } +// getHandler handles GET operations on a particular ids +// Returns a rb.Definition +func (h rbProfileHandler) listHandler(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + rbName := vars["rbname"] + rbVersion := vars["rbversion"] + + ret, err := h.client.List(rbName, rbVersion) + 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 rbProfileHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) diff --git a/src/k8splugin/api/profilehandler_test.go b/src/k8splugin/api/profilehandler_test.go index e81fb262..4dae377c 100644 --- a/src/k8splugin/api/profilehandler_test.go +++ b/src/k8splugin/api/profilehandler_test.go @@ -23,6 +23,7 @@ import ( "net/http" "net/http/httptest" "reflect" + "sort" "testing" "github.com/onap/multicloud-k8s/src/k8splugin/internal/rb" @@ -57,6 +58,14 @@ func (m *mockRBProfile) Get(rbname, rbversion, prname string) (rb.Profile, error return m.Items[0], nil } +func (m *mockRBProfile) List(rbname, rbversion string) ([]rb.Profile, error) { + if m.Err != nil { + return []rb.Profile{}, m.Err + } + + return m.Items, nil +} + func (m *mockRBProfile) Delete(rbname, rbversion, prname string) error { return m.Err } @@ -210,6 +219,98 @@ func TestRBProfileGetHandler(t *testing.T) { } } +func TestRBProfileListHandler(t *testing.T) { + + testCases := []struct { + def string + version string + label string + expected []rb.Profile + expectedCode int + rbProClient *mockRBProfile + }{ + { + def: "test-rbdef", + version: "v1", + label: "List Profiles", + expectedCode: http.StatusOK, + expected: []rb.Profile{ + { + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + ReleaseName: "testprofilereleasename", + Namespace: "ns1", + KubernetesVersion: "1.12.3", + }, + { + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile2", + ReleaseName: "testprofilereleasename", + Namespace: "ns2", + KubernetesVersion: "1.12.3", + }, + }, + rbProClient: &mockRBProfile{ + // list of Profiles that will be returned by the mockclient + Items: []rb.Profile{ + { + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile1", + ReleaseName: "testprofilereleasename", + Namespace: "ns1", + KubernetesVersion: "1.12.3", + }, + { + RBName: "test-rbdef", + RBVersion: "v1", + ProfileName: "profile2", + ReleaseName: "testprofilereleasename", + Namespace: "ns2", + KubernetesVersion: "1.12.3", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + request := httptest.NewRequest("GET", "/v1/rb/definition/"+testCase.def+"/"+testCase.version+"/profile", nil) + resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil, nil)) + + //Check returned code + if resp.StatusCode != testCase.expectedCode { + t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, resp.StatusCode) + } + + //Check returned body only if statusOK + if resp.StatusCode == http.StatusOK { + got := []rb.Profile{} + json.NewDecoder(resp.Body).Decode(&got) + + // Since the order of returned slice is not guaranteed + // Check both and return error if both don't match + sort.Slice(got, func(i, j int) bool { + return got[i].ProfileName < got[j].ProfileName + }) + // Sort both as it is not expected that testCase.expected + // is sorted + sort.Slice(testCase.expected, func(i, j int) bool { + return testCase.expected[i].ProfileName < testCase.expected[j].ProfileName + }) + + if reflect.DeepEqual(testCase.expected, got) == false { + t.Errorf("listHandler returned unexpected body: got %v;"+ + " expected %v", got, testCase.expected) + } + } + }) + } +} + func TestRBProfileDeleteHandler(t *testing.T) { testCases := []struct { |