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 ValidationFailureJson = "{\"errorCode\":402,\"errorMessage\":\"Validation error\"}"
58 ResourceNotFoundJson = "{\"errorCode\":404,\"errorMessage\":\"Resource not found\"}"
59 NodebExistsJson = "{\"errorCode\":406,\"errorMessage\":\"Nodeb already exists\"}"
60 RnibErrorJson = "{\"errorCode\":500,\"errorMessage\":\"RNIB error\"}"
61 InternalErrorJson = "{\"errorCode\":501,\"errorMessage\":\"Internal Server Error. Please try again later\"}"
62 AddEnbUrl = "/nodeb/enb"
66 ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "servedPlmns"}
67 NrNeighbourInformationRequiredFields = []string{"nrCgi", "choiceNrMode", "nrMode"}
68 AddEnbRequestRequiredFields = []string{"ranName", "enb", "globalNbId"}
69 EnbRequiredFields = []string{"enbType", "servedCells"}
70 ServedCellRequiredFields = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "tac"}
73 type controllerGetNodebTestContext struct {
75 nodebInfo *entities.NodebInfo
77 expectedStatusCode int
78 expectedJsonResponse string
81 type controllerGetNodebIdListTestContext struct {
82 nodebIdList []*entities.NbIdentity
84 expectedStatusCode int
85 expectedJsonResponse string
88 type getNodebInfoResult struct {
89 nodebInfo *entities.NodebInfo
93 type updateGnbCellsParams struct {
97 type saveNodebParams struct {
98 nodebInfo *entities.NodebInfo
99 nbIdentity *entities.NbIdentity
103 type removeServedNrCellsParams struct {
104 servedNrCells []*entities.ServedNRCell
108 type controllerUpdateGnbTestContext struct {
109 getNodebInfoResult *getNodebInfoResult
110 removeServedNrCellsParams *removeServedNrCellsParams
111 updateGnbCellsParams *updateGnbCellsParams
112 requestBody map[string]interface{}
113 expectedStatusCode int
114 expectedJsonResponse string
117 type controllerAddEnbTestContext struct {
118 getNodebInfoResult *getNodebInfoResult
119 saveNodebParams *saveNodebParams
120 requestBody map[string]interface{}
121 expectedStatusCode int
122 expectedJsonResponse string
125 func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
127 servedNrCells := []*entities.ServedNRCell{}
129 for _, v := range cellIds {
130 servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{
132 ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{
133 Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{
137 NrMode: entities.Nr_FDD,
139 ServedPlmns: []string{"whatever"},
146 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
147 ret := map[string]interface{}{
149 "choiceNrMode": map[string]interface{}{
150 "tdd": map[string]interface{}{},
156 if len(propToOmit) != 0 {
157 delete(ret, propToOmit)
163 func buildServedNrCellInformation(propToOmit string) map[string]interface{} {
164 ret := map[string]interface{}{
165 "cellId": "whatever",
166 "choiceNrMode": map[string]interface{}{
167 "fdd": map[string]interface{}{},
171 "servedPlmns": []interface{}{
176 if len(propToOmit) != 0 {
177 delete(ret, propToOmit)
183 func buildServedCell(propToOmit string) map[string]interface{} {
184 ret := map[string]interface{}{
185 "cellId": "whatever",
186 "choiceEutraMode": map[string]interface{}{
187 "fdd": map[string]interface{}{},
192 "broadcastPlmns": []interface{}{
197 if len(propToOmit) != 0 {
198 delete(ret, propToOmit)
204 func getAddEnbRequest(propToOmit string) map[string]interface{} {
205 ret := map[string]interface{}{
207 "globalNbId": map[string]interface{}{
208 "plmnId": "whatever",
214 if len(propToOmit) != 0 {
215 delete(ret, propToOmit)
221 func buildEnb(propToOmit string) map[string]interface{} {
222 ret := map[string]interface{}{
224 "servedCells": []interface{}{
228 if len(propToOmit) != 0 {
229 delete(ret, propToOmit)
235 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
237 config := configuration.ParseConfiguration()
239 rmrMessengerMock := &mocks.RmrMessengerMock{}
240 readerMock := &mocks.RnibReaderMock{}
242 writerMock := &mocks.RnibWriterMock{}
244 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
245 rmrSender := getRmrSender(rmrMessengerMock, log)
246 e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
247 httpClientMock := &mocks.HttpClientMock{}
248 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
249 ranListManager := &mocks.RanListManagerMock{}
250 ranAlarmService := &mocks.RanAlarmServiceMock{}
251 ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
252 nodebValidator := managers.NewNodebValidator()
253 handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager, nodebValidator)
254 controller := NewNodebController(log, handlerProvider)
255 return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
258 func TestShutdownHandlerRnibError(t *testing.T) {
259 controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
260 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
262 writer := httptest.NewRecorder()
264 controller.Shutdown(writer, tests.GetHttpRequest())
266 var errorResponse = parseJsonRequest(t, writer.Body)
268 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
269 assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
272 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
273 controller, readerMock, _, _, _ := setupControllerTest(t)
275 configuration := &entities.GeneralConfiguration{}
276 readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
278 writer := httptest.NewRecorder()
280 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
282 controller.SetGeneralConfiguration(writer, httpRequest)
284 var errorResponse = parseJsonRequest(t, writer.Body)
286 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
287 assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
290 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
291 controller, _, _, _, _ := setupControllerTest(t)
293 writer := httptest.NewRecorder()
295 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false, \"someValue\":false}"))
297 controller.SetGeneralConfiguration(writer, httpRequest)
299 var errorResponse = parseJsonRequest(t, writer.Body)
301 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
302 assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
305 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
306 controller, readerMock, _, _, _ := setupControllerTest(t)
307 writer := httptest.NewRecorder()
308 readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
309 req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil)
310 req = mux.SetURLVars(req, map[string]string{"ranName": context.ranName})
311 controller.GetNodeb(writer, req)
312 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
313 bodyBytes, _ := ioutil.ReadAll(writer.Body)
314 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
317 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
318 controller, readerMock, _, _, _ := setupControllerTest(t)
319 writer := httptest.NewRecorder()
320 readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
321 req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil)
322 controller.GetNodebIdList(writer, req)
323 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
324 bodyBytes, _ := ioutil.ReadAll(writer.Body)
325 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
328 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
329 if context.getNodebInfoResult != nil {
330 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
333 if context.removeServedNrCellsParams != nil {
334 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
337 if context.updateGnbCellsParams != nil {
338 updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
339 gnb := entities.Gnb{}
340 _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb)
341 updatedGnb := *updatedNodebInfo.GetGnb()
342 updatedGnb.ServedNrCells = gnb.ServedNrCells
343 writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err)
347 func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
348 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
349 bodyBytes, _ := ioutil.ReadAll(writer.Body)
350 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
351 readerMock.AssertExpectations(t)
352 writerMock.AssertExpectations(t)
355 func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
356 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
357 bodyBytes, _ := ioutil.ReadAll(writer.Body)
358 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
359 readerMock.AssertExpectations(t)
360 writerMock.AssertExpectations(t)
363 func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
364 updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
365 requestBody := getJsonRequestAsBuffer(context.requestBody)
366 req, _ := http.NewRequest(http.MethodPut, updateGnbUrl, requestBody)
367 req.Header.Set("Content-Type", "application/json")
368 req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
372 func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request {
373 requestBody := getJsonRequestAsBuffer(context.requestBody)
374 req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, requestBody)
375 req.Header.Set("Content-Type", "application/json")
379 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
380 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
381 writer := httptest.NewRecorder()
383 activateControllerUpdateGnbMocks(context, readerMock, writerMock)
384 req := buildUpdateGnbRequest(context)
385 controller.UpdateGnb(writer, req)
386 assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
389 func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, addEnbRequest *models.AddEnbRequest) {
390 if context.getNodebInfoResult != nil {
391 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
394 if context.saveNodebParams != nil {
395 nodebInfo := entities.NodebInfo{
396 RanName: addEnbRequest.RanName,
397 Ip: addEnbRequest.Ip,
398 Port: addEnbRequest.Port,
399 GlobalNbId: addEnbRequest.GlobalNbId,
400 Configuration: &entities.NodebInfo_Enb{Enb: addEnbRequest.Enb},
401 ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,
404 nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId}
406 writerMock.On("SaveNodeb", &nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
410 func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestContext) {
411 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
412 writer := httptest.NewRecorder()
413 r := buildAddEnbRequest(context)
414 body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
416 addEnbRequest := models.AddEnbRequest{}
418 _ = json.Unmarshal(body, &addEnbRequest)
419 activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest)
420 r = buildAddEnbRequest(context)
422 controller.AddEnb(writer, r)
423 assertControllerAddEnb(t, context, writer, readerMock, writerMock)
426 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
427 context := controllerUpdateGnbTestContext{
428 getNodebInfoResult: nil,
429 requestBody: map[string]interface{}{
430 "servedNrCells": []interface{}{
433 expectedStatusCode: http.StatusBadRequest,
434 expectedJsonResponse: ValidationFailureJson,
437 controllerUpdateGnbTestExecuter(t, &context)
440 func TestControllerUpdateGnbMissingServedNrCellInformation(t *testing.T) {
441 context := controllerUpdateGnbTestContext{
442 getNodebInfoResult: nil,
443 requestBody: map[string]interface{}{
444 "servedNrCells": []interface{}{
445 map[string]interface{}{
446 "servedNrCellInformation": nil,
450 expectedStatusCode: http.StatusBadRequest,
451 expectedJsonResponse: ValidationFailureJson,
454 controllerUpdateGnbTestExecuter(t, &context)
457 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
459 for _, v := range ServedNrCellInformationRequiredFields {
460 context := controllerUpdateGnbTestContext{
461 getNodebInfoResult: nil,
462 requestBody: map[string]interface{}{
463 "servedNrCells": []interface{}{
464 map[string]interface{}{
465 "servedNrCellInformation": buildServedNrCellInformation(v),
469 expectedStatusCode: http.StatusBadRequest,
470 expectedJsonResponse: ValidationFailureJson,
473 controllerUpdateGnbTestExecuter(t, &context)
477 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
479 servedNrCellInformation := buildServedNrCellInformation("")
480 servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
482 context := controllerUpdateGnbTestContext{
483 getNodebInfoResult: nil,
484 requestBody: map[string]interface{}{
485 "servedNrCells": []interface{}{
486 map[string]interface{}{
487 "servedNrCellInformation": servedNrCellInformation,
491 expectedStatusCode: http.StatusBadRequest,
492 expectedJsonResponse: ValidationFailureJson,
495 controllerUpdateGnbTestExecuter(t, &context)
498 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
500 nrNeighbourInfo := buildNrNeighbourInformation("")
501 nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
503 context := controllerUpdateGnbTestContext{
504 getNodebInfoResult: nil,
505 requestBody: map[string]interface{}{
506 "servedNrCells": []interface{}{
507 map[string]interface{}{
508 "servedNrCellInformation": buildServedNrCellInformation(""),
509 "nrNeighbourInfos": []interface{}{
515 expectedStatusCode: http.StatusBadRequest,
516 expectedJsonResponse: ValidationFailureJson,
519 controllerUpdateGnbTestExecuter(t, &context)
522 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
524 for _, v := range NrNeighbourInformationRequiredFields {
525 context := controllerUpdateGnbTestContext{
526 getNodebInfoResult: nil,
527 requestBody: map[string]interface{}{
528 "servedNrCells": []interface{}{
529 map[string]interface{}{
530 "servedNrCellInformation": buildServedNrCellInformation(""),
531 "nrNeighbourInfos": []interface{}{
532 buildNrNeighbourInformation(v),
537 expectedStatusCode: http.StatusBadRequest,
538 expectedJsonResponse: ValidationFailureJson,
541 controllerUpdateGnbTestExecuter(t, &context)
545 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
546 context := controllerUpdateGnbTestContext{
547 getNodebInfoResult: &getNodebInfoResult{
549 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
551 requestBody: map[string]interface{}{
552 "servedNrCells": []interface{}{
553 map[string]interface{}{
554 "servedNrCellInformation": buildServedNrCellInformation(""),
558 expectedStatusCode: http.StatusNotFound,
559 expectedJsonResponse: ResourceNotFoundJson,
562 controllerUpdateGnbTestExecuter(t, &context)
565 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
566 context := controllerUpdateGnbTestContext{
567 getNodebInfoResult: &getNodebInfoResult{
569 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
571 requestBody: map[string]interface{}{
572 "servedNrCells": []interface{}{
573 map[string]interface{}{
574 "servedNrCellInformation": buildServedNrCellInformation(""),
578 expectedStatusCode: http.StatusInternalServerError,
579 expectedJsonResponse: RnibErrorJson,
582 controllerUpdateGnbTestExecuter(t, &context)
585 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
586 context := controllerUpdateGnbTestContext{
587 getNodebInfoResult: &getNodebInfoResult{
588 nodebInfo: &entities.NodebInfo{
590 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
591 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
595 requestBody: map[string]interface{}{
596 "servedNrCells": []interface{}{
597 map[string]interface{}{
598 "servedNrCellInformation": buildServedNrCellInformation(""),
599 "nrNeighbourInfos": []interface{}{
600 buildNrNeighbourInformation(""),
605 expectedStatusCode: http.StatusInternalServerError,
606 expectedJsonResponse: InternalErrorJson,
609 controllerUpdateGnbTestExecuter(t, &context)
612 func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) {
613 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
614 context := controllerUpdateGnbTestContext{
615 removeServedNrCellsParams: &removeServedNrCellsParams{
616 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
617 servedNrCells: oldServedNrCells,
619 getNodebInfoResult: &getNodebInfoResult{
620 nodebInfo: &entities.NodebInfo{
622 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
623 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
624 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
628 requestBody: map[string]interface{}{
629 "servedNrCells": []interface{}{
630 map[string]interface{}{
631 "servedNrCellInformation": buildServedNrCellInformation(""),
632 "nrNeighbourInfos": []interface{}{
633 buildNrNeighbourInformation(""),
638 expectedStatusCode: http.StatusInternalServerError,
639 expectedJsonResponse: RnibErrorJson,
642 controllerUpdateGnbTestExecuter(t, &context)
645 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
646 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
647 context := controllerUpdateGnbTestContext{
648 removeServedNrCellsParams: &removeServedNrCellsParams{
650 servedNrCells: oldServedNrCells,
652 updateGnbCellsParams: &updateGnbCellsParams{
653 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
655 getNodebInfoResult: &getNodebInfoResult{
656 nodebInfo: &entities.NodebInfo{
658 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
659 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
660 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
664 requestBody: map[string]interface{}{
665 "servedNrCells": []interface{}{
666 map[string]interface{}{
667 "servedNrCellInformation": buildServedNrCellInformation(""),
668 "nrNeighbourInfos": []interface{}{
669 buildNrNeighbourInformation(""),
674 expectedStatusCode: http.StatusInternalServerError,
675 expectedJsonResponse: RnibErrorJson,
678 controllerUpdateGnbTestExecuter(t, &context)
681 func TestControllerUpdateGnbSuccess(t *testing.T) {
682 context := controllerUpdateGnbTestContext{
683 updateGnbCellsParams: &updateGnbCellsParams{
686 getNodebInfoResult: &getNodebInfoResult{
687 nodebInfo: &entities.NodebInfo{
689 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
690 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
691 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
695 requestBody: map[string]interface{}{
696 "servedNrCells": []interface{}{
697 map[string]interface{}{
698 "servedNrCellInformation": buildServedNrCellInformation(""),
699 "nrNeighbourInfos": []interface{}{
700 buildNrNeighbourInformation(""),
705 expectedStatusCode: http.StatusOK,
706 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\"}",
709 controllerUpdateGnbTestExecuter(t, &context)
712 func TestControllerAddEnbGetNodebInternalError(t *testing.T) {
713 context := controllerAddEnbTestContext{
714 getNodebInfoResult: &getNodebInfoResult{
716 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
718 requestBody: getAddEnbRequest(""),
719 expectedStatusCode: http.StatusInternalServerError,
720 expectedJsonResponse: RnibErrorJson,
723 controllerAddEnbTestExecuter(t, &context)
726 func TestControllerAddEnbNodebExistsFailure(t *testing.T) {
727 context := controllerAddEnbTestContext{
728 getNodebInfoResult: &getNodebInfoResult{
729 nodebInfo: &entities.NodebInfo{},
732 requestBody: getAddEnbRequest(""),
733 expectedStatusCode: http.StatusBadRequest,
734 expectedJsonResponse: NodebExistsJson,
737 controllerAddEnbTestExecuter(t, &context)
740 func TestControllerAddEnbSaveNodebFailure(t *testing.T) {
741 context := controllerAddEnbTestContext{
742 saveNodebParams: &saveNodebParams{
743 err: common.NewInternalError(errors.New("#reader.SaveeNodeb - Internal Error")),
745 getNodebInfoResult: &getNodebInfoResult{
747 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
749 requestBody: getAddEnbRequest(""),
750 expectedStatusCode: http.StatusInternalServerError,
751 expectedJsonResponse: RnibErrorJson,
754 controllerAddEnbTestExecuter(t, &context)
757 func TestControllerAddEnbMissingRequiredRequestProps(t *testing.T) {
759 for _, v := range AddEnbRequestRequiredFields {
760 context := controllerAddEnbTestContext{
761 requestBody: getAddEnbRequest(v),
762 expectedStatusCode: http.StatusBadRequest,
763 expectedJsonResponse: ValidationFailureJson,
766 controllerAddEnbTestExecuter(t, &context)
770 func TestControllerAddEnbMissingRequiredEnbProps(t *testing.T) {
772 r := getAddEnbRequest("")
774 for _, v := range EnbRequiredFields {
775 r["enb"] = buildEnb(v)
777 context := controllerAddEnbTestContext{
779 expectedStatusCode: http.StatusBadRequest,
780 expectedJsonResponse: ValidationFailureJson,
783 controllerAddEnbTestExecuter(t, &context)
787 func TestControllerAddEnbMissingRequiredServedCellProps(t *testing.T) {
789 r := getAddEnbRequest("")
791 for _, v := range ServedCellRequiredFields {
794 enbMap, _ := enb.(map[string]interface{})
796 enbMap["servedCells"] = []interface{}{
800 context := controllerAddEnbTestContext{
802 expectedStatusCode: http.StatusBadRequest,
803 expectedJsonResponse: ValidationFailureJson,
806 controllerAddEnbTestExecuter(t, &context)
810 func TestControllerAddEnbSuccess(t *testing.T) {
811 context := controllerAddEnbTestContext{
812 saveNodebParams: &saveNodebParams{
815 getNodebInfoResult: &getNodebInfoResult{
817 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
819 requestBody: map[string]interface{}{
821 "globalNbId": map[string]interface{}{
822 "plmnId": "whatever",
825 "enb": map[string]interface{}{
827 "servedCells": []interface{}{
832 expectedStatusCode: http.StatusCreated,
833 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\"}]}}",
836 controllerAddEnbTestExecuter(t, &context)
839 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
840 b := new(bytes.Buffer)
841 _ = json.NewEncoder(b).Encode(requestJson)
845 func TestControllerGetNodebSuccess(t *testing.T) {
848 context := controllerGetNodebTestContext{
850 nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234},
851 rnibError: rnibError,
852 expectedStatusCode: http.StatusOK,
853 expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName),
856 controllerGetNodebTestExecuter(t, &context)
859 func TestControllerGetNodebNotFound(t *testing.T) {
862 var nodebInfo *entities.NodebInfo
863 context := controllerGetNodebTestContext{
865 nodebInfo: nodebInfo,
866 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
867 expectedStatusCode: http.StatusNotFound,
868 expectedJsonResponse: ResourceNotFoundJson,
871 controllerGetNodebTestExecuter(t, &context)
874 func TestControllerGetNodebInternal(t *testing.T) {
876 var nodebInfo *entities.NodebInfo
877 context := controllerGetNodebTestContext{
879 nodebInfo: nodebInfo,
880 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
881 expectedStatusCode: http.StatusInternalServerError,
882 expectedJsonResponse: RnibErrorJson,
885 controllerGetNodebTestExecuter(t, &context)
888 func TestControllerGetNodebIdListSuccess(t *testing.T) {
890 nodebIdList := []*entities.NbIdentity{
891 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
892 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
895 context := controllerGetNodebIdListTestContext{
896 nodebIdList: nodebIdList,
897 rnibError: rnibError,
898 expectedStatusCode: http.StatusOK,
899 expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]",
902 controllerGetNodebIdListTestExecuter(t, &context)
905 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
907 nodebIdList := []*entities.NbIdentity{}
909 context := controllerGetNodebIdListTestContext{
910 nodebIdList: nodebIdList,
911 rnibError: rnibError,
912 expectedStatusCode: http.StatusOK,
913 expectedJsonResponse: "[]",
916 controllerGetNodebIdListTestExecuter(t, &context)
919 func TestControllerGetNodebIdListInternal(t *testing.T) {
920 var nodebIdList []*entities.NbIdentity
921 context := controllerGetNodebIdListTestContext{
922 nodebIdList: nodebIdList,
923 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
924 expectedStatusCode: http.StatusInternalServerError,
925 expectedJsonResponse: RnibErrorJson,
928 controllerGetNodebIdListTestExecuter(t, &context)
931 func TestHeaderValidationFailed(t *testing.T) {
932 controller, _, _, _, _ := setupControllerTest(t)
934 writer := httptest.NewRecorder()
936 header := &http.Header{}
938 controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true, 0)
940 var errorResponse = parseJsonRequest(t, writer.Body)
941 err := e2managererrors.NewHeaderValidationError()
943 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
944 assert.Equal(t, errorResponse.Code, err.Code)
945 assert.Equal(t, errorResponse.Message, err.Message)
948 func TestShutdownStatusNoContent(t *testing.T) {
949 controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t)
950 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil)
951 readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil)
953 writer := httptest.NewRecorder()
954 controller.Shutdown(writer, tests.GetHttpRequest())
956 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
959 func TestHandleInternalError(t *testing.T) {
960 controller, _, _, _, _ := setupControllerTest(t)
962 writer := httptest.NewRecorder()
963 err := e2managererrors.NewInternalError()
965 controller.handleErrorResponse(err, writer)
966 var errorResponse = parseJsonRequest(t, writer.Body)
968 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
969 assert.Equal(t, errorResponse.Code, err.Code)
970 assert.Equal(t, errorResponse.Message, err.Message)
973 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
974 controller, _, _, _, _ := setupControllerTest(t)
975 writer := httptest.NewRecorder()
976 err := e2managererrors.NewCommandAlreadyInProgressError()
978 controller.handleErrorResponse(err, writer)
979 var errorResponse = parseJsonRequest(t, writer.Body)
981 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
982 assert.Equal(t, errorResponse.Code, err.Code)
983 assert.Equal(t, errorResponse.Message, err.Message)
986 func TestHandleRoutingManagerError(t *testing.T) {
987 controller, _, _, _, _ := setupControllerTest(t)
988 writer := httptest.NewRecorder()
989 err := e2managererrors.NewRoutingManagerError()
991 controller.handleErrorResponse(err, writer)
992 var errorResponse = parseJsonRequest(t, writer.Body)
994 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
995 assert.Equal(t, errorResponse.Code, err.Code)
996 assert.Equal(t, errorResponse.Message, err.Message)
999 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
1000 controller, _, _, _, _ := setupControllerTest(t)
1002 writer := httptest.NewRecorder()
1003 err := e2managererrors.NewE2TInstanceAbsenceError()
1005 controller.handleErrorResponse(err, writer)
1006 var errorResponse = parseJsonRequest(t, writer.Body)
1008 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
1009 assert.Equal(t, errorResponse.Code, err.Code)
1010 assert.Equal(t, errorResponse.Message, err.Message)
1013 func TestValidateHeaders(t *testing.T) {
1014 controller, _, _, _, _ := setupControllerTest(t)
1016 header := http.Header{}
1017 header.Set("Content-Type", "application/json")
1018 result := controller.validateRequestHeader(&header)
1020 assert.Nil(t, result)
1023 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
1025 var errorResponse models.ErrorResponse
1026 body, err := ioutil.ReadAll(r)
1028 t.Errorf("Error cannot deserialize json request")
1030 _ = json.Unmarshal(body, &errorResponse)
1032 return errorResponse
1035 func initLog(t *testing.T) *logger.Logger {
1036 log, err := logger.InitLogger(logger.InfoLevel)
1038 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
1043 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
1044 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
1047 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
1049 var msgSrc unsafe.Pointer
1050 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
1051 rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
1053 writer := httptest.NewRecorder()
1055 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
1056 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
1058 data4Req := map[string]interface{}{"cause": "protocol:transfer-syntax-error"}
1059 b := new(bytes.Buffer)
1060 _ = json.NewEncoder(b).Encode(data4Req)
1061 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1062 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1064 controller.X2Reset(writer, req)
1065 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1069 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
1070 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
1074 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
1076 var msgSrc unsafe.Pointer
1077 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
1078 rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
1080 writer := httptest.NewRecorder()
1082 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
1083 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
1086 b := new(bytes.Buffer)
1087 data4Req := map[string]interface{}{}
1088 _ = json.NewEncoder(b).Encode(data4Req)
1089 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1090 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1092 controller.X2Reset(writer, req)
1093 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
1096 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
1097 controller, _, _, _, _ := setupControllerTest(t)
1101 writer := httptest.NewRecorder()
1103 // Invalid json: attribute name without quotes (should be "cause":).
1104 b := strings.NewReader("{cause:\"protocol:transfer-syntax-error\"")
1105 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
1106 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
1108 controller.X2Reset(writer, req)
1109 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1113 func TestHandleErrorResponse(t *testing.T) {
1114 controller, _, _, _, _ := setupControllerTest(t)
1116 writer := httptest.NewRecorder()
1117 controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
1118 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1120 writer = httptest.NewRecorder()
1121 controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
1122 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
1124 writer = httptest.NewRecorder()
1125 controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
1126 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
1128 writer = httptest.NewRecorder()
1129 controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
1130 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1132 writer = httptest.NewRecorder()
1133 controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
1134 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1136 writer = httptest.NewRecorder()
1137 controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
1138 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1140 writer = httptest.NewRecorder()
1141 controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
1142 assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
1144 writer = httptest.NewRecorder()
1145 controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
1146 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1149 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
1150 rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
1151 rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
1152 return rmrsender.NewRmrSender(log, rmrMessenger)