Prepare Swagger for the 3 APIs
[ric-plt/e2mgr.git] / E2Manager / handlers / httpmsghandlers / health_check_handler_test.go
1 //
2 // Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15
16 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 //  platform project (RICP).
18
19 package httpmsghandlers
20
21 import (
22         "bytes"
23         "e2mgr/configuration"
24         "e2mgr/e2managererrors"
25         "e2mgr/mocks"
26         "e2mgr/models"
27         "e2mgr/rmrCgo"
28         "e2mgr/services"
29         "encoding/xml"
30         "errors"
31         "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
32         "github.com/stretchr/testify/assert"
33         "github.com/stretchr/testify/mock"
34         "io/ioutil"
35         "path/filepath"
36         "strings"
37         "testing"
38         "unsafe"
39 )
40
41 const (
42         e2tInstanceFullAddress                   = "10.0.2.15:9999"
43         e2SetupMsgPrefix                         = e2tInstanceFullAddress + "|"
44         GnbSetupRequestXmlPath                   = "../../tests/resources/setupRequest_gnb.xml"
45 )
46
47 func setupHealthCheckHandlerTest(t *testing.T) (*HealthCheckRequestHandler, services.RNibDataService, *mocks.RnibReaderMock, *mocks.RanListManagerMock, *mocks.RmrMessengerMock) {
48         logger := initLog(t)
49         config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
50
51         readerMock := &mocks.RnibReaderMock{}
52         writerMock := &mocks.RnibWriterMock{}
53
54         rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
55         rmrMessengerMock := &mocks.RmrMessengerMock{}
56         ranListManagerMock := &mocks.RanListManagerMock{}
57
58         rmrSender := getRmrSender(rmrMessengerMock, logger)
59         handler := NewHealthCheckRequestHandler(logger, rnibDataService, ranListManagerMock, rmrSender)
60
61         return handler, rnibDataService, readerMock, ranListManagerMock, rmrMessengerMock
62 }
63
64 func TestHealthCheckRequestHandlerArguementHasRanNameSuccess(t *testing.T) {
65         handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
66         ranNames := []string{"RanName_1"}
67
68         nb1:= createNbIdentity(t,"RanName_1", entities.ConnectionStatus_CONNECTED)
69         oldnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus}
70         newnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus}
71
72         readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil)
73
74         mbuf:= createRMRMbuf(t, nb1)
75         rmrMessengerMock.On("SendMsg",mbuf,true).Return(mbuf,nil)
76         ranListManagerMock.On("UpdateHealthcheckTimeStampSent",nb1.RanName).Return(oldnbIdentity, newnbIdentity)
77         ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil)
78
79         _, err := handler.Handle(models.HealthCheckRequest{ranNames})
80
81         assert.Nil(t, err)
82         readerMock.AssertExpectations(t)
83 }
84
85 func TestHealthCheckRequestHandlerArguementHasNoRanNameSuccess(t *testing.T) {
86         handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
87
88         nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED},
89                 {InventoryName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}}
90
91         ranListManagerMock.On("GetNbIdentityList").Return(nbIdentityList)
92
93         nb1:= createNbIdentity(t,"RanName_1", entities.ConnectionStatus_CONNECTED)
94         oldnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus}
95         newnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus}
96
97         readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil)
98
99         mbuf:= createRMRMbuf(t, nb1)
100         rmrMessengerMock.On("SendMsg",mbuf,true).Return(mbuf,nil)
101         ranListManagerMock.On("UpdateHealthcheckTimeStampSent",nb1.RanName).Return(oldnbIdentity, newnbIdentity)
102         ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil)
103
104         nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
105         readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
106
107         _, err := handler.Handle(models.HealthCheckRequest{[]string{}})
108
109         assert.Nil(t, err)
110
111 }
112
113 func TestHealthCheckRequestHandlerArguementHasNoRanConnectedFailure(t *testing.T) {
114         handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
115
116         nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED},
117                 {InventoryName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}}
118         ranListManagerMock.On("GetNbIdentityList").Return(nbIdentityList)
119
120         nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
121         readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
122
123         nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN}
124         readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
125
126         _, err := handler.Handle(models.HealthCheckRequest{[]string{}})
127
128         rmrMessengerMock.AssertNotCalled(t, "SendMsg", mock.Anything, mock.Anything)
129         ranListManagerMock.AssertNotCalled(t,"UpdateHealthcheckTimeStampSent",mock.Anything)
130         ranListManagerMock.AssertNotCalled(t,"UpdateNbIdentities",mock.Anything, mock.Anything, mock.Anything)
131         assert.IsType(t, &e2managererrors.NoConnectedRanError{}, err)
132
133 }
134
135 func TestHealthCheckRequestHandlerArguementHasRanNameDBErrorFailure(t *testing.T) {
136         handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
137
138         ranNames := []string{"RanName_1"}
139         readerMock.On("GetNodeb", "RanName_1").Return(&entities.NodebInfo{}, errors.New("error"))
140
141         _, err := handler.Handle(models.HealthCheckRequest{ranNames})
142
143         rmrMessengerMock.AssertNotCalled(t, "SendMsg", mock.Anything, mock.Anything)
144         ranListManagerMock.AssertNotCalled(t,"UpdateHealthcheckTimeStampSent",mock.Anything)
145         ranListManagerMock.AssertNotCalled(t,"UpdateNbIdentities",mock.Anything, mock.Anything, mock.Anything)
146         assert.IsType(t, &e2managererrors.RnibDbError{}, err)
147         readerMock.AssertExpectations(t)
148 }
149
150 func createRMRMbuf(t *testing.T, nodebInfo *entities.NodebInfo) *rmrCgo.MBuf{
151         serviceQuery := models.NewRicServiceQueryMessage(nodebInfo.GetGnb().RanFunctions)
152         payLoad, err := xml.Marshal(&serviceQuery.E2APPDU)
153         payLoad = normalizeXml(payLoad)
154
155         if err != nil {
156                 t.Fatal(err)
157         }
158
159         var xAction []byte
160         var msgSrc unsafe.Pointer
161
162         rmrMessage := models.NewRmrMessage(rmrCgo.RIC_SERVICE_QUERY, nodebInfo.RanName, payLoad, xAction, msgSrc)
163         return rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction, rmrMessage.GetMsgSrc())
164 }
165
166 func createNbIdentity(t *testing.T, RanName string,  connectionStatus entities.ConnectionStatus) *entities.NodebInfo {
167         xmlgnb := readXmlFile(t, GnbSetupRequestXmlPath)
168         payload := append([]byte(e2SetupMsgPrefix), xmlgnb...)
169         pipInd := bytes.IndexByte(payload, '|')
170         setupRequest := &models.E2SetupRequestMessage{}
171         err := xml.Unmarshal(normalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
172         if err != nil {
173                 t.Fatal(err)
174         }
175
176         nodeb := &entities.NodebInfo{
177                 AssociatedE2TInstanceAddress: e2tInstanceFullAddress,
178                 RanName:                      RanName,
179                 SetupFromNetwork:             true,
180                 NodeType:                     entities.Node_GNB,
181                 ConnectionStatus:                         connectionStatus,
182                 Configuration: &entities.NodebInfo_Gnb{
183                         Gnb: &entities.Gnb{
184                                 GnbType:      entities.GnbType_GNB,
185                                 RanFunctions: setupRequest.ExtractRanFunctionsList(),
186                         },
187                 },
188                 GlobalNbId: &entities.GlobalNbId{
189                         PlmnId: setupRequest.GetPlmnId(),
190                         NbId:   setupRequest.GetNbId(),
191                 },
192         }
193         return nodeb
194 }
195
196 func normalizeXml(payload []byte) []byte {
197         xmlStr := string(payload)
198         normalized := strings.NewReplacer("&lt;", "<", "&gt;", ">",
199                 "<reject></reject>","<reject/>","<ignore></ignore>","<ignore/>",
200                 "<protocolIEs></protocolIEs>","<protocolIEs/>").Replace(xmlStr)
201         return []byte(normalized)
202 }
203
204 func readXmlFile(t *testing.T, xmlPath string) []byte {
205         path, err := filepath.Abs(xmlPath)
206         if err != nil {
207                 t.Fatal(err)
208         }
209         xmlAsBytes, err := ioutil.ReadFile(path)
210         if err != nil {
211                 t.Fatal(err)
212         }
213
214         return xmlAsBytes
215 }