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"
33 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
34 "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
35 "github.com/stretchr/testify/assert"
36 "github.com/stretchr/testify/mock"
38 //"k8s.io/apimachinery/pkg/runtime"
39 //"k8s.io/client-go/kubernetes/fake"
45 const E2TAddress3 = "10.10.2.17:9800"
47 func initE2TShutdownManagerTest(t *testing.T) (*E2TShutdownManager, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.HttpClientMock, *KubernetesManager) {
49 config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3, E2TInstanceDeletionTimeoutMs: 15000, RnibWriter: configuration.RnibWriterConfig{StateChangeMessageChannel: "RAN_CONNECTION_STATUS_CHANGE"}}
51 readerMock := &mocks.RnibReaderMock{}
52 writerMock := &mocks.RnibWriterMock{}
53 rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
55 e2tInstancesManager := NewE2TInstancesManager(rnibDataService, log)
56 httpClientMock := &mocks.HttpClientMock{}
57 rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
59 ranListManager := NewRanListManager(log)
60 ranAlarmService := services.NewRanAlarmService(log, config)
61 ranConnectStatusChangeManager := NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
62 associationManager := NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager)
63 //kubernetesManager := initKubernetesManagerTest(t)
65 /*shutdownManager := NewE2TShutdownManager(log, config, rnibDataService, e2tInstancesManager, associationManager, kubernetesManager)
67 return shutdownManager, readerMock, writerMock, httpClientMock, kubernetesManager*/
68 shutdownManager := NewE2TShutdownManager(log, config, rnibDataService, e2tInstancesManager, associationManager, nil, ranConnectStatusChangeManager)
70 return shutdownManager, readerMock, writerMock, httpClientMock, nil
73 func TestShutdownSuccess1OutOf3Instances(t *testing.T) {
74 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
76 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
77 e2tInstance1.State = entities.Active
78 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
79 e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
80 e2tInstance2.State = entities.Active
81 e2tInstance2.AssociatedRanList = []string{"test3"}
82 e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
83 e2tInstance3.State = entities.Active
84 e2tInstance3.AssociatedRanList = []string{"test4"}
85 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
87 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
88 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
89 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
90 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
91 nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
92 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
94 e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
95 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
97 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
98 marshaled, _ := json.Marshal(data)
99 body := bytes.NewBuffer(marshaled)
100 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
101 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
103 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
104 writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
107 nodeb1connected := *nodeb1
108 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
109 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1connected, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
111 nodeb1NotAssociated := *nodeb1
112 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
113 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
114 writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
117 nodeb2connected := *nodeb2
118 nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
119 writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
121 nodeb2NotAssociated := *nodeb2
122 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
123 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
124 writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
127 nodeb5connected := *nodeb5
128 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
129 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb5connected, "RAN_CONNECTION_STATUS_CHANGE", "test5_DISCONNECTED").Return(nil)
131 nodeb5NotAssociated := *nodeb5
132 nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
133 nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
134 writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
136 err := shutdownManager.Shutdown(e2tInstance1)
139 readerMock.AssertExpectations(t)
140 writerMock.AssertExpectations(t)
141 httpClientMock.AssertExpectations(t)
144 func TestShutdownSuccess1InstanceWithoutRans(t *testing.T) {
145 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
147 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
148 e2tInstance1.State = entities.Active
149 e2tInstance1.AssociatedRanList = []string{}
150 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
152 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, nil)
153 marshaled, _ := json.Marshal(data)
154 body := bytes.NewBuffer(marshaled)
155 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
156 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
158 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
159 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
160 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
162 err := shutdownManager.Shutdown(e2tInstance1)
165 readerMock.AssertExpectations(t)
166 writerMock.AssertExpectations(t)
167 httpClientMock.AssertExpectations(t)
170 func TestShutdownSuccess1Instance2Rans(t *testing.T) {
171 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
173 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
174 e2tInstance1.State = entities.Active
175 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
176 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
178 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
179 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
180 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
181 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
183 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
184 marshaled, _ := json.Marshal(data)
185 body := bytes.NewBuffer(marshaled)
186 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
187 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
189 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
190 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
191 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
193 /*** nodeb 1 connected ***/
195 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
196 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
198 nodeb1NotAssociated := *nodeb1
199 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
200 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
201 writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
203 /*** nodeb 2 disconnected ***/
205 nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
206 writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
208 nodeb2NotAssociated := *nodeb2
209 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
210 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
211 writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
213 err := shutdownManager.Shutdown(e2tInstance1)
216 readerMock.AssertExpectations(t)
217 writerMock.AssertExpectations(t)
218 httpClientMock.AssertExpectations(t)
221 func TestShutdownE2tInstanceAlreadyBeingDeleted(t *testing.T) {
222 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
224 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
225 e2tInstance1.State = entities.ToBeDeleted
226 e2tInstance1.AssociatedRanList = []string{"test1"}
227 e2tInstance1.DeletionTimestamp = time.Now().UnixNano()
229 err := shutdownManager.Shutdown(e2tInstance1)
232 readerMock.AssertExpectations(t)
233 writerMock.AssertExpectations(t)
234 httpClientMock.AssertExpectations(t)
237 func TestShutdownFailureMarkInstanceAsToBeDeleted(t *testing.T) {
238 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
240 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
241 e2tInstance1.State = entities.Active
242 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
243 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(e2managererrors.NewRnibDbError())
245 err := shutdownManager.Shutdown(e2tInstance1)
247 assert.NotNil(t, err)
248 readerMock.AssertExpectations(t)
249 writerMock.AssertExpectations(t)
250 httpClientMock.AssertExpectations(t)
253 func TestShutdownFailureRoutingManagerError(t *testing.T) {
254 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
256 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
257 e2tInstance1.State = entities.Active
258 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
259 e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
260 e2tInstance2.State = entities.Active
261 e2tInstance2.AssociatedRanList = []string{"test3"}
262 e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
263 e2tInstance3.State = entities.Active
264 e2tInstance3.AssociatedRanList = []string{"test4"}
265 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
267 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
268 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
269 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
270 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
271 nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
272 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
274 e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
275 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
277 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
278 marshaled, _ := json.Marshal(data)
279 body := bytes.NewBuffer(marshaled)
280 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
281 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusBadRequest, Body: respBody}, nil)
283 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
284 writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
286 /*** nodeb 1 connected ***/
287 nodeb1connected := *nodeb1
288 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
289 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1connected, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
291 nodeb1NotAssociated := *nodeb1
292 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
293 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
294 writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
296 /*** nodeb 2 shutting down ***/
297 nodeb2connected := *nodeb2
298 nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
299 writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
301 nodeb2NotAssociated := *nodeb2
302 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
303 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
304 writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
306 /*** nodeb 5 connected ***/
307 nodeb5connected := *nodeb5
308 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
309 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb5connected, "RAN_CONNECTION_STATUS_CHANGE", "test5_DISCONNECTED").Return(nil)
311 nodeb5NotAssociated := *nodeb5
312 nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
313 nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
314 writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
316 err := shutdownManager.Shutdown(e2tInstance1)
319 readerMock.AssertExpectations(t)
320 writerMock.AssertExpectations(t)
321 httpClientMock.AssertExpectations(t)
324 func TestShutdownFailureInClearNodebsAssociation(t *testing.T) {
325 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
327 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
328 e2tInstance1.State = entities.Active
329 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
330 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
332 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
333 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
336 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
337 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
339 nodeb1NotAssociated := *nodeb1
340 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
341 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
342 writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(common.NewInternalError(fmt.Errorf("for tests")))
344 err := shutdownManager.Shutdown(e2tInstance1)
346 assert.NotNil(t, err)
347 readerMock.AssertExpectations(t)
348 writerMock.AssertExpectations(t)
349 httpClientMock.AssertExpectations(t)
352 func TestShutdownFailureInClearNodebsAssociation_UpdateConnectionStatus(t *testing.T) {
353 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
355 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
356 e2tInstance1.State = entities.Active
357 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
358 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
360 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
361 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
364 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
365 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(common.NewInternalError(fmt.Errorf("for tests")))
367 err := shutdownManager.Shutdown(e2tInstance1)
369 assert.NotNil(t, err)
370 readerMock.AssertExpectations(t)
371 writerMock.AssertExpectations(t)
372 httpClientMock.AssertExpectations(t)
375 func TestShutdownResourceNotFoundErrorInGetNodeb(t *testing.T) {
376 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
378 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
379 e2tInstance1.State = entities.Active
380 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
381 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
383 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
384 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
385 var nodeb2 *entities.NodebInfo
386 readerMock.On("GetNodeb", "test2").Return(nodeb2, common.NewResourceNotFoundError("for testing"))
389 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
390 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
392 nodeb1NotAssociated := *nodeb1
393 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
394 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
395 writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
397 err := shutdownManager.Shutdown(e2tInstance1)
399 assert.NotNil(t, err)
400 readerMock.AssertExpectations(t)
401 writerMock.AssertExpectations(t)
402 httpClientMock.AssertExpectations(t)
405 func TestShutdownResourceGeneralErrorInGetNodeb(t *testing.T) {
406 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
408 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
409 e2tInstance1.State = entities.Active
410 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
411 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
413 var nodeb1 *entities.NodebInfo
414 readerMock.On("GetNodeb", "test1").Return(nodeb1, common.NewInternalError(fmt.Errorf("for testing")))
415 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
416 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
418 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
419 marshaled, _ := json.Marshal(data)
420 body := bytes.NewBuffer(marshaled)
421 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
422 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
424 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
425 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
426 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
429 nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
430 writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
432 nodeb2NotAssociated := *nodeb2
433 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
434 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
435 writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
437 err := shutdownManager.Shutdown(e2tInstance1)
440 readerMock.AssertExpectations(t)
441 writerMock.AssertExpectations(t)
442 httpClientMock.AssertExpectations(t)
446 func TestShutdownFailureInRemoveE2TInstance(t *testing.T) {
447 shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
449 e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
450 e2tInstance1.State = entities.Active
451 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
452 e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
453 e2tInstance2.State = entities.Active
454 e2tInstance2.AssociatedRanList = []string{"test3"}
455 e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
456 e2tInstance3.State = entities.Active
457 e2tInstance3.AssociatedRanList = []string{"test4"}
458 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
460 nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
461 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
462 nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
463 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
464 nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
465 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
467 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
468 marshaled, _ := json.Marshal(data)
469 body := bytes.NewBuffer(marshaled)
470 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
471 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
473 writerMock.On("RemoveE2TInstance", E2TAddress).Return(common.NewInternalError(fmt.Errorf("for tests")))
475 /*** nodeb 1 connected ***/
476 nodeb1connected := *nodeb1
477 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
478 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1connected, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
480 nodeb1NotAssociated := *nodeb1
481 nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
482 nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
483 writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
485 /*** nodeb 2 shutting down ***/
486 nodeb2connected := *nodeb2
487 nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
488 writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
490 nodeb2NotAssociated := *nodeb2
491 nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
492 nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
493 writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
495 /*** nodeb 5 connected ***/
496 nodeb5connected := *nodeb5
497 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
498 writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb5connected, "RAN_CONNECTION_STATUS_CHANGE", "test5_DISCONNECTED").Return(nil)
500 nodeb5NotAssociated := *nodeb5
501 nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
502 nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
503 writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
505 err := shutdownManager.Shutdown(e2tInstance1)
507 assert.IsType(t, &e2managererrors.RnibDbError{}, err)
508 readerMock.AssertExpectations(t)
509 writerMock.AssertExpectations(t)
510 httpClientMock.AssertExpectations(t)