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