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 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
79 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
80 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
81 updatedE2tInstance := *e2tInstance
82 updatedE2tInstance.AssociatedRanList = append(updatedE2tInstance.AssociatedRanList, RanName)
83 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
85 err := manager.AssociateRan(E2TAddress, nb)
88 readerMock.AssertExpectations(t)
89 writerMock.AssertExpectations(t)
90 httpClientMock.AssertExpectations(t)
93 func TestAssociateRanRoutingManagerError(t *testing.T) {
94 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
95 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, false)
97 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
98 err := manager.AssociateRan(E2TAddress, nb)
100 assert.NotNil(t, err)
101 assert.IsType(t, &e2managererrors.RoutingManagerError{}, err)
102 readerMock.AssertExpectations(t)
103 writerMock.AssertExpectations(t)
104 httpClientMock.AssertExpectations(t)
107 func TestAssociateRanUpdateNodebError(t *testing.T) {
108 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
109 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
110 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
112 updatedNb.ConnectionAttempts = 0
113 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
114 writerMock.On("UpdateNodebInfo", &updatedNb).Return(e2managererrors.NewRnibDbError())
116 err := manager.AssociateRan(E2TAddress, nb)
118 assert.NotNil(t, err)
119 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
120 readerMock.AssertExpectations(t)
121 writerMock.AssertExpectations(t)
122 httpClientMock.AssertExpectations(t)
125 func TestAssociateRanGetE2tInstanceError(t *testing.T) {
126 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
127 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
128 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
130 updatedNb.ConnectionAttempts = 0
131 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
132 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
133 var e2tInstance *entities.E2TInstance
134 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, errors.New("test"))
136 err := manager.AssociateRan(E2TAddress, nb)
138 assert.NotNil(t, err)
139 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
140 readerMock.AssertExpectations(t)
141 writerMock.AssertExpectations(t)
142 httpClientMock.AssertExpectations(t)
145 func TestAssociateRanSaveE2tInstanceError(t *testing.T) {
146 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
147 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
148 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
150 updatedNb.ConnectionAttempts = 0
151 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
152 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
153 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
154 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
155 updatedE2tInstance := *e2tInstance
156 updatedE2tInstance.AssociatedRanList = append(updatedE2tInstance.AssociatedRanList, RanName)
157 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(errors.New("test"))
159 err := manager.AssociateRan(E2TAddress, nb)
161 assert.NotNil(t, err)
162 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
163 readerMock.AssertExpectations(t)
164 writerMock.AssertExpectations(t)
165 httpClientMock.AssertExpectations(t)
168 func TestDissociateRanSuccess(t *testing.T) {
169 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
170 mockHttpClient(httpClientMock, clients.DissociateRanE2TInstanceApiSuffix, true)
171 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
172 readerMock.On("GetNodeb", RanName).Return(nb, nil)
174 updatedNb.AssociatedE2TInstanceAddress = ""
175 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
176 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
177 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
178 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
179 updatedE2tInstance := *e2tInstance
180 updatedE2tInstance.AssociatedRanList = []string{}
181 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
183 err := manager.DissociateRan(E2TAddress, RanName)
186 readerMock.AssertExpectations(t)
187 writerMock.AssertExpectations(t)
188 httpClientMock.AssertExpectations(t)
191 func TestDissociateRanGetNodebError(t *testing.T) {
192 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
193 var nb *entities.NodebInfo
194 readerMock.On("GetNodeb", RanName).Return(nb, e2managererrors.NewRnibDbError())
196 err := manager.DissociateRan(E2TAddress, RanName)
198 assert.NotNil(t, err)
199 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
200 readerMock.AssertExpectations(t)
201 writerMock.AssertExpectations(t)
202 httpClientMock.AssertExpectations(t)
205 func TestDissociateRanUpdateNodebError(t *testing.T) {
206 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
207 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
208 readerMock.On("GetNodeb", RanName).Return(nb, nil)
210 updatedNb.AssociatedE2TInstanceAddress = ""
211 writerMock.On("UpdateNodebInfo", &updatedNb).Return(e2managererrors.NewRnibDbError())
213 err := manager.DissociateRan(E2TAddress, RanName)
215 assert.NotNil(t, err)
216 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
217 readerMock.AssertExpectations(t)
218 writerMock.AssertExpectations(t)
219 httpClientMock.AssertExpectations(t)
222 func TestDissociateRanGetE2tInstanceError(t *testing.T) {
223 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
224 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
225 readerMock.On("GetNodeb", RanName).Return(nb, nil)
227 updatedNb.AssociatedE2TInstanceAddress = ""
228 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
229 var e2tInstance *entities.E2TInstance
230 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, errors.New("test"))
232 err := manager.DissociateRan(E2TAddress, RanName)
234 assert.NotNil(t, err)
235 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
236 readerMock.AssertExpectations(t)
237 writerMock.AssertExpectations(t)
238 httpClientMock.AssertExpectations(t)
241 func TestDissociateRanSaveE2tInstanceError(t *testing.T) {
242 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
243 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
244 readerMock.On("GetNodeb", RanName).Return(nb, nil)
246 updatedNb.AssociatedE2TInstanceAddress = ""
247 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
248 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
249 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
250 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
251 updatedE2tInstance := *e2tInstance
252 updatedE2tInstance.AssociatedRanList = []string{}
253 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(errors.New("test"))
255 err := manager.DissociateRan(E2TAddress, RanName)
257 assert.NotNil(t, err)
258 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
259 readerMock.AssertExpectations(t)
260 writerMock.AssertExpectations(t)
261 httpClientMock.AssertExpectations(t)
264 func TestDissociateRanRoutingManagerError(t *testing.T) {
265 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
266 mockHttpClient(httpClientMock, clients.DissociateRanE2TInstanceApiSuffix, false)
267 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
268 readerMock.On("GetNodeb", RanName).Return(nb, nil)
270 updatedNb.AssociatedE2TInstanceAddress = ""
271 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
272 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
273 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
274 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
275 updatedE2tInstance := *e2tInstance
276 updatedE2tInstance.AssociatedRanList = []string{}
277 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
279 err := manager.DissociateRan(E2TAddress, RanName)
282 readerMock.AssertExpectations(t)
283 writerMock.AssertExpectations(t)
284 httpClientMock.AssertExpectations(t)
287 func TestRemoveE2tInstanceSuccessWithOrphans(t *testing.T) {
288 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
290 ranNamesToBeDissociated := []string{RanName, "test1"}
291 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, ranNamesToBeDissociated, nil)
292 mockHttpClientDelete(httpClientMock, data, true)
294 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
295 e2tAddresses := []string{E2TAddress}
296 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
297 e2tAddressesNew := []string{}
298 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
300 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:ranNamesToBeDissociated}
301 err := manager.RemoveE2tInstance(e2tInstance1)
304 readerMock.AssertExpectations(t)
305 writerMock.AssertExpectations(t)
306 httpClientMock.AssertExpectations(t)
309 func TestRemoveE2tInstanceFailureRoutingManager(t *testing.T) {
310 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
312 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1"}, nil)
313 mockHttpClientDelete(httpClientMock, data, false)
315 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
316 e2tAddresses := []string{E2TAddress}
317 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
318 e2tAddressesNew := []string{}
319 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
321 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:[]string{"test1"}}
322 //readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, e2managererrors.NewRnibDbError())
323 err := manager.RemoveE2tInstance(e2tInstance1)
326 readerMock.AssertExpectations(t)
327 writerMock.AssertExpectations(t)
328 httpClientMock.AssertExpectations(t)
331 func TestRemoveE2tInstanceFailureInE2TInstanceManager(t *testing.T) {
333 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1"}, nil)
334 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
335 mockHttpClientDelete(httpClientMock, data, true)
337 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
338 var e2tAddresses []string
339 readerMock.On("GetE2TAddresses").Return(e2tAddresses, e2managererrors.NewRnibDbError())
341 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:[]string{"test1"}}
342 err := manager.RemoveE2tInstance(e2tInstance1)
344 assert.NotNil(t, err)
345 readerMock.AssertExpectations(t)
346 writerMock.AssertExpectations(t)
347 httpClientMock.AssertExpectations(t)
350 func TestRemoveE2tInstanceFailureInE2tInstanceAddRansToInstance(t *testing.T) {
351 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
353 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, nil)
354 mockHttpClientDelete(httpClientMock, data, true)
356 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
357 e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
358 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
359 e2tAddressesNew := []string{E2TAddress2, E2TAddress3}
360 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
362 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress}
363 err := manager.RemoveE2tInstance(e2tInstance1)
366 readerMock.AssertExpectations(t)
367 writerMock.AssertExpectations(t)
368 httpClientMock.AssertExpectations(t)
371 func mockHttpClientDelete(httpClientMock *mocks.HttpClientMock, data *models.RoutingManagerDeleteRequestModel, isSuccessful bool) {
373 marshaled, _ := json.Marshal(data)
374 body := bytes.NewBuffer(marshaled)
375 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
376 var respStatusCode int
378 respStatusCode = http.StatusCreated
380 respStatusCode = http.StatusBadRequest
382 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: respStatusCode, Body: respBody}, nil)