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", "nrPci", "servedPlmns"}
67 NrNeighbourInformationRequiredFields = []string{"nrCgi", "choiceNrMode", "nrMode", "nrPci"}
68 EnbRequiredFields = []string{"enbType", "servedCells"}
69 ServedCellRequiredFields = []string{"broadcastPlmns", "cellId", "choiceEutraMode", "eutraMode", "pci", "tac"}
72 type controllerGetNodebTestContext struct {
74 nodebInfo *entities.NodebInfo
76 expectedStatusCode int
77 expectedJsonResponse string
80 type controllerGetNodebIdListTestContext struct {
81 nodebIdList []*entities.NbIdentity
83 expectedStatusCode int
84 expectedJsonResponse string
87 type getNodebInfoResult struct {
88 nodebInfo *entities.NodebInfo
92 type updateGnbCellsParams struct {
96 type saveNodebParams struct {
97 nodebInfo *entities.NodebInfo
98 nbIdentity *entities.NbIdentity
102 type removeServedNrCellsParams struct {
103 servedNrCells []*entities.ServedNRCell
107 type controllerUpdateGnbTestContext struct {
108 getNodebInfoResult *getNodebInfoResult
109 removeServedNrCellsParams *removeServedNrCellsParams
110 updateGnbCellsParams *updateGnbCellsParams
111 requestBody map[string]interface{}
112 expectedStatusCode int
113 expectedJsonResponse string
116 type controllerAddEnbTestContext struct {
117 getNodebInfoResult *getNodebInfoResult
118 saveNodebParams *saveNodebParams
119 requestBody map[string]interface{}
120 expectedStatusCode int
121 expectedJsonResponse string
124 func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
126 servedNrCells := []*entities.ServedNRCell{}
128 for _, v := range cellIds {
129 servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{
131 ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{
132 Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{
136 NrMode: entities.Nr_FDD,
138 ServedPlmns: []string{"whatever"},
145 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
146 ret := map[string]interface{}{
148 "choiceNrMode": map[string]interface{}{
149 "tdd": map[string]interface{}{},
155 if len(propToOmit) != 0 {
156 delete(ret, propToOmit)
162 func buildServedNrCellInformation(propToOmit string) map[string]interface{} {
163 ret := map[string]interface{}{
164 "cellId": "whatever",
165 "choiceNrMode": map[string]interface{}{
166 "fdd": map[string]interface{}{},
170 "servedPlmns": []interface{}{
175 if len(propToOmit) != 0 {
176 delete(ret, propToOmit)
182 func buildServedCell(propToOmit string) map[string]interface{} {
183 ret := map[string]interface{}{
184 "cellId": "whatever",
185 "choiceEutraMode": map[string]interface{}{
186 "fdd": map[string]interface{}{},
191 "broadcastPlmns": []interface{}{
196 if len(propToOmit) != 0 {
197 delete(ret, propToOmit)
203 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
205 config := configuration.ParseConfiguration()
207 rmrMessengerMock := &mocks.RmrMessengerMock{}
208 readerMock := &mocks.RnibReaderMock{}
210 writerMock := &mocks.RnibWriterMock{}
212 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
213 rmrSender := getRmrSender(rmrMessengerMock, log)
214 ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
215 e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
216 httpClientMock := &mocks.HttpClientMock{}
217 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
218 ranListManager := &mocks.RanListManagerMock{}
219 ranAlarmService := &mocks.RanAlarmServiceMock{}
220 ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
222 e2tAssociationManager := managers.NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager)
223 handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, ranSetupManager, e2tInstancesManager, e2tAssociationManager, rmClient, ranConnectStatusChangeManager)
224 controller := NewNodebController(log, handlerProvider)
225 return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
228 func TestShutdownHandlerRnibError(t *testing.T) {
229 controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
230 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
232 writer := httptest.NewRecorder()
234 controller.Shutdown(writer, tests.GetHttpRequest())
236 var errorResponse = parseJsonRequest(t, writer.Body)
238 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
239 assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
242 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
243 controller, readerMock, _, _, _ := setupControllerTest(t)
245 configuration := &entities.GeneralConfiguration{}
246 readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
248 writer := httptest.NewRecorder()
250 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
252 controller.SetGeneralConfiguration(writer, httpRequest)
254 var errorResponse = parseJsonRequest(t, writer.Body)
256 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
257 assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
260 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
261 controller, _, _, _, _ := setupControllerTest(t)
263 writer := httptest.NewRecorder()
265 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false, \"someValue\":false}"))
267 controller.SetGeneralConfiguration(writer, httpRequest)
269 var errorResponse = parseJsonRequest(t, writer.Body)
271 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
272 assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
275 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
276 controller, readerMock, _, _, _ := setupControllerTest(t)
277 writer := httptest.NewRecorder()
278 readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
279 req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil)
280 req = mux.SetURLVars(req, map[string]string{"ranName": context.ranName})
281 controller.GetNodeb(writer, req)
282 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
283 bodyBytes, _ := ioutil.ReadAll(writer.Body)
284 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
287 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
288 controller, readerMock, _, _, _ := setupControllerTest(t)
289 writer := httptest.NewRecorder()
290 readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
291 req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil)
292 controller.GetNodebIdList(writer, req)
293 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
294 bodyBytes, _ := ioutil.ReadAll(writer.Body)
295 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
298 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
299 if context.getNodebInfoResult != nil {
300 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
303 if context.removeServedNrCellsParams != nil {
304 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
307 if context.updateGnbCellsParams != nil {
308 updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
309 gnb := entities.Gnb{}
310 _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb)
311 updatedGnb := *updatedNodebInfo.GetGnb()
312 updatedGnb.ServedNrCells = gnb.ServedNrCells
313 writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err)
317 func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
318 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
319 bodyBytes, _ := ioutil.ReadAll(writer.Body)
320 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
321 readerMock.AssertExpectations(t)
322 writerMock.AssertExpectations(t)
325 func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
326 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
327 bodyBytes, _ := ioutil.ReadAll(writer.Body)
328 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
329 readerMock.AssertExpectations(t)
330 writerMock.AssertExpectations(t)
333 func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
334 updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
335 requestBody := getJsonRequestAsBuffer(context.requestBody)
336 req, _ := http.NewRequest(http.MethodPut, updateGnbUrl, requestBody)
337 req.Header.Set("Content-Type", "application/json")
338 req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
342 func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request {
343 requestBody := getJsonRequestAsBuffer(context.requestBody)
344 req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, requestBody)
345 req.Header.Set("Content-Type", "application/json")
349 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
350 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
351 writer := httptest.NewRecorder()
353 activateControllerUpdateGnbMocks(context, readerMock, writerMock)
354 req := buildUpdateGnbRequest(context)
355 controller.UpdateGnb(writer, req)
356 assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
359 func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, addEnbRequest *models.AddEnbRequest) {
360 if context.getNodebInfoResult != nil {
361 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
364 if context.saveNodebParams != nil {
365 nodebInfo := entities.NodebInfo{
366 RanName: addEnbRequest.RanName,
367 Ip: addEnbRequest.Ip,
368 Port: addEnbRequest.Port,
369 GlobalNbId: addEnbRequest.GlobalNbId,
370 Configuration: &entities.NodebInfo_Enb{Enb: addEnbRequest.Enb},
371 ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,
374 nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId}
376 writerMock.On("SaveNodeb",&nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
380 func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestContext) {
381 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
382 writer := httptest.NewRecorder()
383 r := buildAddEnbRequest(context)
385 body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
387 addEnbRequest := models.AddEnbRequest{}
389 _ = json.Unmarshal(body, &addEnbRequest)
390 activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest)
391 controller.AddEnb(writer, buildAddEnbRequest(context))
392 assertControllerAddEnb(t, context, writer, readerMock, writerMock)
395 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
396 context := controllerUpdateGnbTestContext{
397 getNodebInfoResult: nil,
398 requestBody: map[string]interface{}{
399 "servedNrCells": []interface{}{
402 expectedStatusCode: http.StatusBadRequest,
403 expectedJsonResponse: ValidationFailureJson,
406 controllerUpdateGnbTestExecuter(t, &context)
409 func TestControllerUpdateGnbMissingServedNrCellInformation(t *testing.T) {
410 context := controllerUpdateGnbTestContext{
411 getNodebInfoResult: nil,
412 requestBody: map[string]interface{}{
413 "servedNrCells": []interface{}{
414 map[string]interface{}{
415 "servedNrCellInformation": nil,
419 expectedStatusCode: http.StatusBadRequest,
420 expectedJsonResponse: ValidationFailureJson,
423 controllerUpdateGnbTestExecuter(t, &context)
426 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
428 for _, v := range ServedNrCellInformationRequiredFields {
429 context := controllerUpdateGnbTestContext{
430 getNodebInfoResult: nil,
431 requestBody: map[string]interface{}{
432 "servedNrCells": []interface{}{
433 map[string]interface{}{
434 "servedNrCellInformation": buildServedNrCellInformation(v),
438 expectedStatusCode: http.StatusBadRequest,
439 expectedJsonResponse: ValidationFailureJson,
442 controllerUpdateGnbTestExecuter(t, &context)
446 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
448 servedNrCellInformation := buildServedNrCellInformation("")
449 servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
451 context := controllerUpdateGnbTestContext{
452 getNodebInfoResult: nil,
453 requestBody: map[string]interface{}{
454 "servedNrCells": []interface{}{
455 map[string]interface{}{
456 "servedNrCellInformation": servedNrCellInformation,
460 expectedStatusCode: http.StatusBadRequest,
461 expectedJsonResponse: ValidationFailureJson,
464 controllerUpdateGnbTestExecuter(t, &context)
467 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
469 nrNeighbourInfo := buildNrNeighbourInformation("")
470 nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
472 context := controllerUpdateGnbTestContext{
473 getNodebInfoResult: nil,
474 requestBody: map[string]interface{}{
475 "servedNrCells": []interface{}{
476 map[string]interface{}{
477 "servedNrCellInformation": buildServedNrCellInformation(""),
478 "nrNeighbourInfos": []interface{}{
484 expectedStatusCode: http.StatusBadRequest,
485 expectedJsonResponse: ValidationFailureJson,
488 controllerUpdateGnbTestExecuter(t, &context)
491 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
493 for _, v := range NrNeighbourInformationRequiredFields {
494 context := controllerUpdateGnbTestContext{
495 getNodebInfoResult: nil,
496 requestBody: map[string]interface{}{
497 "servedNrCells": []interface{}{
498 map[string]interface{}{
499 "servedNrCellInformation": buildServedNrCellInformation(""),
500 "nrNeighbourInfos": []interface{}{
501 buildNrNeighbourInformation(v),
506 expectedStatusCode: http.StatusBadRequest,
507 expectedJsonResponse: ValidationFailureJson,
510 controllerUpdateGnbTestExecuter(t, &context)
514 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
515 context := controllerUpdateGnbTestContext{
516 getNodebInfoResult: &getNodebInfoResult{
518 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
520 requestBody: map[string]interface{}{
521 "servedNrCells": []interface{}{
522 map[string]interface{}{
523 "servedNrCellInformation": buildServedNrCellInformation(""),
527 expectedStatusCode: http.StatusNotFound,
528 expectedJsonResponse: ResourceNotFoundJson,
531 controllerUpdateGnbTestExecuter(t, &context)
534 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
535 context := controllerUpdateGnbTestContext{
536 getNodebInfoResult: &getNodebInfoResult{
538 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
540 requestBody: map[string]interface{}{
541 "servedNrCells": []interface{}{
542 map[string]interface{}{
543 "servedNrCellInformation": buildServedNrCellInformation(""),
547 expectedStatusCode: http.StatusInternalServerError,
548 expectedJsonResponse: RnibErrorJson,
551 controllerUpdateGnbTestExecuter(t, &context)
554 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
555 context := controllerUpdateGnbTestContext{
556 getNodebInfoResult: &getNodebInfoResult{
557 nodebInfo: &entities.NodebInfo{
559 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
560 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
564 requestBody: map[string]interface{}{
565 "servedNrCells": []interface{}{
566 map[string]interface{}{
567 "servedNrCellInformation": buildServedNrCellInformation(""),
568 "nrNeighbourInfos": []interface{}{
569 buildNrNeighbourInformation(""),
574 expectedStatusCode: http.StatusInternalServerError,
575 expectedJsonResponse: InternalErrorJson,
578 controllerUpdateGnbTestExecuter(t, &context)
581 func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) {
582 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
583 context := controllerUpdateGnbTestContext{
584 removeServedNrCellsParams: &removeServedNrCellsParams{
585 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
586 servedNrCells: oldServedNrCells,
588 getNodebInfoResult: &getNodebInfoResult{
589 nodebInfo: &entities.NodebInfo{
591 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
592 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
593 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
597 requestBody: map[string]interface{}{
598 "servedNrCells": []interface{}{
599 map[string]interface{}{
600 "servedNrCellInformation": buildServedNrCellInformation(""),
601 "nrNeighbourInfos": []interface{}{
602 buildNrNeighbourInformation(""),
607 expectedStatusCode: http.StatusInternalServerError,
608 expectedJsonResponse: RnibErrorJson,
611 controllerUpdateGnbTestExecuter(t, &context)
614 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
615 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
616 context := controllerUpdateGnbTestContext{
617 removeServedNrCellsParams: &removeServedNrCellsParams{
619 servedNrCells: oldServedNrCells,
621 updateGnbCellsParams: &updateGnbCellsParams{
622 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
624 getNodebInfoResult: &getNodebInfoResult{
625 nodebInfo: &entities.NodebInfo{
627 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
628 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
629 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
633 requestBody: map[string]interface{}{
634 "servedNrCells": []interface{}{
635 map[string]interface{}{
636 "servedNrCellInformation": buildServedNrCellInformation(""),
637 "nrNeighbourInfos": []interface{}{
638 buildNrNeighbourInformation(""),
643 expectedStatusCode: http.StatusInternalServerError,
644 expectedJsonResponse: RnibErrorJson,
647 controllerUpdateGnbTestExecuter(t, &context)
650 func TestControllerUpdateGnbSuccess(t *testing.T) {
651 context := controllerUpdateGnbTestContext{
652 updateGnbCellsParams: &updateGnbCellsParams{
655 getNodebInfoResult: &getNodebInfoResult{
656 nodebInfo: &entities.NodebInfo{
658 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
659 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
660 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
664 requestBody: map[string]interface{}{
665 "servedNrCells": []interface{}{
666 map[string]interface{}{
667 "servedNrCellInformation": buildServedNrCellInformation(""),
668 "nrNeighbourInfos": []interface{}{
669 buildNrNeighbourInformation(""),
674 expectedStatusCode: http.StatusOK,
675 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\"}",
678 controllerUpdateGnbTestExecuter(t, &context)
681 func TestControllerAddEnbSuccess(t *testing.T) {
682 context := controllerAddEnbTestContext{
683 saveNodebParams: &saveNodebParams{
686 getNodebInfoResult: &getNodebInfoResult{
688 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
690 requestBody: map[string]interface{}{
692 "globalNbId": map[string]interface{}{
693 "plmnId": "whatever",
696 "enb": map[string]interface{}{
698 "servedCells": []interface{}{
703 expectedStatusCode: http.StatusCreated,
704 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\"}]}}",
707 controllerAddEnbTestExecuter(t, &context)
710 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
711 b := new(bytes.Buffer)
712 _ = json.NewEncoder(b).Encode(requestJson)
716 func TestControllerGetNodebSuccess(t *testing.T) {
719 context := controllerGetNodebTestContext{
721 nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234},
722 rnibError: rnibError,
723 expectedStatusCode: http.StatusOK,
724 expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName),
727 controllerGetNodebTestExecuter(t, &context)
730 func TestControllerGetNodebNotFound(t *testing.T) {
733 var nodebInfo *entities.NodebInfo
734 context := controllerGetNodebTestContext{
736 nodebInfo: nodebInfo,
737 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
738 expectedStatusCode: http.StatusNotFound,
739 expectedJsonResponse: ResourceNotFoundJson,
742 controllerGetNodebTestExecuter(t, &context)
745 func TestControllerGetNodebInternal(t *testing.T) {
747 var nodebInfo *entities.NodebInfo
748 context := controllerGetNodebTestContext{
750 nodebInfo: nodebInfo,
751 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
752 expectedStatusCode: http.StatusInternalServerError,
753 expectedJsonResponse: RnibErrorJson,
756 controllerGetNodebTestExecuter(t, &context)
759 func TestControllerGetNodebIdListSuccess(t *testing.T) {
761 nodebIdList := []*entities.NbIdentity{
762 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
763 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
766 context := controllerGetNodebIdListTestContext{
767 nodebIdList: nodebIdList,
768 rnibError: rnibError,
769 expectedStatusCode: http.StatusOK,
770 expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]",
773 controllerGetNodebIdListTestExecuter(t, &context)
776 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
778 nodebIdList := []*entities.NbIdentity{}
780 context := controllerGetNodebIdListTestContext{
781 nodebIdList: nodebIdList,
782 rnibError: rnibError,
783 expectedStatusCode: http.StatusOK,
784 expectedJsonResponse: "[]",
787 controllerGetNodebIdListTestExecuter(t, &context)
790 func TestControllerGetNodebIdListInternal(t *testing.T) {
791 var nodebIdList []*entities.NbIdentity
792 context := controllerGetNodebIdListTestContext{
793 nodebIdList: nodebIdList,
794 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
795 expectedStatusCode: http.StatusInternalServerError,
796 expectedJsonResponse: RnibErrorJson,
799 controllerGetNodebIdListTestExecuter(t, &context)
802 func TestHeaderValidationFailed(t *testing.T) {
803 controller, _, _, _, _ := setupControllerTest(t)
805 writer := httptest.NewRecorder()
807 header := &http.Header{}
809 controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true, 0)
811 var errorResponse = parseJsonRequest(t, writer.Body)
812 err := e2managererrors.NewHeaderValidationError()
814 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
815 assert.Equal(t, errorResponse.Code, err.Code)
816 assert.Equal(t, errorResponse.Message, err.Message)
819 func TestShutdownStatusNoContent(t *testing.T) {
820 controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t)
821 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil)
822 readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil)
824 writer := httptest.NewRecorder()
825 controller.Shutdown(writer, tests.GetHttpRequest())
827 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
830 func TestHandleInternalError(t *testing.T) {
831 controller, _, _, _, _ := setupControllerTest(t)
833 writer := httptest.NewRecorder()
834 err := e2managererrors.NewInternalError()
836 controller.handleErrorResponse(err, writer)
837 var errorResponse = parseJsonRequest(t, writer.Body)
839 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
840 assert.Equal(t, errorResponse.Code, err.Code)
841 assert.Equal(t, errorResponse.Message, err.Message)
844 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
845 controller, _, _, _, _ := setupControllerTest(t)
846 writer := httptest.NewRecorder()
847 err := e2managererrors.NewCommandAlreadyInProgressError()
849 controller.handleErrorResponse(err, writer)
850 var errorResponse = parseJsonRequest(t, writer.Body)
852 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
853 assert.Equal(t, errorResponse.Code, err.Code)
854 assert.Equal(t, errorResponse.Message, err.Message)
857 func TestHandleRoutingManagerError(t *testing.T) {
858 controller, _, _, _, _ := setupControllerTest(t)
859 writer := httptest.NewRecorder()
860 err := e2managererrors.NewRoutingManagerError()
862 controller.handleErrorResponse(err, writer)
863 var errorResponse = parseJsonRequest(t, writer.Body)
865 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
866 assert.Equal(t, errorResponse.Code, err.Code)
867 assert.Equal(t, errorResponse.Message, err.Message)
870 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
871 controller, _, _, _, _ := setupControllerTest(t)
873 writer := httptest.NewRecorder()
874 err := e2managererrors.NewE2TInstanceAbsenceError()
876 controller.handleErrorResponse(err, writer)
877 var errorResponse = parseJsonRequest(t, writer.Body)
879 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
880 assert.Equal(t, errorResponse.Code, err.Code)
881 assert.Equal(t, errorResponse.Message, err.Message)
884 func TestValidateHeaders(t *testing.T) {
885 controller, _, _, _, _ := setupControllerTest(t)
887 header := http.Header{}
888 header.Set("Content-Type", "application/json")
889 result := controller.validateRequestHeader(&header)
891 assert.Nil(t, result)
894 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
896 var errorResponse models.ErrorResponse
897 body, err := ioutil.ReadAll(r)
899 t.Errorf("Error cannot deserialize json request")
901 _ = json.Unmarshal(body, &errorResponse)
906 func initLog(t *testing.T) *logger.Logger {
907 log, err := logger.InitLogger(logger.InfoLevel)
909 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
914 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
915 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
918 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
920 var msgSrc unsafe.Pointer
921 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
922 rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
924 writer := httptest.NewRecorder()
926 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
927 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
929 data4Req := map[string]interface{}{"cause": "protocol:transfer-syntax-error"}
930 b := new(bytes.Buffer)
931 _ = json.NewEncoder(b).Encode(data4Req)
932 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
933 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
935 controller.X2Reset(writer, req)
936 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
940 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
941 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
945 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
947 var msgSrc unsafe.Pointer
948 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
949 rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
951 writer := httptest.NewRecorder()
953 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
954 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
957 b := new(bytes.Buffer)
958 data4Req := map[string]interface{}{}
959 _ = json.NewEncoder(b).Encode(data4Req)
960 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
961 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
963 controller.X2Reset(writer, req)
964 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
967 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
968 controller, _, _, _, _ := setupControllerTest(t)
972 writer := httptest.NewRecorder()
974 // Invalid json: attribute name without quotes (should be "cause":).
975 b := strings.NewReader("{cause:\"protocol:transfer-syntax-error\"")
976 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
977 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
979 controller.X2Reset(writer, req)
980 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
984 func TestHandleErrorResponse(t *testing.T) {
985 controller, _, _, _, _ := setupControllerTest(t)
987 writer := httptest.NewRecorder()
988 controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
989 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
991 writer = httptest.NewRecorder()
992 controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
993 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
995 writer = httptest.NewRecorder()
996 controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
997 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
999 writer = httptest.NewRecorder()
1000 controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
1001 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1003 writer = httptest.NewRecorder()
1004 controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
1005 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1007 writer = httptest.NewRecorder()
1008 controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
1009 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1011 writer = httptest.NewRecorder()
1012 controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
1013 assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
1015 writer = httptest.NewRecorder()
1016 controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
1017 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1020 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
1021 rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
1022 rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
1023 return rmrsender.NewRmrSender(log, rmrMessenger)