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