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 e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
215 httpClientMock := &mocks.HttpClientMock{}
216 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
217 ranListManager := &mocks.RanListManagerMock{}
218 ranAlarmService := &mocks.RanAlarmServiceMock{}
219 ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
220 nodebValidator := managers.NewNodebValidator()
221 handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager, nodebValidator)
222 controller := NewNodebController(log, handlerProvider)
223 return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
226 func TestShutdownHandlerRnibError(t *testing.T) {
227 controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
228 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
230 writer := httptest.NewRecorder()
232 controller.Shutdown(writer, tests.GetHttpRequest())
234 var errorResponse = parseJsonRequest(t, writer.Body)
236 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
237 assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
240 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
241 controller, readerMock, _, _, _ := setupControllerTest(t)
243 configuration := &entities.GeneralConfiguration{}
244 readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
246 writer := httptest.NewRecorder()
248 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
250 controller.SetGeneralConfiguration(writer, httpRequest)
252 var errorResponse = parseJsonRequest(t, writer.Body)
254 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
255 assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
258 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
259 controller, _, _, _, _ := setupControllerTest(t)
261 writer := httptest.NewRecorder()
263 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false, \"someValue\":false}"))
265 controller.SetGeneralConfiguration(writer, httpRequest)
267 var errorResponse = parseJsonRequest(t, writer.Body)
269 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
270 assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
273 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
274 controller, readerMock, _, _, _ := setupControllerTest(t)
275 writer := httptest.NewRecorder()
276 readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
277 req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil)
278 req = mux.SetURLVars(req, map[string]string{"ranName": context.ranName})
279 controller.GetNodeb(writer, req)
280 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
281 bodyBytes, _ := ioutil.ReadAll(writer.Body)
282 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
285 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
286 controller, readerMock, _, _, _ := setupControllerTest(t)
287 writer := httptest.NewRecorder()
288 readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
289 req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil)
290 controller.GetNodebIdList(writer, req)
291 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
292 bodyBytes, _ := ioutil.ReadAll(writer.Body)
293 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
296 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
297 if context.getNodebInfoResult != nil {
298 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
301 if context.removeServedNrCellsParams != nil {
302 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
305 if context.updateGnbCellsParams != nil {
306 updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
307 gnb := entities.Gnb{}
308 _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb)
309 updatedGnb := *updatedNodebInfo.GetGnb()
310 updatedGnb.ServedNrCells = gnb.ServedNrCells
311 writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err)
315 func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
316 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
317 bodyBytes, _ := ioutil.ReadAll(writer.Body)
318 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
319 readerMock.AssertExpectations(t)
320 writerMock.AssertExpectations(t)
323 func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
324 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
325 bodyBytes, _ := ioutil.ReadAll(writer.Body)
326 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
327 readerMock.AssertExpectations(t)
328 writerMock.AssertExpectations(t)
331 func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
332 updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
333 requestBody := getJsonRequestAsBuffer(context.requestBody)
334 req, _ := http.NewRequest(http.MethodPut, updateGnbUrl, requestBody)
335 req.Header.Set("Content-Type", "application/json")
336 req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
340 func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request {
341 requestBody := getJsonRequestAsBuffer(context.requestBody)
342 req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, requestBody)
343 req.Header.Set("Content-Type", "application/json")
347 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
348 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
349 writer := httptest.NewRecorder()
351 activateControllerUpdateGnbMocks(context, readerMock, writerMock)
352 req := buildUpdateGnbRequest(context)
353 controller.UpdateGnb(writer, req)
354 assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
357 func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, addEnbRequest *models.AddEnbRequest) {
358 if context.getNodebInfoResult != nil {
359 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
362 if context.saveNodebParams != nil {
363 nodebInfo := entities.NodebInfo{
364 RanName: addEnbRequest.RanName,
365 Ip: addEnbRequest.Ip,
366 Port: addEnbRequest.Port,
367 GlobalNbId: addEnbRequest.GlobalNbId,
368 Configuration: &entities.NodebInfo_Enb{Enb: addEnbRequest.Enb},
369 ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,
372 nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId}
374 writerMock.On("SaveNodeb",&nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
378 func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestContext) {
379 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
380 writer := httptest.NewRecorder()
381 r := buildAddEnbRequest(context)
383 body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
385 addEnbRequest := models.AddEnbRequest{}
387 _ = json.Unmarshal(body, &addEnbRequest)
388 activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest)
389 controller.AddEnb(writer, buildAddEnbRequest(context))
390 assertControllerAddEnb(t, context, writer, readerMock, writerMock)
393 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
394 context := controllerUpdateGnbTestContext{
395 getNodebInfoResult: nil,
396 requestBody: map[string]interface{}{
397 "servedNrCells": []interface{}{
400 expectedStatusCode: http.StatusBadRequest,
401 expectedJsonResponse: ValidationFailureJson,
404 controllerUpdateGnbTestExecuter(t, &context)
407 func TestControllerUpdateGnbMissingServedNrCellInformation(t *testing.T) {
408 context := controllerUpdateGnbTestContext{
409 getNodebInfoResult: nil,
410 requestBody: map[string]interface{}{
411 "servedNrCells": []interface{}{
412 map[string]interface{}{
413 "servedNrCellInformation": nil,
417 expectedStatusCode: http.StatusBadRequest,
418 expectedJsonResponse: ValidationFailureJson,
421 controllerUpdateGnbTestExecuter(t, &context)
424 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
426 for _, v := range ServedNrCellInformationRequiredFields {
427 context := controllerUpdateGnbTestContext{
428 getNodebInfoResult: nil,
429 requestBody: map[string]interface{}{
430 "servedNrCells": []interface{}{
431 map[string]interface{}{
432 "servedNrCellInformation": buildServedNrCellInformation(v),
436 expectedStatusCode: http.StatusBadRequest,
437 expectedJsonResponse: ValidationFailureJson,
440 controllerUpdateGnbTestExecuter(t, &context)
444 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
446 servedNrCellInformation := buildServedNrCellInformation("")
447 servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
449 context := controllerUpdateGnbTestContext{
450 getNodebInfoResult: nil,
451 requestBody: map[string]interface{}{
452 "servedNrCells": []interface{}{
453 map[string]interface{}{
454 "servedNrCellInformation": servedNrCellInformation,
458 expectedStatusCode: http.StatusBadRequest,
459 expectedJsonResponse: ValidationFailureJson,
462 controllerUpdateGnbTestExecuter(t, &context)
465 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
467 nrNeighbourInfo := buildNrNeighbourInformation("")
468 nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
470 context := controllerUpdateGnbTestContext{
471 getNodebInfoResult: nil,
472 requestBody: map[string]interface{}{
473 "servedNrCells": []interface{}{
474 map[string]interface{}{
475 "servedNrCellInformation": buildServedNrCellInformation(""),
476 "nrNeighbourInfos": []interface{}{
482 expectedStatusCode: http.StatusBadRequest,
483 expectedJsonResponse: ValidationFailureJson,
486 controllerUpdateGnbTestExecuter(t, &context)
489 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
491 for _, v := range NrNeighbourInformationRequiredFields {
492 context := controllerUpdateGnbTestContext{
493 getNodebInfoResult: nil,
494 requestBody: map[string]interface{}{
495 "servedNrCells": []interface{}{
496 map[string]interface{}{
497 "servedNrCellInformation": buildServedNrCellInformation(""),
498 "nrNeighbourInfos": []interface{}{
499 buildNrNeighbourInformation(v),
504 expectedStatusCode: http.StatusBadRequest,
505 expectedJsonResponse: ValidationFailureJson,
508 controllerUpdateGnbTestExecuter(t, &context)
512 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
513 context := controllerUpdateGnbTestContext{
514 getNodebInfoResult: &getNodebInfoResult{
516 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
518 requestBody: map[string]interface{}{
519 "servedNrCells": []interface{}{
520 map[string]interface{}{
521 "servedNrCellInformation": buildServedNrCellInformation(""),
525 expectedStatusCode: http.StatusNotFound,
526 expectedJsonResponse: ResourceNotFoundJson,
529 controllerUpdateGnbTestExecuter(t, &context)
532 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
533 context := controllerUpdateGnbTestContext{
534 getNodebInfoResult: &getNodebInfoResult{
536 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
538 requestBody: map[string]interface{}{
539 "servedNrCells": []interface{}{
540 map[string]interface{}{
541 "servedNrCellInformation": buildServedNrCellInformation(""),
545 expectedStatusCode: http.StatusInternalServerError,
546 expectedJsonResponse: RnibErrorJson,
549 controllerUpdateGnbTestExecuter(t, &context)
552 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
553 context := controllerUpdateGnbTestContext{
554 getNodebInfoResult: &getNodebInfoResult{
555 nodebInfo: &entities.NodebInfo{
557 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
558 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
562 requestBody: map[string]interface{}{
563 "servedNrCells": []interface{}{
564 map[string]interface{}{
565 "servedNrCellInformation": buildServedNrCellInformation(""),
566 "nrNeighbourInfos": []interface{}{
567 buildNrNeighbourInformation(""),
572 expectedStatusCode: http.StatusInternalServerError,
573 expectedJsonResponse: InternalErrorJson,
576 controllerUpdateGnbTestExecuter(t, &context)
579 func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) {
580 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
581 context := controllerUpdateGnbTestContext{
582 removeServedNrCellsParams: &removeServedNrCellsParams{
583 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
584 servedNrCells: oldServedNrCells,
586 getNodebInfoResult: &getNodebInfoResult{
587 nodebInfo: &entities.NodebInfo{
589 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
590 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
591 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
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: RnibErrorJson,
609 controllerUpdateGnbTestExecuter(t, &context)
612 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
613 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
614 context := controllerUpdateGnbTestContext{
615 removeServedNrCellsParams: &removeServedNrCellsParams{
617 servedNrCells: oldServedNrCells,
619 updateGnbCellsParams: &updateGnbCellsParams{
620 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
622 getNodebInfoResult: &getNodebInfoResult{
623 nodebInfo: &entities.NodebInfo{
625 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
626 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
627 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
631 requestBody: map[string]interface{}{
632 "servedNrCells": []interface{}{
633 map[string]interface{}{
634 "servedNrCellInformation": buildServedNrCellInformation(""),
635 "nrNeighbourInfos": []interface{}{
636 buildNrNeighbourInformation(""),
641 expectedStatusCode: http.StatusInternalServerError,
642 expectedJsonResponse: RnibErrorJson,
645 controllerUpdateGnbTestExecuter(t, &context)
648 func TestControllerUpdateGnbSuccess(t *testing.T) {
649 context := controllerUpdateGnbTestContext{
650 updateGnbCellsParams: &updateGnbCellsParams{
653 getNodebInfoResult: &getNodebInfoResult{
654 nodebInfo: &entities.NodebInfo{
656 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
657 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
658 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
662 requestBody: map[string]interface{}{
663 "servedNrCells": []interface{}{
664 map[string]interface{}{
665 "servedNrCellInformation": buildServedNrCellInformation(""),
666 "nrNeighbourInfos": []interface{}{
667 buildNrNeighbourInformation(""),
672 expectedStatusCode: http.StatusOK,
673 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\"}",
676 controllerUpdateGnbTestExecuter(t, &context)
679 func TestControllerAddEnbSuccess(t *testing.T) {
680 context := controllerAddEnbTestContext{
681 saveNodebParams: &saveNodebParams{
684 getNodebInfoResult: &getNodebInfoResult{
686 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
688 requestBody: map[string]interface{}{
690 "globalNbId": map[string]interface{}{
691 "plmnId": "whatever",
694 "enb": map[string]interface{}{
696 "servedCells": []interface{}{
701 expectedStatusCode: http.StatusCreated,
702 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\"}]}}",
705 controllerAddEnbTestExecuter(t, &context)
708 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
709 b := new(bytes.Buffer)
710 _ = json.NewEncoder(b).Encode(requestJson)
714 func TestControllerGetNodebSuccess(t *testing.T) {
717 context := controllerGetNodebTestContext{
719 nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234},
720 rnibError: rnibError,
721 expectedStatusCode: http.StatusOK,
722 expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName),
725 controllerGetNodebTestExecuter(t, &context)
728 func TestControllerGetNodebNotFound(t *testing.T) {
731 var nodebInfo *entities.NodebInfo
732 context := controllerGetNodebTestContext{
734 nodebInfo: nodebInfo,
735 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
736 expectedStatusCode: http.StatusNotFound,
737 expectedJsonResponse: ResourceNotFoundJson,
740 controllerGetNodebTestExecuter(t, &context)
743 func TestControllerGetNodebInternal(t *testing.T) {
745 var nodebInfo *entities.NodebInfo
746 context := controllerGetNodebTestContext{
748 nodebInfo: nodebInfo,
749 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
750 expectedStatusCode: http.StatusInternalServerError,
751 expectedJsonResponse: RnibErrorJson,
754 controllerGetNodebTestExecuter(t, &context)
757 func TestControllerGetNodebIdListSuccess(t *testing.T) {
759 nodebIdList := []*entities.NbIdentity{
760 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
761 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
764 context := controllerGetNodebIdListTestContext{
765 nodebIdList: nodebIdList,
766 rnibError: rnibError,
767 expectedStatusCode: http.StatusOK,
768 expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]",
771 controllerGetNodebIdListTestExecuter(t, &context)
774 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
776 nodebIdList := []*entities.NbIdentity{}
778 context := controllerGetNodebIdListTestContext{
779 nodebIdList: nodebIdList,
780 rnibError: rnibError,
781 expectedStatusCode: http.StatusOK,
782 expectedJsonResponse: "[]",
785 controllerGetNodebIdListTestExecuter(t, &context)
788 func TestControllerGetNodebIdListInternal(t *testing.T) {
789 var nodebIdList []*entities.NbIdentity
790 context := controllerGetNodebIdListTestContext{
791 nodebIdList: nodebIdList,
792 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
793 expectedStatusCode: http.StatusInternalServerError,
794 expectedJsonResponse: RnibErrorJson,
797 controllerGetNodebIdListTestExecuter(t, &context)
800 func TestHeaderValidationFailed(t *testing.T) {
801 controller, _, _, _, _ := setupControllerTest(t)
803 writer := httptest.NewRecorder()
805 header := &http.Header{}
807 controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true, 0)
809 var errorResponse = parseJsonRequest(t, writer.Body)
810 err := e2managererrors.NewHeaderValidationError()
812 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
813 assert.Equal(t, errorResponse.Code, err.Code)
814 assert.Equal(t, errorResponse.Message, err.Message)
817 func TestShutdownStatusNoContent(t *testing.T) {
818 controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t)
819 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil)
820 readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil)
822 writer := httptest.NewRecorder()
823 controller.Shutdown(writer, tests.GetHttpRequest())
825 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
828 func TestHandleInternalError(t *testing.T) {
829 controller, _, _, _, _ := setupControllerTest(t)
831 writer := httptest.NewRecorder()
832 err := e2managererrors.NewInternalError()
834 controller.handleErrorResponse(err, writer)
835 var errorResponse = parseJsonRequest(t, writer.Body)
837 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
838 assert.Equal(t, errorResponse.Code, err.Code)
839 assert.Equal(t, errorResponse.Message, err.Message)
842 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
843 controller, _, _, _, _ := setupControllerTest(t)
844 writer := httptest.NewRecorder()
845 err := e2managererrors.NewCommandAlreadyInProgressError()
847 controller.handleErrorResponse(err, writer)
848 var errorResponse = parseJsonRequest(t, writer.Body)
850 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
851 assert.Equal(t, errorResponse.Code, err.Code)
852 assert.Equal(t, errorResponse.Message, err.Message)
855 func TestHandleRoutingManagerError(t *testing.T) {
856 controller, _, _, _, _ := setupControllerTest(t)
857 writer := httptest.NewRecorder()
858 err := e2managererrors.NewRoutingManagerError()
860 controller.handleErrorResponse(err, writer)
861 var errorResponse = parseJsonRequest(t, writer.Body)
863 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
864 assert.Equal(t, errorResponse.Code, err.Code)
865 assert.Equal(t, errorResponse.Message, err.Message)
868 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
869 controller, _, _, _, _ := setupControllerTest(t)
871 writer := httptest.NewRecorder()
872 err := e2managererrors.NewE2TInstanceAbsenceError()
874 controller.handleErrorResponse(err, writer)
875 var errorResponse = parseJsonRequest(t, writer.Body)
877 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
878 assert.Equal(t, errorResponse.Code, err.Code)
879 assert.Equal(t, errorResponse.Message, err.Message)
882 func TestValidateHeaders(t *testing.T) {
883 controller, _, _, _, _ := setupControllerTest(t)
885 header := http.Header{}
886 header.Set("Content-Type", "application/json")
887 result := controller.validateRequestHeader(&header)
889 assert.Nil(t, result)
892 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
894 var errorResponse models.ErrorResponse
895 body, err := ioutil.ReadAll(r)
897 t.Errorf("Error cannot deserialize json request")
899 _ = json.Unmarshal(body, &errorResponse)
904 func initLog(t *testing.T) *logger.Logger {
905 log, err := logger.InitLogger(logger.InfoLevel)
907 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
912 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
913 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
916 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
918 var msgSrc unsafe.Pointer
919 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
920 rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
922 writer := httptest.NewRecorder()
924 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
925 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
927 data4Req := map[string]interface{}{"cause": "protocol:transfer-syntax-error"}
928 b := new(bytes.Buffer)
929 _ = json.NewEncoder(b).Encode(data4Req)
930 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
931 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
933 controller.X2Reset(writer, req)
934 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
938 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
939 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
943 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
945 var msgSrc unsafe.Pointer
946 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
947 rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
949 writer := httptest.NewRecorder()
951 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
952 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
955 b := new(bytes.Buffer)
956 data4Req := map[string]interface{}{}
957 _ = json.NewEncoder(b).Encode(data4Req)
958 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
959 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
961 controller.X2Reset(writer, req)
962 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
965 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
966 controller, _, _, _, _ := setupControllerTest(t)
970 writer := httptest.NewRecorder()
972 // Invalid json: attribute name without quotes (should be "cause":).
973 b := strings.NewReader("{cause:\"protocol:transfer-syntax-error\"")
974 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
975 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
977 controller.X2Reset(writer, req)
978 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
982 func TestHandleErrorResponse(t *testing.T) {
983 controller, _, _, _, _ := setupControllerTest(t)
985 writer := httptest.NewRecorder()
986 controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
987 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
989 writer = httptest.NewRecorder()
990 controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
991 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
993 writer = httptest.NewRecorder()
994 controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
995 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
997 writer = httptest.NewRecorder()
998 controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
999 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1001 writer = httptest.NewRecorder()
1002 controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
1003 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1005 writer = httptest.NewRecorder()
1006 controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
1007 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1009 writer = httptest.NewRecorder()
1010 controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
1011 assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
1013 writer = httptest.NewRecorder()
1014 controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
1015 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1018 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
1019 rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
1020 rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
1021 return rmrsender.NewRmrSender(log, rmrMessenger)