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