X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=E2Manager%2Fcontrollers%2Fnodeb_controller_test.go;h=cd22cc6d6050b726c9d15121ced2d154ef4da329;hb=d287336cfb4d5c74634fe7af38e7d5e9265671e4;hp=0cbeb503ca56109149a342dd347bdfecb127ca36;hpb=b2f2743968c5cda9a708bf5a6f32678caabd6976;p=ric-plt%2Fe2mgr.git diff --git a/E2Manager/controllers/nodeb_controller_test.go b/E2Manager/controllers/nodeb_controller_test.go index 0cbeb50..cd22cc6 100644 --- a/E2Manager/controllers/nodeb_controller_test.go +++ b/E2Manager/controllers/nodeb_controller_test.go @@ -1,6 +1,7 @@ // // Copyright 2019 AT&T Intellectual Property // Copyright 2019 Nokia +// Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -54,6 +55,7 @@ import ( const ( RanName = "test" AssociatedE2TInstanceAddress = "10.0.2.15:38000" + CorruptedJson = "{\"errorCode\":401,\"errorMessage\":\"corrupted json\"}" ValidationFailureJson = "{\"errorCode\":402,\"errorMessage\":\"Validation error\"}" ResourceNotFoundJson = "{\"errorCode\":404,\"errorMessage\":\"Resource not found\"}" NodebExistsJson = "{\"errorCode\":406,\"errorMessage\":\"Nodeb already exists\"}" @@ -63,10 +65,13 @@ const ( ) var ( - ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "nrPci", "servedPlmns"} - NrNeighbourInformationRequiredFields = []string{"nrCgi", "choiceNrMode", "nrMode", "nrPci"} + ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "servedPlmns"} + NrNeighbourInformationRequiredFields = []string{"nrCgi", "choiceNrMode", "nrMode"} + AddEnbRequestRequiredFields = []string{"ranName", "enb", "globalNbId"} + UpdateEnbRequestRequiredFields = []string{"enb"} + GlobalIdRequiredFields = []string{"plmnId", "nbId"} EnbRequiredFields = []string{"enbType", "servedCells"} - ServedCellRequiredFields = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "pci", "tac"} + ServedCellRequiredFields = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "tac"} ) type controllerGetNodebTestContext struct { @@ -93,17 +98,37 @@ type updateGnbCellsParams struct { err error } -type saveNodebParams struct { - nodebInfo *entities.NodebInfo - nbIdentity *entities.NbIdentity +type updateEnbCellsParams struct { + err error +} + +type addEnbParams struct { err error } +type addNbIdentityParams struct { + err error +} + +type removeServedCellsParams struct { + servedCellInfo []*entities.ServedCellInfo + err error +} + type removeServedNrCellsParams struct { servedNrCells []*entities.ServedNRCell err error } +type controllerUpdateEnbTestContext struct { + getNodebInfoResult *getNodebInfoResult + removeServedCellsParams *removeServedCellsParams + updateEnbCellsParams *updateEnbCellsParams + requestBody map[string]interface{} + expectedStatusCode int + expectedJsonResponse string +} + type controllerUpdateGnbTestContext struct { getNodebInfoResult *getNodebInfoResult removeServedNrCellsParams *removeServedNrCellsParams @@ -115,12 +140,19 @@ type controllerUpdateGnbTestContext struct { type controllerAddEnbTestContext struct { getNodebInfoResult *getNodebInfoResult - saveNodebParams *saveNodebParams + addEnbParams *addEnbParams + addNbIdentityParams *addNbIdentityParams requestBody map[string]interface{} expectedStatusCode int expectedJsonResponse string } +type controllerDeleteEnbTestContext struct { + getNodebInfoResult *getNodebInfoResult + expectedStatusCode int + expectedJsonResponse string +} + func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell { servedNrCells := []*entities.ServedNRCell{} @@ -129,9 +161,7 @@ func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell { servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{ CellId: v, ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{ - Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{ - - }, + Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{}, }, NrMode: entities.Nr_FDD, NrPci: 5, @@ -142,6 +172,24 @@ func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell { return servedNrCells } +func generateServedCells(cellIds ...string) []*entities.ServedCellInfo { + + var servedCells []*entities.ServedCellInfo + + for i, v := range cellIds { + servedCells = append(servedCells, &entities.ServedCellInfo{ + CellId: v, + ChoiceEutraMode: &entities.ChoiceEUTRAMode{ + Fdd: &entities.FddInfo{}, + }, + Pci: uint32(i + 1), + BroadcastPlmns: []string{"whatever"}, + }) + } + + return servedCells +} + func buildNrNeighbourInformation(propToOmit string) map[string]interface{} { ret := map[string]interface{}{ "nrCgi": "whatever", @@ -200,7 +248,85 @@ func buildServedCell(propToOmit string) map[string]interface{} { return ret } -func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) { +func getUpdateEnbRequest(propToOmit string) map[string]interface{} { + ret := map[string]interface{}{ + "enb": buildEnb(propToOmit), + } + + if len(propToOmit) != 0 { + delete(ret, propToOmit) + } + + return ret +} + +func getAddEnbRequest(propToOmit string) map[string]interface{} { + ret := map[string]interface{}{ + "ranName": RanName, + "globalNbId": buildGlobalNbId(""), + "enb": buildEnb(""), + } + + if len(propToOmit) != 0 { + delete(ret, propToOmit) + } + + return ret +} + +func buildEnb(propToOmit string) map[string]interface{} { + ret := map[string]interface{}{ + "enbType": 1, + "servedCells": []interface{}{ + buildServedCell(""), + }} + + if len(propToOmit) != 0 { + delete(ret, propToOmit) + } + + return ret +} + +func buildGlobalNbId(propToOmit string) map[string]interface{} { + ret := map[string]interface{}{ + "plmnId": "whatever", + "nbId": "whatever2", + } + + if len(propToOmit) != 0 { + delete(ret, propToOmit) + } + + return ret +} + +func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock, managers.RanListManager) { + log := initLog(t) + config := configuration.ParseConfiguration() + + rmrMessengerMock := &mocks.RmrMessengerMock{} + readerMock := &mocks.RnibReaderMock{} + + writerMock := &mocks.RnibWriterMock{} + + rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock) + rmrSender := getRmrSender(rmrMessengerMock, log) + e2tInstancesManager := &mocks.E2TInstancesManagerMock{} + httpClientMock := &mocks.HttpClientMock{} + rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock) + ranListManager := managers.NewRanListManager(log, rnibDataService) + ranAlarmService := &mocks.RanAlarmServiceMock{} + ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService) + nodebValidator := managers.NewNodebValidator() + updateEnbManager := managers.NewUpdateEnbManager(log, rnibDataService, nodebValidator) + updateGnbManager := managers.NewUpdateGnbManager(log, rnibDataService, nodebValidator) + handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager, nodebValidator, updateEnbManager, updateGnbManager, ranListManager) + controller := NewNodebController(log, handlerProvider) + return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager, ranListManager +} + +func setupDeleteEnbControllerTest(t *testing.T, preAddNbIdentity bool) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *entities.NbIdentity) { log := initLog(t) config := configuration.ParseConfiguration() @@ -214,17 +340,26 @@ func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, e2tInstancesManager := &mocks.E2TInstancesManagerMock{} httpClientMock := &mocks.HttpClientMock{} rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock) - ranListManager := &mocks.RanListManagerMock{} + ranListManager := managers.NewRanListManager(log, rnibDataService) + var nbIdentity *entities.NbIdentity + if preAddNbIdentity { + nbIdentity = &entities.NbIdentity{InventoryName: RanName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}} + writerMock.On("AddNbIdentity", entities.Node_ENB, nbIdentity).Return(nil) + ranListManager.AddNbIdentity(entities.Node_ENB, nbIdentity) + } ranAlarmService := &mocks.RanAlarmServiceMock{} ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService) nodebValidator := managers.NewNodebValidator() - handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager, nodebValidator) + updateEnbManager := managers.NewUpdateEnbManager(log, rnibDataService, nodebValidator) + updateGnbManager := managers.NewUpdateGnbManager(log, rnibDataService, nodebValidator) + + handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager, nodebValidator, updateEnbManager, updateGnbManager, ranListManager) controller := NewNodebController(log, handlerProvider) - return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager + return controller, readerMock, writerMock, nbIdentity } func TestShutdownHandlerRnibError(t *testing.T) { - controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t) + controller, _, _, _, e2tInstancesManagerMock, _ := setupControllerTest(t) e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError()) writer := httptest.NewRecorder() @@ -238,7 +373,7 @@ func TestShutdownHandlerRnibError(t *testing.T) { } func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) { - controller, readerMock, _, _, _ := setupControllerTest(t) + controller, readerMock, _, _, _, _ := setupControllerTest(t) configuration := &entities.GeneralConfiguration{} readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError()) @@ -256,7 +391,7 @@ func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) { } func TestSetGeneralConfigurationInvalidJson(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() @@ -271,7 +406,7 @@ func TestSetGeneralConfigurationInvalidJson(t *testing.T) { } func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) { - controller, readerMock, _, _, _ := setupControllerTest(t) + controller, readerMock, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError) req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil) @@ -283,14 +418,42 @@ func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTes } func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) { - controller, readerMock, _, _, _ := setupControllerTest(t) + controller, readerMock, _, _, _, ranListManager := setupControllerTest(t) writer := httptest.NewRecorder() readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError) - req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil) + + err := ranListManager.InitNbIdentityMap() + if err != nil { + t.Errorf("Error cannot init identity") + } + + req, _ := http.NewRequest(http.MethodGet, "/nodeb/states", nil) controller.GetNodebIdList(writer, req) assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode) bodyBytes, _ := ioutil.ReadAll(writer.Body) - assert.Equal(t, context.expectedJsonResponse, string(bodyBytes)) + assert.Contains(t, context.expectedJsonResponse, string(bodyBytes)) +} + +func activateControllerUpdateEnbMocks(context *controllerUpdateEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, updateEnbRequest *models.UpdateEnbRequest) { + if context.getNodebInfoResult != nil { + readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError) + } + + if context.removeServedCellsParams != nil { + writerMock.On("RemoveServedCells", RanName, context.removeServedCellsParams.servedCellInfo).Return(context.removeServedCellsParams.err) + } + + if context.updateEnbCellsParams != nil { + updatedNodebInfo := *context.getNodebInfoResult.nodebInfo + + if context.getNodebInfoResult.nodebInfo.SetupFromNetwork { + updateEnbRequest.Enb.EnbType = context.getNodebInfoResult.nodebInfo.GetEnb().EnbType + } + + updatedNodebInfo.Configuration = &entities.NodebInfo_Enb{Enb: updateEnbRequest.Enb} + + writerMock.On("UpdateEnb", &updatedNodebInfo, updateEnbRequest.Enb.ServedCells).Return(context.updateEnbCellsParams.err) + } } func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) { @@ -320,6 +483,14 @@ func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestCon writerMock.AssertExpectations(t) } +func assertControllerUpdateEnb(t *testing.T, context *controllerUpdateEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) { + assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode) + bodyBytes, _ := ioutil.ReadAll(writer.Body) + assert.Equal(t, context.expectedJsonResponse, string(bodyBytes)) + readerMock.AssertExpectations(t) + writerMock.AssertExpectations(t) +} + func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) { assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode) bodyBytes, _ := ioutil.ReadAll(writer.Body) @@ -328,8 +499,25 @@ func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writerMock.AssertExpectations(t) } +func assertControllerDeleteEnb(t *testing.T, context *controllerDeleteEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) { + assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode) + bodyBytes, _ := ioutil.ReadAll(writer.Body) + assert.Equal(t, context.expectedJsonResponse, string(bodyBytes)) + readerMock.AssertExpectations(t) + writerMock.AssertExpectations(t) +} + +func buildUpdateEnbRequest(context *controllerUpdateEnbTestContext) *http.Request { + updateEnbUrl := fmt.Sprintf("/nodeb/enb/%s", RanName) + requestBody := getJsonRequestAsBuffer(context.requestBody) + req, _ := http.NewRequest(http.MethodPut, updateEnbUrl, requestBody) + req.Header.Set("Content-Type", "application/json") + req = mux.SetURLVars(req, map[string]string{"ranName": RanName}) + return req +} + func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request { - updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName) + updateGnbUrl := fmt.Sprintf("/nodeb/gnb/%s", RanName) requestBody := getJsonRequestAsBuffer(context.requestBody) req, _ := http.NewRequest(http.MethodPut, updateGnbUrl, requestBody) req.Header.Set("Content-Type", "application/json") @@ -344,8 +532,27 @@ func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request { return req } +func controllerUpdateEnbTestExecuter(t *testing.T, context *controllerUpdateEnbTestContext) { + controller, readerMock, writerMock, _, _, _ := setupControllerTest(t) + writer := httptest.NewRecorder() + + r := buildUpdateEnbRequest(context) + body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest)) + + updateEnbRequest := models.UpdateEnbRequest{} + _ = json.Unmarshal(body, &updateEnbRequest) + + activateControllerUpdateEnbMocks(context, readerMock, writerMock, &updateEnbRequest) + r = buildUpdateEnbRequest(context) + defer r.Body.Close() + + controller.UpdateEnb(writer, r) + + assertControllerUpdateEnb(t, context, writer, readerMock, writerMock) +} + func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) { - controller, readerMock, writerMock, _, _ := setupControllerTest(t) + controller, readerMock, writerMock, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() activateControllerUpdateGnbMocks(context, readerMock, writerMock) @@ -359,43 +566,71 @@ func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerM readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError) } - if context.saveNodebParams != nil { + if context.addEnbParams != nil { nodebInfo := entities.NodebInfo{ RanName: addEnbRequest.RanName, Ip: addEnbRequest.Ip, Port: addEnbRequest.Port, + NodeType: entities.Node_ENB, GlobalNbId: addEnbRequest.GlobalNbId, Configuration: &entities.NodebInfo_Enb{Enb: addEnbRequest.Enb}, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, } - nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId} + writerMock.On("AddEnb", &nodebInfo).Return(context.addEnbParams.err) + } - writerMock.On("SaveNodeb",&nbIdentity, &nodebInfo).Return(context.saveNodebParams.err) + if context.addNbIdentityParams != nil { + nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED} + writerMock.On("AddNbIdentity", entities.Node_ENB, &nbIdentity).Return(context.addNbIdentityParams.err) } } func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestContext) { - controller, readerMock, writerMock, _, _ := setupControllerTest(t) + controller, readerMock, writerMock, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() r := buildAddEnbRequest(context) - defer r.Body.Close() body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest)) addEnbRequest := models.AddEnbRequest{} _ = json.Unmarshal(body, &addEnbRequest) activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest) - controller.AddEnb(writer, buildAddEnbRequest(context)) + r = buildAddEnbRequest(context) + defer r.Body.Close() + controller.AddEnb(writer, r) assertControllerAddEnb(t, context, writer, readerMock, writerMock) } +func controllerDeleteEnbTestExecuter(t *testing.T, context *controllerDeleteEnbTestContext, preAddNbIdentity bool) { + controller, readerMock, writerMock, nbIdentity := setupDeleteEnbControllerTest(t, preAddNbIdentity) + readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError) + if context.getNodebInfoResult.rnibError == nil && context.getNodebInfoResult.nodebInfo.GetNodeType() == entities.Node_ENB && + !context.getNodebInfoResult.nodebInfo.SetupFromNetwork { + writerMock.On("RemoveEnb", context.getNodebInfoResult.nodebInfo).Return(nil) + if preAddNbIdentity { + writerMock.On("RemoveNbIdentity", entities.Node_ENB, nbIdentity).Return(nil) + } + } + writer := httptest.NewRecorder() + r, _ := http.NewRequest(http.MethodDelete, AddEnbUrl+"/"+RanName, nil) + r.Header.Set("Content-Type", "application/json") + r = mux.SetURLVars(r, map[string]string{"ranName": RanName}) + controller.DeleteEnb(writer, r) + assertControllerDeleteEnb(t, context, writer, readerMock, writerMock) +} + +/* +UpdateGnb UTs +*/ + +// BEGIN - UpdateGnb Validation Failure UTs + func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) { context := controllerUpdateGnbTestContext{ getNodebInfoResult: nil, requestBody: map[string]interface{}{ - "servedNrCells": []interface{}{ - }, + "servedNrCells": []interface{}{}, }, expectedStatusCode: http.StatusBadRequest, expectedJsonResponse: ValidationFailureJson, @@ -509,6 +744,8 @@ func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing } } +// END - UpdateGnb Validation Failure UTs + func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) { context := controllerUpdateGnbTestContext{ getNodebInfoResult: &getNodebInfoResult{ @@ -556,6 +793,7 @@ func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_ENB, }, rnibError: nil, }, @@ -569,8 +807,8 @@ func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) }, }, }, - expectedStatusCode: http.StatusInternalServerError, - expectedJsonResponse: InternalErrorJson, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, } controllerUpdateGnbTestExecuter(t, &context) @@ -589,6 +827,7 @@ func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}}, + NodeType: entities.Node_GNB, }, rnibError: nil, }, @@ -625,6 +864,7 @@ func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) { ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}}, + NodeType: entities.Node_GNB, }, rnibError: nil, }, @@ -645,7 +885,9 @@ func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) { controllerUpdateGnbTestExecuter(t, &context) } -func TestControllerUpdateGnbSuccess(t *testing.T) { +func TestControllerUpdateGnbExistingEmptyCellsSuccess(t *testing.T) { + oldServedNrCells := []*entities.ServedNRCell{} + context := controllerUpdateGnbTestContext{ updateGnbCellsParams: &updateGnbCellsParams{ err: nil, @@ -655,7 +897,8 @@ func TestControllerUpdateGnbSuccess(t *testing.T) { RanName: RanName, ConnectionStatus: entities.ConnectionStatus_CONNECTED, AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, - Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}}, + Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}}, + NodeType: entities.Node_GNB, }, rnibError: nil, }, @@ -670,135 +913,691 @@ func TestControllerUpdateGnbSuccess(t *testing.T) { }, }, expectedStatusCode: http.StatusOK, - expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"gnb\":{\"servedNrCells\":[{\"servedNrCellInformation\":{\"nrPci\":1,\"cellId\":\"whatever\",\"servedPlmns\":[\"whatever\"],\"nrMode\":\"FDD\",\"choiceNrMode\":{\"fdd\":{}}},\"nrNeighbourInfos\":[{\"nrPci\":1,\"nrCgi\":\"whatever\",\"nrMode\":\"FDD\",\"choiceNrMode\":{\"tdd\":{}}}]}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\"}", + expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"nodeType\":\"GNB\",\"gnb\":{\"servedNrCells\":[{\"servedNrCellInformation\":{\"nrPci\":1,\"cellId\":\"whatever\",\"servedPlmns\":[\"whatever\"],\"nrMode\":\"FDD\",\"choiceNrMode\":{\"fdd\":{}}},\"nrNeighbourInfos\":[{\"nrPci\":1,\"nrCgi\":\"whatever\",\"nrMode\":\"FDD\",\"choiceNrMode\":{\"tdd\":{}}}]}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\"}", } controllerUpdateGnbTestExecuter(t, &context) } -func TestControllerAddEnbSuccess(t *testing.T) { - context := controllerAddEnbTestContext{ - saveNodebParams: &saveNodebParams{ +func TestControllerUpdateGnbSuccess(t *testing.T) { + oldServedNrCells := generateServedNrCells("whatever1", "whatever2") + + context := controllerUpdateGnbTestContext{ + removeServedNrCellsParams: &removeServedNrCellsParams{ + err: nil, + servedNrCells: oldServedNrCells, + }, + updateGnbCellsParams: &updateGnbCellsParams{ err: nil, }, getNodebInfoResult: &getNodebInfoResult{ - nodebInfo: nil, - rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"), + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}}, + NodeType: entities.Node_GNB, + }, + rnibError: nil, }, requestBody: map[string]interface{}{ - "ranName": RanName, - "globalNbId": map[string]interface{}{ - "plmnId": "whatever", - "nbId": "whatever2", - }, - "enb": map[string]interface{}{ - "enbType": 1, - "servedCells": []interface{}{ - buildServedCell(""), + "servedNrCells": []interface{}{ + map[string]interface{}{ + "servedNrCellInformation": buildServedNrCellInformation(""), + "nrNeighbourInfos": []interface{}{ + buildNrNeighbourInformation(""), + }, }, }, }, - expectedStatusCode: http.StatusCreated, - expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"DISCONNECTED\",\"globalNbId\":{\"plmnId\":\"whatever\",\"nbId\":\"whatever2\"},\"enb\":{\"enbType\":\"MACRO_ENB\",\"servedCells\":[{\"pci\":1,\"cellId\":\"whatever\",\"tac\":\"whatever3\",\"broadcastPlmns\":[\"whatever\"],\"choiceEutraMode\":{\"fdd\":{}},\"eutraMode\":\"FDD\"}]}}", + expectedStatusCode: http.StatusOK, + expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"nodeType\":\"GNB\",\"gnb\":{\"servedNrCells\":[{\"servedNrCellInformation\":{\"nrPci\":1,\"cellId\":\"whatever\",\"servedPlmns\":[\"whatever\"],\"nrMode\":\"FDD\",\"choiceNrMode\":{\"fdd\":{}}},\"nrNeighbourInfos\":[{\"nrPci\":1,\"nrCgi\":\"whatever\",\"nrMode\":\"FDD\",\"choiceNrMode\":{\"tdd\":{}}}]}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\"}", } - controllerAddEnbTestExecuter(t, &context) + controllerUpdateGnbTestExecuter(t, &context) } -func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer { - b := new(bytes.Buffer) - _ = json.NewEncoder(b).Encode(requestJson) - return b -} +/* +UpdateEnb UTs +*/ -func TestControllerGetNodebSuccess(t *testing.T) { - ranName := "test" - var rnibError error - context := controllerGetNodebTestContext{ - ranName: ranName, - nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234}, - rnibError: rnibError, - expectedStatusCode: http.StatusOK, - expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName), - } +func TestControllerUpdateEnbInvalidRequest(t *testing.T) { + controller, _, _, _, _, _ := setupControllerTest(t) - controllerGetNodebTestExecuter(t, &context) -} + writer := httptest.NewRecorder() + invalidJson := strings.NewReader("{enb:\"whatever\"") -func TestControllerGetNodebNotFound(t *testing.T) { + updateEnbUrl := fmt.Sprintf("/nodeb/enb/%s", RanName) + req, _ := http.NewRequest(http.MethodPut, updateEnbUrl, invalidJson) + req.Header.Set("Content-Type", "application/json") + req = mux.SetURLVars(req, map[string]string{"ranName": RanName}) - ranName := "test" - var nodebInfo *entities.NodebInfo - context := controllerGetNodebTestContext{ - ranName: ranName, - nodebInfo: nodebInfo, - rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"), - expectedStatusCode: http.StatusNotFound, - expectedJsonResponse: ResourceNotFoundJson, - } + controller.UpdateEnb(writer, req) - controllerGetNodebTestExecuter(t, &context) + assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode) + bodyBytes, _ := ioutil.ReadAll(writer.Body) + assert.Equal(t, CorruptedJson, string(bodyBytes)) } -func TestControllerGetNodebInternal(t *testing.T) { - ranName := "test" - var nodebInfo *entities.NodebInfo - context := controllerGetNodebTestContext{ - ranName: ranName, - nodebInfo: nodebInfo, - rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")), - expectedStatusCode: http.StatusInternalServerError, - expectedJsonResponse: RnibErrorJson, +func TestControllerUpdateEnbEmptyEnbType(t *testing.T) { + context := controllerUpdateEnbTestContext{ + getNodebInfoResult: nil, + requestBody: getUpdateEnbRequest(EnbRequiredFields[0]), + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, } - controllerGetNodebTestExecuter(t, &context) + controllerUpdateEnbTestExecuter(t, &context) } -func TestControllerGetNodebIdListSuccess(t *testing.T) { - var rnibError error - nodebIdList := []*entities.NbIdentity{ - {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}}, - {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}}, +func TestControllerUpdateEnbEmptyServedCells(t *testing.T) { + context := controllerUpdateEnbTestContext{ + getNodebInfoResult: nil, + requestBody: getUpdateEnbRequest(EnbRequiredFields[1]), + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, } - context := controllerGetNodebIdListTestContext{ - nodebIdList: nodebIdList, - rnibError: rnibError, - expectedStatusCode: http.StatusOK, - expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]", + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbMissingEnb(t *testing.T) { + context := controllerUpdateEnbTestContext{ + getNodebInfoResult: nil, + requestBody: getUpdateEnbRequest(UpdateEnbRequestRequiredFields[0]), + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, } - controllerGetNodebIdListTestExecuter(t, &context) + controllerUpdateEnbTestExecuter(t, &context) } -func TestControllerGetNodebIdListEmptySuccess(t *testing.T) { - var rnibError error - nodebIdList := []*entities.NbIdentity{} +func TestControllerUpdateEnbMissingRequiredServedCellProps(t *testing.T) { - context := controllerGetNodebIdListTestContext{ - nodebIdList: nodebIdList, - rnibError: rnibError, - expectedStatusCode: http.StatusOK, - expectedJsonResponse: "[]", - } + r := getUpdateEnbRequest("") - controllerGetNodebIdListTestExecuter(t, &context) -} + for _, v := range ServedCellRequiredFields { + enb := r["enb"] -func TestControllerGetNodebIdListInternal(t *testing.T) { - var nodebIdList []*entities.NbIdentity - context := controllerGetNodebIdListTestContext{ - nodebIdList: nodebIdList, + enbMap, _ := enb.(map[string]interface{}) + + enbMap["servedCells"] = []interface{}{ + buildServedCell(v), + } + + context := controllerUpdateEnbTestContext{ + requestBody: r, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerUpdateEnbTestExecuter(t, &context) + } +} + +func TestControllerUpdateEnbValidServedCellsGetNodebNotFound(t *testing.T) { + context := controllerUpdateEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"), + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusNotFound, + expectedJsonResponse: ResourceNotFoundJson, + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbValidServedCellsGetNodebInternalError(t *testing.T) { + context := controllerUpdateEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")), + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbGetNodebSuccessGnbTypeFailure(t *testing.T) { + oldServedCells := generateServedCells("whatever1", "whatever2") + context := controllerUpdateEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_GNB, + Configuration: &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells}}, + }, + rnibError: nil, + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbGetNodebSuccessRemoveServedCellsFailure(t *testing.T) { + oldServedCells := generateServedCells("whatever1", "whatever2") + context := controllerUpdateEnbTestContext{ + removeServedCellsParams: &removeServedCellsParams{ + err: common.NewInternalError(errors.New("#writer.RemoveServedCells - Internal Error")), + servedCellInfo: oldServedCells, + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_ENB, + Configuration: &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells}}, + }, + rnibError: nil, + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbGetNodebSuccessUpdateEnbFailure(t *testing.T) { + oldServedCells := generateServedCells("whatever1", "whatever2") + context := controllerUpdateEnbTestContext{ + removeServedCellsParams: &removeServedCellsParams{ + err: nil, + servedCellInfo: oldServedCells, + }, + updateEnbCellsParams: &updateEnbCellsParams{ + err: common.NewInternalError(errors.New("#writer.UpdateEnb - Internal Error")), + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_ENB, + Configuration: &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells, EnbType: entities.EnbType_MACRO_ENB}}, + }, + rnibError: nil, + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbExistingEmptyCellsSuccess(t *testing.T) { + oldServedCells := []*entities.ServedCellInfo{} + context := controllerUpdateEnbTestContext{ + updateEnbCellsParams: &updateEnbCellsParams{ + err: nil, + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_ENB, + Configuration: &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells, EnbType: entities.EnbType_MACRO_ENB}}, + }, + rnibError: nil, + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusOK, + expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"nodeType\":\"ENB\",\"enb\":{\"enbType\":\"MACRO_ENB\",\"servedCells\":[{\"pci\":1,\"cellId\":\"whatever\",\"tac\":\"whatever3\",\"broadcastPlmns\":[\"whatever\"],\"choiceEutraMode\":{\"fdd\":{}},\"eutraMode\":\"FDD\"}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\"}", + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbNgEnbFailure(t *testing.T) { + + requestBody := map[string]interface{}{ + "enb": map[string]interface{}{ + "enbType": 3, + "servedCells": []interface{}{ + buildServedCell(""), + }}, + } + + oldServedCells := generateServedCells("whatever1", "whatever2") + + context := controllerUpdateEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_ENB, + Configuration: &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells, EnbType: entities.EnbType_MACRO_NG_ENB}}, + }, + rnibError: nil, + }, + requestBody: requestBody, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbSuccessSetupFromNwFalse(t *testing.T) { + oldServedCells := generateServedCells("whatever1", "whatever2") + context := controllerUpdateEnbTestContext{ + removeServedCellsParams: &removeServedCellsParams{ + err: nil, + servedCellInfo: oldServedCells, + }, + updateEnbCellsParams: &updateEnbCellsParams{ + err: nil, + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_ENB, + Configuration: &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells, EnbType: entities.EnbType_LONG_MACRO_ENB}}, + }, + rnibError: nil, + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusOK, + expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"nodeType\":\"ENB\",\"enb\":{\"enbType\":\"MACRO_ENB\",\"servedCells\":[{\"pci\":1,\"cellId\":\"whatever\",\"tac\":\"whatever3\",\"broadcastPlmns\":[\"whatever\"],\"choiceEutraMode\":{\"fdd\":{}},\"eutraMode\":\"FDD\"}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\"}", + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +func TestControllerUpdateEnbSuccessSetupFromNwTrue(t *testing.T) { + oldServedCells := generateServedCells("whatever1", "whatever2") + context := controllerUpdateEnbTestContext{ + removeServedCellsParams: &removeServedCellsParams{ + err: nil, + servedCellInfo: oldServedCells, + }, + updateEnbCellsParams: &updateEnbCellsParams{ + err: nil, + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{ + RanName: RanName, + ConnectionStatus: entities.ConnectionStatus_CONNECTED, + AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress, + NodeType: entities.Node_ENB, + Configuration: &entities.NodebInfo_Enb{Enb: &entities.Enb{ServedCells: oldServedCells, EnbType: entities.EnbType_LONG_MACRO_ENB}}, + SetupFromNetwork: true, + }, + rnibError: nil, + }, + requestBody: getUpdateEnbRequest(""), + expectedStatusCode: http.StatusOK, + expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"nodeType\":\"ENB\",\"enb\":{\"enbType\":\"LONG_MACRO_ENB\",\"servedCells\":[{\"pci\":1,\"cellId\":\"whatever\",\"tac\":\"whatever3\",\"broadcastPlmns\":[\"whatever\"],\"choiceEutraMode\":{\"fdd\":{}},\"eutraMode\":\"FDD\"}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\",\"setupFromNetwork\":true}", + } + + controllerUpdateEnbTestExecuter(t, &context) +} + +/* +AddEnb UTs +*/ + +func TestControllerAddEnbGetNodebInternalError(t *testing.T) { + context := controllerAddEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")), + }, + requestBody: getAddEnbRequest(""), + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerAddEnbTestExecuter(t, &context) +} + +func TestControllerAddEnbNodebExistsFailure(t *testing.T) { + context := controllerAddEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{}, + rnibError: nil, + }, + requestBody: getAddEnbRequest(""), + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: NodebExistsJson, + } + + controllerAddEnbTestExecuter(t, &context) +} + +func TestControllerAddEnbSaveNodebFailure(t *testing.T) { + context := controllerAddEnbTestContext{ + addEnbParams: &addEnbParams{ + err: common.NewInternalError(errors.New("#reader.AddEnb - Internal Error")), + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"), + }, + requestBody: getAddEnbRequest(""), + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerAddEnbTestExecuter(t, &context) +} + +func TestControllerAddEnbAddNbIdentityFailure(t *testing.T) { + context := controllerAddEnbTestContext{ + addEnbParams: &addEnbParams{ + err: nil, + }, + addNbIdentityParams: &addNbIdentityParams{ + err: common.NewInternalError(errors.New("#writer.addNbIdentity - Internal Error")), + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"), + }, + requestBody: getAddEnbRequest(""), + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerAddEnbTestExecuter(t, &context) +} + +func TestControllerAddEnbMissingRequiredRequestProps(t *testing.T) { + + for _, v := range AddEnbRequestRequiredFields { + context := controllerAddEnbTestContext{ + requestBody: getAddEnbRequest(v), + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerAddEnbTestExecuter(t, &context) + } +} + +func TestControllerAddEnbInvalidRequest(t *testing.T) { + controller, _, _, _, _, _ := setupControllerTest(t) + writer := httptest.NewRecorder() + + // Invalid json: attribute name without quotes (should be "cause":). + invalidJson := strings.NewReader("{ranName:\"whatever\"") + req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, invalidJson) + + controller.AddEnb(writer, req) + assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode) + bodyBytes, _ := ioutil.ReadAll(writer.Body) + assert.Equal(t, CorruptedJson, string(bodyBytes)) + +} + +func TestControllerAddEnbMissingRequiredGlobalNbIdProps(t *testing.T) { + + r := getAddEnbRequest("") + + for _, v := range GlobalIdRequiredFields { + r["globalNbId"] = buildGlobalNbId(v) + + context := controllerAddEnbTestContext{ + requestBody: r, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerAddEnbTestExecuter(t, &context) + } +} + +func TestControllerAddEnbMissingRequiredEnbProps(t *testing.T) { + + r := getAddEnbRequest("") + + for _, v := range EnbRequiredFields { + r["enb"] = buildEnb(v) + + context := controllerAddEnbTestContext{ + requestBody: r, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerAddEnbTestExecuter(t, &context) + } +} + +func TestControllerAddEnbMissingRequiredServedCellProps(t *testing.T) { + + r := getAddEnbRequest("") + + for _, v := range ServedCellRequiredFields { + enb := r["enb"] + + enbMap, _ := enb.(map[string]interface{}) + + enbMap["servedCells"] = []interface{}{ + buildServedCell(v), + } + + context := controllerAddEnbTestContext{ + requestBody: r, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerAddEnbTestExecuter(t, &context) + } +} + +func TestControllerAddEnbNgEnbFailure(t *testing.T) { + + requestBody := map[string]interface{}{ + "ranName": RanName, + "globalNbId": buildGlobalNbId(""), + "enb": map[string]interface{}{ + "enbType": 5, + "servedCells": []interface{}{ + buildServedCell(""), + }, + }, + } + + context := controllerAddEnbTestContext{ + requestBody: requestBody, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerAddEnbTestExecuter(t, &context) +} + +func TestControllerAddEnbSuccess(t *testing.T) { + context := controllerAddEnbTestContext{ + addEnbParams: &addEnbParams{ + err: nil, + }, + addNbIdentityParams: &addNbIdentityParams{ + err: nil, + }, + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"), + }, + requestBody: getAddEnbRequest(""), + expectedStatusCode: http.StatusCreated, + expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"DISCONNECTED\",\"globalNbId\":{\"plmnId\":\"whatever\",\"nbId\":\"whatever2\"},\"nodeType\":\"ENB\",\"enb\":{\"enbType\":\"MACRO_ENB\",\"servedCells\":[{\"pci\":1,\"cellId\":\"whatever\",\"tac\":\"whatever3\",\"broadcastPlmns\":[\"whatever\"],\"choiceEutraMode\":{\"fdd\":{}},\"eutraMode\":\"FDD\"}]}}", + } + + controllerAddEnbTestExecuter(t, &context) +} + +func TestControllerDeleteEnbGetNodebInternalError(t *testing.T) { + context := controllerDeleteEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")), + }, + expectedStatusCode: http.StatusInternalServerError, + expectedJsonResponse: RnibErrorJson, + } + + controllerDeleteEnbTestExecuter(t, &context, false) +} + +/* +DeleteEnb UTs +*/ + +func TestControllerDeleteEnbNodebNotExistsFailure(t *testing.T) { + context := controllerDeleteEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: nil, + rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found"), + }, + expectedStatusCode: http.StatusNotFound, + expectedJsonResponse: ResourceNotFoundJson, + } + + controllerDeleteEnbTestExecuter(t, &context, false) +} + +func TestControllerDeleteEnbNodebNotEnb(t *testing.T) { + context := controllerDeleteEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{RanName: "ran1", NodeType: entities.Node_GNB, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}, + rnibError: nil, + }, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + + controllerDeleteEnbTestExecuter(t, &context, false) +} + +func TestControllerDeleteEnbSetupFromNetworkTrueFailure(t *testing.T) { + context := controllerDeleteEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{RanName: RanName, NodeType: entities.Node_ENB, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, SetupFromNetwork: true}, + rnibError: nil, + }, + expectedStatusCode: http.StatusBadRequest, + expectedJsonResponse: ValidationFailureJson, + } + controllerDeleteEnbTestExecuter(t, &context, true) +} + +func TestControllerDeleteEnbSuccess(t *testing.T) { + context := controllerDeleteEnbTestContext{ + getNodebInfoResult: &getNodebInfoResult{ + nodebInfo: &entities.NodebInfo{RanName: RanName, NodeType: entities.Node_ENB, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}, + rnibError: nil, + }, + expectedStatusCode: http.StatusNoContent, + expectedJsonResponse: "", + } + controllerDeleteEnbTestExecuter(t, &context, true) +} + +func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer { + b := new(bytes.Buffer) + _ = json.NewEncoder(b).Encode(requestJson) + return b +} + +/* +GetNodeb UTs +*/ + +func TestControllerGetNodebSuccess(t *testing.T) { + ranName := "test" + var rnibError error + context := controllerGetNodebTestContext{ + ranName: ranName, + nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234}, + rnibError: rnibError, + expectedStatusCode: http.StatusOK, + expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName), + } + + controllerGetNodebTestExecuter(t, &context) +} + +func TestControllerGetNodebNotFound(t *testing.T) { + + ranName := "test" + var nodebInfo *entities.NodebInfo + context := controllerGetNodebTestContext{ + ranName: ranName, + nodebInfo: nodebInfo, + rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"), + expectedStatusCode: http.StatusNotFound, + expectedJsonResponse: ResourceNotFoundJson, + } + + controllerGetNodebTestExecuter(t, &context) +} + +func TestControllerGetNodebInternal(t *testing.T) { + ranName := "test" + var nodebInfo *entities.NodebInfo + context := controllerGetNodebTestContext{ + ranName: ranName, + nodebInfo: nodebInfo, rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")), expectedStatusCode: http.StatusInternalServerError, expectedJsonResponse: RnibErrorJson, } + controllerGetNodebTestExecuter(t, &context) +} + +func TestControllerGetNodebIdListSuccess(t *testing.T) { + var rnibError error + nodebIdList := []*entities.NbIdentity{ + {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}}, + {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}}, + } + + context := controllerGetNodebIdListTestContext{ + nodebIdList: nodebIdList, + rnibError: rnibError, + expectedStatusCode: http.StatusOK, + expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}][{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}},{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}}]", + } + + controllerGetNodebIdListTestExecuter(t, &context) +} + +func TestControllerGetNodebIdListEmptySuccess(t *testing.T) { + var rnibError error + var nodebIdList []*entities.NbIdentity + + context := controllerGetNodebIdListTestContext{ + nodebIdList: nodebIdList, + rnibError: rnibError, + expectedStatusCode: http.StatusOK, + expectedJsonResponse: "[]", + } + controllerGetNodebIdListTestExecuter(t, &context) } func TestHeaderValidationFailed(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() @@ -815,7 +1614,7 @@ func TestHeaderValidationFailed(t *testing.T) { } func TestShutdownStatusNoContent(t *testing.T) { - controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t) + controller, readerMock, _, _, e2tInstancesManagerMock, _ := setupControllerTest(t) e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil) readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil) @@ -826,7 +1625,7 @@ func TestShutdownStatusNoContent(t *testing.T) { } func TestHandleInternalError(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() err := e2managererrors.NewInternalError() @@ -840,7 +1639,7 @@ func TestHandleInternalError(t *testing.T) { } func TestHandleCommandAlreadyInProgressError(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() err := e2managererrors.NewCommandAlreadyInProgressError() @@ -853,7 +1652,7 @@ func TestHandleCommandAlreadyInProgressError(t *testing.T) { } func TestHandleRoutingManagerError(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() err := e2managererrors.NewRoutingManagerError() @@ -866,7 +1665,7 @@ func TestHandleRoutingManagerError(t *testing.T) { } func TestHandleE2TInstanceAbsenceError(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() err := e2managererrors.NewE2TInstanceAbsenceError() @@ -880,7 +1679,7 @@ func TestHandleE2TInstanceAbsenceError(t *testing.T) { } func TestValidateHeaders(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) header := http.Header{} header.Set("Content-Type", "application/json") @@ -910,7 +1709,7 @@ func initLog(t *testing.T) *logger.Logger { } func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) { - controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t) + controller, readerMock, _, rmrMessengerMock, _, _ := setupControllerTest(t) ranName := "test1" payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40} @@ -936,7 +1735,7 @@ func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) { } func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) { - controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t) + controller, readerMock, _, rmrMessengerMock, _, _ := setupControllerTest(t) ranName := "test1" // o&m intervention @@ -962,8 +1761,23 @@ func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) { assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode) } +func TestX2ResetHandleFailureBodyReadError(t *testing.T) { + controller, _, _, _, _, _ := setupControllerTest(t) + + ranName := "test1" + writer := httptest.NewRecorder() + + // Fake reader to return reading error. + req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", errReader(0)) + req = mux.SetURLVars(req, map[string]string{"ranName": ranName}) + + controller.X2Reset(writer, req) + assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode) + +} + func TestX2ResetHandleFailureInvalidBody(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) ranName := "test1" @@ -979,8 +1793,36 @@ func TestX2ResetHandleFailureInvalidBody(t *testing.T) { } +/* +func TestControllerHealthCheckRequestSuccess(t *testing.T) { + controller, readerMock, _, rmrMessengerMock, _, _ := setupControllerTest(t) + + ranName := "test1" + // o&m intervention + payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64} + var xAction []byte + var msgSrc unsafe.Pointer + msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc) + rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil) + + writer := httptest.NewRecorder() + + var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED} + readerMock.On("GetNodeb", ranName).Return(nodeb, nil) + + data4Req := map[string]interface{}{"ranList": []string{"abcd"}} + b := new(bytes.Buffer) + _ = json.NewEncoder(b).Encode(data4Req) + req, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/health", b) + req = mux.SetURLVars(req, map[string]string{"ranName": ranName}) + + controller.HealthCheckRequest(writer, req) + assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode) +} +*/ + func TestHandleErrorResponse(t *testing.T) { - controller, _, _, _, _ := setupControllerTest(t) + controller, _, _, _, _, _ := setupControllerTest(t) writer := httptest.NewRecorder() controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer) @@ -1006,6 +1848,10 @@ func TestHandleErrorResponse(t *testing.T) { controller.handleErrorResponse(e2managererrors.NewRmrError(), writer) assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode) + writer = httptest.NewRecorder() + controller.handleErrorResponse(e2managererrors.NewNoConnectedRanError(), writer) + assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode) + writer = httptest.NewRecorder() controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer) assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode) @@ -1020,3 +1866,9 @@ func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger) return rmrsender.NewRmrSender(log, rmrMessenger) } + +type errReader int + +func (errReader) Read(p []byte) (n int, err error) { + return 0, errors.New("test error") +}