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"
45 const E2TAddress3 = "10.10.2.17:9800"
47 func initE2TShutdownManagerTest(t *testing.T) (*E2TShutdownManager, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.HttpClientMock, *mocks.RmrMessengerMock) {
49 config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3, E2TInstanceDeletionTimeoutMs: 15000}
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)
58 associationManager := NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient)
59 rmrMessengerMock := &mocks.RmrMessengerMock{}
60 rmrSender := initRmrSender(rmrMessengerMock, log)
61 ranSetupManager := NewRanSetupManager(log, rmrSender, rnibDataService)
62 shutdownManager := NewE2TShutdownManager(log, config, rnibDataService, e2tInstancesManager, associationManager, ranSetupManager)
64 return shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock
67 func TestShutdownSuccess1OutOf3Instances(t *testing.T) {
68 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
70 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
71 e2tInstance1.State = entities.Active
72 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
73 e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
74 e2tInstance2.State = entities.Active
75 e2tInstance2.AssociatedRanList = []string{"test3"}
76 e2tInstance3 := entities.NewE2TInstance(E2TAddress3)
77 e2tInstance3.State = entities.Active
78 e2tInstance3.AssociatedRanList = []string{"test4"}
79 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
81 nodeb1 := &entities.NodebInfo{RanName:"test1", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
82 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
83 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
84 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
85 nodeb5 := &entities.NodebInfo{RanName:"test5", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
86 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
88 e2tAddresses := []string{E2TAddress, E2TAddress2,E2TAddress3}
89 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
90 readerMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance2,e2tInstance3}, nil)
92 e2tDataList := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress2, "test1", "test5")}
93 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, e2tDataList)
94 marshaled, _ := json.Marshal(data)
95 body := bytes.NewBuffer(marshaled)
96 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
97 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
99 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
100 writerMock.On("SaveE2TAddresses", []string{E2TAddress2,E2TAddress3}).Return(nil)
102 readerMock.On("GetE2TInstance", E2TAddress2).Return(e2tInstance2, nil)
103 e2tInstance2updated := *e2tInstance2
104 e2tInstance2updated.AssociatedRanList = append(e2tInstance2updated.AssociatedRanList, "test1", "test5")
105 writerMock.On("SaveE2TInstance", &e2tInstance2updated).Return(nil)
108 nodeb1new.AssociatedE2TInstanceAddress = E2TAddress2
109 nodeb1new.ConnectionStatus = entities.ConnectionStatus_CONNECTING
110 nodeb1new.ConnectionAttempts = 1
111 writerMock.On("UpdateNodebInfo", &nodeb1new).Return(nil)
113 nodeb5new.AssociatedE2TInstanceAddress = E2TAddress2
114 nodeb5new.ConnectionStatus = entities.ConnectionStatus_CONNECTING
115 nodeb5new.ConnectionAttempts = 1
116 writerMock.On("UpdateNodebInfo", &nodeb5new).Return(nil)
118 nodeb1connected := *nodeb1
119 nodeb1connected.AssociatedE2TInstanceAddress = E2TAddress2
120 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_CONNECTED
121 writerMock.On("UpdateNodebInfo", &nodeb1connected).Return(nil)
122 nodeb5connected := *nodeb5
123 nodeb5connected.AssociatedE2TInstanceAddress = E2TAddress2
124 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_CONNECTED
125 writerMock.On("UpdateNodebInfo", &nodeb5connected).Return(nil)
127 payload := e2pdus.PackedX2setupRequest
128 xaction1 := []byte("test1")
129 msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), "test1", &payload, &xaction1)
130 rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg1, nil)
131 xaction5 := []byte("test5")
132 msg5 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), "test5", &payload, &xaction5)
133 rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg5, nil)
135 err := shutdownManager.Shutdown(e2tInstance1)
138 readerMock.AssertExpectations(t)
139 writerMock.AssertExpectations(t)
140 httpClientMock.AssertExpectations(t)
141 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)
144 func TestShutdownSuccess1InstanceWithoutRans(t *testing.T) {
145 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
147 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
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)
168 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
171 func TestShutdownSuccess1Instance2Rans(t *testing.T) {
172 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
174 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
175 e2tInstance1.State = entities.Active
176 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
177 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
179 nodeb1 := &entities.NodebInfo{RanName:"test1", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
180 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
181 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
182 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
184 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
185 marshaled, _ := json.Marshal(data)
186 body := bytes.NewBuffer(marshaled)
187 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
188 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
190 e2tInstance1updated := *e2tInstance1
191 e2tInstance1updated.State = entities.ToBeDeleted
192 readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{&e2tInstance1updated}, nil)
194 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
195 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
196 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
199 nodeb1new.AssociatedE2TInstanceAddress = ""
200 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
201 writerMock.On("UpdateNodebInfo", &nodeb1new).Return(nil)
203 nodeb2new.AssociatedE2TInstanceAddress = ""
204 nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
205 writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
207 err := shutdownManager.Shutdown(e2tInstance1)
210 readerMock.AssertExpectations(t)
211 writerMock.AssertExpectations(t)
212 httpClientMock.AssertExpectations(t)
213 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
218 func TestShutdownE2tInstanceAlreadyBeingDeleted(t *testing.T) {
219 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
221 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
222 e2tInstance1.State = entities.ToBeDeleted
223 e2tInstance1.AssociatedRanList = []string{"test1"}
224 e2tInstance1.DeletionTimestamp = time.Now().UnixNano()
226 err := shutdownManager.Shutdown(e2tInstance1)
229 readerMock.AssertExpectations(t)
230 writerMock.AssertExpectations(t)
231 httpClientMock.AssertExpectations(t)
232 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
235 func TestShutdownFailureMarkInstanceAsToBeDeleted(t *testing.T) {
236 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
238 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
239 e2tInstance1.State = entities.Active
240 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
241 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(e2managererrors.NewRnibDbError())
243 err := shutdownManager.Shutdown(e2tInstance1)
245 assert.NotNil(t, err)
246 readerMock.AssertExpectations(t)
247 writerMock.AssertExpectations(t)
248 httpClientMock.AssertExpectations(t)
249 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
252 func TestShutdownFailureReassociatingInMemoryNodebNotFound(t *testing.T) {
253 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
255 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
256 e2tInstance1.State = entities.Active
257 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
258 e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
259 e2tInstance2.State = entities.Active
260 e2tInstance2.AssociatedRanList = []string{"test3"}
261 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
263 var nodeb1 *entities.NodebInfo
264 readerMock.On("GetNodeb", "test1").Return(nodeb1, common.NewResourceNotFoundError("for tests"))
265 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
266 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
268 e2tAddresses := []string{E2TAddress, E2TAddress2}
269 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
270 readerMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance2}, nil)
272 e2tDataList := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress2, "test2")}
273 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, e2tDataList)
274 marshaled, _ := json.Marshal(data)
275 body := bytes.NewBuffer(marshaled)
276 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
277 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
279 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
280 writerMock.On("SaveE2TAddresses", []string{E2TAddress2}).Return(nil)
282 readerMock.On("GetE2TInstance", E2TAddress2).Return(e2tInstance2, nil)
283 e2tInstance2updated := *e2tInstance2
284 e2tInstance2updated.AssociatedRanList = append(e2tInstance2updated.AssociatedRanList, "test2")
285 writerMock.On("SaveE2TInstance", &e2tInstance2updated).Return(nil)
288 nodeb2new.AssociatedE2TInstanceAddress = E2TAddress2
289 nodeb2new.ConnectionStatus = entities.ConnectionStatus_CONNECTING
290 nodeb2new.ConnectionAttempts = 1
291 writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
293 nodeb2connected := *nodeb2
294 nodeb2connected.AssociatedE2TInstanceAddress = E2TAddress2
295 nodeb2connected.ConnectionStatus = entities.ConnectionStatus_CONNECTED
296 writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
298 payload := e2pdus.PackedX2setupRequest
299 xaction2 := []byte("test2")
300 msg2 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), "test2", &payload, &xaction2)
301 rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg2, nil)
303 err := shutdownManager.Shutdown(e2tInstance1)
306 readerMock.AssertExpectations(t)
307 writerMock.AssertExpectations(t)
308 httpClientMock.AssertExpectations(t)
309 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 1)
312 func TestShutdownFailureReassociatingInMemoryGetNodebError(t *testing.T) {
313 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
315 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
316 e2tInstance1.State = entities.Active
317 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
318 e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
319 e2tInstance2.State = entities.Active
320 e2tInstance2.AssociatedRanList = []string{"test3"}
321 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
323 var nodeb1 *entities.NodebInfo
324 readerMock.On("GetNodeb", "test1").Return(nodeb1, common.NewInternalError(fmt.Errorf("for tests")))
326 err := shutdownManager.Shutdown(e2tInstance1)
328 assert.NotNil(t, err)
329 readerMock.AssertExpectations(t)
330 writerMock.AssertExpectations(t)
331 httpClientMock.AssertExpectations(t)
332 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
335 func TestShutdownFailureRoutingManagerError(t *testing.T) {
336 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
338 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
339 e2tInstance1.State = entities.Active
340 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
341 e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
342 e2tInstance2.State = entities.Active
343 e2tInstance2.AssociatedRanList = []string{"test3"}
344 e2tInstance3 := entities.NewE2TInstance(E2TAddress3)
345 e2tInstance3.State = entities.Active
346 e2tInstance3.AssociatedRanList = []string{"test4"}
347 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
349 nodeb1 := &entities.NodebInfo{RanName:"test1", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
350 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
351 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
352 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
353 nodeb5 := &entities.NodebInfo{RanName:"test5", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
354 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
356 e2tAddresses := []string{E2TAddress, E2TAddress2,E2TAddress3}
357 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
358 readerMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance2,e2tInstance3}, nil)
360 e2tDataList := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress2, "test1", "test5")}
361 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, e2tDataList)
362 marshaled, _ := json.Marshal(data)
363 body := bytes.NewBuffer(marshaled)
364 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
365 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusBadRequest, Body: respBody}, nil)
367 readerMock.On("GetE2TInstance", E2TAddress).Return(e2tInstance1, nil)
368 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.RoutingManagerFailure })).Return(nil)
370 err := shutdownManager.Shutdown(e2tInstance1)
372 assert.NotNil(t, err)
373 readerMock.AssertExpectations(t)
374 writerMock.AssertExpectations(t)
375 httpClientMock.AssertExpectations(t)
376 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
379 func TestShutdownFailureInClearNodebsAssociation(t *testing.T) {
380 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
382 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
383 e2tInstance1.State = entities.Active
384 e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
385 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
387 nodeb1 := &entities.NodebInfo{RanName:"test1", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
388 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
389 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
390 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
392 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
393 marshaled, _ := json.Marshal(data)
394 body := bytes.NewBuffer(marshaled)
395 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
396 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
398 e2tInstance1updated := *e2tInstance1
399 e2tInstance1updated.State = entities.ToBeDeleted
400 readerMock.On("GetE2TInstances", []string{E2TAddress}).Return([]*entities.E2TInstance{&e2tInstance1updated}, nil)
402 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
403 readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
404 writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
407 nodeb1new.AssociatedE2TInstanceAddress = ""
408 nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
409 writerMock.On("UpdateNodebInfo", &nodeb1new).Return(common.NewInternalError(fmt.Errorf("for tests")))
411 err := shutdownManager.Shutdown(e2tInstance1)
413 assert.NotNil(t, err)
414 readerMock.AssertExpectations(t)
415 writerMock.AssertExpectations(t)
416 httpClientMock.AssertExpectations(t)
417 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
420 func TestShutdownFailureInRmr(t *testing.T) {
421 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
423 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
424 e2tInstance1.State = entities.Active
425 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
426 e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
427 e2tInstance2.State = entities.Active
428 e2tInstance2.AssociatedRanList = []string{"test3"}
429 e2tInstance3 := entities.NewE2TInstance(E2TAddress3)
430 e2tInstance3.State = entities.Active
431 e2tInstance3.AssociatedRanList = []string{"test4"}
432 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
434 nodeb1 := &entities.NodebInfo{RanName:"test1", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
435 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
436 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
437 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
438 nodeb5 := &entities.NodebInfo{RanName:"test5", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
439 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
441 e2tAddresses := []string{E2TAddress, E2TAddress2,E2TAddress3}
442 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
443 readerMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance2,e2tInstance3}, nil)
445 e2tDataList := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress2, "test1", "test5")}
446 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, e2tDataList)
447 marshaled, _ := json.Marshal(data)
448 body := bytes.NewBuffer(marshaled)
449 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
450 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
452 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
453 writerMock.On("SaveE2TAddresses", []string{E2TAddress2,E2TAddress3}).Return(nil)
455 readerMock.On("GetE2TInstance", E2TAddress2).Return(e2tInstance2, nil)
456 e2tInstance2updated := *e2tInstance2
457 e2tInstance2updated.AssociatedRanList = []string{"test3", "test1", "test5"}
458 writerMock.On("SaveE2TInstance", &e2tInstance2updated).Return(nil)
460 nodeb1reassigned := *nodeb1
461 nodeb1reassigned.AssociatedE2TInstanceAddress = E2TAddress2
462 writerMock.On("UpdateNodebInfo", &nodeb1reassigned).Return(nil)
463 nodeb5reassigned := *nodeb5
464 nodeb5reassigned.AssociatedE2TInstanceAddress = E2TAddress2
465 writerMock.On("UpdateNodebInfo", &nodeb5reassigned).Return(nil)
468 nodeb1new.AssociatedE2TInstanceAddress = E2TAddress2
469 nodeb1new.ConnectionStatus = entities.ConnectionStatus_CONNECTING
470 nodeb1new.ConnectionAttempts = 1
471 writerMock.On("UpdateNodebInfo", &nodeb1new).Return(nil)
473 nodeb5new.AssociatedE2TInstanceAddress = E2TAddress2
474 nodeb5new.ConnectionStatus = entities.ConnectionStatus_CONNECTING
475 nodeb5new.ConnectionAttempts = 1
476 writerMock.On("UpdateNodebInfo", &nodeb5new).Return(nil)
478 nodeb1connected := *nodeb1
479 nodeb1connected.AssociatedE2TInstanceAddress = E2TAddress2
480 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
481 nodeb1connected.ConnectionAttempts = 0
482 //nodeb1connected.E2ApplicationProtocol = entities.E2ApplicationProtocol_X2_SETUP_REQUEST
483 writerMock.On("UpdateNodebInfo", &nodeb1connected).Return(nil)
484 nodeb5connected := *nodeb5
485 nodeb5connected.AssociatedE2TInstanceAddress = E2TAddress2
486 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
487 nodeb5connected.ConnectionAttempts = 0
488 //nodeb5connected.E2ApplicationProtocol = entities.E2ApplicationProtocol_X2_SETUP_REQUEST
489 writerMock.On("UpdateNodebInfo", &nodeb5connected).Return(nil)
491 payload := e2pdus.PackedX2setupRequest
492 xaction1 := []byte("test1")
493 msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), "test1", &payload, &xaction1)
494 rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg1, common.NewInternalError(fmt.Errorf("for test")))
495 xaction2 := []byte("test5")
496 msg2 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), "test5", &payload, &xaction2)
497 rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg2, common.NewInternalError(fmt.Errorf("for test")))
499 err := shutdownManager.Shutdown(e2tInstance1)
502 readerMock.AssertExpectations(t)
503 writerMock.AssertExpectations(t)
504 httpClientMock.AssertExpectations(t)
505 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)
508 func TestShutdownFailureDbErrorInAsociateAndSetupNodebs(t *testing.T) {
509 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
511 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
512 e2tInstance1.State = entities.Active
513 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
514 e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
515 e2tInstance2.State = entities.Active
516 e2tInstance2.AssociatedRanList = []string{"test3"}
517 e2tInstance3 := entities.NewE2TInstance(E2TAddress3)
518 e2tInstance3.State = entities.Active
519 e2tInstance3.AssociatedRanList = []string{"test4"}
520 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
522 nodeb1 := &entities.NodebInfo{RanName:"test1", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
523 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
524 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
525 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
526 nodeb5 := &entities.NodebInfo{RanName:"test5", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
527 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
529 e2tAddresses := []string{E2TAddress, E2TAddress2,E2TAddress3}
530 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
531 readerMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance2,e2tInstance3}, nil)
533 e2tDataList := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress2, "test1", "test5")}
534 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, e2tDataList)
535 marshaled, _ := json.Marshal(data)
536 body := bytes.NewBuffer(marshaled)
537 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
538 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
540 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
541 writerMock.On("SaveE2TAddresses", []string{E2TAddress2,E2TAddress3}).Return(nil)
543 readerMock.On("GetE2TInstance", E2TAddress2).Return(e2tInstance2, nil)
544 e2tInstance2updated := *e2tInstance2
545 e2tInstance2updated.AssociatedRanList = []string{"test3", "test1", "test5"}
546 writerMock.On("SaveE2TInstance", &e2tInstance2updated).Return(nil)
548 nodeb1reassigned := *nodeb1
549 nodeb1reassigned.AssociatedE2TInstanceAddress = E2TAddress2
550 writerMock.On("UpdateNodebInfo", &nodeb1reassigned).Return(common.NewInternalError(fmt.Errorf("for tests")))
552 err := shutdownManager.Shutdown(e2tInstance1)
554 assert.NotNil(t, err)
555 readerMock.AssertExpectations(t)
556 writerMock.AssertExpectations(t)
557 httpClientMock.AssertExpectations(t)
558 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 0)
561 func TestShutdownSuccess1OutOf3InstancesStateIsRoutingManagerFailure(t *testing.T) {
562 shutdownManager, readerMock, writerMock, httpClientMock, rmrMessengerMock := initE2TShutdownManagerTest(t)
564 e2tInstance1 := entities.NewE2TInstance(E2TAddress)
565 e2tInstance1.State = entities.RoutingManagerFailure
566 e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
567 e2tInstance2 := entities.NewE2TInstance(E2TAddress2)
568 e2tInstance2.State = entities.Active
569 e2tInstance2.AssociatedRanList = []string{"test3"}
570 e2tInstance3 := entities.NewE2TInstance(E2TAddress3)
571 e2tInstance3.State = entities.Active
572 e2tInstance3.AssociatedRanList = []string{"test4"}
573 writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
575 nodeb1 := &entities.NodebInfo{RanName:"test1", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
576 readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
577 nodeb2 := &entities.NodebInfo{RanName:"test2", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
578 readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
579 nodeb5 := &entities.NodebInfo{RanName:"test5", AssociatedE2TInstanceAddress:E2TAddress, ConnectionStatus:entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol:entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
580 readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
582 e2tAddresses := []string{E2TAddress, E2TAddress2,E2TAddress3}
583 readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
584 readerMock.On("GetE2TInstances", e2tAddresses).Return([]*entities.E2TInstance{e2tInstance2,e2tInstance3}, nil)
586 e2tDataList := models.RoutingManagerE2TDataList{models.NewRoutingManagerE2TData(E2TAddress2, "test1", "test5")}
587 data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, e2tDataList)
588 marshaled, _ := json.Marshal(data)
589 body := bytes.NewBuffer(marshaled)
590 respBody := ioutil.NopCloser(bytes.NewBufferString(""))
591 httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
593 writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
594 writerMock.On("SaveE2TAddresses", []string{E2TAddress2,E2TAddress3}).Return(nil)
596 readerMock.On("GetE2TInstance", E2TAddress2).Return(e2tInstance2, nil)
597 e2tInstance2updated := *e2tInstance2
598 e2tInstance2updated.AssociatedRanList = []string{"test3", "test1", "test5"}
599 writerMock.On("SaveE2TInstance", &e2tInstance2updated).Return(nil)
602 nodeb1new.AssociatedE2TInstanceAddress = E2TAddress2
603 nodeb1new.ConnectionStatus = entities.ConnectionStatus_CONNECTING
604 nodeb1new.ConnectionAttempts = 1
605 writerMock.On("UpdateNodebInfo", &nodeb1new).Return(nil)
607 nodeb5new.AssociatedE2TInstanceAddress = E2TAddress2
608 nodeb5new.ConnectionStatus = entities.ConnectionStatus_CONNECTING
609 nodeb5new.ConnectionAttempts = 1
610 writerMock.On("UpdateNodebInfo", &nodeb5new).Return(nil)
612 nodeb1connected := *nodeb1
613 nodeb1connected.AssociatedE2TInstanceAddress = E2TAddress2
614 nodeb1connected.ConnectionStatus = entities.ConnectionStatus_CONNECTED
615 //nodeb1connected.E2ApplicationProtocol = entities.E2ApplicationProtocol_X2_SETUP_REQUEST
616 writerMock.On("UpdateNodebInfo", &nodeb1connected).Return(nil)
617 nodeb5connected := *nodeb5
618 nodeb5connected.AssociatedE2TInstanceAddress = E2TAddress2
619 nodeb5connected.ConnectionStatus = entities.ConnectionStatus_CONNECTED
620 //nodeb5connected.E2ApplicationProtocol = entities.E2ApplicationProtocol_X2_SETUP_REQUEST
621 writerMock.On("UpdateNodebInfo", &nodeb5connected).Return(nil)
623 payload := e2pdus.PackedX2setupRequest
624 xaction1 := []byte("test1")
625 msg1 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), "test1", &payload, &xaction1)
626 rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg1, nil)
627 xaction5 := []byte("test5")
628 msg5 := rmrCgo.NewMBuf(rmrCgo.RIC_X2_SETUP_REQ, len(payload), "test5", &payload, &xaction5)
629 rmrMessengerMock.On("SendMsg",mock.Anything, true).Return(msg5, nil)
631 err := shutdownManager.Shutdown(e2tInstance1)
634 readerMock.AssertExpectations(t)
635 writerMock.AssertExpectations(t)
636 httpClientMock.AssertExpectations(t)
637 rmrMessengerMock.AssertNumberOfCalls(t, "SendMsg", 2)