2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
17 // This source code is part of the near-RT RIC (RAN Intelligent Controller)
18 // platform project (RICP).
26 "e2mgr/e2managererrors"
31 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
32 "github.com/pkg/errors"
33 "github.com/stretchr/testify/assert"
39 const RanName = "test"
41 func initE2TAssociationManagerTest(t *testing.T) (*E2TAssociationManager, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.HttpClientMock) {
43 config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
45 readerMock := &mocks.RnibReaderMock{}
46 writerMock := &mocks.RnibWriterMock{}
47 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
49 e2tInstancesManager := NewE2TInstancesManager(rnibDataService, log)
50 httpClientMock := &mocks.HttpClientMock{}
51 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
52 manager := NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient)
54 return manager, readerMock, writerMock, httpClientMock
57 func mockHttpClient(httpClientMock *mocks.HttpClientMock, apiSuffix string, isSuccessful bool) {
58 data := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress, RanName)}
59 marshaled, _ := json.Marshal(data)
60 body := bytes.NewBuffer(marshaled)
61 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
62 var respStatusCode int
64 respStatusCode = http.StatusCreated
66 respStatusCode = http.StatusBadRequest
68 httpClientMock.On("Post", apiSuffix, "application/json", body).Return(&http.Response{StatusCode: respStatusCode, Body: respBody}, nil)
71 func TestAssociateRanSuccess(t *testing.T) {
72 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
73 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
74 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
76 updatedNb.ConnectionAttempts = 0
77 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
78 updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
79 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
80 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
81 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
82 updatedE2tInstance := *e2tInstance
83 updatedE2tInstance.AssociatedRanList = append(updatedE2tInstance.AssociatedRanList, RanName)
84 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
86 err := manager.AssociateRan(E2TAddress, nb)
89 readerMock.AssertExpectations(t)
90 writerMock.AssertExpectations(t)
91 httpClientMock.AssertExpectations(t)
94 func TestAssociateRanRoutingManagerError(t *testing.T) {
95 manager, _, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
96 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, false)
97 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
98 writerMock.On("UpdateNodebInfo", nb).Return(nil)
100 err := manager.AssociateRan(E2TAddress, nb)
102 assert.NotNil(t, err)
103 assert.IsType(t, &e2managererrors.RoutingManagerError{}, err)
104 writerMock.AssertExpectations(t)
105 httpClientMock.AssertExpectations(t)
108 func TestAssociateRanUpdateNodebError(t *testing.T) {
109 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
110 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
111 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
113 updatedNb.ConnectionAttempts = 0
114 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
115 updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
116 writerMock.On("UpdateNodebInfo", &updatedNb).Return(e2managererrors.NewRnibDbError())
118 err := manager.AssociateRan(E2TAddress, nb)
120 assert.NotNil(t, err)
121 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
122 readerMock.AssertExpectations(t)
123 writerMock.AssertExpectations(t)
124 httpClientMock.AssertExpectations(t)
127 func TestAssociateRanGetE2tInstanceError(t *testing.T) {
128 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
129 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
130 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
132 updatedNb.ConnectionAttempts = 0
133 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
134 updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
135 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
136 var e2tInstance *entities.E2TInstance
137 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, errors.New("test"))
139 err := manager.AssociateRan(E2TAddress, nb)
141 assert.NotNil(t, err)
142 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
143 readerMock.AssertExpectations(t)
144 writerMock.AssertExpectations(t)
145 httpClientMock.AssertExpectations(t)
148 func TestAssociateRanSaveE2tInstanceError(t *testing.T) {
149 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
150 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
151 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
153 updatedNb.ConnectionAttempts = 0
154 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
155 updatedNb.ConnectionStatus = entities.ConnectionStatus_CONNECTED
156 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
157 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
158 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
159 updatedE2tInstance := *e2tInstance
160 updatedE2tInstance.AssociatedRanList = append(updatedE2tInstance.AssociatedRanList, RanName)
161 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(errors.New("test"))
163 err := manager.AssociateRan(E2TAddress, nb)
165 assert.NotNil(t, err)
166 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
167 readerMock.AssertExpectations(t)
168 writerMock.AssertExpectations(t)
169 httpClientMock.AssertExpectations(t)
172 func TestDissociateRanSuccess(t *testing.T) {
173 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
174 mockHttpClient(httpClientMock, clients.DissociateRanE2TInstanceApiSuffix, true)
175 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
176 readerMock.On("GetNodeb", RanName).Return(nb, nil)
178 updatedNb.AssociatedE2TInstanceAddress = ""
179 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
180 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
181 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
182 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
183 updatedE2tInstance := *e2tInstance
184 updatedE2tInstance.AssociatedRanList = []string{}
185 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
187 err := manager.DissociateRan(E2TAddress, RanName)
190 readerMock.AssertExpectations(t)
191 writerMock.AssertExpectations(t)
192 httpClientMock.AssertExpectations(t)
195 func TestDissociateRanGetNodebError(t *testing.T) {
196 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
197 var nb *entities.NodebInfo
198 readerMock.On("GetNodeb", RanName).Return(nb, e2managererrors.NewRnibDbError())
200 err := manager.DissociateRan(E2TAddress, RanName)
202 assert.NotNil(t, err)
203 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
204 readerMock.AssertExpectations(t)
205 writerMock.AssertExpectations(t)
206 httpClientMock.AssertExpectations(t)
209 func TestDissociateRanUpdateNodebError(t *testing.T) {
210 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
211 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
212 readerMock.On("GetNodeb", RanName).Return(nb, nil)
214 updatedNb.AssociatedE2TInstanceAddress = ""
215 writerMock.On("UpdateNodebInfo", &updatedNb).Return(e2managererrors.NewRnibDbError())
217 err := manager.DissociateRan(E2TAddress, RanName)
219 assert.NotNil(t, err)
220 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
221 readerMock.AssertExpectations(t)
222 writerMock.AssertExpectations(t)
223 httpClientMock.AssertExpectations(t)
226 func TestDissociateRanGetE2tInstanceError(t *testing.T) {
227 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
228 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
229 readerMock.On("GetNodeb", RanName).Return(nb, nil)
231 updatedNb.AssociatedE2TInstanceAddress = ""
232 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
233 var e2tInstance *entities.E2TInstance
234 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, errors.New("test"))
236 err := manager.DissociateRan(E2TAddress, RanName)
238 assert.NotNil(t, err)
239 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
240 readerMock.AssertExpectations(t)
241 writerMock.AssertExpectations(t)
242 httpClientMock.AssertExpectations(t)
245 func TestDissociateRanSaveE2tInstanceError(t *testing.T) {
246 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
247 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
248 readerMock.On("GetNodeb", RanName).Return(nb, nil)
250 updatedNb.AssociatedE2TInstanceAddress = ""
251 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
252 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
253 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
254 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
255 updatedE2tInstance := *e2tInstance
256 updatedE2tInstance.AssociatedRanList = []string{}
257 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(errors.New("test"))
259 err := manager.DissociateRan(E2TAddress, RanName)
261 assert.NotNil(t, err)
262 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
263 readerMock.AssertExpectations(t)
264 writerMock.AssertExpectations(t)
265 httpClientMock.AssertExpectations(t)
268 func TestDissociateRanRoutingManagerError(t *testing.T) {
269 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
270 mockHttpClient(httpClientMock, clients.DissociateRanE2TInstanceApiSuffix, false)
271 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
272 readerMock.On("GetNodeb", RanName).Return(nb, nil)
274 updatedNb.AssociatedE2TInstanceAddress = ""
275 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
276 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
277 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
278 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
279 updatedE2tInstance := *e2tInstance
280 updatedE2tInstance.AssociatedRanList = []string{}
281 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
283 err := manager.DissociateRan(E2TAddress, RanName)
286 readerMock.AssertExpectations(t)
287 writerMock.AssertExpectations(t)
288 httpClientMock.AssertExpectations(t)
291 func TestRemoveE2tInstanceSuccessWithOrphans(t *testing.T) {
292 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
294 ranNamesToBeDissociated := []string{RanName, "test1"}
295 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, ranNamesToBeDissociated, nil)
296 mockHttpClientDelete(httpClientMock, data, true)
298 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
299 e2tAddresses := []string{E2TAddress}
300 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
301 e2tAddressesNew := []string{}
302 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
304 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:ranNamesToBeDissociated}
305 err := manager.RemoveE2tInstance(e2tInstance1)
308 readerMock.AssertExpectations(t)
309 writerMock.AssertExpectations(t)
310 httpClientMock.AssertExpectations(t)
313 func TestRemoveE2tInstanceFailureRoutingManager(t *testing.T) {
314 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
316 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1"}, nil)
317 mockHttpClientDelete(httpClientMock, data, false)
319 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
320 e2tAddresses := []string{E2TAddress}
321 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
322 e2tAddressesNew := []string{}
323 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
325 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:[]string{"test1"}}
326 //readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, e2managererrors.NewRnibDbError())
327 err := manager.RemoveE2tInstance(e2tInstance1)
330 readerMock.AssertExpectations(t)
331 writerMock.AssertExpectations(t)
332 httpClientMock.AssertExpectations(t)
335 func TestRemoveE2tInstanceFailureInE2TInstanceManager(t *testing.T) {
337 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1"}, nil)
338 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
339 mockHttpClientDelete(httpClientMock, data, true)
341 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
342 var e2tAddresses []string
343 readerMock.On("GetE2TAddresses").Return(e2tAddresses, e2managererrors.NewRnibDbError())
345 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:[]string{"test1"}}
346 err := manager.RemoveE2tInstance(e2tInstance1)
348 assert.NotNil(t, err)
349 readerMock.AssertExpectations(t)
350 writerMock.AssertExpectations(t)
351 httpClientMock.AssertExpectations(t)
354 func TestRemoveE2tInstanceFailureInE2tInstanceAddRansToInstance(t *testing.T) {
355 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
357 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, nil)
358 mockHttpClientDelete(httpClientMock, data, true)
360 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
361 e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
362 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
363 e2tAddressesNew := []string{E2TAddress2, E2TAddress3}
364 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
366 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress}
367 err := manager.RemoveE2tInstance(e2tInstance1)
370 readerMock.AssertExpectations(t)
371 writerMock.AssertExpectations(t)
372 httpClientMock.AssertExpectations(t)
375 func mockHttpClientDelete(httpClientMock *mocks.HttpClientMock, data *models.RoutingManagerDeleteRequestModel, isSuccessful bool) {
377 marshaled, _ := json.Marshal(data)
378 body := bytes.NewBuffer(marshaled)
379 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
380 var respStatusCode int
382 respStatusCode = http.StatusCreated
384 respStatusCode = http.StatusBadRequest
386 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: respStatusCode, Body: respBody}, nil)