2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // This source code is part of the near-RT RIC (RAN Intelligent Controller)
18 // platform project (RICP).
26 "e2mgr/e2managererrors"
31 "e2mgr/providers/httpmsghandlerprovider"
34 "e2mgr/services/rmrsender"
38 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
39 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
40 "github.com/golang/protobuf/jsonpb"
41 "github.com/gorilla/mux"
42 "github.com/pkg/errors"
43 "github.com/stretchr/testify/assert"
44 "github.com/stretchr/testify/mock"
56 AssociatedE2TInstanceAddress = "10.0.2.15:38000"
57 CorruptedJson = "{\"errorCode\":401,\"errorMessage\":\"corrupted json\"}"
58 ValidationFailureJson = "{\"errorCode\":402,\"errorMessage\":\"Validation error\"}"
59 ResourceNotFoundJson = "{\"errorCode\":404,\"errorMessage\":\"Resource not found\"}"
60 NodebExistsJson = "{\"errorCode\":406,\"errorMessage\":\"Nodeb already exists\"}"
61 RnibErrorJson = "{\"errorCode\":500,\"errorMessage\":\"RNIB error\"}"
62 InternalErrorJson = "{\"errorCode\":501,\"errorMessage\":\"Internal Server Error. Please try again later\"}"
63 AddEnbUrl = "/nodeb/enb"
67 ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "servedPlmns"}
68 NrNeighbourInformationRequiredFields = []string{"nrCgi", "choiceNrMode", "nrMode"}
69 AddEnbRequestRequiredFields = []string{"ranName", "enb", "globalNbId"}
70 GlobalIdRequiredFields = []string{"plmnId", "nbId"}
71 EnbRequiredFields = []string{"enbType", "servedCells"}
72 ServedCellRequiredFields = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "tac"}
75 type controllerGetNodebTestContext struct {
77 nodebInfo *entities.NodebInfo
79 expectedStatusCode int
80 expectedJsonResponse string
83 type controllerGetNodebIdListTestContext struct {
84 nodebIdList []*entities.NbIdentity
86 expectedStatusCode int
87 expectedJsonResponse string
90 type getNodebInfoResult struct {
91 nodebInfo *entities.NodebInfo
95 type updateGnbCellsParams struct {
99 type saveNodebParams struct {
100 nodebInfo *entities.NodebInfo
101 nbIdentity *entities.NbIdentity
105 type removeServedNrCellsParams struct {
106 servedNrCells []*entities.ServedNRCell
110 type controllerUpdateGnbTestContext struct {
111 getNodebInfoResult *getNodebInfoResult
112 removeServedNrCellsParams *removeServedNrCellsParams
113 updateGnbCellsParams *updateGnbCellsParams
114 requestBody map[string]interface{}
115 expectedStatusCode int
116 expectedJsonResponse string
119 type controllerAddEnbTestContext struct {
120 getNodebInfoResult *getNodebInfoResult
121 saveNodebParams *saveNodebParams
122 requestBody map[string]interface{}
123 expectedStatusCode int
124 expectedJsonResponse string
127 type controllerDeleteEnbTestContext struct {
128 getNodebInfoResult *getNodebInfoResult
129 expectedStatusCode int
130 expectedJsonResponse string
133 func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
135 servedNrCells := []*entities.ServedNRCell{}
137 for _, v := range cellIds {
138 servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{
140 ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{
141 Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{
145 NrMode: entities.Nr_FDD,
147 ServedPlmns: []string{"whatever"},
154 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
155 ret := map[string]interface{}{
157 "choiceNrMode": map[string]interface{}{
158 "tdd": map[string]interface{}{},
164 if len(propToOmit) != 0 {
165 delete(ret, propToOmit)
171 func buildServedNrCellInformation(propToOmit string) map[string]interface{} {
172 ret := map[string]interface{}{
173 "cellId": "whatever",
174 "choiceNrMode": map[string]interface{}{
175 "fdd": map[string]interface{}{},
179 "servedPlmns": []interface{}{
184 if len(propToOmit) != 0 {
185 delete(ret, propToOmit)
191 func buildServedCell(propToOmit string) map[string]interface{} {
192 ret := map[string]interface{}{
193 "cellId": "whatever",
194 "choiceEutraMode": map[string]interface{}{
195 "fdd": map[string]interface{}{},
200 "broadcastPlmns": []interface{}{
205 if len(propToOmit) != 0 {
206 delete(ret, propToOmit)
212 func getAddEnbRequest(propToOmit string) map[string]interface{} {
213 ret := map[string]interface{}{
215 "globalNbId": buildGlobalNbId(""),
219 if len(propToOmit) != 0 {
220 delete(ret, propToOmit)
226 func buildEnb(propToOmit string) map[string]interface{} {
227 ret := map[string]interface{}{
229 "servedCells": []interface{}{
233 if len(propToOmit) != 0 {
234 delete(ret, propToOmit)
240 func buildGlobalNbId(propToOmit string) map[string]interface{} {
241 ret := map[string]interface{}{
242 "plmnId": "whatever",
246 if len(propToOmit) != 0 {
247 delete(ret, propToOmit)
253 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
255 config := configuration.ParseConfiguration()
257 rmrMessengerMock := &mocks.RmrMessengerMock{}
258 readerMock := &mocks.RnibReaderMock{}
260 writerMock := &mocks.RnibWriterMock{}
262 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
263 rmrSender := getRmrSender(rmrMessengerMock, log)
264 e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
265 httpClientMock := &mocks.HttpClientMock{}
266 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
267 ranListManager := &mocks.RanListManagerMock{}
268 ranAlarmService := &mocks.RanAlarmServiceMock{}
269 ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
270 nodebValidator := managers.NewNodebValidator()
271 updateEnbManager := managers.NewUpdateEnbManager(log, rnibDataService, nodebValidator)
273 handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager, nodebValidator, updateEnbManager)
274 controller := NewNodebController(log, handlerProvider)
275 return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
278 func TestShutdownHandlerRnibError(t *testing.T) {
279 controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
280 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
282 writer := httptest.NewRecorder()
284 controller.Shutdown(writer, tests.GetHttpRequest())
286 var errorResponse = parseJsonRequest(t, writer.Body)
288 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
289 assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
292 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
293 controller, readerMock, _, _, _ := setupControllerTest(t)
295 configuration := &entities.GeneralConfiguration{}
296 readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
298 writer := httptest.NewRecorder()
300 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
302 controller.SetGeneralConfiguration(writer, httpRequest)
304 var errorResponse = parseJsonRequest(t, writer.Body)
306 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
307 assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
310 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
311 controller, _, _, _, _ := setupControllerTest(t)
313 writer := httptest.NewRecorder()
315 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false, \"someValue\":false}"))
317 controller.SetGeneralConfiguration(writer, httpRequest)
319 var errorResponse = parseJsonRequest(t, writer.Body)
321 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
322 assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
325 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
326 controller, readerMock, _, _, _ := setupControllerTest(t)
327 writer := httptest.NewRecorder()
328 readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
329 req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil)
330 req = mux.SetURLVars(req, map[string]string{"ranName": context.ranName})
331 controller.GetNodeb(writer, req)
332 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
333 bodyBytes, _ := ioutil.ReadAll(writer.Body)
334 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
337 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
338 controller, readerMock, _, _, _ := setupControllerTest(t)
339 writer := httptest.NewRecorder()
340 readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
341 req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil)
342 controller.GetNodebIdList(writer, req)
343 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
344 bodyBytes, _ := ioutil.ReadAll(writer.Body)
345 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
348 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
349 if context.getNodebInfoResult != nil {
350 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
353 if context.removeServedNrCellsParams != nil {
354 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
357 if context.updateGnbCellsParams != nil {
358 updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
359 gnb := entities.Gnb{}
360 _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb)
361 updatedGnb := *updatedNodebInfo.GetGnb()
362 updatedGnb.ServedNrCells = gnb.ServedNrCells
363 writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err)
367 func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
368 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
369 bodyBytes, _ := ioutil.ReadAll(writer.Body)
370 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
371 readerMock.AssertExpectations(t)
372 writerMock.AssertExpectations(t)
375 func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
376 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
377 bodyBytes, _ := ioutil.ReadAll(writer.Body)
378 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
379 readerMock.AssertExpectations(t)
380 writerMock.AssertExpectations(t)
383 func assertControllerDeleteEnb(t *testing.T, context *controllerDeleteEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
384 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
385 bodyBytes, _ := ioutil.ReadAll(writer.Body)
386 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
387 readerMock.AssertExpectations(t)
388 writerMock.AssertExpectations(t)
391 func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
392 updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
393 requestBody := getJsonRequestAsBuffer(context.requestBody)
394 req, _ := http.NewRequest(http.MethodPut, updateGnbUrl, requestBody)
395 req.Header.Set("Content-Type", "application/json")
396 req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
400 func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request {
401 requestBody := getJsonRequestAsBuffer(context.requestBody)
402 req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, requestBody)
403 req.Header.Set("Content-Type", "application/json")
407 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
408 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
409 writer := httptest.NewRecorder()
411 activateControllerUpdateGnbMocks(context, readerMock, writerMock)
412 req := buildUpdateGnbRequest(context)
413 controller.UpdateGnb(writer, req)
414 assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
417 func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, addEnbRequest *models.AddEnbRequest) {
418 if context.getNodebInfoResult != nil {
419 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
422 if context.saveNodebParams != nil {
423 nodebInfo := entities.NodebInfo{
424 RanName: addEnbRequest.RanName,
425 Ip: addEnbRequest.Ip,
426 Port: addEnbRequest.Port,
427 NodeType: entities.Node_ENB,
428 GlobalNbId: addEnbRequest.GlobalNbId,
429 Configuration: &entities.NodebInfo_Enb{Enb: addEnbRequest.Enb},
430 ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,
433 nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId}
435 writerMock.On("SaveNodeb", &nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
439 func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestContext) {
440 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
441 writer := httptest.NewRecorder()
442 r := buildAddEnbRequest(context)
443 body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
445 addEnbRequest := models.AddEnbRequest{}
447 _ = json.Unmarshal(body, &addEnbRequest)
448 activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest)
449 r = buildAddEnbRequest(context)
451 controller.AddEnb(writer, r)
452 assertControllerAddEnb(t, context, writer, readerMock, writerMock)
455 func controllerDeleteEnbTestExecuter(t *testing.T, context *controllerDeleteEnbTestContext) {
456 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
457 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
458 if context.getNodebInfoResult.rnibError == nil && context.getNodebInfoResult.nodebInfo.GetNodeType() == entities.Node_ENB {
459 writerMock.On("RemoveEnb", context.getNodebInfoResult.nodebInfo).Return(nil)
461 writer := httptest.NewRecorder()
462 r, _ := http.NewRequest(http.MethodDelete, AddEnbUrl+"/"+RanName, nil)
463 r.Header.Set("Content-Type", "application/json")
464 r = mux.SetURLVars(r, map[string]string{"ranName": RanName})
465 controller.DeleteEnb(writer, r)
466 assertControllerDeleteEnb(t, context, writer, readerMock, writerMock)
469 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
470 context := controllerUpdateGnbTestContext{
471 getNodebInfoResult: nil,
472 requestBody: map[string]interface{}{
473 "servedNrCells": []interface{}{
476 expectedStatusCode: http.StatusBadRequest,
477 expectedJsonResponse: ValidationFailureJson,
480 controllerUpdateGnbTestExecuter(t, &context)
483 func TestControllerUpdateGnbMissingServedNrCellInformation(t *testing.T) {
484 context := controllerUpdateGnbTestContext{
485 getNodebInfoResult: nil,
486 requestBody: map[string]interface{}{
487 "servedNrCells": []interface{}{
488 map[string]interface{}{
489 "servedNrCellInformation": nil,
493 expectedStatusCode: http.StatusBadRequest,
494 expectedJsonResponse: ValidationFailureJson,
497 controllerUpdateGnbTestExecuter(t, &context)
500 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
502 for _, v := range ServedNrCellInformationRequiredFields {
503 context := controllerUpdateGnbTestContext{
504 getNodebInfoResult: nil,
505 requestBody: map[string]interface{}{
506 "servedNrCells": []interface{}{
507 map[string]interface{}{
508 "servedNrCellInformation": buildServedNrCellInformation(v),
512 expectedStatusCode: http.StatusBadRequest,
513 expectedJsonResponse: ValidationFailureJson,
516 controllerUpdateGnbTestExecuter(t, &context)
520 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
522 servedNrCellInformation := buildServedNrCellInformation("")
523 servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
525 context := controllerUpdateGnbTestContext{
526 getNodebInfoResult: nil,
527 requestBody: map[string]interface{}{
528 "servedNrCells": []interface{}{
529 map[string]interface{}{
530 "servedNrCellInformation": servedNrCellInformation,
534 expectedStatusCode: http.StatusBadRequest,
535 expectedJsonResponse: ValidationFailureJson,
538 controllerUpdateGnbTestExecuter(t, &context)
541 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
543 nrNeighbourInfo := buildNrNeighbourInformation("")
544 nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
546 context := controllerUpdateGnbTestContext{
547 getNodebInfoResult: nil,
548 requestBody: map[string]interface{}{
549 "servedNrCells": []interface{}{
550 map[string]interface{}{
551 "servedNrCellInformation": buildServedNrCellInformation(""),
552 "nrNeighbourInfos": []interface{}{
558 expectedStatusCode: http.StatusBadRequest,
559 expectedJsonResponse: ValidationFailureJson,
562 controllerUpdateGnbTestExecuter(t, &context)
565 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
567 for _, v := range NrNeighbourInformationRequiredFields {
568 context := controllerUpdateGnbTestContext{
569 getNodebInfoResult: nil,
570 requestBody: map[string]interface{}{
571 "servedNrCells": []interface{}{
572 map[string]interface{}{
573 "servedNrCellInformation": buildServedNrCellInformation(""),
574 "nrNeighbourInfos": []interface{}{
575 buildNrNeighbourInformation(v),
580 expectedStatusCode: http.StatusBadRequest,
581 expectedJsonResponse: ValidationFailureJson,
584 controllerUpdateGnbTestExecuter(t, &context)
588 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
589 context := controllerUpdateGnbTestContext{
590 getNodebInfoResult: &getNodebInfoResult{
592 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
594 requestBody: map[string]interface{}{
595 "servedNrCells": []interface{}{
596 map[string]interface{}{
597 "servedNrCellInformation": buildServedNrCellInformation(""),
601 expectedStatusCode: http.StatusNotFound,
602 expectedJsonResponse: ResourceNotFoundJson,
605 controllerUpdateGnbTestExecuter(t, &context)
608 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
609 context := controllerUpdateGnbTestContext{
610 getNodebInfoResult: &getNodebInfoResult{
612 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
614 requestBody: map[string]interface{}{
615 "servedNrCells": []interface{}{
616 map[string]interface{}{
617 "servedNrCellInformation": buildServedNrCellInformation(""),
621 expectedStatusCode: http.StatusInternalServerError,
622 expectedJsonResponse: RnibErrorJson,
625 controllerUpdateGnbTestExecuter(t, &context)
628 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
629 context := controllerUpdateGnbTestContext{
630 getNodebInfoResult: &getNodebInfoResult{
631 nodebInfo: &entities.NodebInfo{
633 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
634 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
638 requestBody: map[string]interface{}{
639 "servedNrCells": []interface{}{
640 map[string]interface{}{
641 "servedNrCellInformation": buildServedNrCellInformation(""),
642 "nrNeighbourInfos": []interface{}{
643 buildNrNeighbourInformation(""),
648 expectedStatusCode: http.StatusInternalServerError,
649 expectedJsonResponse: InternalErrorJson,
652 controllerUpdateGnbTestExecuter(t, &context)
655 func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) {
656 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
657 context := controllerUpdateGnbTestContext{
658 removeServedNrCellsParams: &removeServedNrCellsParams{
659 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
660 servedNrCells: oldServedNrCells,
662 getNodebInfoResult: &getNodebInfoResult{
663 nodebInfo: &entities.NodebInfo{
665 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
666 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
667 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
671 requestBody: map[string]interface{}{
672 "servedNrCells": []interface{}{
673 map[string]interface{}{
674 "servedNrCellInformation": buildServedNrCellInformation(""),
675 "nrNeighbourInfos": []interface{}{
676 buildNrNeighbourInformation(""),
681 expectedStatusCode: http.StatusInternalServerError,
682 expectedJsonResponse: RnibErrorJson,
685 controllerUpdateGnbTestExecuter(t, &context)
688 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
689 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
690 context := controllerUpdateGnbTestContext{
691 removeServedNrCellsParams: &removeServedNrCellsParams{
693 servedNrCells: oldServedNrCells,
695 updateGnbCellsParams: &updateGnbCellsParams{
696 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
698 getNodebInfoResult: &getNodebInfoResult{
699 nodebInfo: &entities.NodebInfo{
701 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
702 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
703 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
707 requestBody: map[string]interface{}{
708 "servedNrCells": []interface{}{
709 map[string]interface{}{
710 "servedNrCellInformation": buildServedNrCellInformation(""),
711 "nrNeighbourInfos": []interface{}{
712 buildNrNeighbourInformation(""),
717 expectedStatusCode: http.StatusInternalServerError,
718 expectedJsonResponse: RnibErrorJson,
721 controllerUpdateGnbTestExecuter(t, &context)
724 func TestControllerUpdateGnbSuccess(t *testing.T) {
725 context := controllerUpdateGnbTestContext{
726 updateGnbCellsParams: &updateGnbCellsParams{
729 getNodebInfoResult: &getNodebInfoResult{
730 nodebInfo: &entities.NodebInfo{
732 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
733 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
734 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
738 requestBody: map[string]interface{}{
739 "servedNrCells": []interface{}{
740 map[string]interface{}{
741 "servedNrCellInformation": buildServedNrCellInformation(""),
742 "nrNeighbourInfos": []interface{}{
743 buildNrNeighbourInformation(""),
748 expectedStatusCode: http.StatusOK,
749 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\"}",
752 controllerUpdateGnbTestExecuter(t, &context)
755 func TestControllerAddEnbGetNodebInternalError(t *testing.T) {
756 context := controllerAddEnbTestContext{
757 getNodebInfoResult: &getNodebInfoResult{
759 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
761 requestBody: getAddEnbRequest(""),
762 expectedStatusCode: http.StatusInternalServerError,
763 expectedJsonResponse: RnibErrorJson,
766 controllerAddEnbTestExecuter(t, &context)
769 func TestControllerAddEnbNodebExistsFailure(t *testing.T) {
770 context := controllerAddEnbTestContext{
771 getNodebInfoResult: &getNodebInfoResult{
772 nodebInfo: &entities.NodebInfo{},
775 requestBody: getAddEnbRequest(""),
776 expectedStatusCode: http.StatusBadRequest,
777 expectedJsonResponse: NodebExistsJson,
780 controllerAddEnbTestExecuter(t, &context)
783 func TestControllerAddEnbSaveNodebFailure(t *testing.T) {
784 context := controllerAddEnbTestContext{
785 saveNodebParams: &saveNodebParams{
786 err: common.NewInternalError(errors.New("#reader.SaveeNodeb - Internal Error")),
788 getNodebInfoResult: &getNodebInfoResult{
790 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
792 requestBody: getAddEnbRequest(""),
793 expectedStatusCode: http.StatusInternalServerError,
794 expectedJsonResponse: RnibErrorJson,
797 controllerAddEnbTestExecuter(t, &context)
800 func TestControllerAddEnbMissingRequiredRequestProps(t *testing.T) {
802 for _, v := range AddEnbRequestRequiredFields {
803 context := controllerAddEnbTestContext{
804 requestBody: getAddEnbRequest(v),
805 expectedStatusCode: http.StatusBadRequest,
806 expectedJsonResponse: ValidationFailureJson,
809 controllerAddEnbTestExecuter(t, &context)
813 func TestControllerAddEnbInvalidRequest(t *testing.T) {
814 controller, _, _, _, _ := setupControllerTest(t)
815 writer := httptest.NewRecorder()
817 // Invalid json: attribute name without quotes (should be "cause":).
818 invalidJson := strings.NewReader("{ranName:\"whatever\"")
819 req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, invalidJson)
821 controller.AddEnb(writer, req)
822 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
823 bodyBytes, _ := ioutil.ReadAll(writer.Body)
824 assert.Equal(t, CorruptedJson, string(bodyBytes))
828 func TestControllerAddEnbMissingRequiredGlobalNbIdProps(t *testing.T) {
830 r := getAddEnbRequest("")
832 for _, v := range GlobalIdRequiredFields {
833 r["globalNbId"] = buildGlobalNbId(v)
835 context := controllerAddEnbTestContext{
837 expectedStatusCode: http.StatusBadRequest,
838 expectedJsonResponse: ValidationFailureJson,
841 controllerAddEnbTestExecuter(t, &context)
845 func TestControllerAddEnbMissingRequiredEnbProps(t *testing.T) {
847 r := getAddEnbRequest("")
849 for _, v := range EnbRequiredFields {
850 r["enb"] = buildEnb(v)
852 context := controllerAddEnbTestContext{
854 expectedStatusCode: http.StatusBadRequest,
855 expectedJsonResponse: ValidationFailureJson,
858 controllerAddEnbTestExecuter(t, &context)
862 func TestControllerAddEnbMissingRequiredServedCellProps(t *testing.T) {
864 r := getAddEnbRequest("")
866 for _, v := range ServedCellRequiredFields {
869 enbMap, _ := enb.(map[string]interface{})
871 enbMap["servedCells"] = []interface{}{
875 context := controllerAddEnbTestContext{
877 expectedStatusCode: http.StatusBadRequest,
878 expectedJsonResponse: ValidationFailureJson,
881 controllerAddEnbTestExecuter(t, &context)
885 func TestControllerAddEnbSuccess(t *testing.T) {
886 context := controllerAddEnbTestContext{
887 saveNodebParams: &saveNodebParams{
890 getNodebInfoResult: &getNodebInfoResult{
892 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
894 requestBody: map[string]interface{}{
896 "globalNbId": map[string]interface{}{
897 "plmnId": "whatever",
900 "enb": map[string]interface{}{
902 "servedCells": []interface{}{
907 expectedStatusCode: http.StatusCreated,
908 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\"}]}}",
911 controllerAddEnbTestExecuter(t, &context)
914 func TestControllerDeleteEnbGetNodebInternalError(t *testing.T) {
915 context := controllerDeleteEnbTestContext{
916 getNodebInfoResult: &getNodebInfoResult{
918 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
920 expectedStatusCode: http.StatusInternalServerError,
921 expectedJsonResponse: RnibErrorJson,
924 controllerDeleteEnbTestExecuter(t, &context)
927 func TestControllerDeleteEnbNodebNotExistsFailure(t *testing.T) {
928 context := controllerDeleteEnbTestContext{
929 getNodebInfoResult: &getNodebInfoResult{
931 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found"),
933 expectedStatusCode: http.StatusNotFound,
934 expectedJsonResponse: ResourceNotFoundJson,
937 controllerDeleteEnbTestExecuter(t, &context)
940 func TestControllerDeleteEnbNodebNotEnb(t *testing.T) {
941 context := controllerDeleteEnbTestContext{
942 getNodebInfoResult: &getNodebInfoResult{
943 nodebInfo: &entities.NodebInfo{RanName: "ran1", NodeType: entities.Node_GNB, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED},
946 expectedStatusCode: http.StatusBadRequest,
947 expectedJsonResponse: ValidationFailureJson,
950 controllerDeleteEnbTestExecuter(t, &context)
953 func TestControllerDeleteEnbSuccess(t *testing.T) {
954 context := controllerDeleteEnbTestContext{
955 getNodebInfoResult: &getNodebInfoResult{
956 nodebInfo: &entities.NodebInfo{RanName: "ran1", NodeType: entities.Node_ENB, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED},
959 expectedStatusCode: http.StatusNoContent,
960 expectedJsonResponse: "",
962 controllerDeleteEnbTestExecuter(t, &context)
965 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
966 b := new(bytes.Buffer)
967 _ = json.NewEncoder(b).Encode(requestJson)
971 func TestControllerGetNodebSuccess(t *testing.T) {
974 context := controllerGetNodebTestContext{
976 nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234},
977 rnibError: rnibError,
978 expectedStatusCode: http.StatusOK,
979 expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName),
982 controllerGetNodebTestExecuter(t, &context)
985 func TestControllerGetNodebNotFound(t *testing.T) {
988 var nodebInfo *entities.NodebInfo
989 context := controllerGetNodebTestContext{
991 nodebInfo: nodebInfo,
992 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
993 expectedStatusCode: http.StatusNotFound,
994 expectedJsonResponse: ResourceNotFoundJson,
997 controllerGetNodebTestExecuter(t, &context)
1000 func TestControllerGetNodebInternal(t *testing.T) {
1002 var nodebInfo *entities.NodebInfo
1003 context := controllerGetNodebTestContext{
1005 nodebInfo: nodebInfo,
1006 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
1007 expectedStatusCode: http.StatusInternalServerError,
1008 expectedJsonResponse: RnibErrorJson,
1011 controllerGetNodebTestExecuter(t, &context)
1014 func TestControllerGetNodebIdListSuccess(t *testing.T) {
1016 nodebIdList := []*entities.NbIdentity{
1017 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
1018 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
1021 context := controllerGetNodebIdListTestContext{
1022 nodebIdList: nodebIdList,
1023 rnibError: rnibError,
1024 expectedStatusCode: http.StatusOK,
1025 expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]",
1028 controllerGetNodebIdListTestExecuter(t, &context)
1031 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
1033 var nodebIdList []*entities.NbIdentity
1035 context := controllerGetNodebIdListTestContext{
1036 nodebIdList: nodebIdList,
1037 rnibError: rnibError,
1038 expectedStatusCode: http.StatusOK,
1039 expectedJsonResponse: "[]",
1042 controllerGetNodebIdListTestExecuter(t, &context)
1045 func TestControllerGetNodebIdListInternal(t *testing.T) {
1046 var nodebIdList []*entities.NbIdentity
1047 context := controllerGetNodebIdListTestContext{
1048 nodebIdList: nodebIdList,
1049 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
1050 expectedStatusCode: http.StatusInternalServerError,
1051 expectedJsonResponse: RnibErrorJson,
1054 controllerGetNodebIdListTestExecuter(t, &context)
1057 func TestHeaderValidationFailed(t *testing.T) {
1058 controller, _, _, _, _ := setupControllerTest(t)
1060 writer := httptest.NewRecorder()
1062 header := &http.Header{}
1064 controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true, 0)
1066 var errorResponse = parseJsonRequest(t, writer.Body)
1067 err := e2managererrors.NewHeaderValidationError()
1069 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
1070 assert.Equal(t, errorResponse.Code, err.Code)
1071 assert.Equal(t, errorResponse.Message, err.Message)
1074 func TestShutdownStatusNoContent(t *testing.T) {
1075 controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t)
1076 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil)
1077 readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil)
1079 writer := httptest.NewRecorder()
1080 controller.Shutdown(writer, tests.GetHttpRequest())
1082 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1085 func TestHandleInternalError(t *testing.T) {
1086 controller, _, _, _, _ := setupControllerTest(t)
1088 writer := httptest.NewRecorder()
1089 err := e2managererrors.NewInternalError()
1091 controller.handleErrorResponse(err, writer)
1092 var errorResponse = parseJsonRequest(t, writer.Body)
1094 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1095 assert.Equal(t, errorResponse.Code, err.Code)
1096 assert.Equal(t, errorResponse.Message, err.Message)
1099 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
1100 controller, _, _, _, _ := setupControllerTest(t)
1101 writer := httptest.NewRecorder()
1102 err := e2managererrors.NewCommandAlreadyInProgressError()
1104 controller.handleErrorResponse(err, writer)
1105 var errorResponse = parseJsonRequest(t, writer.Body)
1107 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
1108 assert.Equal(t, errorResponse.Code, err.Code)
1109 assert.Equal(t, errorResponse.Message, err.Message)
1112 func TestHandleRoutingManagerError(t *testing.T) {
1113 controller, _, _, _, _ := setupControllerTest(t)
1114 writer := httptest.NewRecorder()
1115 err := e2managererrors.NewRoutingManagerError()
1117 controller.handleErrorResponse(err, writer)
1118 var errorResponse = parseJsonRequest(t, writer.Body)
1120 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
1121 assert.Equal(t, errorResponse.Code, err.Code)
1122 assert.Equal(t, errorResponse.Message, err.Message)
1125 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
1126 controller, _, _, _, _ := setupControllerTest(t)
1128 writer := httptest.NewRecorder()
1129 err := e2managererrors.NewE2TInstanceAbsenceError()
1131 controller.handleErrorResponse(err, writer)
1132 var errorResponse = parseJsonRequest(t, writer.Body)
1134 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
1135 assert.Equal(t, errorResponse.Code, err.Code)
1136 assert.Equal(t, errorResponse.Message, err.Message)
1139 func TestValidateHeaders(t *testing.T) {
1140 controller, _, _, _, _ := setupControllerTest(t)
1142 header := http.Header{}
1143 header.Set("Content-Type", "application/json")
1144 result := controller.validateRequestHeader(&header)
1146 assert.Nil(t, result)
1149 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
1151 var errorResponse models.ErrorResponse
1152 body, err := ioutil.ReadAll(r)
1154 t.Errorf("Error cannot deserialize json request")
1156 _ = json.Unmarshal(body, &errorResponse)
1158 return errorResponse
1161 func initLog(t *testing.T) *logger.Logger {
1162 log, err := logger.InitLogger(logger.InfoLevel)
1164 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
1169 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
1170 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
1173 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
1175 var msgSrc unsafe.Pointer
1176 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
1177 rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
1179 writer := httptest.NewRecorder()
1181 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
1182 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
1184 data4Req := map[string]interface{}{"cause": "protocol:transfer-syntax-error"}
1185 b := new(bytes.Buffer)
1186 _ = json.NewEncoder(b).Encode(data4Req)
1187 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1188 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1190 controller.X2Reset(writer, req)
1191 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1195 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
1196 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
1200 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
1202 var msgSrc unsafe.Pointer
1203 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
1204 rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
1206 writer := httptest.NewRecorder()
1208 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
1209 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
1212 b := new(bytes.Buffer)
1213 data4Req := map[string]interface{}{}
1214 _ = json.NewEncoder(b).Encode(data4Req)
1215 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1216 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1218 controller.X2Reset(writer, req)
1219 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1222 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
1223 controller, _, _, _, _ := setupControllerTest(t)
1227 writer := httptest.NewRecorder()
1229 // Invalid json: attribute name without quotes (should be "cause":).
1230 b := strings.NewReader("{cause:\"protocol:transfer-syntax-error\"")
1231 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1232 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1234 controller.X2Reset(writer, req)
1235 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1239 func TestHandleErrorResponse(t *testing.T) {
1240 controller, _, _, _, _ := setupControllerTest(t)
1242 writer := httptest.NewRecorder()
1243 controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
1244 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1246 writer = httptest.NewRecorder()
1247 controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
1248 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
1250 writer = httptest.NewRecorder()
1251 controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
1252 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
1254 writer = httptest.NewRecorder()
1255 controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
1256 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1258 writer = httptest.NewRecorder()
1259 controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
1260 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1262 writer = httptest.NewRecorder()
1263 controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
1264 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1266 writer = httptest.NewRecorder()
1267 controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
1268 assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
1270 writer = httptest.NewRecorder()
1271 controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
1272 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1275 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
1276 rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
1277 rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
1278 return rmrsender.NewRmrSender(log, rmrMessenger)