2 // Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
16 // This source code is part of the near-RT RIC (RAN Intelligent Controller)
17 // platform project (RICP).
19 package httpmsghandlers
24 "e2mgr/e2managererrors"
32 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
33 "github.com/stretchr/testify/assert"
34 "github.com/stretchr/testify/mock"
41 e2tInstanceFullAddress = "10.0.2.15:9999"
42 e2SetupMsgPrefix = e2tInstanceFullAddress + "|"
43 GnbSetupRequestXmlPath = "../../tests/resources/setupRequest/setupRequest_gnb.xml"
46 func setupHealthCheckHandlerTest(t *testing.T) (*HealthCheckRequestHandler, services.RNibDataService, *mocks.RnibReaderMock, *mocks.RanListManagerMock, *mocks.RmrMessengerMock) {
48 config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
50 readerMock := &mocks.RnibReaderMock{}
51 writerMock := &mocks.RnibWriterMock{}
53 rnibDataService := services.NewRnibDataService(logger, config, readerMock, writerMock)
54 rmrMessengerMock := &mocks.RmrMessengerMock{}
55 ranListManagerMock := &mocks.RanListManagerMock{}
57 rmrSender := getRmrSender(rmrMessengerMock, logger)
58 handler := NewHealthCheckRequestHandler(logger, rnibDataService, ranListManagerMock, rmrSender)
60 return handler, rnibDataService, readerMock, ranListManagerMock, rmrMessengerMock
63 func TestHealthCheckRequestHandlerArguementHasRanNameSuccess(t *testing.T) {
64 handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
65 ranNames := []string{"RanName_1"}
67 nb1:= createNbIdentity(t,"RanName_1", entities.ConnectionStatus_CONNECTED)
68 oldnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus}
69 newnbIdentity := &entities.NbIdentity{InventoryName: nb1.RanName, ConnectionStatus: nb1.ConnectionStatus}
71 readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil)
73 mbuf:= createRMRMbuf(t, nb1)
74 rmrMessengerMock.On("SendMsg",mbuf,true).Return(mbuf,nil)
75 ranListManagerMock.On("UpdateHealthcheckTimeStampSent",nb1.RanName).Return(oldnbIdentity, newnbIdentity)
76 ranListManagerMock.On("UpdateNbIdentities",nb1.NodeType, []*entities.NbIdentity{oldnbIdentity}, []*entities.NbIdentity{newnbIdentity}).Return(nil)
78 resp, err := handler.Handle(models.HealthCheckRequest{ranNames})
80 assert.IsType(t, &models.HealthCheckSuccessResponse{}, resp)
82 readerMock.AssertExpectations(t)
85 func TestHealthCheckRequestHandlerArguementHasNoRanNameSuccess(t *testing.T) {
86 handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
88 nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_CONNECTED},
89 {InventoryName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}}
91 ranListManagerMock.On("GetNbIdentityList").Return(nbIdentityList)
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}
97 readerMock.On("GetNodeb", nb1.RanName).Return(nb1, nil)
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)
104 nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
105 readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
107 resp, err := handler.Handle(models.HealthCheckRequest{[]string{}})
110 assert.IsType(t, &models.HealthCheckSuccessResponse{}, resp)
114 func TestHealthCheckRequestHandlerArguementHasNoRanConnectedFailure(t *testing.T) {
115 handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
117 nbIdentityList := []*entities.NbIdentity{{InventoryName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED},
118 {InventoryName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}}
119 ranListManagerMock.On("GetNbIdentityList").Return(nbIdentityList)
121 nb1 := &entities.NodebInfo{RanName: "RanName_1", ConnectionStatus: entities.ConnectionStatus_DISCONNECTED}
122 readerMock.On("GetNodeb", "RanName_1").Return(nb1, nil)
124 nb2 := &entities.NodebInfo{RanName: "RanName_2", ConnectionStatus: entities.ConnectionStatus_SHUT_DOWN}
125 readerMock.On("GetNodeb", "RanName_2").Return(nb2, nil)
127 _, err := handler.Handle(models.HealthCheckRequest{[]string{}})
129 rmrMessengerMock.AssertNotCalled(t, "SendMsg", mock.Anything, mock.Anything)
130 ranListManagerMock.AssertNotCalled(t,"UpdateHealthcheckTimeStampSent",mock.Anything)
131 ranListManagerMock.AssertNotCalled(t,"UpdateNbIdentities",mock.Anything, mock.Anything, mock.Anything)
132 assert.IsType(t, &e2managererrors.NoConnectedRanError{}, err)
136 func TestHealthCheckRequestHandlerArguementHasRanNameDBErrorFailure(t *testing.T) {
137 handler, _, readerMock, ranListManagerMock, rmrMessengerMock := setupHealthCheckHandlerTest(t)
139 ranNames := []string{"RanName_1"}
140 readerMock.On("GetNodeb", "RanName_1").Return(&entities.NodebInfo{}, errors.New("error"))
142 _, err := handler.Handle(models.HealthCheckRequest{ranNames})
144 rmrMessengerMock.AssertNotCalled(t, "SendMsg", mock.Anything, mock.Anything)
145 ranListManagerMock.AssertNotCalled(t,"UpdateHealthcheckTimeStampSent",mock.Anything)
146 ranListManagerMock.AssertNotCalled(t,"UpdateNbIdentities",mock.Anything, mock.Anything, mock.Anything)
147 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
148 readerMock.AssertExpectations(t)
151 func createRMRMbuf(t *testing.T, nodebInfo *entities.NodebInfo) *rmrCgo.MBuf{
152 serviceQuery := models.NewRicServiceQueryMessage(nodebInfo.GetGnb().RanFunctions)
153 payLoad, err := xml.Marshal(&serviceQuery.E2APPDU)
154 payLoad = utils.NormalizeXml(payLoad)
155 tagsToReplace := []string{"reject","ignore","protocolIEs"}
156 payLoad = utils.ReplaceEmptyTagsWithSelfClosing(payLoad, tagsToReplace)
163 var msgSrc unsafe.Pointer
165 rmrMessage := models.NewRmrMessage(rmrCgo.RIC_SERVICE_QUERY, nodebInfo.RanName, payLoad, xAction, msgSrc)
166 return rmrCgo.NewMBuf(rmrMessage.MsgType, len(rmrMessage.Payload), rmrMessage.RanName, &rmrMessage.Payload, &rmrMessage.XAction, rmrMessage.GetMsgSrc())
169 func createNbIdentity(t *testing.T, RanName string, connectionStatus entities.ConnectionStatus) *entities.NodebInfo {
170 xmlgnb := utils.ReadXmlFile(t, GnbSetupRequestXmlPath)
171 payload := append([]byte(e2SetupMsgPrefix), xmlgnb...)
172 pipInd := bytes.IndexByte(payload, '|')
173 setupRequest := &models.E2SetupRequestMessage{}
174 err := xml.Unmarshal(utils.NormalizeXml(payload[pipInd+1:]), &setupRequest.E2APPDU)
179 nodeb := &entities.NodebInfo{
180 AssociatedE2TInstanceAddress: e2tInstanceFullAddress,
182 SetupFromNetwork: true,
183 NodeType: entities.Node_GNB,
184 ConnectionStatus: connectionStatus,
185 Configuration: &entities.NodebInfo_Gnb{
187 GnbType: entities.GnbType_GNB,
188 RanFunctions: setupRequest.ExtractRanFunctionsList(),
191 GlobalNbId: &entities.GlobalNbId{
192 PlmnId: setupRequest.GetPlmnId(),
193 NbId: setupRequest.GetNbId(),
199 func normalizeXml(payload []byte) []byte {
200 xmlStr := string(payload)
201 normalized := strings.NewReplacer("<", "<", ">", ">",
202 "<reject></reject>","<reject/>","<ignore></ignore>","<ignore/>",
203 "<protocolIEs></protocolIEs>","<protocolIEs/>").Replace(xmlStr)
204 return []byte(normalized)