[RIC-431] Add Enb | Configuration changes | Some refactoring | K8S yamls
[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/logger"
28         "e2mgr/managers"
29         "e2mgr/mocks"
30         "e2mgr/models"
31         "e2mgr/providers/httpmsghandlerprovider"
32         "e2mgr/rmrCgo"
33         "e2mgr/services"
34         "e2mgr/services/rmrsender"
35         "e2mgr/tests"
36         "encoding/json"
37         "fmt"
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"
45         "io"
46         "io/ioutil"
47         "net/http"
48         "net/http/httptest"
49         "strings"
50         "testing"
51         "unsafe"
52 )
53
54 const (
55         RanName                      = "test"
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"
63 )
64
65 var (
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"}
70 )
71
72 type controllerGetNodebTestContext struct {
73         ranName              string
74         nodebInfo            *entities.NodebInfo
75         rnibError            error
76         expectedStatusCode   int
77         expectedJsonResponse string
78 }
79
80 type controllerGetNodebIdListTestContext struct {
81         nodebIdList          []*entities.NbIdentity
82         rnibError            error
83         expectedStatusCode   int
84         expectedJsonResponse string
85 }
86
87 type getNodebInfoResult struct {
88         nodebInfo *entities.NodebInfo
89         rnibError error
90 }
91
92 type updateGnbCellsParams struct {
93         err error
94 }
95
96 type saveNodebParams struct {
97         nodebInfo *entities.NodebInfo
98         nbIdentity *entities.NbIdentity
99         err error
100 }
101
102 type removeServedNrCellsParams struct {
103         servedNrCells []*entities.ServedNRCell
104         err           error
105 }
106
107 type controllerUpdateGnbTestContext struct {
108         getNodebInfoResult        *getNodebInfoResult
109         removeServedNrCellsParams *removeServedNrCellsParams
110         updateGnbCellsParams      *updateGnbCellsParams
111         requestBody               map[string]interface{}
112         expectedStatusCode        int
113         expectedJsonResponse      string
114 }
115
116 type controllerAddEnbTestContext struct {
117         getNodebInfoResult   *getNodebInfoResult
118         saveNodebParams      *saveNodebParams
119         requestBody          map[string]interface{}
120         expectedStatusCode   int
121         expectedJsonResponse string
122 }
123
124 func generateServedNrCells(cellIds ...string) []*entities.ServedNRCell {
125
126         servedNrCells := []*entities.ServedNRCell{}
127
128         for _, v := range cellIds {
129                 servedNrCells = append(servedNrCells, &entities.ServedNRCell{ServedNrCellInformation: &entities.ServedNRCellInformation{
130                         CellId: v,
131                         ChoiceNrMode: &entities.ServedNRCellInformation_ChoiceNRMode{
132                                 Fdd: &entities.ServedNRCellInformation_ChoiceNRMode_FddInfo{
133
134                                 },
135                         },
136                         NrMode:      entities.Nr_FDD,
137                         NrPci:       5,
138                         ServedPlmns: []string{"whatever"},
139                 }})
140         }
141
142         return servedNrCells
143 }
144
145 func buildNrNeighbourInformation(propToOmit string) map[string]interface{} {
146         ret := map[string]interface{}{
147                 "nrCgi": "whatever",
148                 "choiceNrMode": map[string]interface{}{
149                         "tdd": map[string]interface{}{},
150                 },
151                 "nrMode": 1,
152                 "nrPci":  1,
153         }
154
155         if len(propToOmit) != 0 {
156                 delete(ret, propToOmit)
157         }
158
159         return ret
160 }
161
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{}{},
167                 },
168                 "nrMode": 1,
169                 "nrPci":  1,
170                 "servedPlmns": []interface{}{
171                         "whatever",
172                 },
173         }
174
175         if len(propToOmit) != 0 {
176                 delete(ret, propToOmit)
177         }
178
179         return ret
180 }
181
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{}{},
187                 },
188                 "eutraMode": 1,
189                 "pci":       1,
190                 "tac":       "whatever3",
191                 "broadcastPlmns": []interface{}{
192                         "whatever",
193                 },
194         }
195
196         if len(propToOmit) != 0 {
197                 delete(ret, propToOmit)
198         }
199
200         return ret
201 }
202
203 func setupControllerTest(t *testing.T) (*NodebController, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.RmrMessengerMock, *mocks.E2TInstancesManagerMock) {
204         log := initLog(t)
205         config := configuration.ParseConfiguration()
206
207         rmrMessengerMock := &mocks.RmrMessengerMock{}
208         readerMock := &mocks.RnibReaderMock{}
209
210         writerMock := &mocks.RnibWriterMock{}
211
212         rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
213         rmrSender := getRmrSender(rmrMessengerMock, log)
214         ranSetupManager := managers.NewRanSetupManager(log, rmrSender, rnibDataService)
215         e2tInstancesManager := &mocks.E2TInstancesManagerMock{}
216         httpClientMock := &mocks.HttpClientMock{}
217         rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
218         ranListManager := &mocks.RanListManagerMock{}
219         ranAlarmService := &mocks.RanAlarmServiceMock{}
220         ranConnectStatusChangeManager := managers.NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
221
222         e2tAssociationManager := managers.NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager)
223         handlerProvider := httpmsghandlerprovider.NewIncomingRequestHandlerProvider(log, rmrSender, config, rnibDataService, ranSetupManager, e2tInstancesManager, e2tAssociationManager, rmClient, ranConnectStatusChangeManager)
224         controller := NewNodebController(log, handlerProvider)
225         return controller, readerMock, writerMock, rmrMessengerMock, e2tInstancesManager
226 }
227
228 func TestShutdownHandlerRnibError(t *testing.T) {
229         controller, _, _, _, e2tInstancesManagerMock := setupControllerTest(t)
230         e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, e2managererrors.NewRnibDbError())
231
232         writer := httptest.NewRecorder()
233
234         controller.Shutdown(writer, tests.GetHttpRequest())
235
236         var errorResponse = parseJsonRequest(t, writer.Body)
237
238         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
239         assert.Equal(t, errorResponse.Code, e2managererrors.NewRnibDbError().Code)
240 }
241
242 func TestSetGeneralConfigurationHandlerRnibError(t *testing.T) {
243         controller, readerMock, _, _, _ := setupControllerTest(t)
244
245         configuration := &entities.GeneralConfiguration{}
246         readerMock.On("GetGeneralConfiguration").Return(configuration, e2managererrors.NewRnibDbError())
247
248         writer := httptest.NewRecorder()
249
250         httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false}"))
251
252         controller.SetGeneralConfiguration(writer, httpRequest)
253
254         var errorResponse = parseJsonRequest(t, writer.Body)
255
256         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
257         assert.Equal(t, e2managererrors.NewRnibDbError().Code, errorResponse.Code)
258 }
259
260 func TestSetGeneralConfigurationInvalidJson(t *testing.T) {
261         controller, _, _, _, _ := setupControllerTest(t)
262
263         writer := httptest.NewRecorder()
264
265         httpRequest, _ := http.NewRequest("PUT", "https://localhost:3800/v1/nodeb/parameters", strings.NewReader("{\"enableRic\":false, \"someValue\":false}"))
266
267         controller.SetGeneralConfiguration(writer, httpRequest)
268
269         var errorResponse = parseJsonRequest(t, writer.Body)
270
271         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
272         assert.Equal(t, e2managererrors.NewInvalidJsonError().Code, errorResponse.Code)
273 }
274
275 func controllerGetNodebTestExecuter(t *testing.T, context *controllerGetNodebTestContext) {
276         controller, readerMock, _, _, _ := setupControllerTest(t)
277         writer := httptest.NewRecorder()
278         readerMock.On("GetNodeb", context.ranName).Return(context.nodebInfo, context.rnibError)
279         req, _ := http.NewRequest(http.MethodGet, "/nodeb", nil)
280         req = mux.SetURLVars(req, map[string]string{"ranName": context.ranName})
281         controller.GetNodeb(writer, req)
282         assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
283         bodyBytes, _ := ioutil.ReadAll(writer.Body)
284         assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
285 }
286
287 func controllerGetNodebIdListTestExecuter(t *testing.T, context *controllerGetNodebIdListTestContext) {
288         controller, readerMock, _, _, _ := setupControllerTest(t)
289         writer := httptest.NewRecorder()
290         readerMock.On("GetListNodebIds").Return(context.nodebIdList, context.rnibError)
291         req, _ := http.NewRequest(http.MethodGet, "/nodeb/ids", nil)
292         controller.GetNodebIdList(writer, req)
293         assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
294         bodyBytes, _ := ioutil.ReadAll(writer.Body)
295         assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
296 }
297
298 func activateControllerUpdateGnbMocks(context *controllerUpdateGnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
299         if context.getNodebInfoResult != nil {
300                 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
301         }
302
303         if context.removeServedNrCellsParams != nil {
304                 writerMock.On("RemoveServedNrCells", RanName, context.removeServedNrCellsParams.servedNrCells).Return(context.removeServedNrCellsParams.err)
305         }
306
307         if context.updateGnbCellsParams != nil {
308                 updatedNodebInfo := *context.getNodebInfoResult.nodebInfo
309                 gnb := entities.Gnb{}
310                 _ = jsonpb.Unmarshal(getJsonRequestAsBuffer(context.requestBody), &gnb)
311                 updatedGnb := *updatedNodebInfo.GetGnb()
312                 updatedGnb.ServedNrCells = gnb.ServedNrCells
313                 writerMock.On("UpdateGnbCells", &updatedNodebInfo, gnb.ServedNrCells).Return(context.updateGnbCellsParams.err)
314         }
315 }
316
317 func assertControllerUpdateGnb(t *testing.T, context *controllerUpdateGnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
318         assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
319         bodyBytes, _ := ioutil.ReadAll(writer.Body)
320         assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
321         readerMock.AssertExpectations(t)
322         writerMock.AssertExpectations(t)
323 }
324
325 func assertControllerAddEnb(t *testing.T, context *controllerAddEnbTestContext, writer *httptest.ResponseRecorder, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock) {
326         assert.Equal(t, context.expectedStatusCode, writer.Result().StatusCode)
327         bodyBytes, _ := ioutil.ReadAll(writer.Body)
328         assert.Equal(t, context.expectedJsonResponse, string(bodyBytes))
329         readerMock.AssertExpectations(t)
330         writerMock.AssertExpectations(t)
331 }
332
333 func buildUpdateGnbRequest(context *controllerUpdateGnbTestContext) *http.Request {
334         updateGnbUrl := fmt.Sprintf("/nodeb/%s/update", RanName)
335         requestBody := getJsonRequestAsBuffer(context.requestBody)
336         req, _ := http.NewRequest(http.MethodPut, updateGnbUrl, requestBody)
337         req.Header.Set("Content-Type", "application/json")
338         req = mux.SetURLVars(req, map[string]string{"ranName": RanName})
339         return req
340 }
341
342 func buildAddEnbRequest(context *controllerAddEnbTestContext) *http.Request {
343         requestBody := getJsonRequestAsBuffer(context.requestBody)
344         req, _ := http.NewRequest(http.MethodPost, AddEnbUrl, requestBody)
345         req.Header.Set("Content-Type", "application/json")
346         return req
347 }
348
349 func controllerUpdateGnbTestExecuter(t *testing.T, context *controllerUpdateGnbTestContext) {
350         controller, readerMock, writerMock, _, _ := setupControllerTest(t)
351         writer := httptest.NewRecorder()
352
353         activateControllerUpdateGnbMocks(context, readerMock, writerMock)
354         req := buildUpdateGnbRequest(context)
355         controller.UpdateGnb(writer, req)
356         assertControllerUpdateGnb(t, context, writer, readerMock, writerMock)
357 }
358
359 func activateControllerAddEnbMocks(context *controllerAddEnbTestContext, readerMock *mocks.RnibReaderMock, writerMock *mocks.RnibWriterMock, addEnbRequest *models.AddEnbRequest) {
360         if context.getNodebInfoResult != nil {
361                 readerMock.On("GetNodeb", RanName).Return(context.getNodebInfoResult.nodebInfo, context.getNodebInfoResult.rnibError)
362         }
363
364         if context.saveNodebParams != nil {
365                 nodebInfo := entities.NodebInfo{
366                         RanName:          addEnbRequest.RanName,
367                         Ip:               addEnbRequest.Ip,
368                         Port:             addEnbRequest.Port,
369                         GlobalNbId:       addEnbRequest.GlobalNbId,
370                         Configuration:    &entities.NodebInfo_Enb{Enb: addEnbRequest.Enb},
371                         ConnectionStatus: entities.ConnectionStatus_DISCONNECTED,
372                 }
373
374                 nbIdentity := entities.NbIdentity{InventoryName: addEnbRequest.RanName, GlobalNbId: addEnbRequest.GlobalNbId}
375
376                 writerMock.On("SaveNodeb",&nbIdentity, &nodebInfo).Return(context.saveNodebParams.err)
377         }
378 }
379
380 func controllerAddEnbTestExecuter(t *testing.T, context *controllerAddEnbTestContext) {
381         controller, readerMock, writerMock, _, _ := setupControllerTest(t)
382         writer := httptest.NewRecorder()
383         r := buildAddEnbRequest(context)
384         defer r.Body.Close()
385         body, _ := ioutil.ReadAll(io.LimitReader(r.Body, LimitRequest))
386
387         addEnbRequest := models.AddEnbRequest{}
388
389         _ = json.Unmarshal(body, &addEnbRequest)
390         activateControllerAddEnbMocks(context, readerMock, writerMock, &addEnbRequest)
391         controller.AddEnb(writer, buildAddEnbRequest(context))
392         assertControllerAddEnb(t, context, writer, readerMock, writerMock)
393 }
394
395 func TestControllerUpdateGnbEmptyServedNrCells(t *testing.T) {
396         context := controllerUpdateGnbTestContext{
397                 getNodebInfoResult: nil,
398                 requestBody: map[string]interface{}{
399                         "servedNrCells": []interface{}{
400                         },
401                 },
402                 expectedStatusCode:   http.StatusBadRequest,
403                 expectedJsonResponse: ValidationFailureJson,
404         }
405
406         controllerUpdateGnbTestExecuter(t, &context)
407 }
408
409 func TestControllerUpdateGnbMissingServedNrCellInformation(t *testing.T) {
410         context := controllerUpdateGnbTestContext{
411                 getNodebInfoResult: nil,
412                 requestBody: map[string]interface{}{
413                         "servedNrCells": []interface{}{
414                                 map[string]interface{}{
415                                         "servedNrCellInformation": nil,
416                                 },
417                         },
418                 },
419                 expectedStatusCode:   http.StatusBadRequest,
420                 expectedJsonResponse: ValidationFailureJson,
421         }
422
423         controllerUpdateGnbTestExecuter(t, &context)
424 }
425
426 func TestControllerUpdateGnbMissingServedNrCellRequiredProp(t *testing.T) {
427
428         for _, v := range ServedNrCellInformationRequiredFields {
429                 context := controllerUpdateGnbTestContext{
430                         getNodebInfoResult: nil,
431                         requestBody: map[string]interface{}{
432                                 "servedNrCells": []interface{}{
433                                         map[string]interface{}{
434                                                 "servedNrCellInformation": buildServedNrCellInformation(v),
435                                         },
436                                 },
437                         },
438                         expectedStatusCode:   http.StatusBadRequest,
439                         expectedJsonResponse: ValidationFailureJson,
440                 }
441
442                 controllerUpdateGnbTestExecuter(t, &context)
443         }
444 }
445
446 func TestControllerUpdateGnbMissingServedNrCellFddOrTdd(t *testing.T) {
447
448         servedNrCellInformation := buildServedNrCellInformation("")
449         servedNrCellInformation["choiceNrMode"] = map[string]interface{}{}
450
451         context := controllerUpdateGnbTestContext{
452                 getNodebInfoResult: nil,
453                 requestBody: map[string]interface{}{
454                         "servedNrCells": []interface{}{
455                                 map[string]interface{}{
456                                         "servedNrCellInformation": servedNrCellInformation,
457                                 },
458                         },
459                 },
460                 expectedStatusCode:   http.StatusBadRequest,
461                 expectedJsonResponse: ValidationFailureJson,
462         }
463
464         controllerUpdateGnbTestExecuter(t, &context)
465 }
466
467 func TestControllerUpdateGnbMissingNeighbourInfoFddOrTdd(t *testing.T) {
468
469         nrNeighbourInfo := buildNrNeighbourInformation("")
470         nrNeighbourInfo["choiceNrMode"] = map[string]interface{}{}
471
472         context := controllerUpdateGnbTestContext{
473                 getNodebInfoResult: nil,
474                 requestBody: map[string]interface{}{
475                         "servedNrCells": []interface{}{
476                                 map[string]interface{}{
477                                         "servedNrCellInformation": buildServedNrCellInformation(""),
478                                         "nrNeighbourInfos": []interface{}{
479                                                 nrNeighbourInfo,
480                                         },
481                                 },
482                         },
483                 },
484                 expectedStatusCode:   http.StatusBadRequest,
485                 expectedJsonResponse: ValidationFailureJson,
486         }
487
488         controllerUpdateGnbTestExecuter(t, &context)
489 }
490
491 func TestControllerUpdateGnbMissingNrNeighbourInformationRequiredProp(t *testing.T) {
492
493         for _, v := range NrNeighbourInformationRequiredFields {
494                 context := controllerUpdateGnbTestContext{
495                         getNodebInfoResult: nil,
496                         requestBody: map[string]interface{}{
497                                 "servedNrCells": []interface{}{
498                                         map[string]interface{}{
499                                                 "servedNrCellInformation": buildServedNrCellInformation(""),
500                                                 "nrNeighbourInfos": []interface{}{
501                                                         buildNrNeighbourInformation(v),
502                                                 },
503                                         },
504                                 },
505                         },
506                         expectedStatusCode:   http.StatusBadRequest,
507                         expectedJsonResponse: ValidationFailureJson,
508                 }
509
510                 controllerUpdateGnbTestExecuter(t, &context)
511         }
512 }
513
514 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebNotFound(t *testing.T) {
515         context := controllerUpdateGnbTestContext{
516                 getNodebInfoResult: &getNodebInfoResult{
517                         nodebInfo: nil,
518                         rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
519                 },
520                 requestBody: map[string]interface{}{
521                         "servedNrCells": []interface{}{
522                                 map[string]interface{}{
523                                         "servedNrCellInformation": buildServedNrCellInformation(""),
524                                 },
525                         },
526                 },
527                 expectedStatusCode:   http.StatusNotFound,
528                 expectedJsonResponse: ResourceNotFoundJson,
529         }
530
531         controllerUpdateGnbTestExecuter(t, &context)
532 }
533
534 func TestControllerUpdateGnbValidServedNrCellInformationGetNodebInternalError(t *testing.T) {
535         context := controllerUpdateGnbTestContext{
536                 getNodebInfoResult: &getNodebInfoResult{
537                         nodebInfo: nil,
538                         rnibError: common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
539                 },
540                 requestBody: map[string]interface{}{
541                         "servedNrCells": []interface{}{
542                                 map[string]interface{}{
543                                         "servedNrCellInformation": buildServedNrCellInformation(""),
544                                 },
545                         },
546                 },
547                 expectedStatusCode:   http.StatusInternalServerError,
548                 expectedJsonResponse: RnibErrorJson,
549         }
550
551         controllerUpdateGnbTestExecuter(t, &context)
552 }
553
554 func TestControllerUpdateGnbGetNodebSuccessInvalidGnbConfiguration(t *testing.T) {
555         context := controllerUpdateGnbTestContext{
556                 getNodebInfoResult: &getNodebInfoResult{
557                         nodebInfo: &entities.NodebInfo{
558                                 RanName:                      RanName,
559                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
560                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
561                         },
562                         rnibError: nil,
563                 },
564                 requestBody: map[string]interface{}{
565                         "servedNrCells": []interface{}{
566                                 map[string]interface{}{
567                                         "servedNrCellInformation": buildServedNrCellInformation(""),
568                                         "nrNeighbourInfos": []interface{}{
569                                                 buildNrNeighbourInformation(""),
570                                         },
571                                 },
572                         },
573                 },
574                 expectedStatusCode:   http.StatusInternalServerError,
575                 expectedJsonResponse: InternalErrorJson,
576         }
577
578         controllerUpdateGnbTestExecuter(t, &context)
579 }
580
581 func TestControllerUpdateGnbGetNodebSuccessRemoveServedNrCellsFailure(t *testing.T) {
582         oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
583         context := controllerUpdateGnbTestContext{
584                 removeServedNrCellsParams: &removeServedNrCellsParams{
585                         err:           common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
586                         servedNrCells: oldServedNrCells,
587                 },
588                 getNodebInfoResult: &getNodebInfoResult{
589                         nodebInfo: &entities.NodebInfo{
590                                 RanName:                      RanName,
591                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
592                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
593                                 Configuration:                &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
594                         },
595                         rnibError: nil,
596                 },
597                 requestBody: map[string]interface{}{
598                         "servedNrCells": []interface{}{
599                                 map[string]interface{}{
600                                         "servedNrCellInformation": buildServedNrCellInformation(""),
601                                         "nrNeighbourInfos": []interface{}{
602                                                 buildNrNeighbourInformation(""),
603                                         },
604                                 },
605                         },
606                 },
607                 expectedStatusCode:   http.StatusInternalServerError,
608                 expectedJsonResponse: RnibErrorJson,
609         }
610
611         controllerUpdateGnbTestExecuter(t, &context)
612 }
613
614 func TestControllerUpdateGnbGetNodebSuccessUpdateGnbCellsFailure(t *testing.T) {
615         oldServedNrCells := generateServedNrCells("whatever1", "whatever2")
616         context := controllerUpdateGnbTestContext{
617                 removeServedNrCellsParams: &removeServedNrCellsParams{
618                         err:           nil,
619                         servedNrCells: oldServedNrCells,
620                 },
621                 updateGnbCellsParams: &updateGnbCellsParams{
622                         err: common.NewInternalError(errors.New("#writer.UpdateGnbCells - Internal Error")),
623                 },
624                 getNodebInfoResult: &getNodebInfoResult{
625                         nodebInfo: &entities.NodebInfo{
626                                 RanName:                      RanName,
627                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
628                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
629                                 Configuration:                &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{ServedNrCells: oldServedNrCells}},
630                         },
631                         rnibError: nil,
632                 },
633                 requestBody: map[string]interface{}{
634                         "servedNrCells": []interface{}{
635                                 map[string]interface{}{
636                                         "servedNrCellInformation": buildServedNrCellInformation(""),
637                                         "nrNeighbourInfos": []interface{}{
638                                                 buildNrNeighbourInformation(""),
639                                         },
640                                 },
641                         },
642                 },
643                 expectedStatusCode:   http.StatusInternalServerError,
644                 expectedJsonResponse: RnibErrorJson,
645         }
646
647         controllerUpdateGnbTestExecuter(t, &context)
648 }
649
650 func TestControllerUpdateGnbSuccess(t *testing.T) {
651         context := controllerUpdateGnbTestContext{
652                 updateGnbCellsParams: &updateGnbCellsParams{
653                         err: nil,
654                 },
655                 getNodebInfoResult: &getNodebInfoResult{
656                         nodebInfo: &entities.NodebInfo{
657                                 RanName:                      RanName,
658                                 ConnectionStatus:             entities.ConnectionStatus_CONNECTED,
659                                 AssociatedE2TInstanceAddress: AssociatedE2TInstanceAddress,
660                                 Configuration:                &entities.NodebInfo_Gnb{Gnb: &entities.Gnb{}},
661                         },
662                         rnibError: nil,
663                 },
664                 requestBody: map[string]interface{}{
665                         "servedNrCells": []interface{}{
666                                 map[string]interface{}{
667                                         "servedNrCellInformation": buildServedNrCellInformation(""),
668                                         "nrNeighbourInfos": []interface{}{
669                                                 buildNrNeighbourInformation(""),
670                                         },
671                                 },
672                         },
673                 },
674                 expectedStatusCode:   http.StatusOK,
675                 expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"CONNECTED\",\"gnb\":{\"servedNrCells\":[{\"servedNrCellInformation\":{\"nrPci\":1,\"cellId\":\"whatever\",\"servedPlmns\":[\"whatever\"],\"nrMode\":\"FDD\",\"choiceNrMode\":{\"fdd\":{}}},\"nrNeighbourInfos\":[{\"nrPci\":1,\"nrCgi\":\"whatever\",\"nrMode\":\"FDD\",\"choiceNrMode\":{\"tdd\":{}}}]}]},\"associatedE2tInstanceAddress\":\"10.0.2.15:38000\"}",
676         }
677
678         controllerUpdateGnbTestExecuter(t, &context)
679 }
680
681 func TestControllerAddEnbSuccess(t *testing.T) {
682         context := controllerAddEnbTestContext{
683                 saveNodebParams: &saveNodebParams{
684                         err: nil,
685                 },
686                 getNodebInfoResult: &getNodebInfoResult{
687                         nodebInfo: nil,
688                         rnibError: common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
689                 },
690                 requestBody: map[string]interface{}{
691                         "ranName": RanName,
692                         "globalNbId": map[string]interface{}{
693                                 "plmnId": "whatever",
694                                 "nbId":   "whatever2",
695                         },
696                         "enb": map[string]interface{}{
697                                 "enbType": 1,
698                                 "servedCells": []interface{}{
699                                         buildServedCell(""),
700                                 },
701                         },
702                 },
703                 expectedStatusCode:   http.StatusCreated,
704                 expectedJsonResponse: "{\"ranName\":\"test\",\"connectionStatus\":\"DISCONNECTED\",\"globalNbId\":{\"plmnId\":\"whatever\",\"nbId\":\"whatever2\"},\"enb\":{\"enbType\":\"MACRO_ENB\",\"servedCells\":[{\"pci\":1,\"cellId\":\"whatever\",\"tac\":\"whatever3\",\"broadcastPlmns\":[\"whatever\"],\"choiceEutraMode\":{\"fdd\":{}},\"eutraMode\":\"FDD\"}]}}",
705         }
706
707         controllerAddEnbTestExecuter(t, &context)
708 }
709
710 func getJsonRequestAsBuffer(requestJson map[string]interface{}) *bytes.Buffer {
711         b := new(bytes.Buffer)
712         _ = json.NewEncoder(b).Encode(requestJson)
713         return b
714 }
715
716 func TestControllerGetNodebSuccess(t *testing.T) {
717         ranName := "test"
718         var rnibError error
719         context := controllerGetNodebTestContext{
720                 ranName:              ranName,
721                 nodebInfo:            &entities.NodebInfo{RanName: ranName, Ip: "10.0.2.15", Port: 1234},
722                 rnibError:            rnibError,
723                 expectedStatusCode:   http.StatusOK,
724                 expectedJsonResponse: fmt.Sprintf("{\"ranName\":\"%s\",\"ip\":\"10.0.2.15\",\"port\":1234}", ranName),
725         }
726
727         controllerGetNodebTestExecuter(t, &context)
728 }
729
730 func TestControllerGetNodebNotFound(t *testing.T) {
731
732         ranName := "test"
733         var nodebInfo *entities.NodebInfo
734         context := controllerGetNodebTestContext{
735                 ranName:              ranName,
736                 nodebInfo:            nodebInfo,
737                 rnibError:            common.NewResourceNotFoundError("#reader.GetNodeb - Not found Error"),
738                 expectedStatusCode:   http.StatusNotFound,
739                 expectedJsonResponse: ResourceNotFoundJson,
740         }
741
742         controllerGetNodebTestExecuter(t, &context)
743 }
744
745 func TestControllerGetNodebInternal(t *testing.T) {
746         ranName := "test"
747         var nodebInfo *entities.NodebInfo
748         context := controllerGetNodebTestContext{
749                 ranName:              ranName,
750                 nodebInfo:            nodebInfo,
751                 rnibError:            common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
752                 expectedStatusCode:   http.StatusInternalServerError,
753                 expectedJsonResponse: RnibErrorJson,
754         }
755
756         controllerGetNodebTestExecuter(t, &context)
757 }
758
759 func TestControllerGetNodebIdListSuccess(t *testing.T) {
760         var rnibError error
761         nodebIdList := []*entities.NbIdentity{
762                 {InventoryName: "test1", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId1", NbId: "nbId1"}},
763                 {InventoryName: "test2", GlobalNbId: &entities.GlobalNbId{PlmnId: "plmnId2", NbId: "nbId2"}},
764         }
765
766         context := controllerGetNodebIdListTestContext{
767                 nodebIdList:          nodebIdList,
768                 rnibError:            rnibError,
769                 expectedStatusCode:   http.StatusOK,
770                 expectedJsonResponse: "[{\"inventoryName\":\"test1\",\"globalNbId\":{\"plmnId\":\"plmnId1\",\"nbId\":\"nbId1\"}},{\"inventoryName\":\"test2\",\"globalNbId\":{\"plmnId\":\"plmnId2\",\"nbId\":\"nbId2\"}}]",
771         }
772
773         controllerGetNodebIdListTestExecuter(t, &context)
774 }
775
776 func TestControllerGetNodebIdListEmptySuccess(t *testing.T) {
777         var rnibError error
778         nodebIdList := []*entities.NbIdentity{}
779
780         context := controllerGetNodebIdListTestContext{
781                 nodebIdList:          nodebIdList,
782                 rnibError:            rnibError,
783                 expectedStatusCode:   http.StatusOK,
784                 expectedJsonResponse: "[]",
785         }
786
787         controllerGetNodebIdListTestExecuter(t, &context)
788 }
789
790 func TestControllerGetNodebIdListInternal(t *testing.T) {
791         var nodebIdList []*entities.NbIdentity
792         context := controllerGetNodebIdListTestContext{
793                 nodebIdList:          nodebIdList,
794                 rnibError:            common.NewInternalError(errors.New("#reader.GetNodeb - Internal Error")),
795                 expectedStatusCode:   http.StatusInternalServerError,
796                 expectedJsonResponse: RnibErrorJson,
797         }
798
799         controllerGetNodebIdListTestExecuter(t, &context)
800 }
801
802 func TestHeaderValidationFailed(t *testing.T) {
803         controller, _, _, _, _ := setupControllerTest(t)
804
805         writer := httptest.NewRecorder()
806
807         header := &http.Header{}
808
809         controller.handleRequest(writer, header, httpmsghandlerprovider.ShutdownRequest, nil, true, 0)
810
811         var errorResponse = parseJsonRequest(t, writer.Body)
812         err := e2managererrors.NewHeaderValidationError()
813
814         assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
815         assert.Equal(t, errorResponse.Code, err.Code)
816         assert.Equal(t, errorResponse.Message, err.Message)
817 }
818
819 func TestShutdownStatusNoContent(t *testing.T) {
820         controller, readerMock, _, _, e2tInstancesManagerMock := setupControllerTest(t)
821         e2tInstancesManagerMock.On("GetE2TAddresses").Return([]string{}, nil)
822         readerMock.On("GetListNodebIds").Return([]*entities.NbIdentity{}, nil)
823
824         writer := httptest.NewRecorder()
825         controller.Shutdown(writer, tests.GetHttpRequest())
826
827         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
828 }
829
830 func TestHandleInternalError(t *testing.T) {
831         controller, _, _, _, _ := setupControllerTest(t)
832
833         writer := httptest.NewRecorder()
834         err := e2managererrors.NewInternalError()
835
836         controller.handleErrorResponse(err, writer)
837         var errorResponse = parseJsonRequest(t, writer.Body)
838
839         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
840         assert.Equal(t, errorResponse.Code, err.Code)
841         assert.Equal(t, errorResponse.Message, err.Message)
842 }
843
844 func TestHandleCommandAlreadyInProgressError(t *testing.T) {
845         controller, _, _, _, _ := setupControllerTest(t)
846         writer := httptest.NewRecorder()
847         err := e2managererrors.NewCommandAlreadyInProgressError()
848
849         controller.handleErrorResponse(err, writer)
850         var errorResponse = parseJsonRequest(t, writer.Body)
851
852         assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
853         assert.Equal(t, errorResponse.Code, err.Code)
854         assert.Equal(t, errorResponse.Message, err.Message)
855 }
856
857 func TestHandleRoutingManagerError(t *testing.T) {
858         controller, _, _, _, _ := setupControllerTest(t)
859         writer := httptest.NewRecorder()
860         err := e2managererrors.NewRoutingManagerError()
861
862         controller.handleErrorResponse(err, writer)
863         var errorResponse = parseJsonRequest(t, writer.Body)
864
865         assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
866         assert.Equal(t, errorResponse.Code, err.Code)
867         assert.Equal(t, errorResponse.Message, err.Message)
868 }
869
870 func TestHandleE2TInstanceAbsenceError(t *testing.T) {
871         controller, _, _, _, _ := setupControllerTest(t)
872
873         writer := httptest.NewRecorder()
874         err := e2managererrors.NewE2TInstanceAbsenceError()
875
876         controller.handleErrorResponse(err, writer)
877         var errorResponse = parseJsonRequest(t, writer.Body)
878
879         assert.Equal(t, http.StatusServiceUnavailable, writer.Result().StatusCode)
880         assert.Equal(t, errorResponse.Code, err.Code)
881         assert.Equal(t, errorResponse.Message, err.Message)
882 }
883
884 func TestValidateHeaders(t *testing.T) {
885         controller, _, _, _, _ := setupControllerTest(t)
886
887         header := http.Header{}
888         header.Set("Content-Type", "application/json")
889         result := controller.validateRequestHeader(&header)
890
891         assert.Nil(t, result)
892 }
893
894 func parseJsonRequest(t *testing.T, r io.Reader) models.ErrorResponse {
895
896         var errorResponse models.ErrorResponse
897         body, err := ioutil.ReadAll(r)
898         if err != nil {
899                 t.Errorf("Error cannot deserialize json request")
900         }
901         _ = json.Unmarshal(body, &errorResponse)
902
903         return errorResponse
904 }
905
906 func initLog(t *testing.T) *logger.Logger {
907         log, err := logger.InitLogger(logger.InfoLevel)
908         if err != nil {
909                 t.Errorf("#delete_all_request_handler_test.TestHandleSuccessFlow - failed to initialize logger, error: %s", err)
910         }
911         return log
912 }
913
914 func TestX2ResetHandleSuccessfulRequestedCause(t *testing.T) {
915         controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
916
917         ranName := "test1"
918         payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x40}
919         var xAction []byte
920         var msgSrc unsafe.Pointer
921         msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
922         rmrMessengerMock.On("SendMsg", msg, mock.Anything).Return(msg, nil)
923
924         writer := httptest.NewRecorder()
925
926         var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
927         readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
928
929         data4Req := map[string]interface{}{"cause": "protocol:transfer-syntax-error"}
930         b := new(bytes.Buffer)
931         _ = json.NewEncoder(b).Encode(data4Req)
932         req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
933         req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
934
935         controller.X2Reset(writer, req)
936         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
937
938 }
939
940 func TestX2ResetHandleSuccessfulRequestedDefault(t *testing.T) {
941         controller, readerMock, _, rmrMessengerMock, _ := setupControllerTest(t)
942
943         ranName := "test1"
944         // o&m intervention
945         payload := []byte{0x00, 0x07, 0x00, 0x08, 0x00, 0x00, 0x01, 0x00, 0x05, 0x40, 0x01, 0x64}
946         var xAction []byte
947         var msgSrc unsafe.Pointer
948         msg := rmrCgo.NewMBuf(rmrCgo.RIC_X2_RESET, len(payload), ranName, &payload, &xAction, msgSrc)
949         rmrMessengerMock.On("SendMsg", msg, true).Return(msg, nil)
950
951         writer := httptest.NewRecorder()
952
953         var nodeb = &entities.NodebInfo{ConnectionStatus: entities.ConnectionStatus_CONNECTED}
954         readerMock.On("GetNodeb", ranName).Return(nodeb, nil)
955
956         // no body
957         b := new(bytes.Buffer)
958         data4Req := map[string]interface{}{}
959         _ = json.NewEncoder(b).Encode(data4Req)
960         req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
961         req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
962
963         controller.X2Reset(writer, req)
964         assert.Equal(t, http.StatusNoContent, writer.Result().StatusCode)
965 }
966
967 func TestX2ResetHandleFailureInvalidBody(t *testing.T) {
968         controller, _, _, _, _ := setupControllerTest(t)
969
970         ranName := "test1"
971
972         writer := httptest.NewRecorder()
973
974         // Invalid json: attribute name without quotes (should be "cause":).
975         b := strings.NewReader("{cause:\"protocol:transfer-syntax-error\"")
976         req, _ := http.NewRequest("PUT", "https://localhost:3800/nodeb-reset", b)
977         req = mux.SetURLVars(req, map[string]string{"ranName": ranName})
978
979         controller.X2Reset(writer, req)
980         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
981
982 }
983
984 func TestHandleErrorResponse(t *testing.T) {
985         controller, _, _, _, _ := setupControllerTest(t)
986
987         writer := httptest.NewRecorder()
988         controller.handleErrorResponse(e2managererrors.NewRnibDbError(), writer)
989         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
990
991         writer = httptest.NewRecorder()
992         controller.handleErrorResponse(e2managererrors.NewCommandAlreadyInProgressError(), writer)
993         assert.Equal(t, http.StatusMethodNotAllowed, writer.Result().StatusCode)
994
995         writer = httptest.NewRecorder()
996         controller.handleErrorResponse(e2managererrors.NewHeaderValidationError(), writer)
997         assert.Equal(t, http.StatusUnsupportedMediaType, writer.Result().StatusCode)
998
999         writer = httptest.NewRecorder()
1000         controller.handleErrorResponse(e2managererrors.NewWrongStateError("", ""), writer)
1001         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1002
1003         writer = httptest.NewRecorder()
1004         controller.handleErrorResponse(e2managererrors.NewRequestValidationError(), writer)
1005         assert.Equal(t, http.StatusBadRequest, writer.Result().StatusCode)
1006
1007         writer = httptest.NewRecorder()
1008         controller.handleErrorResponse(e2managererrors.NewRmrError(), writer)
1009         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1010
1011         writer = httptest.NewRecorder()
1012         controller.handleErrorResponse(e2managererrors.NewResourceNotFoundError(), writer)
1013         assert.Equal(t, http.StatusNotFound, writer.Result().StatusCode)
1014
1015         writer = httptest.NewRecorder()
1016         controller.handleErrorResponse(fmt.Errorf("ErrorError"), writer)
1017         assert.Equal(t, http.StatusInternalServerError, writer.Result().StatusCode)
1018 }
1019
1020 func getRmrSender(rmrMessengerMock *mocks.RmrMessengerMock, log *logger.Logger) *rmrsender.RmrSender {
1021         rmrMessenger := rmrCgo.RmrMessenger(rmrMessengerMock)
1022         rmrMessengerMock.On("Init", tests.GetPort(), tests.MaxMsgSize, tests.Flags, log).Return(&rmrMessenger)
1023         return rmrsender.NewRmrSender(log, rmrMessenger)
1024 }