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"
32 "e2mgr/providers/httpmsghandlerprovider"
35 "e2mgr/services/rmrsender"
39 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
40 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
41 "github.com/golang/protobuf/jsonpb"
42 "github.com/gorilla/mux"
43 "github.com/pkg/errors"
44 "github.com/stretchr/testify/assert"
45 "github.com/stretchr/testify/mock"
57 AssociatedE2TInstanceAddress = "10.0.2.15:38000"
58 ValidationFailureJson = "{\"errorCode\":402,\"errorMessage\":\"Validation error\"}"
59 ResourceNotFoundJson = "{\"errorCode\":404,\"errorMessage\":\"Resource not found\"}"
60 RnibErrorJson = "{\"errorCode\":500,\"errorMessage\":\"RNIB error\"}"
61 InternalErrorJson = "{\"errorCode\":501,\"errorMessage\":\"Internal Server Error. Please try again later\"}"
65 ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "nrPci", "servedPlmns"}
66 NrNeighbourInformationRequiredFields = []string{"nrCgi", "choiceNrMode", "nrMode", "nrPci"}
69 type controllerGetNodebTestContext struct {
71 nodebInfo *entities.NodebInfo
73 expectedStatusCode int
74 expectedJsonResponse string
77 type controllerGetNodebIdListTestContext struct {
78 nodebIdList []*entities.NbIdentity
80 expectedStatusCode int
81 expectedJsonResponse string
84 type getNodebInfoResult struct {
85 nodebInfo *entities.NodebInfo
89 type updateGnbCellsParams struct {
93 type removeServedNrCellsParams struct {
94 servedNrCells []*entities.ServedNRCell
98 type controllerUpdateGnbTestContext struct {
99 getNodebInfoResult *getNodebInfoResult
100 removeServedNrCellsParams *removeServedNrCellsParams
101 updateGnbCellsParams *updateGnbCellsParams
102 requestBody map[string]interface{}
103 expectedStatusCode int
104 expectedJsonResponse string
107 func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
109 servedNrCells := []*entities.ServedNRCell{}
111 for _, v := range cellIds {
112 servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{
114 ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{
115 Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{
119 NrMode: entities.Nr_FDD,
121 ServedPlmns: []string{"whatever"},
128 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
129 ret := map[string]interface{}{
131 "choiceNrMode": map[string]interface{}{
132 "tdd": map[string]interface{}{},
138 if len(propToOmit) != 0 {
139 delete(ret, propToOmit)
145 func buildServedNrCellInformation(propToOmit string) map[string]interface{} {
146 ret := map[string]interface{}{
147 "cellId": "whatever",
148 "choiceNrMode": map[string]interface{}{
149 "fdd": map[string]interface{}{},
153 "servedPlmns": []interface{}{
158 if len(propToOmit) != 0 {
159 delete(ret, propToOmit)
165 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
167 config := configuration.ParseConfiguration()
169 rmrMessengerMock := &mocks.RmrMessengerMock{}
170 readerMock := &mocks.RnibReaderMock{}
172 writerMock := &mocks.RnibWriterMock{}
174 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
175 rmrSender := getRmrSender(rmrMessengerMock, log)
176 ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
177 e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
178 httpClientMock := &mocks.HttpClientMock{}
179 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
180 e2tAssociationManager := managers.NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient)
181 handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, ranSetupManager, e2tInstancesManager, e2tAssociationManager, rmClient)
182 controller := NewNodebController(log, handlerProvider)
183 return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
186 func TestX2SetupInvalidBody(t *testing.T) {
188 controller, _, _, _, _ := setupControllerTest(t)
190 header := http.Header{}
191 header.Set("Content-Type", "application/json")
192 httpRequest, _ := http.NewRequest("POST", "http://localhost:3800/v1/nodeb/x2-setup", strings.NewReader("{}{}"))
193 httpRequest.Header = header
195 writer := httptest.NewRecorder()
196 controller.X2Setup(writer, httpRequest)
198 var errorResponse = parseJsonRequest(t, writer.Body)
200 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
201 assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
204 func TestX2SetupSuccess(t *testing.T) {
206 controller, readerMock, writerMock, rmrMessengerMock, _ := setupControllerTest(t)
209 nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, AssociatedE2TInstanceAddress: "10.0.2.15:8989"}
210 readerMock.On("GetNodeb", ranName).Return(nb, nil)
212 writerMock.On("UpdateNodebInfo", &nbUpdated).Return(nil)
214 var nbUpdated2 = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST, AssociatedE2TInstanceAddress: "10.0.2.15:8989"}
215 writerMock.On("UpdateNodebInfo", nbUpdated2).Return(nil)
217 payload := e2pdus.PackedX2setupRequest
219 var msgSrc unsafe.Pointer
220 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xAction, msgSrc)
222 rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
224 header := http.Header{}
225 header.Set("Content-Type", "application/json")
226 httpRequest := tests.GetHttpRequest()
227 httpRequest.Header = header
229 writer := httptest.NewRecorder()
230 controller.X2Setup(writer, httpRequest)
232 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
235 func TestEndcSetupSuccess(t *testing.T) {
237 controller, readerMock, writerMock, rmrMessengerMock, _ := setupControllerTest(t)
240 nb := &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, AssociatedE2TInstanceAddress: "10.0.2.15:8989"}
241 readerMock.On("GetNodeb", ranName).Return(nb, nil)
243 writerMock.On("UpdateNodebInfo", &nbUpdated).Return(nil)
245 var nbUpdated2 = &entities.NodebInfo{RanName: ranName, ConnectionStatus: entities.ConnectionStatus_CONNECTING, E2ApplicationProtocol: entities.E2ApplicationProtocol_ENDC_X2_SETUP_REQUEST, AssociatedE2TInstanceAddress: "10.0.2.15:8989"}
246 writerMock.On("UpdateNodebInfo", nbUpdated2).Return(nil)
248 payload := e2pdus.PackedEndcX2setupRequest
250 var msgSrc unsafe.Pointer
251 msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xAction, msgSrc)
253 rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
255 header := http.Header{}
256 header.Set("Content-Type", "application/json")
257 httpRequest := tests.GetHttpRequest()
258 httpRequest.Header = header
260 writer := httptest.NewRecorder()
261 controller.EndcSetup(writer, httpRequest)
263 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
266 func TestShutdownHandlerRnibError(t *testing.T) {
267 controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
268 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
270 writer := httptest.NewRecorder()
272 controller.Shutdown(writer, tests.GetHttpRequest())
274 var errorResponse = parseJsonRequest(t, writer.Body)
276 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
277 assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
280 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
281 controller, readerMock, _, _, _ := setupControllerTest(t)
283 configuration := &entities.GeneralConfiguration{}
284 readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
286 writer := httptest.NewRecorder()
288 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
290 controller.SetGeneralConfiguration(writer, httpRequest)
292 var errorResponse = parseJsonRequest(t, writer.Body)
294 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
295 assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
298 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
299 controller, _, _, _, _ := setupControllerTest(t)
301 writer := httptest.NewRecorder()
303 httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{}{}"))
305 controller.SetGeneralConfiguration(writer, httpRequest)
307 var errorResponse = parseJsonRequest(t, writer.Body)
309 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
310 assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
313 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
314 controller, readerMock, _, _, _ := setupControllerTest(t)
315 writer := httptest.NewRecorder()
316 readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
317 req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil)
318 req = mux.SetURLVars(req, map[string]string{"ranName": context.ranName})
319 controller.GetNodeb(writer, req)
320 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
321 bodyBytes, _ := ioutil.ReadAll(writer.Body)
322 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
325 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
326 controller, readerMock, _, _, _ := setupControllerTest(t)
327 writer := httptest.NewRecorder()
328 readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
329 req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil)
330 controller.GetNodebIdList(writer, req)
331 assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
332 bodyBytes, _ := ioutil.ReadAll(writer.Body)
333 assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
336 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
337 if context.getNodebInfoResult != nil {
338 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
341 if context.removeServedNrCellsParams != nil {
342 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
345 if context.updateGnbCellsParams != nil {
346 updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
347 gnb := entities.Gnb{}
348 _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb)
349 updatedGnb := *updatedNodebInfo.GetGnb()
350 updatedGnb.ServedNrCells = gnb.ServedNrCells
351 writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err)
355 func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestContext, 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)
362 if context.getNodebInfoResult != nil {
363 readerMock.AssertNotCalled(t, "GetNodeb")
366 if context.updateGnbCellsParams != nil {
367 writerMock.AssertNotCalled(t, "UpdateGnb")
370 if context.removeServedNrCellsParams != nil {
371 writerMock.AssertNotCalled(t, "RemoveServedNrCells")
375 func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
376 updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
377 requestBody := getJsonRequestAsBuffer(context.requestBody)
378 req, _ := http.NewRequest(http.MethodGet, updateGnbUrl, requestBody)
379 req.Header.Set("Content-Type", "application/json")
380 req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
384 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
385 controller, readerMock, writerMock, _, _ := setupControllerTest(t)
386 writer := httptest.NewRecorder()
388 activateControllerUpdateGnbMocks(context, readerMock, writerMock)
389 req := buildUpdateGnbRequest(context)
390 controller.UpdateGnb(writer, req)
391 assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
394 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
395 context := controllerUpdateGnbTestContext{
396 getNodebInfoResult: nil,
397 requestBody: map[string]interface{}{
398 "servedNrCells": []interface{}{
401 expectedStatusCode: http.StatusBadRequest,
402 expectedJsonResponse: ValidationFailureJson,
405 controllerUpdateGnbTestExecuter(t, &context)
408 func TestControllerUpdateGnbMissingServedNrCellInformation(t *testing.T) {
409 context := controllerUpdateGnbTestContext{
410 getNodebInfoResult: nil,
411 requestBody: map[string]interface{}{
412 "servedNrCells": []interface{}{
413 map[string]interface{}{
414 "servedNrCellInformation": nil,
418 expectedStatusCode: http.StatusBadRequest,
419 expectedJsonResponse: ValidationFailureJson,
422 controllerUpdateGnbTestExecuter(t, &context)
425 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
427 for _, v := range ServedNrCellInformationRequiredFields {
428 context := controllerUpdateGnbTestContext{
429 getNodebInfoResult: nil,
430 requestBody: map[string]interface{}{
431 "servedNrCells": []interface{}{
432 map[string]interface{}{
433 "servedNrCellInformation": buildServedNrCellInformation(v),
437 expectedStatusCode: http.StatusBadRequest,
438 expectedJsonResponse: ValidationFailureJson,
441 controllerUpdateGnbTestExecuter(t, &context)
445 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
447 servedNrCellInformation := buildServedNrCellInformation("")
448 servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
450 context := controllerUpdateGnbTestContext{
451 getNodebInfoResult: nil,
452 requestBody: map[string]interface{}{
453 "servedNrCells": []interface{}{
454 map[string]interface{}{
455 "servedNrCellInformation": servedNrCellInformation,
459 expectedStatusCode: http.StatusBadRequest,
460 expectedJsonResponse: ValidationFailureJson,
463 controllerUpdateGnbTestExecuter(t, &context)
466 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
468 nrNeighbourInfo := buildNrNeighbourInformation("")
469 nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
471 context := controllerUpdateGnbTestContext{
472 getNodebInfoResult: nil,
473 requestBody: map[string]interface{}{
474 "servedNrCells": []interface{}{
475 map[string]interface{}{
476 "servedNrCellInformation": buildServedNrCellInformation(""),
477 "nrNeighbourInfos": []interface{}{
483 expectedStatusCode: http.StatusBadRequest,
484 expectedJsonResponse: ValidationFailureJson,
487 controllerUpdateGnbTestExecuter(t, &context)
490 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
492 for _, v := range NrNeighbourInformationRequiredFields {
493 context := controllerUpdateGnbTestContext{
494 getNodebInfoResult: nil,
495 requestBody: map[string]interface{}{
496 "servedNrCells": []interface{}{
497 map[string]interface{}{
498 "servedNrCellInformation": buildServedNrCellInformation(""),
499 "nrNeighbourInfos": []interface{}{
500 buildNrNeighbourInformation(v),
505 expectedStatusCode: http.StatusBadRequest,
506 expectedJsonResponse: ValidationFailureJson,
509 controllerUpdateGnbTestExecuter(t, &context)
513 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
514 context := controllerUpdateGnbTestContext{
515 getNodebInfoResult: &getNodebInfoResult{
517 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
519 requestBody: map[string]interface{}{
520 "servedNrCells": []interface{}{
521 map[string]interface{}{
522 "servedNrCellInformation": buildServedNrCellInformation(""),
526 expectedStatusCode: http.StatusNotFound,
527 expectedJsonResponse: ResourceNotFoundJson,
530 controllerUpdateGnbTestExecuter(t, &context)
533 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
534 context := controllerUpdateGnbTestContext{
535 getNodebInfoResult: &getNodebInfoResult{
537 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
539 requestBody: map[string]interface{}{
540 "servedNrCells": []interface{}{
541 map[string]interface{}{
542 "servedNrCellInformation": buildServedNrCellInformation(""),
546 expectedStatusCode: http.StatusInternalServerError,
547 expectedJsonResponse: RnibErrorJson,
550 controllerUpdateGnbTestExecuter(t, &context)
553 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
554 context := controllerUpdateGnbTestContext{
555 getNodebInfoResult: &getNodebInfoResult{
556 nodebInfo: &entities.NodebInfo{
558 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
559 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
563 requestBody: map[string]interface{}{
564 "servedNrCells": []interface{}{
565 map[string]interface{}{
566 "servedNrCellInformation": buildServedNrCellInformation(""),
567 "nrNeighbourInfos": []interface{}{
568 buildNrNeighbourInformation(""),
573 expectedStatusCode: http.StatusInternalServerError,
574 expectedJsonResponse: InternalErrorJson,
577 controllerUpdateGnbTestExecuter(t, &context)
580 func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) {
581 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
582 context := controllerUpdateGnbTestContext{
583 removeServedNrCellsParams: &removeServedNrCellsParams{
584 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
585 servedNrCells: oldServedNrCells,
587 getNodebInfoResult: &getNodebInfoResult{
588 nodebInfo: &entities.NodebInfo{
590 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
591 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
592 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
596 requestBody: map[string]interface{}{
597 "servedNrCells": []interface{}{
598 map[string]interface{}{
599 "servedNrCellInformation": buildServedNrCellInformation(""),
600 "nrNeighbourInfos": []interface{}{
601 buildNrNeighbourInformation(""),
606 expectedStatusCode: http.StatusInternalServerError,
607 expectedJsonResponse: RnibErrorJson,
610 controllerUpdateGnbTestExecuter(t, &context)
613 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
614 oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
615 context := controllerUpdateGnbTestContext{
616 removeServedNrCellsParams: &removeServedNrCellsParams{
618 servedNrCells: oldServedNrCells,
620 updateGnbCellsParams: &updateGnbCellsParams{
621 err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
623 getNodebInfoResult: &getNodebInfoResult{
624 nodebInfo: &entities.NodebInfo{
626 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
627 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
628 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
632 requestBody: map[string]interface{}{
633 "servedNrCells": []interface{}{
634 map[string]interface{}{
635 "servedNrCellInformation": buildServedNrCellInformation(""),
636 "nrNeighbourInfos": []interface{}{
637 buildNrNeighbourInformation(""),
642 expectedStatusCode: http.StatusInternalServerError,
643 expectedJsonResponse: RnibErrorJson,
646 controllerUpdateGnbTestExecuter(t, &context)
649 func TestControllerUpdateGnbSuccess(t *testing.T) {
650 context := controllerUpdateGnbTestContext{
651 updateGnbCellsParams: &updateGnbCellsParams{
654 getNodebInfoResult: &getNodebInfoResult{
655 nodebInfo: &entities.NodebInfo{
657 ConnectionStatus: entities.ConnectionStatus_CONNECTED,
658 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
659 Configuration: &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
663 requestBody: map[string]interface{}{
664 "servedNrCells": []interface{}{
665 map[string]interface{}{
666 "servedNrCellInformation": buildServedNrCellInformation(""),
667 "nrNeighbourInfos": []interface{}{
668 buildNrNeighbourInformation(""),
673 expectedStatusCode: http.StatusOK,
674 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\"}",
677 controllerUpdateGnbTestExecuter(t, &context)
680 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
681 b := new(bytes.Buffer)
682 _ = json.NewEncoder(b).Encode(requestJson)
686 func TestControllerGetNodebSuccess(t *testing.T) {
689 context := controllerGetNodebTestContext{
691 nodebInfo: &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234},
692 rnibError: rnibError,
693 expectedStatusCode: http.StatusOK,
694 expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName),
697 controllerGetNodebTestExecuter(t, &context)
700 func TestControllerGetNodebNotFound(t *testing.T) {
703 var nodebInfo *entities.NodebInfo
704 context := controllerGetNodebTestContext{
706 nodebInfo: nodebInfo,
707 rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
708 expectedStatusCode: http.StatusNotFound,
709 expectedJsonResponse: ResourceNotFoundJson,
712 controllerGetNodebTestExecuter(t, &context)
715 func TestControllerGetNodebInternal(t *testing.T) {
717 var nodebInfo *entities.NodebInfo
718 context := controllerGetNodebTestContext{
720 nodebInfo: nodebInfo,
721 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
722 expectedStatusCode: http.StatusInternalServerError,
723 expectedJsonResponse: RnibErrorJson,
726 controllerGetNodebTestExecuter(t, &context)
729 func TestControllerGetNodebIdListSuccess(t *testing.T) {
731 nodebIdList := []*entities.NbIdentity{
732 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
733 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
736 context := controllerGetNodebIdListTestContext{
737 nodebIdList: nodebIdList,
738 rnibError: rnibError,
739 expectedStatusCode: http.StatusOK,
740 expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]",
743 controllerGetNodebIdListTestExecuter(t, &context)
746 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
748 nodebIdList := []*entities.NbIdentity{}
750 context := controllerGetNodebIdListTestContext{
751 nodebIdList: nodebIdList,
752 rnibError: rnibError,
753 expectedStatusCode: http.StatusOK,
754 expectedJsonResponse: "[]",
757 controllerGetNodebIdListTestExecuter(t, &context)
760 func TestControllerGetNodebIdListInternal(t *testing.T) {
761 var nodebIdList []*entities.NbIdentity
762 context := controllerGetNodebIdListTestContext{
763 nodebIdList: nodebIdList,
764 rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
765 expectedStatusCode: http.StatusInternalServerError,
766 expectedJsonResponse: RnibErrorJson,
769 controllerGetNodebIdListTestExecuter(t, &context)
772 func TestHeaderValidationFailed(t *testing.T) {
773 controller, _, _, _, _ := setupControllerTest(t)
775 writer := httptest.NewRecorder()
777 header := &http.Header{}
779 controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true)
781 var errorResponse = parseJsonRequest(t, writer.Body)
782 err := e2managererrors.NewHeaderValidationError()
784 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
785 assert.Equal(t, errorResponse.Code, err.Code)
786 assert.Equal(t, errorResponse.Message, err.Message)
789 func TestShutdownStatusNoContent(t *testing.T) {
790 controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t)
791 e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil)
792 readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil)
794 writer := httptest.NewRecorder()
795 controller.Shutdown(writer, tests.GetHttpRequest())
797 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
800 func TestHandleInternalError(t *testing.T) {
801 controller, _, _, _, _ := setupControllerTest(t)
803 writer := httptest.NewRecorder()
804 err := e2managererrors.NewInternalError()
806 controller.handleErrorResponse(err, writer)
807 var errorResponse = parseJsonRequest(t, writer.Body)
809 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
810 assert.Equal(t, errorResponse.Code, err.Code)
811 assert.Equal(t, errorResponse.Message, err.Message)
814 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
815 controller, _, _, _, _ := setupControllerTest(t)
816 writer := httptest.NewRecorder()
817 err := e2managererrors.NewCommandAlreadyInProgressError()
819 controller.handleErrorResponse(err, writer)
820 var errorResponse = parseJsonRequest(t, writer.Body)
822 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
823 assert.Equal(t, errorResponse.Code, err.Code)
824 assert.Equal(t, errorResponse.Message, err.Message)
827 func TestHandleRoutingManagerError(t *testing.T) {
828 controller, _, _, _, _ := setupControllerTest(t)
829 writer := httptest.NewRecorder()
830 err := e2managererrors.NewRoutingManagerError()
832 controller.handleErrorResponse(err, writer)
833 var errorResponse = parseJsonRequest(t, writer.Body)
835 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
836 assert.Equal(t, errorResponse.Code, err.Code)
837 assert.Equal(t, errorResponse.Message, err.Message)
840 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
841 controller, _, _, _, _ := setupControllerTest(t)
843 writer := httptest.NewRecorder()
844 err := e2managererrors.NewE2TInstanceAbsenceError()
846 controller.handleErrorResponse(err, writer)
847 var errorResponse = parseJsonRequest(t, writer.Body)
849 assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
850 assert.Equal(t, errorResponse.Code, err.Code)
851 assert.Equal(t, errorResponse.Message, err.Message)
854 func TestValidateHeaders(t *testing.T) {
855 controller, _, _, _, _ := setupControllerTest(t)
857 header := http.Header{}
858 header.Set("Content-Type", "application/json")
859 result := controller.validateRequestHeader(&header)
861 assert.Nil(t, result)
864 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
866 var errorResponse models.ErrorResponse
867 body, err := ioutil.ReadAll(r)
869 t.Errorf("Error cannot deserialize json request")
871 _ = json.Unmarshal(body, &errorResponse)
876 func initLog(t *testing.T) *logger.Logger {
877 log, err := logger.InitLogger(logger.InfoLevel)
879 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
884 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
885 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
888 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
890 var msgSrc unsafe.Pointer
891 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
892 rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
894 writer := httptest.NewRecorder()
896 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
897 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
899 data4Req := map[string]interface{}{"cause": "protocol:transfer-syntax-error"}
900 b := new(bytes.Buffer)
901 _ = json.NewEncoder(b).Encode(data4Req)
902 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
903 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
905 controller.X2Reset(writer, req)
906 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
910 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
911 controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
915 payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
917 var msgSrc unsafe.Pointer
918 msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
919 rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
921 writer := httptest.NewRecorder()
923 var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
924 readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
927 b := new(bytes.Buffer)
928 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
929 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
931 controller.X2Reset(writer, req)
932 assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
936 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
937 controller, _, _, _, _ := setupControllerTest(t)
941 writer := httptest.NewRecorder()
943 // Invalid json: attribute name without quotes (should be "cause":).
944 b := strings.NewReader("{cause:\"protocol:transfer-syntax-error\"")
945 req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
946 req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
948 controller.X2Reset(writer, req)
949 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
953 func TestHandleErrorResponse(t *testing.T) {
954 controller, _, _, _, _ := setupControllerTest(t)
956 writer := httptest.NewRecorder()
957 controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
958 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
960 writer = httptest.NewRecorder()
961 controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
962 assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
964 writer = httptest.NewRecorder()
965 controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
966 assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
968 writer = httptest.NewRecorder()
969 controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
970 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
972 writer = httptest.NewRecorder()
973 controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
974 assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
976 writer = httptest.NewRecorder()
977 controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
978 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
980 writer = httptest.NewRecorder()
981 controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
982 assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
984 writer = httptest.NewRecorder()
985 controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
986 assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
989 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
990 rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
991 rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
992 return rmrsender.NewRmrSender(log, rmrMessenger)