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