| /* |
| ================================================================================== |
| 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 ( |
| "net/http" |
| "net/http/httptest" |
| "testing" |
| "reflect" |
| "strconv" |
| "os" |
| "bytes" |
| "errors" |
| "encoding/json" |
| "github.com/gorilla/mux" |
| ) |
| |
| var x XappManager |
| var xapp Xapp |
| var xapps []Xapp |
| var helmError error |
| |
| type MockedHelmer struct { |
| } |
| |
| 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() |
| |
| code := m.Run() |
| os.Exit(code) |
| } |
| |
| func TestGetHealthCheck(t *testing.T) { |
| req, _ := http.NewRequest("GET", "/ric/v1/health", 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 |
| } |