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 func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
129 servedNrCells := []*entities.ServedNRCell{}
131 for _, v := range cellIds {
132 servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{
134 ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{
135 Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{
139 NrMode: entities.Nr_FDD,
141 ServedPlmns: []string{"whatever"},
148 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
149 ret := map[string]interface{}{
151 "choiceNrMode": map[string]interface{}{
152 "tdd": map[string]interface{}{},
158 if len(propToOmit) != 0 {
159 delete(ret, propToOmit)
165 func buildServedNrCellInformation(propToOmit string) map[string]interface{} {
166 ret := map[string]interface{}{
167 "cellId": "whatever",
168 "choiceNrMode": map[string]interface{}{
169 "fdd": map[string]interface{}{},
173 "servedPlmns": []interface{}{
178 if len(propToOmit) != 0 {
179 delete(ret, propToOmit)
185 func buildServedCell(propToOmit string) map[string]interface{} {
186 ret := map[string]interface{}{
187 "cellId": "whatever",
188 "choiceEutraMode": map[string]interface{}{
189 "fdd": map[string]interface{}{},
194 "broadcastPlmns": []interface{}{
199 if len(propToOmit) != 0 {
200 delete(ret, propToOmit)
206 func getAddEnbRequest(propToOmit string) map[string]interface{} {
207 ret := map[string]interface{}{
209 "globalNbId": buildGlobalNbId(""),
213 if len(propToOmit) != 0 {
214 delete(ret, propToOmit)
220 func buildEnb(propToOmit string) map[string]interface{} {
221 ret := map[string]interface{}{
223 "servedCells": []interface{}{
227 if len(propToOmit) != 0 {
228 delete(ret, propToOmit)
234 func buildGlobalNbId(propToOmit string) map[string]interface{} {
235 ret := map[string]interface{}{
236 "plmnId": "whatever",
240 if len(propToOmit) != 0 {
241 delete(ret, propToOmit)
247 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
249 config := configuration.ParseConfiguration()
251 rmrMessengerMock := &mocks.RmrMessengerMock{}
252 readerMock := &mocks.RnibReaderMock{}
254 writerMock := &mocks.RnibWriterMock{}
256 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
257 rmrSender := getRmrSender(rmrMessengerMock, log)
258 e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
259 httpClientMock := &mocks.HttpClientMock{}
260 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
261 ranListManager := &mocks.RanListManagerMock{}
262 ranAlarmService := &mocks.RanAlarmServiceMock{}
263 ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
264 nodebValidator := managers.NewNodebValidator()
265 handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager, nodebValidator)
266 controller := NewNodebController(log, handlerProvider)
267 return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
270 func TestShutdownHandlerRnibError(t *testing.T) {
271 controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
272 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
274 writer := httptest.NewRecorder()
276 controller.Shutdown(writer, tests.GetHttpRequest())
278 var errorResponse = parseJsonRequest(t, writer.Body)
280 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
281 assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
284 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
285 controller, readerMock, _, _, _ := setupControllerTest(t)
287 configuration := &entities.GeneralConfiguration{}
288 readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
290 writer := httptest.NewRecorder()
292 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
294 controller.SetGeneralConfiguration(writer, httpRequest)
296 var errorResponse = parseJsonRequest(t, writer.Body)
298 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
299 assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
302 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
303 controller, _, _, _, _ := setupControllerTest(t)
305 writer := httptest.NewRecorder()
307 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false, \"someValue\":false}"))
309 controller.SetGeneralConfiguration(writer, httpRequest)
311 var errorResponse = parseJsonRequest(t, writer.Body)
313 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
314 assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
317 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
318 controller, readerMock, _, _, _ := setupControllerTest(t)
319 writer := httptest.NewRecorder()
320 readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
321 req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil)
322 req = mux.SetURLVars(req, map[string]string{"ranName": context.ranName})
323 controller.GetNodeb(writer, req)
324 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
325 bodyBytes, _ := ioutil.ReadAll(writer.Body)
326 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
329 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
330 controller, readerMock, _, _, _ := setupControllerTest(t)
331 writer := httptest.NewRecorder()
332 readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
333 req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil)
334 controller.GetNodebIdList(writer, req)
335 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
336 bodyBytes, _ := ioutil.ReadAll(writer.Body)
337 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
340 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
341 if context.getNodebInfoResult != nil {
342 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
345 if context.removeServedNrCellsParams != nil {
346 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
349 if context.updateGnbCellsParams != nil {
350 updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
351 gnb := entities.Gnb{}
352 _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb)
353 updatedGnb := *updatedNodebInfo.GetGnb()
354 updatedGnb.ServedNrCells = gnb.ServedNrCells
355 writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err)
359 func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
360 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
361 bodyBytes, _ := ioutil.ReadAll(writer.Body)
362 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
363 readerMock.AssertExpectations(t)
364 writerMock.AssertExpectations(t)
367 func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, 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 buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
376 updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
377 requestBody := getJsonRequestAsBuffer(context.requestBody)
378 req, _ := http.NewRequest(http.MethodPut, updateGnbUrl, requestBody)
379 req.Header.Set("Content-Type", "application/json")
380 req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
384 func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request {
385 requestBody := getJsonRequestAsBuffer(context.requestBody)
386 req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, requestBody)
387 req.Header.Set("Content-Type", "application/json")
391 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
392 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
393 writer := httptest.NewRecorder()
395 activateControllerUpdateGnbMocks(context, readerMock, writerMock)
396 req := buildUpdateGnbRequest(context)
397 controller.UpdateGnb(writer, req)
398 assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
401 func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, addEnbRequest *models.AddEnbRequest) {
402 if context.getNodebInfoResult != nil {
403 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
406 if context.saveNodebParams != nil {
407 nodebInfo := entities.NodebInfo{
408 RanName: addEnbRequest.RanName,
409 Ip: addEnbRequest.Ip,
410 Port: addEnbRequest.Port,
411 NodeType: entities.Node_ENB,
412 GlobalNbId: addEnbRequest.GlobalNbId,
413 Configuration: &entities.NodebInfo_Enb{Enb: addEnbRequest.Enb},
414 ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,
417 nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId}
419 writerMock.On("SaveNodeb", &nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
423 func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestContext) {
424 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
425 writer := httptest.NewRecorder()
426 r := buildAddEnbRequest(context)
427 body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
429 addEnbRequest := models.AddEnbRequest{}
431 _ = json.Unmarshal(body, &addEnbRequest)
432 activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest)
433 r = buildAddEnbRequest(context)
435 controller.AddEnb(writer, r)
436 assertControllerAddEnb(t, context, writer, readerMock, writerMock)
439 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
440 context := controllerUpdateGnbTestContext{
441 getNodebInfoResult: nil,
442 requestBody: map[string]interface{}{
443 "servedNrCells": []interface{}{
446 expectedStatusCode: http.StatusBadRequest,
447 expectedJsonResponse: ValidationFailureJson,
450 controllerUpdateGnbTestExecuter(t, &context)
453 func TestControllerUpdateGnbMissingServedNrCellInformation(t *testing.T) {
454 context := controllerUpdateGnbTestContext{
455 getNodebInfoResult: nil,
456 requestBody: map[string]interface{}{
457 "servedNrCells": []interface{}{
458 map[string]interface{}{
459 "servedNrCellInformation": nil,
463 expectedStatusCode: http.StatusBadRequest,
464 expectedJsonResponse: ValidationFailureJson,
467 controllerUpdateGnbTestExecuter(t, &context)
470 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
472 for _, v := range ServedNrCellInformationRequiredFields {
473 context := controllerUpdateGnbTestContext{
474 getNodebInfoResult: nil,
475 requestBody: map[string]interface{}{
476 "servedNrCells": []interface{}{
477 map[string]interface{}{
478 "servedNrCellInformation": buildServedNrCellInformation(v),
482 expectedStatusCode: http.StatusBadRequest,
483 expectedJsonResponse: ValidationFailureJson,
486 controllerUpdateGnbTestExecuter(t, &context)
490 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
492 servedNrCellInformation := buildServedNrCellInformation("")
493 servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
495 context := controllerUpdateGnbTestContext{
496 getNodebInfoResult: nil,
497 requestBody: map[string]interface{}{
498 "servedNrCells": []interface{}{
499 map[string]interface{}{
500 "servedNrCellInformation": servedNrCellInformation,
504 expectedStatusCode: http.StatusBadRequest,
505 expectedJsonResponse: ValidationFailureJson,
508 controllerUpdateGnbTestExecuter(t, &context)
511 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
513 nrNeighbourInfo := buildNrNeighbourInformation("")
514 nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
516 context := controllerUpdateGnbTestContext{
517 getNodebInfoResult: nil,
518 requestBody: map[string]interface{}{
519 "servedNrCells": []interface{}{
520 map[string]interface{}{
521 "servedNrCellInformation": buildServedNrCellInformation(""),
522 "nrNeighbourInfos": []interface{}{
528 expectedStatusCode: http.StatusBadRequest,
529 expectedJsonResponse: ValidationFailureJson,
532 controllerUpdateGnbTestExecuter(t, &context)
535 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
537 for _, v := range NrNeighbourInformationRequiredFields {
538 context := controllerUpdateGnbTestContext{
539 getNodebInfoResult: nil,
540 requestBody: map[string]interface{}{
541 "servedNrCells": []interface{}{
542 map[string]interface{}{
543 "servedNrCellInformation": buildServedNrCellInformation(""),
544 "nrNeighbourInfos": []interface{}{
545 buildNrNeighbourInformation(v),
550 expectedStatusCode: http.StatusBadRequest,
551 expectedJsonResponse: ValidationFailureJson,
554 controllerUpdateGnbTestExecuter(t, &context)
558 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
559 context := controllerUpdateGnbTestContext{
560 getNodebInfoResult: &getNodebInfoResult{
562 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
564 requestBody: map[string]interface{}{
565 "servedNrCells": []interface{}{
566 map[string]interface{}{
567 "servedNrCellInformation": buildServedNrCellInformation(""),
571 expectedStatusCode: http.StatusNotFound,
572 expectedJsonResponse: ResourceNotFoundJson,
575 controllerUpdateGnbTestExecuter(t, &context)
578 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
579 context := controllerUpdateGnbTestContext{
580 getNodebInfoResult: &getNodebInfoResult{
582 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
584 requestBody: map[string]interface{}{
585 "servedNrCells": []interface{}{
586 map[string]interface{}{
587 "servedNrCellInformation": buildServedNrCellInformation(""),
591 expectedStatusCode: http.StatusInternalServerError,
592 expectedJsonResponse: RnibErrorJson,
595 controllerUpdateGnbTestExecuter(t, &context)
598 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
599 context := controllerUpdateGnbTestContext{
600 getNodebInfoResult: &getNodebInfoResult{
601 nodebInfo: &entities.NodebInfo{
603 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
604 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
608 requestBody: map[string]interface{}{
609 "servedNrCells": []interface{}{
610 map[string]interface{}{
611 "servedNrCellInformation": buildServedNrCellInformation(""),
612 "nrNeighbourInfos": []interface{}{
613 buildNrNeighbourInformation(""),
618 expectedStatusCode: http.StatusInternalServerError,
619 expectedJsonResponse: InternalErrorJson,
622 controllerUpdateGnbTestExecuter(t, &context)
625 func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) {
626 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
627 context := controllerUpdateGnbTestContext{
628 removeServedNrCellsParams: &removeServedNrCellsParams{
629 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
630 servedNrCells: oldServedNrCells,
632 getNodebInfoResult: &getNodebInfoResult{
633 nodebInfo: &entities.NodebInfo{
635 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
636 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
637 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
641 requestBody: map[string]interface{}{
642 "servedNrCells": []interface{}{
643 map[string]interface{}{
644 "servedNrCellInformation": buildServedNrCellInformation(""),
645 "nrNeighbourInfos": []interface{}{
646 buildNrNeighbourInformation(""),
651 expectedStatusCode: http.StatusInternalServerError,
652 expectedJsonResponse: RnibErrorJson,
655 controllerUpdateGnbTestExecuter(t, &context)
658 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
659 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
660 context := controllerUpdateGnbTestContext{
661 removeServedNrCellsParams: &removeServedNrCellsParams{
663 servedNrCells: oldServedNrCells,
665 updateGnbCellsParams: &updateGnbCellsParams{
666 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
668 getNodebInfoResult: &getNodebInfoResult{
669 nodebInfo: &entities.NodebInfo{
671 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
672 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
673 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
677 requestBody: map[string]interface{}{
678 "servedNrCells": []interface{}{
679 map[string]interface{}{
680 "servedNrCellInformation": buildServedNrCellInformation(""),
681 "nrNeighbourInfos": []interface{}{
682 buildNrNeighbourInformation(""),
687 expectedStatusCode: http.StatusInternalServerError,
688 expectedJsonResponse: RnibErrorJson,
691 controllerUpdateGnbTestExecuter(t, &context)
694 func TestControllerUpdateGnbSuccess(t *testing.T) {
695 context := controllerUpdateGnbTestContext{
696 updateGnbCellsParams: &updateGnbCellsParams{
699 getNodebInfoResult: &getNodebInfoResult{
700 nodebInfo: &entities.NodebInfo{
702 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
703 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
704 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
708 requestBody: map[string]interface{}{
709 "servedNrCells": []interface{}{
710 map[string]interface{}{
711 "servedNrCellInformation": buildServedNrCellInformation(""),
712 "nrNeighbourInfos": []interface{}{
713 buildNrNeighbourInformation(""),
718 expectedStatusCode: http.StatusOK,
719 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\"}",
722 controllerUpdateGnbTestExecuter(t, &context)
725 func TestControllerAddEnbGetNodebInternalError(t *testing.T) {
726 context := controllerAddEnbTestContext{
727 getNodebInfoResult: &getNodebInfoResult{
729 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
731 requestBody: getAddEnbRequest(""),
732 expectedStatusCode: http.StatusInternalServerError,
733 expectedJsonResponse: RnibErrorJson,
736 controllerAddEnbTestExecuter(t, &context)
739 func TestControllerAddEnbNodebExistsFailure(t *testing.T) {
740 context := controllerAddEnbTestContext{
741 getNodebInfoResult: &getNodebInfoResult{
742 nodebInfo: &entities.NodebInfo{},
745 requestBody: getAddEnbRequest(""),
746 expectedStatusCode: http.StatusBadRequest,
747 expectedJsonResponse: NodebExistsJson,
750 controllerAddEnbTestExecuter(t, &context)
753 func TestControllerAddEnbSaveNodebFailure(t *testing.T) {
754 context := controllerAddEnbTestContext{
755 saveNodebParams: &saveNodebParams{
756 err: common.NewInternalError(errors.New("#reader.SaveeNodeb - Internal Error")),
758 getNodebInfoResult: &getNodebInfoResult{
760 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
762 requestBody: getAddEnbRequest(""),
763 expectedStatusCode: http.StatusInternalServerError,
764 expectedJsonResponse: RnibErrorJson,
767 controllerAddEnbTestExecuter(t, &context)
770 func TestControllerAddEnbMissingRequiredRequestProps(t *testing.T) {
772 for _, v := range AddEnbRequestRequiredFields {
773 context := controllerAddEnbTestContext{
774 requestBody: getAddEnbRequest(v),
775 expectedStatusCode: http.StatusBadRequest,
776 expectedJsonResponse: ValidationFailureJson,
779 controllerAddEnbTestExecuter(t, &context)
783 func TestControllerAddEnbInvalidRequest(t *testing.T) {
784 controller, _, _, _, _ := setupControllerTest(t)
785 writer := httptest.NewRecorder()
787 // Invalid json: attribute name without quotes (should be "cause":).
788 invalidJson := strings.NewReader("{ranName:\"whatever\"")
789 req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, invalidJson)
791 controller.AddEnb(writer, req)
792 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
793 bodyBytes, _ := ioutil.ReadAll(writer.Body)
794 assert.Equal(t, CorruptedJson, string(bodyBytes))
798 func TestControllerAddEnbMissingRequiredGlobalNbIdProps(t *testing.T) {
800 r := getAddEnbRequest("")
802 for _, v := range GlobalIdRequiredFields {
803 r["globalNbId"] = buildGlobalNbId(v)
805 context := controllerAddEnbTestContext{
807 expectedStatusCode: http.StatusBadRequest,
808 expectedJsonResponse: ValidationFailureJson,
811 controllerAddEnbTestExecuter(t, &context)
815 func TestControllerAddEnbMissingRequiredEnbProps(t *testing.T) {
817 r := getAddEnbRequest("")
819 for _, v := range EnbRequiredFields {
820 r["enb"] = buildEnb(v)
822 context := controllerAddEnbTestContext{
824 expectedStatusCode: http.StatusBadRequest,
825 expectedJsonResponse: ValidationFailureJson,
828 controllerAddEnbTestExecuter(t, &context)
832 func TestControllerAddEnbMissingRequiredServedCellProps(t *testing.T) {
834 r := getAddEnbRequest("")
836 for _, v := range ServedCellRequiredFields {
839 enbMap, _ := enb.(map[string]interface{})
841 enbMap["servedCells"] = []interface{}{
845 context := controllerAddEnbTestContext{
847 expectedStatusCode: http.StatusBadRequest,
848 expectedJsonResponse: ValidationFailureJson,
851 controllerAddEnbTestExecuter(t, &context)
855 func TestControllerAddEnbSuccess(t *testing.T) {
856 context := controllerAddEnbTestContext{
857 saveNodebParams: &saveNodebParams{
860 getNodebInfoResult: &getNodebInfoResult{
862 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
864 requestBody: map[string]interface{}{
866 "globalNbId": map[string]interface{}{
867 "plmnId": "whatever",
870 "enb": map[string]interface{}{
872 "servedCells": []interface{}{
877 expectedStatusCode: http.StatusCreated,
878 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\"}]}}",
881 controllerAddEnbTestExecuter(t, &context)
884 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
885 b := new(bytes.Buffer)
886 _ = json.NewEncoder(b).Encode(requestJson)
890 func TestControllerGetNodebSuccess(t *testing.T) {
893 context := controllerGetNodebTestContext{
895 nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234},
896 rnibError: rnibError,
897 expectedStatusCode: http.StatusOK,
898 expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName),
901 controllerGetNodebTestExecuter(t, &context)
904 func TestControllerGetNodebNotFound(t *testing.T) {
907 var nodebInfo *entities.NodebInfo
908 context := controllerGetNodebTestContext{
910 nodebInfo: nodebInfo,
911 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
912 expectedStatusCode: http.StatusNotFound,
913 expectedJsonResponse: ResourceNotFoundJson,
916 controllerGetNodebTestExecuter(t, &context)
919 func TestControllerGetNodebInternal(t *testing.T) {
921 var nodebInfo *entities.NodebInfo
922 context := controllerGetNodebTestContext{
924 nodebInfo: nodebInfo,
925 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
926 expectedStatusCode: http.StatusInternalServerError,
927 expectedJsonResponse: RnibErrorJson,
930 controllerGetNodebTestExecuter(t, &context)
933 func TestControllerGetNodebIdListSuccess(t *testing.T) {
935 nodebIdList := []*entities.NbIdentity{
936 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
937 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
940 context := controllerGetNodebIdListTestContext{
941 nodebIdList: nodebIdList,
942 rnibError: rnibError,
943 expectedStatusCode: http.StatusOK,
944 expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]",
947 controllerGetNodebIdListTestExecuter(t, &context)
950 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
952 nodebIdList := []*entities.NbIdentity{}
954 context := controllerGetNodebIdListTestContext{
955 nodebIdList: nodebIdList,
956 rnibError: rnibError,
957 expectedStatusCode: http.StatusOK,
958 expectedJsonResponse: "[]",
961 controllerGetNodebIdListTestExecuter(t, &context)
964 func TestControllerGetNodebIdListInternal(t *testing.T) {
965 var nodebIdList []*entities.NbIdentity
966 context := controllerGetNodebIdListTestContext{
967 nodebIdList: nodebIdList,
968 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
969 expectedStatusCode: http.StatusInternalServerError,
970 expectedJsonResponse: RnibErrorJson,
973 controllerGetNodebIdListTestExecuter(t, &context)
976 func TestHeaderValidationFailed(t *testing.T) {
977 controller, _, _, _, _ := setupControllerTest(t)
979 writer := httptest.NewRecorder()
981 header := &http.Header{}
983 controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true, 0)
985 var errorResponse = parseJsonRequest(t, writer.Body)
986 err := e2managererrors.NewHeaderValidationError()
988 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
989 assert.Equal(t, errorResponse.Code, err.Code)
990 assert.Equal(t, errorResponse.Message, err.Message)
993 func TestShutdownStatusNoContent(t *testing.T) {
994 controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t)
995 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil)
996 readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil)
998 writer := httptest.NewRecorder()
999 controller.Shutdown(writer, tests.GetHttpRequest())
1001 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1004 func TestHandleInternalError(t *testing.T) {
1005 controller, _, _, _, _ := setupControllerTest(t)
1007 writer := httptest.NewRecorder()
1008 err := e2managererrors.NewInternalError()
1010 controller.handleErrorResponse(err, writer)
1011 var errorResponse = parseJsonRequest(t, writer.Body)
1013 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1014 assert.Equal(t, errorResponse.Code, err.Code)
1015 assert.Equal(t, errorResponse.Message, err.Message)
1018 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
1019 controller, _, _, _, _ := setupControllerTest(t)
1020 writer := httptest.NewRecorder()
1021 err := e2managererrors.NewCommandAlreadyInProgressError()
1023 controller.handleErrorResponse(err, writer)
1024 var errorResponse = parseJsonRequest(t, writer.Body)
1026 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
1027 assert.Equal(t, errorResponse.Code, err.Code)
1028 assert.Equal(t, errorResponse.Message, err.Message)
1031 func TestHandleRoutingManagerError(t *testing.T) {
1032 controller, _, _, _, _ := setupControllerTest(t)
1033 writer := httptest.NewRecorder()
1034 err := e2managererrors.NewRoutingManagerError()
1036 controller.handleErrorResponse(err, writer)
1037 var errorResponse = parseJsonRequest(t, writer.Body)
1039 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
1040 assert.Equal(t, errorResponse.Code, err.Code)
1041 assert.Equal(t, errorResponse.Message, err.Message)
1044 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
1045 controller, _, _, _, _ := setupControllerTest(t)
1047 writer := httptest.NewRecorder()
1048 err := e2managererrors.NewE2TInstanceAbsenceError()
1050 controller.handleErrorResponse(err, writer)
1051 var errorResponse = parseJsonRequest(t, writer.Body)
1053 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
1054 assert.Equal(t, errorResponse.Code, err.Code)
1055 assert.Equal(t, errorResponse.Message, err.Message)
1058 func TestValidateHeaders(t *testing.T) {
1059 controller, _, _, _, _ := setupControllerTest(t)
1061 header := http.Header{}
1062 header.Set("Content-Type", "application/json")
1063 result := controller.validateRequestHeader(&header)
1065 assert.Nil(t, result)
1068 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
1070 var errorResponse models.ErrorResponse
1071 body, err := ioutil.ReadAll(r)
1073 t.Errorf("Error cannot deserialize json request")
1075 _ = json.Unmarshal(body, &errorResponse)
1077 return errorResponse
1080 func initLog(t *testing.T) *logger.Logger {
1081 log, err := logger.InitLogger(logger.InfoLevel)
1083 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
1088 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
1089 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
1092 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
1094 var msgSrc unsafe.Pointer
1095 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
1096 rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
1098 writer := httptest.NewRecorder()
1100 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
1101 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
1103 data4Req := map[string]interface{}{"cause": "protocol:transfer-syntax-error"}
1104 b := new(bytes.Buffer)
1105 _ = json.NewEncoder(b).Encode(data4Req)
1106 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1107 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1109 controller.X2Reset(writer, req)
1110 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1114 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
1115 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
1119 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
1121 var msgSrc unsafe.Pointer
1122 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
1123 rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
1125 writer := httptest.NewRecorder()
1127 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
1128 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
1131 b := new(bytes.Buffer)
1132 data4Req := map[string]interface{}{}
1133 _ = json.NewEncoder(b).Encode(data4Req)
1134 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1135 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1137 controller.X2Reset(writer, req)
1138 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1141 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
1142 controller, _, _, _, _ := setupControllerTest(t)
1146 writer := httptest.NewRecorder()
1148 // Invalid json: attribute name without quotes (should be "cause":).
1149 b := strings.NewReader("{cause:\"protocol:transfer-syntax-error\"")
1150 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1151 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1153 controller.X2Reset(writer, req)
1154 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1158 func TestHandleErrorResponse(t *testing.T) {
1159 controller, _, _, _, _ := setupControllerTest(t)
1161 writer := httptest.NewRecorder()
1162 controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
1163 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1165 writer = httptest.NewRecorder()
1166 controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
1167 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
1169 writer = httptest.NewRecorder()
1170 controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
1171 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
1173 writer = httptest.NewRecorder()
1174 controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
1175 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1177 writer = httptest.NewRecorder()
1178 controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
1179 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1181 writer = httptest.NewRecorder()
1182 controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
1183 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1185 writer = httptest.NewRecorder()
1186 controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
1187 assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
1189 writer = httptest.NewRecorder()
1190 controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
1191 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1194 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
1195 rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
1196 rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
1197 return rmrsender.NewRmrSender(log, rmrMessenger)