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.
18 // This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 // platform project (RICP).
27 "e2mgr/e2managererrors"
35 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
36 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
37 "github.com/stretchr/testify/assert"
38 "github.com/stretchr/testify/mock"
40 //"k8s.io/apimachinery/pkg/runtime"
41 //"k8s.io/client-go/kubernetes/fake"
47 const E2TAddress3 = "10.10.2.17:9800"
49 func initE2TShutdownManagerTest(t *testing.T) (*E2TShutdownManager, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.HttpClientMock) {
51 config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3, E2TInstanceDeletionTimeoutMs: 15000, RnibWriter: configuration.RnibWriterConfig{StateChangeMessageChannel: "RAN_CONNECTION_STATUS_CHANGE"}}
53 readerMock := &mocks.RnibReaderMock{}
54 writerMock := &mocks.RnibWriterMock{}
55 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
57 e2tInstancesManager := NewE2TInstancesManager(rnibDataService, log)
58 httpClientMock := &mocks.HttpClientMock{}
59 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
61 ranListManager := NewRanListManager(log, rnibDataService)
62 ranAlarmService := services.NewRanAlarmService(log, config)
63 ranConnectStatusChangeManager := NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
64 associationManager := NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager)
65 shutdownManager := NewE2TShutdownManager(log, config, rnibDataService, e2tInstancesManager, associationManager, ranConnectStatusChangeManager)
67 return shutdownManager, readerMock, writerMock, httpClientMock
70 func TestShutdownSuccess1OutOf3Instances(t *testing.T) {
71 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
73 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
74 e2tInstance1.State = entities.Active
75 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
76 e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
77 e2tInstance2.State = entities.Active
78 e2tInstance2.AssociatedRanList = []string{"test3"}
79 e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
80 e2tInstance3.State = entities.Active
81 e2tInstance3.AssociatedRanList = []string{"test4"}
82 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
83 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
86 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
87 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
88 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
89 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
90 nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
91 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
93 e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
94 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
96 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
97 marshaled, _ := json.Marshal(data)
98 body := bytes.NewBuffer(marshaled)
99 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
100 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
102 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
103 writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
106 nodeb1connected := *nodeb1
107 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
108 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test1_DISCONNECTED").Return(nil)
110 nodeb1NotAssociated := *nodeb1
111 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
112 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
113 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
116 nodeb2connected := *nodeb2
117 nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
118 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
120 nodeb2NotAssociated := *nodeb2
121 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
122 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
123 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
126 nodeb5connected := *nodeb5
127 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
128 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test5_DISCONNECTED").Return(nil)
130 nodeb5NotAssociated := *nodeb5
131 nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
132 nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
133 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
135 err := shutdownManager.Shutdown(e2tInstance1)
138 readerMock.AssertExpectations(t)
139 writerMock.AssertExpectations(t)
140 httpClientMock.AssertExpectations(t)
143 func TestShutdownSuccess1InstanceWithoutRans(t *testing.T) {
144 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
146 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
147 e2tInstance1.State = entities.Active
148 e2tInstance1.AssociatedRanList = []string{}
149 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
150 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
153 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, nil)
154 marshaled, _ := json.Marshal(data)
155 body := bytes.NewBuffer(marshaled)
156 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
157 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
159 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
160 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
161 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
163 err := shutdownManager.Shutdown(e2tInstance1)
166 readerMock.AssertExpectations(t)
167 writerMock.AssertExpectations(t)
168 httpClientMock.AssertExpectations(t)
171 func TestShutdownSuccess1Instance2Rans(t *testing.T) {
172 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
174 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
175 e2tInstance1.State = entities.Active
176 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
177 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
178 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
181 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
182 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
183 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
184 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
186 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
187 marshaled, _ := json.Marshal(data)
188 body := bytes.NewBuffer(marshaled)
189 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
190 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
192 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
193 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
194 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
196 /*** nodeb 1 connected ***/
198 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
199 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test1_DISCONNECTED").Return(nil)
201 nodeb1NotAssociated := *nodeb1
202 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
203 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
204 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
206 /*** nodeb 2 disconnected ***/
208 nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
209 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
211 nodeb2NotAssociated := *nodeb2
212 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
213 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
214 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
216 err := shutdownManager.Shutdown(e2tInstance1)
219 readerMock.AssertExpectations(t)
220 writerMock.AssertExpectations(t)
221 httpClientMock.AssertExpectations(t)
224 func TestShutdownE2tInstanceAlreadyBeingDeleted(t *testing.T) {
225 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
227 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
228 e2tInstance1.State = entities.ToBeDeleted
229 e2tInstance1.AssociatedRanList = []string{"test1"}
230 e2tInstance1.DeletionTimestamp = time.Now().UnixNano()
232 err := shutdownManager.Shutdown(e2tInstance1)
235 readerMock.AssertExpectations(t)
236 writerMock.AssertExpectations(t)
237 httpClientMock.AssertExpectations(t)
240 func TestShutdownFailureMarkInstanceAsToBeDeleted(t *testing.T) {
241 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
243 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
244 e2tInstance1.State = entities.Active
245 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
246 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
247 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
248 })).Return(e2managererrors.NewRnibDbError())
250 err := shutdownManager.Shutdown(e2tInstance1)
252 assert.NotNil(t, err)
253 readerMock.AssertExpectations(t)
254 writerMock.AssertExpectations(t)
255 httpClientMock.AssertExpectations(t)
258 func TestShutdownFailureRoutingManagerError(t *testing.T) {
259 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
261 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
262 e2tInstance1.State = entities.Active
263 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
264 e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
265 e2tInstance2.State = entities.Active
266 e2tInstance2.AssociatedRanList = []string{"test3"}
267 e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
268 e2tInstance3.State = entities.Active
269 e2tInstance3.AssociatedRanList = []string{"test4"}
270 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
271 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
274 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
275 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
276 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
277 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
278 nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
279 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
281 e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
282 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
284 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
285 marshaled, _ := json.Marshal(data)
286 body := bytes.NewBuffer(marshaled)
287 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
288 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusBadRequest, Body: respBody}, nil)
290 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
291 writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
293 /*** nodeb 1 connected ***/
294 nodeb1connected := *nodeb1
295 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
296 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test1_DISCONNECTED").Return(nil)
298 nodeb1NotAssociated := *nodeb1
299 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
300 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
301 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
303 /*** nodeb 2 shutting down ***/
304 nodeb2connected := *nodeb2
305 nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
306 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
308 nodeb2NotAssociated := *nodeb2
309 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
310 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
311 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
313 /*** nodeb 5 connected ***/
314 nodeb5connected := *nodeb5
315 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
316 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test5_DISCONNECTED").Return(nil)
318 nodeb5NotAssociated := *nodeb5
319 nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
320 nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
321 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
323 err := shutdownManager.Shutdown(e2tInstance1)
326 readerMock.AssertExpectations(t)
327 writerMock.AssertExpectations(t)
328 httpClientMock.AssertExpectations(t)
331 func TestShutdownFailureInClearNodebsAssociation(t *testing.T) {
332 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
334 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
335 e2tInstance1.State = entities.Active
336 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
337 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
338 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
341 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
342 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
345 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
346 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test1_DISCONNECTED").Return(nil)
348 nodeb1NotAssociated := *nodeb1
349 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
350 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
351 writerMock.On("UpdateNodebInfo", mock.Anything).Return(common.NewInternalError(fmt.Errorf("for tests")))
353 err := shutdownManager.Shutdown(e2tInstance1)
355 assert.NotNil(t, err)
356 readerMock.AssertExpectations(t)
357 writerMock.AssertExpectations(t)
358 httpClientMock.AssertExpectations(t)
361 func TestShutdownFailureInClearNodebsAssociation_UpdateConnectionStatus(t *testing.T) {
362 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
364 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
365 e2tInstance1.State = entities.Active
366 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
367 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
368 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
371 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
372 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
375 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
376 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test1_DISCONNECTED").Return(common.NewInternalError(fmt.Errorf("for tests")))
378 err := shutdownManager.Shutdown(e2tInstance1)
380 assert.NotNil(t, err)
381 readerMock.AssertExpectations(t)
382 writerMock.AssertExpectations(t)
383 httpClientMock.AssertExpectations(t)
386 func TestShutdownResourceNotFoundErrorInGetNodeb(t *testing.T) {
387 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
389 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
390 e2tInstance1.State = entities.Active
391 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
392 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
393 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
396 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
397 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
398 var nodeb2 *entities.NodebInfo
399 readerMock.On("GetNodeb", "test2").Return(nodeb2, common.NewResourceNotFoundError("for testing"))
402 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
403 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test1_DISCONNECTED").Return(nil)
405 nodeb1NotAssociated := *nodeb1
406 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
407 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
408 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
410 err := shutdownManager.Shutdown(e2tInstance1)
412 assert.NotNil(t, err)
413 readerMock.AssertExpectations(t)
414 writerMock.AssertExpectations(t)
415 httpClientMock.AssertExpectations(t)
418 func TestShutdownResourceGeneralErrorInGetNodeb(t *testing.T) {
419 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
421 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
422 e2tInstance1.State = entities.Active
423 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
424 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
425 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
428 var nodeb1 *entities.NodebInfo
429 readerMock.On("GetNodeb", "test1").Return(nodeb1, common.NewInternalError(fmt.Errorf("for testing")))
430 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
431 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
433 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
434 marshaled, _ := json.Marshal(data)
435 body := bytes.NewBuffer(marshaled)
436 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
437 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
439 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
440 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
441 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
444 nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
445 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
447 nodeb2NotAssociated := *nodeb2
448 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
449 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
450 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
452 err := shutdownManager.Shutdown(e2tInstance1)
455 readerMock.AssertExpectations(t)
456 writerMock.AssertExpectations(t)
457 httpClientMock.AssertExpectations(t)
461 func TestShutdownFailureInRemoveE2TInstance(t *testing.T) {
462 shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
464 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
465 e2tInstance1.State = entities.Active
466 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
467 e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
468 e2tInstance2.State = entities.Active
469 e2tInstance2.AssociatedRanList = []string{"test3"}
470 e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
471 e2tInstance3.State = entities.Active
472 e2tInstance3.AssociatedRanList = []string{"test4"}
473 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool {
474 return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted
477 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
478 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
479 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
480 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
481 nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
482 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
484 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
485 marshaled, _ := json.Marshal(data)
486 body := bytes.NewBuffer(marshaled)
487 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
488 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
490 writerMock.On("RemoveE2TInstance", E2TAddress).Return(common.NewInternalError(fmt.Errorf("for tests")))
492 /*** nodeb 1 connected ***/
493 nodeb1connected := *nodeb1
494 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
495 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test1_DISCONNECTED").Return(nil)
497 nodeb1NotAssociated := *nodeb1
498 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
499 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
500 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
502 /*** nodeb 2 shutting down ***/
503 nodeb2connected := *nodeb2
504 nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
505 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
507 nodeb2NotAssociated := *nodeb2
508 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
509 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
510 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
512 /*** nodeb 5 connected ***/
513 nodeb5connected := *nodeb5
514 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
515 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", mock.Anything, "test5_DISCONNECTED").Return(nil)
517 nodeb5NotAssociated := *nodeb5
518 nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
519 nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
520 writerMock.On("UpdateNodebInfo", mock.Anything).Return(nil)
522 err := shutdownManager.Shutdown(e2tInstance1)
524 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
525 readerMock.AssertExpectations(t)
526 writerMock.AssertExpectations(t)
527 httpClientMock.AssertExpectations(t)