X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=cmd%2Fappmgr%2Fapi_test.go;fp=cmd%2Fappmgr%2Fapi_test.go;h=7b9691cf19e4aace82558af8e80adb228ba29265;hb=193caf9d7e08b84a0b9c1f0352924a7efd77e77c;hp=0000000000000000000000000000000000000000;hpb=cb4b2ad8e2f99eadea145e480da556c58b0a47b5;p=ric-plt%2Fappmgr.git diff --git a/cmd/appmgr/api_test.go b/cmd/appmgr/api_test.go new file mode 100755 index 0000000..7b9691c --- /dev/null +++ b/cmd/appmgr/api_test.go @@ -0,0 +1,272 @@ +/* +================================================================================== + Copyright (c) 2019 AT&T Intellectual Property. + Copyright (c) 2019 Nokia + + 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 main + +import ( + "bytes" + "encoding/json" + "errors" + "github.com/gorilla/mux" + "net/http" + "net/http/httptest" + "os" + "reflect" + "strconv" + "testing" + "time" +) + +var x XappManager +var xapp Xapp +var xapps []Xapp +var helmError error + +type MockedHelmer struct { +} + +func (sd *MockedHelmer) Initialize() { +} + +func (h *MockedHelmer) Status(name string) (Xapp, error) { + return xapp, helmError +} + +func (h *MockedHelmer) StatusAll() ([]Xapp, error) { + return xapps, helmError +} + +func (h *MockedHelmer) List() (names []string, err error) { + return names, helmError +} + +func (h *MockedHelmer) Install(name string) (Xapp, error) { + return xapp, helmError +} + +func (h *MockedHelmer) Delete(name string) (Xapp, error) { + return xapp, helmError +} + +// Test cases +func TestMain(m *testing.M) { + loadConfig() + + xapp = Xapp{} + xapps = []Xapp{} + + h := MockedHelmer{} + x = XappManager{} + x.Initialize(&h) + + // Just run on the background (for coverage) + go x.Run() + x.ready = true + + time.Sleep(time.Duration(2 * time.Second)) + + code := m.Run() + os.Exit(code) +} + +func TestGetHealthCheck(t *testing.T) { + req, _ := http.NewRequest("GET", "/ric/v1/health/ready", nil) + response := executeRequest(req) + + checkResponseCode(t, http.StatusOK, response.Code) +} + +func TestGetAppsReturnsEmpty(t *testing.T) { + req, _ := http.NewRequest("GET", "/ric/v1/xapps", nil) + response := executeRequest(req) + + checkResponseCode(t, http.StatusOK, response.Code) + if body := response.Body.String(); body != "[]" { + t.Errorf("handler returned unexpected body: got %v want []", body) + } +} + +func TestCreateXApp(t *testing.T) { + xapp = generateXapp("dummy-xapp", "started", "1.0", "dummy-xapp-1234-5678", "running", "127.0.0.1", "9999") + + payload := []byte(`{"name":"dummy-xapp"}`) + req, _ := http.NewRequest("POST", "/ric/v1/xapps", bytes.NewBuffer(payload)) + response := executeRequest(req) + + checkResponseData(t, response, http.StatusCreated, false) +} + +func TestGetAppsReturnsListOfXapps(t *testing.T) { + xapps = append(xapps, xapp) + req, _ := http.NewRequest("GET", "/ric/v1/xapps", nil) + response := executeRequest(req) + + checkResponseData(t, response, http.StatusOK, true) +} + +func TestGetAppByIdReturnsGivenXapp(t *testing.T) { + req, _ := http.NewRequest("GET", "/ric/v1/xapps/"+xapp.Name, nil) + response := executeRequest(req) + + checkResponseData(t, response, http.StatusOK, false) +} + +func TestGetAppInstanceByIdReturnsGivenXapp(t *testing.T) { + req, _ := http.NewRequest("GET", "/ric/v1/xapps/"+xapp.Name+"/instances/dummy-xapp-1234-5678", nil) + response := executeRequest(req) + + var ins XappInstance + checkResponseCode(t, http.StatusOK, response.Code) + json.NewDecoder(response.Body).Decode(&ins) + + if !reflect.DeepEqual(ins, xapp.Instances[0]) { + t.Errorf("handler returned unexpected body: got: %v, expected: %v", ins, xapp.Instances[0]) + } +} + +func TestDeleteAppRemovesGivenXapp(t *testing.T) { + req, _ := http.NewRequest("DELETE", "/ric/v1/xapps/"+xapp.Name, nil) + response := executeRequest(req) + + checkResponseData(t, response, http.StatusNoContent, false) + + // Xapp not found from the Redis DB + helmError = errors.New("Not found") + + req, _ = http.NewRequest("GET", "/ric/v1/xapps/"+xapp.Name, nil) + response = executeRequest(req) + checkResponseCode(t, http.StatusNotFound, response.Code) +} + +// Error handling +func TestGetXappReturnsError(t *testing.T) { + helmError = errors.New("Not found") + + req, _ := http.NewRequest("GET", "/ric/v1/xapps/invalidXappName", nil) + response := executeRequest(req) + checkResponseCode(t, http.StatusNotFound, response.Code) +} + +func TestGetXappInstanceReturnsError(t *testing.T) { + helmError = errors.New("Some error") + + req, _ := http.NewRequest("GET", "/ric/v1/xapps/"+xapp.Name+"/instances/invalidXappName", nil) + response := executeRequest(req) + checkResponseCode(t, http.StatusNotFound, response.Code) +} + +func TestGetXappListReturnsError(t *testing.T) { + helmError = errors.New("Internal error") + + req, _ := http.NewRequest("GET", "/ric/v1/xapps", nil) + response := executeRequest(req) + checkResponseCode(t, http.StatusInternalServerError, response.Code) +} + +func TestCreateXAppWithoutXappData(t *testing.T) { + req, _ := http.NewRequest("POST", "/ric/v1/xapps", nil) + response := executeRequest(req) + checkResponseData(t, response, http.StatusMethodNotAllowed, false) +} + +func TestCreateXAppWithInvalidXappData(t *testing.T) { + body := []byte("Invalid JSON data ...") + + req, _ := http.NewRequest("POST", "/ric/v1/xapps", bytes.NewBuffer(body)) + response := executeRequest(req) + checkResponseData(t, response, http.StatusMethodNotAllowed, false) +} + +func TestCreateXAppReturnsError(t *testing.T) { + helmError = errors.New("Not found") + + payload := []byte(`{"name":"dummy-xapp"}`) + req, _ := http.NewRequest("POST", "/ric/v1/xapps", bytes.NewBuffer(payload)) + response := executeRequest(req) + + checkResponseData(t, response, http.StatusInternalServerError, false) +} + +func TestDeleteXappListReturnsError(t *testing.T) { + helmError = errors.New("Internal error") + + req, _ := http.NewRequest("DELETE", "/ric/v1/xapps/invalidXappName", nil) + response := executeRequest(req) + checkResponseCode(t, http.StatusInternalServerError, response.Code) +} + +// Helper functions +type fn func(w http.ResponseWriter, r *http.Request) + +func executeRequest(req *http.Request) *httptest.ResponseRecorder { + rr := httptest.NewRecorder() + + vars := map[string]string{ + "id": "1", + } + req = mux.SetURLVars(req, vars) + + x.router.ServeHTTP(rr, req) + + return rr +} + +func checkResponseCode(t *testing.T, expected, actual int) { + if expected != actual { + t.Errorf("Expected response code %d. Got %d\n", expected, actual) + } +} + +func checkResponseData(t *testing.T, response *httptest.ResponseRecorder, expectedHttpStatus int, isList bool) { + expectedData := xapp + + checkResponseCode(t, expectedHttpStatus, response.Code) + if isList == true { + jsonResp := []Xapp{} + json.NewDecoder(response.Body).Decode(&jsonResp) + + if !reflect.DeepEqual(jsonResp[0], expectedData) { + t.Errorf("handler returned unexpected body: %v", jsonResp) + } + } else { + json.NewDecoder(response.Body).Decode(&xapp) + + if !reflect.DeepEqual(xapp, expectedData) { + t.Errorf("handler returned unexpected body: got: %v, expected: %v", xapp, expectedData) + } + } +} + +func generateXapp(name, status, ver, iname, istatus, ip, port string) (x Xapp) { + x.Name = name + x.Status = status + x.Version = ver + p, _ := strconv.Atoi(port) + instance := XappInstance{ + Name: iname, + Status: istatus, + Ip: ip, + Port: p, + TxMessages: []string{"RIC_E2_TERMINATION_HC_REQUEST", "RIC_E2_MANAGER_HC_REQUEST"}, + RxMessages: []string{"RIC_E2_TERMINATION_HC_RESPONSE", "RIC_E2_MANAGER_HC_RESPONSE"}, + } + x.Instances = append(x.Instances, instance) + + return +}