1543674b6917bd3e2a53f46ba84294e41c65d1b2
[ric-plt/e2mgr.git] / E2Manager / controllers / nodeb_controller_test.go
1 //
2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
4 //
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
8 //
9 //      http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16
17 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
18 //  platform project (RICP).
19
20 package controllers
21
22 import (
23         "bytes"
24         "e2mgr/clients"
25         "e2mgr/configuration"
26         "e2mgr/e2managererrors"
27         "e2mgr/e2pdus"
28         "e2mgr/logger"
29         "e2mgr/managers"
30         "e2mgr/mocks"
31         "e2mgr/models"
32         "e2mgr/providers/httpmsghandlerprovider"
33         "e2mgr/rmrCgo"
34         "e2mgr/services"
35         "e2mgr/services/rmrsender"
36         "e2mgr/tests"
37         "encoding/json"
38         "fmt"
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"
46         "io"
47         "io/ioutil"
48         "net/http"
49         "net/http/httptest"
50         "strings"
51         "testing"
52         "unsafe"
53 )
54
55 const (
56         RanName                      = "test"
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\"}"
62 )
63
64 var (
65         ServedNrCellInformationRequiredFields = []string{"cellId", "choiceNrMode", "nrMode", "nrPci", "servedPlmns"}
66         NrNeighbourInformationRequiredFields  = []string{"nrCgi", "choiceNrMode", "nrMode", "nrPci"}
67 )
68
69 type controllerGetNodebTestContext struct {
70         ranName              string
71         nodebInfo            *entities.NodebInfo
72         rnibError            error
73         expectedStatusCode   int
74         expectedJsonResponse string
75 }
76
77 type controllerGetNodebIdListTestContext struct {
78         nodebIdList          []*entities.NbIdentity
79         rnibError            error
80         expectedStatusCode   int
81         expectedJsonResponse string
82 }
83
84 type getNodebInfoResult struct {
85         nodebInfo *entities.NodebInfo
86         rnibError error
87 }
88
89 type updateGnbCellsParams struct {
90         err error
91 }
92
93 type removeServedNrCellsParams struct {
94         servedNrCells []*entities.ServedNRCell
95         err           error
96 }
97
98 type controllerUpdateGnbTestContext struct {
99         getNodebInfoResult        *getNodebInfoResult
100         removeServedNrCellsParams *removeServedNrCellsParams
101         updateGnbCellsParams      *updateGnbCellsParams
102         requestBody               map[string]interface{}
103         expectedStatusCode        int
104         expectedJsonResponse      string
105 }
106
107 func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
108
109         servedNrCells := []*entities.ServedNRCell{}
110
111         for _, v := range cellIds {
112                 servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{
113                         CellId: v,
114                         ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{
115                                 Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{
116
117                                 },
118                         },
119                         NrMode:      entities.Nr_FDD,
120                         NrPci:       5,
121                         ServedPlmns: []string{"whatever"},
122                 }})
123         }
124
125         return servedNrCells
126 }
127
128 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
129         ret := map[string]interface{}{
130                 "nrCgi": "whatever",
131                 "choiceNrMode": map[string]interface{}{
132                         "tdd": map[string]interface{}{},
133                 },
134                 "nrMode": 1,
135                 "nrPci":  1,
136         }
137
138         if len(propToOmit) != 0 {
139                 delete(ret, propToOmit)
140         }
141
142         return ret
143 }
144
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{}{},
150                 },
151                 "nrMode": 1,
152                 "nrPci":  1,
153                 "servedPlmns": []interface{}{
154                         "whatever",
155                 },
156         }
157
158         if len(propToOmit) != 0 {
159                 delete(ret, propToOmit)
160         }
161
162         return ret
163 }
164
165 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
166         log := initLog(t)
167         config := configuration.ParseConfiguration()
168
169         rmrMessengerMock := &mocks.RmrMessengerMock{}
170         readerMock := &mocks.RnibReaderMock{}
171
172         writerMock := &mocks.RnibWriterMock{}
173
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
184 }
185
186 func TestX2SetupInvalidBody(t *testing.T) {
187
188         controller, _, _, _, _ := setupControllerTest(t)
189
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
194
195         writer := httptest.NewRecorder()
196         controller.X2Setup(writer, httpRequest)
197
198         var errorResponse = parseJsonRequest(t, writer.Body)
199
200         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
201         assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
202 }
203
204 func TestX2SetupSuccess(t *testing.T) {
205
206         controller, readerMock, writerMock, rmrMessengerMock, _ := setupControllerTest(t)
207
208         ranName := "test"
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)
211         var nbUpdated = *nb
212         writerMock.On("UpdateNodebInfo", &nbUpdated).Return(nil)
213
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)
216
217         payload := e2pdus.PackedX2setupRequest
218         var xAction []byte
219         var msgSrc unsafe.Pointer
220         msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), ranName, &payload, &xAction, msgSrc)
221
222         rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
223
224         header := http.Header{}
225         header.Set("Content-Type", "application/json")
226         httpRequest := tests.GetHttpRequest()
227         httpRequest.Header = header
228
229         writer := httptest.NewRecorder()
230         controller.X2Setup(writer, httpRequest)
231
232         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
233 }
234
235 func TestEndcSetupSuccess(t *testing.T) {
236
237         controller, readerMock, writerMock, rmrMessengerMock, _ := setupControllerTest(t)
238
239         ranName := "test"
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)
242         var nbUpdated = *nb
243         writerMock.On("UpdateNodebInfo", &nbUpdated).Return(nil)
244
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)
247
248         payload := e2pdus.PackedEndcX2setupRequest
249         var xAction []byte
250         var msgSrc unsafe.Pointer
251         msg := rmrCgo.NewMBuf(rmrCgo.RIC_ENDC_X2_SETUP_REQ, len(payload), ranName, &payload, &xAction, msgSrc)
252
253         rmrMessengerMock.On("SendMsg", mock.Anything, true).Return(msg, nil)
254
255         header := http.Header{}
256         header.Set("Content-Type", "application/json")
257         httpRequest := tests.GetHttpRequest()
258         httpRequest.Header = header
259
260         writer := httptest.NewRecorder()
261         controller.EndcSetup(writer, httpRequest)
262
263         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
264 }
265
266 func TestShutdownHandlerRnibError(t *testing.T) {
267         controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
268         e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
269
270         writer := httptest.NewRecorder()
271
272         controller.Shutdown(writer, tests.GetHttpRequest())
273
274         var errorResponse = parseJsonRequest(t, writer.Body)
275
276         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
277         assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
278 }
279
280 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
281         controller, readerMock, _, _, _ := setupControllerTest(t)
282
283         configuration := &entities.GeneralConfiguration{}
284         readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
285
286         writer := httptest.NewRecorder()
287
288         httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
289
290         controller.SetGeneralConfiguration(writer, httpRequest)
291
292         var errorResponse = parseJsonRequest(t, writer.Body)
293
294         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
295         assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
296 }
297
298 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
299         controller, _, _, _, _ := setupControllerTest(t)
300
301         writer := httptest.NewRecorder()
302
303         httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{}{}"))
304
305         controller.SetGeneralConfiguration(writer, httpRequest)
306
307         var errorResponse = parseJsonRequest(t, writer.Body)
308
309         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
310         assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
311 }
312
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))
323 }
324
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))
334 }
335
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)
339         }
340
341         if context.removeServedNrCellsParams != nil {
342                 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
343         }
344
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)
352         }
353 }
354
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)
361
362         if context.getNodebInfoResult != nil {
363                 readerMock.AssertNotCalled(t, "GetNodeb")
364         }
365
366         if context.updateGnbCellsParams != nil {
367                 writerMock.AssertNotCalled(t, "UpdateGnb")
368         }
369
370         if context.removeServedNrCellsParams != nil {
371                 writerMock.AssertNotCalled(t, "RemoveServedNrCells")
372         }
373 }
374
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})
381         return req
382 }
383
384 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
385         controller, readerMock, writerMock, _, _ := setupControllerTest(t)
386         writer := httptest.NewRecorder()
387
388         activateControllerUpdateGnbMocks(context, readerMock, writerMock)
389         req := buildUpdateGnbRequest(context)
390         controller.UpdateGnb(writer, req)
391         assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
392 }
393
394 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
395         context := controllerUpdateGnbTestContext{
396                 getNodebInfoResult: nil,
397                 requestBody: map[string]interface{}{
398                         "servedNrCells": []interface{}{
399                         },
400                 },
401                 expectedStatusCode:   http.StatusBadRequest,
402                 expectedJsonResponse: ValidationFailureJson,
403         }
404
405         controllerUpdateGnbTestExecuter(t, &context)
406 }
407
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,
415                                 },
416                         },
417                 },
418                 expectedStatusCode:   http.StatusBadRequest,
419                 expectedJsonResponse: ValidationFailureJson,
420         }
421
422         controllerUpdateGnbTestExecuter(t, &context)
423 }
424
425 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
426
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),
434                                         },
435                                 },
436                         },
437                         expectedStatusCode:   http.StatusBadRequest,
438                         expectedJsonResponse: ValidationFailureJson,
439                 }
440
441                 controllerUpdateGnbTestExecuter(t, &context)
442         }
443 }
444
445 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
446
447         servedNrCellInformation := buildServedNrCellInformation("")
448         servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
449
450         context := controllerUpdateGnbTestContext{
451                 getNodebInfoResult: nil,
452                 requestBody: map[string]interface{}{
453                         "servedNrCells": []interface{}{
454                                 map[string]interface{}{
455                                         "servedNrCellInformation": servedNrCellInformation,
456                                 },
457                         },
458                 },
459                 expectedStatusCode:   http.StatusBadRequest,
460                 expectedJsonResponse: ValidationFailureJson,
461         }
462
463         controllerUpdateGnbTestExecuter(t, &context)
464 }
465
466 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
467
468         nrNeighbourInfo := buildNrNeighbourInformation("")
469         nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
470
471         context := controllerUpdateGnbTestContext{
472                 getNodebInfoResult: nil,
473                 requestBody: map[string]interface{}{
474                         "servedNrCells": []interface{}{
475                                 map[string]interface{}{
476                                         "servedNrCellInformation": buildServedNrCellInformation(""),
477                                         "nrNeighbourInfos": []interface{}{
478                                                 nrNeighbourInfo,
479                                         },
480                                 },
481                         },
482                 },
483                 expectedStatusCode:   http.StatusBadRequest,
484                 expectedJsonResponse: ValidationFailureJson,
485         }
486
487         controllerUpdateGnbTestExecuter(t, &context)
488 }
489
490 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
491
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),
501                                                 },
502                                         },
503                                 },
504                         },
505                         expectedStatusCode:   http.StatusBadRequest,
506                         expectedJsonResponse: ValidationFailureJson,
507                 }
508
509                 controllerUpdateGnbTestExecuter(t, &context)
510         }
511 }
512
513 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
514         context := controllerUpdateGnbTestContext{
515                 getNodebInfoResult: &getNodebInfoResult{
516                         nodebInfo: nil,
517                         rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
518                 },
519                 requestBody: map[string]interface{}{
520                         "servedNrCells": []interface{}{
521                                 map[string]interface{}{
522                                         "servedNrCellInformation": buildServedNrCellInformation(""),
523                                 },
524                         },
525                 },
526                 expectedStatusCode:   http.StatusNotFound,
527                 expectedJsonResponse: ResourceNotFoundJson,
528         }
529
530         controllerUpdateGnbTestExecuter(t, &context)
531 }
532
533 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
534         context := controllerUpdateGnbTestContext{
535                 getNodebInfoResult: &getNodebInfoResult{
536                         nodebInfo: nil,
537                         rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
538                 },
539                 requestBody: map[string]interface{}{
540                         "servedNrCells": []interface{}{
541                                 map[string]interface{}{
542                                         "servedNrCellInformation": buildServedNrCellInformation(""),
543                                 },
544                         },
545                 },
546                 expectedStatusCode:   http.StatusInternalServerError,
547                 expectedJsonResponse: RnibErrorJson,
548         }
549
550         controllerUpdateGnbTestExecuter(t, &context)
551 }
552
553 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
554         context := controllerUpdateGnbTestContext{
555                 getNodebInfoResult: &getNodebInfoResult{
556                         nodebInfo: &entities.NodebInfo{
557                                 RanName:                      RanName,
558                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
559                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
560                         },
561                         rnibError: nil,
562                 },
563                 requestBody: map[string]interface{}{
564                         "servedNrCells": []interface{}{
565                                 map[string]interface{}{
566                                         "servedNrCellInformation": buildServedNrCellInformation(""),
567                                         "nrNeighbourInfos": []interface{}{
568                                                 buildNrNeighbourInformation(""),
569                                         },
570                                 },
571                         },
572                 },
573                 expectedStatusCode:   http.StatusInternalServerError,
574                 expectedJsonResponse: InternalErrorJson,
575         }
576
577         controllerUpdateGnbTestExecuter(t, &context)
578 }
579
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,
586                 },
587                 getNodebInfoResult: &getNodebInfoResult{
588                         nodebInfo: &entities.NodebInfo{
589                                 RanName:                      RanName,
590                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
591                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
592                                 Configuration:                &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
593                         },
594                         rnibError: nil,
595                 },
596                 requestBody: map[string]interface{}{
597                         "servedNrCells": []interface{}{
598                                 map[string]interface{}{
599                                         "servedNrCellInformation": buildServedNrCellInformation(""),
600                                         "nrNeighbourInfos": []interface{}{
601                                                 buildNrNeighbourInformation(""),
602                                         },
603                                 },
604                         },
605                 },
606                 expectedStatusCode:   http.StatusInternalServerError,
607                 expectedJsonResponse: RnibErrorJson,
608         }
609
610         controllerUpdateGnbTestExecuter(t, &context)
611 }
612
613 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
614         oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
615         context := controllerUpdateGnbTestContext{
616                 removeServedNrCellsParams: &removeServedNrCellsParams{
617                         err:           nil,
618                         servedNrCells: oldServedNrCells,
619                 },
620                 updateGnbCellsParams: &updateGnbCellsParams{
621                         err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
622                 },
623                 getNodebInfoResult: &getNodebInfoResult{
624                         nodebInfo: &entities.NodebInfo{
625                                 RanName:                      RanName,
626                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
627                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
628                                 Configuration:                &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
629                         },
630                         rnibError: nil,
631                 },
632                 requestBody: map[string]interface{}{
633                         "servedNrCells": []interface{}{
634                                 map[string]interface{}{
635                                         "servedNrCellInformation": buildServedNrCellInformation(""),
636                                         "nrNeighbourInfos": []interface{}{
637                                                 buildNrNeighbourInformation(""),
638                                         },
639                                 },
640                         },
641                 },
642                 expectedStatusCode:   http.StatusInternalServerError,
643                 expectedJsonResponse: RnibErrorJson,
644         }
645
646         controllerUpdateGnbTestExecuter(t, &context)
647 }
648
649 func TestControllerUpdateGnbSuccess(t *testing.T) {
650         context := controllerUpdateGnbTestContext{
651                 updateGnbCellsParams: &updateGnbCellsParams{
652                         err: nil,
653                 },
654                 getNodebInfoResult: &getNodebInfoResult{
655                         nodebInfo: &entities.NodebInfo{
656                                 RanName:                      RanName,
657                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
658                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
659                                 Configuration:                &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
660                         },
661                         rnibError: nil,
662                 },
663                 requestBody: map[string]interface{}{
664                         "servedNrCells": []interface{}{
665                                 map[string]interface{}{
666                                         "servedNrCellInformation": buildServedNrCellInformation(""),
667                                         "nrNeighbourInfos": []interface{}{
668                                                 buildNrNeighbourInformation(""),
669                                         },
670                                 },
671                         },
672                 },
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\"}",
675         }
676
677         controllerUpdateGnbTestExecuter(t, &context)
678 }
679
680 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
681         b := new(bytes.Buffer)
682         _ = json.NewEncoder(b).Encode(requestJson)
683         return b
684 }
685
686 func TestControllerGetNodebSuccess(t *testing.T) {
687         ranName := "test"
688         var rnibError error
689         context := controllerGetNodebTestContext{
690                 ranName:              ranName,
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),
695         }
696
697         controllerGetNodebTestExecuter(t, &context)
698 }
699
700 func TestControllerGetNodebNotFound(t *testing.T) {
701
702         ranName := "test"
703         var nodebInfo *entities.NodebInfo
704         context := controllerGetNodebTestContext{
705                 ranName:              ranName,
706                 nodebInfo:            nodebInfo,
707                 rnibError:            common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
708                 expectedStatusCode:   http.StatusNotFound,
709                 expectedJsonResponse: ResourceNotFoundJson,
710         }
711
712         controllerGetNodebTestExecuter(t, &context)
713 }
714
715 func TestControllerGetNodebInternal(t *testing.T) {
716         ranName := "test"
717         var nodebInfo *entities.NodebInfo
718         context := controllerGetNodebTestContext{
719                 ranName:              ranName,
720                 nodebInfo:            nodebInfo,
721                 rnibError:            common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
722                 expectedStatusCode:   http.StatusInternalServerError,
723                 expectedJsonResponse: RnibErrorJson,
724         }
725
726         controllerGetNodebTestExecuter(t, &context)
727 }
728
729 func TestControllerGetNodebIdListSuccess(t *testing.T) {
730         var rnibError error
731         nodebIdList := []*entities.NbIdentity{
732                 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
733                 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
734         }
735
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\"}}]",
741         }
742
743         controllerGetNodebIdListTestExecuter(t, &context)
744 }
745
746 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
747         var rnibError error
748         nodebIdList := []*entities.NbIdentity{}
749
750         context := controllerGetNodebIdListTestContext{
751                 nodebIdList:          nodebIdList,
752                 rnibError:            rnibError,
753                 expectedStatusCode:   http.StatusOK,
754                 expectedJsonResponse: "[]",
755         }
756
757         controllerGetNodebIdListTestExecuter(t, &context)
758 }
759
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,
767         }
768
769         controllerGetNodebIdListTestExecuter(t, &context)
770 }
771
772 func TestHeaderValidationFailed(t *testing.T) {
773         controller, _, _, _, _ := setupControllerTest(t)
774
775         writer := httptest.NewRecorder()
776
777         header := &http.Header{}
778
779         controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true)
780
781         var errorResponse = parseJsonRequest(t, writer.Body)
782         err := e2managererrors.NewHeaderValidationError()
783
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)
787 }
788
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)
793
794         writer := httptest.NewRecorder()
795         controller.Shutdown(writer, tests.GetHttpRequest())
796
797         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
798 }
799
800 func TestHandleInternalError(t *testing.T) {
801         controller, _, _, _, _ := setupControllerTest(t)
802
803         writer := httptest.NewRecorder()
804         err := e2managererrors.NewInternalError()
805
806         controller.handleErrorResponse(err, writer)
807         var errorResponse = parseJsonRequest(t, writer.Body)
808
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)
812 }
813
814 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
815         controller, _, _, _, _ := setupControllerTest(t)
816         writer := httptest.NewRecorder()
817         err := e2managererrors.NewCommandAlreadyInProgressError()
818
819         controller.handleErrorResponse(err, writer)
820         var errorResponse = parseJsonRequest(t, writer.Body)
821
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)
825 }
826
827 func TestHandleRoutingManagerError(t *testing.T) {
828         controller, _, _, _, _ := setupControllerTest(t)
829         writer := httptest.NewRecorder()
830         err := e2managererrors.NewRoutingManagerError()
831
832         controller.handleErrorResponse(err, writer)
833         var errorResponse = parseJsonRequest(t, writer.Body)
834
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)
838 }
839
840 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
841         controller, _, _, _, _ := setupControllerTest(t)
842
843         writer := httptest.NewRecorder()
844         err := e2managererrors.NewE2TInstanceAbsenceError()
845
846         controller.handleErrorResponse(err, writer)
847         var errorResponse = parseJsonRequest(t, writer.Body)
848
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)
852 }
853
854 func TestValidateHeaders(t *testing.T) {
855         controller, _, _, _, _ := setupControllerTest(t)
856
857         header := http.Header{}
858         header.Set("Content-Type", "application/json")
859         result := controller.validateRequestHeader(&header)
860
861         assert.Nil(t, result)
862 }
863
864 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
865
866         var errorResponse models.ErrorResponse
867         body, err := ioutil.ReadAll(r)
868         if err != nil {
869                 t.Errorf("Error cannot deserialize json request")
870         }
871         _ = json.Unmarshal(body, &errorResponse)
872
873         return errorResponse
874 }
875
876 func initLog(t *testing.T) *logger.Logger {
877         log, err := logger.InitLogger(logger.InfoLevel)
878         if err != nil {
879                 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
880         }
881         return log
882 }
883
884 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
885         controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
886
887         ranName := "test1"
888         payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
889         var xAction []byte
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)
893
894         writer := httptest.NewRecorder()
895
896         var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
897         readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
898
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})
904
905         controller.X2Reset(writer, req)
906         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
907
908 }
909
910 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
911         controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
912
913         ranName := "test1"
914         // o&m intervention
915         payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
916         var xAction []byte
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)
920
921         writer := httptest.NewRecorder()
922
923         var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
924         readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
925
926         // no body
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})
930
931         controller.X2Reset(writer, req)
932         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
933
934 }
935
936 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
937         controller, _, _, _, _ := setupControllerTest(t)
938
939         ranName := "test1"
940
941         writer := httptest.NewRecorder()
942
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})
947
948         controller.X2Reset(writer, req)
949         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
950
951 }
952
953 func TestHandleErrorResponse(t *testing.T) {
954         controller, _, _, _, _ := setupControllerTest(t)
955
956         writer := httptest.NewRecorder()
957         controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
958         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
959
960         writer = httptest.NewRecorder()
961         controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
962         assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
963
964         writer = httptest.NewRecorder()
965         controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
966         assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
967
968         writer = httptest.NewRecorder()
969         controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
970         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
971
972         writer = httptest.NewRecorder()
973         controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
974         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
975
976         writer = httptest.NewRecorder()
977         controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
978         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
979
980         writer = httptest.NewRecorder()
981         controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
982         assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
983
984         writer = httptest.NewRecorder()
985         controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
986         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
987 }
988
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)
993 }