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"
34 "github.com/stretchr/testify/mock"
40 const RanName = "test"
42 func initE2TAssociationManagerTest(t *testing.T) (*E2TAssociationManager, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.HttpClientMock) {
44 config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3}
46 readerMock := &mocks.RnibReaderMock{}
47 writerMock := &mocks.RnibWriterMock{}
48 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
50 e2tInstancesManager := NewE2TInstancesManager(rnibDataService, log)
51 httpClientMock := &mocks.HttpClientMock{}
52 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
53 manager := NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient)
55 return manager, readerMock, writerMock, httpClientMock
58 func mockHttpClient(httpClientMock *mocks.HttpClientMock, apiSuffix string, isSuccessful bool) {
59 data := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress, RanName)}
60 marshaled, _ := json.Marshal(data)
61 body := bytes.NewBuffer(marshaled)
62 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
63 var respStatusCode int
65 respStatusCode = http.StatusCreated
67 respStatusCode = http.StatusBadRequest
69 httpClientMock.On("Post", apiSuffix, "application/json", body).Return(&http.Response{StatusCode: respStatusCode, Body: respBody}, nil)
72 func TestAssociateRanSuccess(t *testing.T) {
73 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
74 mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
75 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
77 updatedNb.ConnectionAttempts = 0
78 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
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, readerMock, 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)
99 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
100 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
101 writerMock.On("SaveE2TInstance", mock.Anything).Return(nil)
102 err := manager.AssociateRan(E2TAddress, nb)
105 readerMock.AssertExpectations(t)
106 writerMock.AssertExpectations(t)
107 httpClientMock.AssertExpectations(t)
110 func TestAssociateRanUpdateNodebError(t *testing.T) {
111 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
112 //mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
113 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
115 updatedNb.ConnectionAttempts = 0
116 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
117 writerMock.On("UpdateNodebInfo", &updatedNb).Return(e2managererrors.NewRnibDbError())
119 err := manager.AssociateRan(E2TAddress, nb)
121 assert.NotNil(t, err)
122 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
123 readerMock.AssertExpectations(t)
124 writerMock.AssertExpectations(t)
125 httpClientMock.AssertExpectations(t)
128 func TestAssociateRanGetE2tInstanceError(t *testing.T) {
129 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
130 //mockHttpClient(httpClientMock, clients.AssociateRanToE2TInstanceApiSuffix, true)
131 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: "", ConnectionAttempts: 1}
133 updatedNb.ConnectionAttempts = 0
134 updatedNb.AssociatedE2TInstanceAddress = E2TAddress
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 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
156 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
157 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
158 updatedE2tInstance := *e2tInstance
159 updatedE2tInstance.AssociatedRanList = append(updatedE2tInstance.AssociatedRanList, RanName)
160 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(errors.New("test"))
162 err := manager.AssociateRan(E2TAddress, nb)
164 assert.NotNil(t, err)
165 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
166 readerMock.AssertExpectations(t)
167 writerMock.AssertExpectations(t)
168 httpClientMock.AssertExpectations(t)
171 func TestDissociateRanSuccess(t *testing.T) {
172 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
173 mockHttpClient(httpClientMock, clients.DissociateRanE2TInstanceApiSuffix, true)
174 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
175 readerMock.On("GetNodeb", RanName).Return(nb, nil)
177 updatedNb.AssociatedE2TInstanceAddress = ""
178 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
179 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
180 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
181 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
182 updatedE2tInstance := *e2tInstance
183 updatedE2tInstance.AssociatedRanList = []string{}
184 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
186 err := manager.DissociateRan(E2TAddress, RanName)
189 readerMock.AssertExpectations(t)
190 writerMock.AssertExpectations(t)
191 httpClientMock.AssertExpectations(t)
194 func TestDissociateRanGetNodebError(t *testing.T) {
195 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
196 var nb *entities.NodebInfo
197 readerMock.On("GetNodeb", RanName).Return(nb, e2managererrors.NewRnibDbError())
199 err := manager.DissociateRan(E2TAddress, RanName)
201 assert.NotNil(t, err)
202 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
203 readerMock.AssertExpectations(t)
204 writerMock.AssertExpectations(t)
205 httpClientMock.AssertExpectations(t)
208 func TestDissociateRanUpdateNodebError(t *testing.T) {
209 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
210 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
211 readerMock.On("GetNodeb", RanName).Return(nb, nil)
213 updatedNb.AssociatedE2TInstanceAddress = ""
214 writerMock.On("UpdateNodebInfo", &updatedNb).Return(e2managererrors.NewRnibDbError())
216 err := manager.DissociateRan(E2TAddress, RanName)
218 assert.NotNil(t, err)
219 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
220 readerMock.AssertExpectations(t)
221 writerMock.AssertExpectations(t)
222 httpClientMock.AssertExpectations(t)
225 func TestDissociateRanGetE2tInstanceError(t *testing.T) {
226 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
227 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
228 readerMock.On("GetNodeb", RanName).Return(nb, nil)
230 updatedNb.AssociatedE2TInstanceAddress = ""
231 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
232 var e2tInstance *entities.E2TInstance
233 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, errors.New("test"))
235 err := manager.DissociateRan(E2TAddress, RanName)
237 assert.NotNil(t, err)
238 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
239 readerMock.AssertExpectations(t)
240 writerMock.AssertExpectations(t)
241 httpClientMock.AssertExpectations(t)
244 func TestDissociateRanSaveE2tInstanceError(t *testing.T) {
245 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
246 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
247 readerMock.On("GetNodeb", RanName).Return(nb, nil)
249 updatedNb.AssociatedE2TInstanceAddress = ""
250 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
251 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
252 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
253 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
254 updatedE2tInstance := *e2tInstance
255 updatedE2tInstance.AssociatedRanList = []string{}
256 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(errors.New("test"))
258 err := manager.DissociateRan(E2TAddress, RanName)
260 assert.NotNil(t, err)
261 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
262 readerMock.AssertExpectations(t)
263 writerMock.AssertExpectations(t)
264 httpClientMock.AssertExpectations(t)
267 func TestDissociateRanRoutingManagerError(t *testing.T) {
268 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
269 mockHttpClient(httpClientMock, clients.DissociateRanE2TInstanceApiSuffix, false)
270 nb := &entities.NodebInfo{RanName: RanName, AssociatedE2TInstanceAddress: E2TAddress, ConnectionAttempts: 1}
271 readerMock.On("GetNodeb", RanName).Return(nb, nil)
273 updatedNb.AssociatedE2TInstanceAddress = ""
274 writerMock.On("UpdateNodebInfo", &updatedNb).Return(nil)
275 e2tInstance := &entities.E2TInstance{Address: E2TAddress}
276 e2tInstance.AssociatedRanList = append(e2tInstance.AssociatedRanList, RanName)
277 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance, nil)
278 updatedE2tInstance := *e2tInstance
279 updatedE2tInstance.AssociatedRanList = []string{}
280 writerMock.On("SaveE2TInstance", &updatedE2tInstance).Return(nil)
282 err := manager.DissociateRan(E2TAddress, RanName)
285 readerMock.AssertExpectations(t)
286 writerMock.AssertExpectations(t)
287 httpClientMock.AssertExpectations(t)
290 func TestRemoveE2tInstanceSuccessWithOrphans(t *testing.T) {
291 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
293 ranNamesToBeDissociated := []string{RanName, "test1"}
294 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, ranNamesToBeDissociated, nil)
295 mockHttpClientDelete(httpClientMock, data, true)
297 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
298 e2tAddresses := []string{E2TAddress}
299 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
300 e2tAddressesNew := []string{}
301 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
303 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:ranNamesToBeDissociated}
304 err := manager.RemoveE2tInstance(e2tInstance1)
307 readerMock.AssertExpectations(t)
308 writerMock.AssertExpectations(t)
309 httpClientMock.AssertExpectations(t)
312 func TestRemoveE2tInstanceFailureRoutingManager(t *testing.T) {
313 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
315 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1"}, nil)
316 mockHttpClientDelete(httpClientMock, data, false)
318 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
319 e2tAddresses := []string{E2TAddress}
320 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
321 e2tAddressesNew := []string{}
322 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
324 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:[]string{"test1"}}
325 //readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, e2managererrors.NewRnibDbError())
326 err := manager.RemoveE2tInstance(e2tInstance1)
329 readerMock.AssertExpectations(t)
330 writerMock.AssertExpectations(t)
331 httpClientMock.AssertExpectations(t)
334 func TestRemoveE2tInstanceFailureInE2TInstanceManager(t *testing.T) {
336 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1"}, nil)
337 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
338 mockHttpClientDelete(httpClientMock, data, true)
340 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
341 var e2tAddresses []string
342 readerMock.On("GetE2TAddresses").Return(e2tAddresses, e2managererrors.NewRnibDbError())
344 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress, AssociatedRanList:[]string{"test1"}}
345 err := manager.RemoveE2tInstance(e2tInstance1)
347 assert.NotNil(t, err)
348 readerMock.AssertExpectations(t)
349 writerMock.AssertExpectations(t)
350 httpClientMock.AssertExpectations(t)
353 func TestRemoveE2tInstanceFailureInE2tInstanceAddRansToInstance(t *testing.T) {
354 manager, readerMock, writerMock, httpClientMock := initE2TAssociationManagerTest(t)
356 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, nil)
357 mockHttpClientDelete(httpClientMock, data, true)
359 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
360 e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
361 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
362 e2tAddressesNew := []string{E2TAddress2, E2TAddress3}
363 writerMock.On("SaveE2TAddresses", e2tAddressesNew).Return(nil)
365 e2tInstance1 := &entities.E2TInstance{Address: E2TAddress}
366 err := manager.RemoveE2tInstance(e2tInstance1)
369 readerMock.AssertExpectations(t)
370 writerMock.AssertExpectations(t)
371 httpClientMock.AssertExpectations(t)
374 func mockHttpClientDelete(httpClientMock *mocks.HttpClientMock, data *models.RoutingManagerDeleteRequestModel, isSuccessful bool) {
376 marshaled, _ := json.Marshal(data)
377 body := bytes.NewBuffer(marshaled)
378 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
379 var respStatusCode int
381 respStatusCode = http.StatusCreated
383 respStatusCode = http.StatusBadRequest
385 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: respStatusCode, Body: respBody}, nil)