537d153ffe3da3078cc3d189446c159754cf3469
[ric-plt/e2mgr.git] / E2Manager / managers / e2t_shutdown_manager_test.go
1 //
2 // Copyright 2019 AT&T Intellectual Property
3 // Copyright 2019 Nokia
4 //
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
8 //
9 //      http://www.apache.org/licenses/LICENSE-2.0
10 //
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.
16 //
17
18 //  This source code is part of the near-RT RIC (RAN Intelligent Controller)
19 //  platform project (RICP).
20
21 package managers
22
23 import (
24         "bytes"
25         "e2mgr/clients"
26         "e2mgr/configuration"
27         "e2mgr/e2managererrors"
28         "e2mgr/mocks"
29         "e2mgr/models"
30         "e2mgr/services"
31         "encoding/json"
32         "fmt"
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"
37         "io/ioutil"
38         //"k8s.io/apimachinery/pkg/runtime"
39         //"k8s.io/client-go/kubernetes/fake"
40         "net/http"
41         "testing"
42         "time"
43 )
44
45 const E2TAddress3 = "10.10.2.17:9800"
46
47 func initE2TShutdownManagerTest(t *testing.T) (*E2TShutdownManager, *mocks.RnibReaderMock, *mocks.RnibWriterMock, *mocks.HttpClientMock) {
48         log := initLog(t)
49         config := &configuration.Configuration{RnibRetryIntervalMs: 10, MaxRnibConnectionAttempts: 3, E2TInstanceDeletionTimeoutMs: 15000, RnibWriter: configuration.RnibWriterConfig{StateChangeMessageChannel: "RAN_CONNECTION_STATUS_CHANGE"}}
50
51         readerMock := &mocks.RnibReaderMock{}
52         writerMock := &mocks.RnibWriterMock{}
53         rnibDataService := services.NewRnibDataService(log, config, readerMock, writerMock)
54
55         e2tInstancesManager := NewE2TInstancesManager(rnibDataService, log)
56         httpClientMock := &mocks.HttpClientMock{}
57         rmClient := clients.NewRoutingManagerClient(log, config, httpClientMock)
58
59         ranListManager := NewRanListManager(log, rnibDataService)
60         ranAlarmService := services.NewRanAlarmService(log, config)
61         ranConnectStatusChangeManager := NewRanConnectStatusChangeManager(log, rnibDataService, ranListManager, ranAlarmService)
62         associationManager := NewE2TAssociationManager(log, rnibDataService, e2tInstancesManager, rmClient, ranConnectStatusChangeManager)
63         shutdownManager := NewE2TShutdownManager(log, config, rnibDataService, e2tInstancesManager, associationManager, ranConnectStatusChangeManager)
64
65         return shutdownManager, readerMock, writerMock, httpClientMock
66 }
67
68 func TestShutdownSuccess1OutOf3Instances(t *testing.T) {
69         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
70
71         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
72         e2tInstance1.State = entities.Active
73         e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
74         e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
75         e2tInstance2.State = entities.Active
76         e2tInstance2.AssociatedRanList = []string{"test3"}
77         e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
78         e2tInstance3.State = entities.Active
79         e2tInstance3.AssociatedRanList = []string{"test4"}
80         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
81
82         nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
83         readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
84         nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
85         readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
86         nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
87         readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
88
89         e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
90         readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
91
92         data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
93         marshaled, _ := json.Marshal(data)
94         body := bytes.NewBuffer(marshaled)
95         respBody := ioutil.NopCloser(bytes.NewBufferString(""))
96         httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
97
98         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
99         writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
100
101         /*** nodeb 1 ***/
102         nodeb1connected := *nodeb1
103         nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
104         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1connected, "test1_DISCONNECTED").Return(nil)
105
106         nodeb1NotAssociated := *nodeb1
107         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
108         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
109         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
110
111         /*** nodeb 2 ***/
112         nodeb2connected := *nodeb2
113         nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
114         writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
115
116         nodeb2NotAssociated := *nodeb2
117         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
118         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
119         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
120
121         /*** nodeb 5 ***/
122         nodeb5connected := *nodeb5
123         nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
124         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb5connected, "test5_DISCONNECTED").Return(nil)
125
126         nodeb5NotAssociated := *nodeb5
127         nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
128         nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
129         writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
130
131         err := shutdownManager.Shutdown(e2tInstance1)
132
133         assert.Nil(t, err)
134         readerMock.AssertExpectations(t)
135         writerMock.AssertExpectations(t)
136         httpClientMock.AssertExpectations(t)
137 }
138
139 func TestShutdownSuccess1InstanceWithoutRans(t *testing.T) {
140         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
141
142         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
143         e2tInstance1.State = entities.Active
144         e2tInstance1.AssociatedRanList = []string{}
145         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
146
147         data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, nil, nil)
148         marshaled, _ := json.Marshal(data)
149         body := bytes.NewBuffer(marshaled)
150         respBody := ioutil.NopCloser(bytes.NewBufferString(""))
151         httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
152
153         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
154         readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
155         writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
156
157         err := shutdownManager.Shutdown(e2tInstance1)
158
159         assert.Nil(t, err)
160         readerMock.AssertExpectations(t)
161         writerMock.AssertExpectations(t)
162         httpClientMock.AssertExpectations(t)
163 }
164
165 func TestShutdownSuccess1Instance2Rans(t *testing.T) {
166         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
167
168         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
169         e2tInstance1.State = entities.Active
170         e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
171         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
172
173         nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
174         readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
175         nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
176         readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
177
178         data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
179         marshaled, _ := json.Marshal(data)
180         body := bytes.NewBuffer(marshaled)
181         respBody := ioutil.NopCloser(bytes.NewBufferString(""))
182         httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
183
184         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
185         readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
186         writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
187
188         /*** nodeb 1 connected ***/
189         nodeb1new := *nodeb1
190         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
191         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "test1_DISCONNECTED").Return(nil)
192
193         nodeb1NotAssociated := *nodeb1
194         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
195         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
196         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
197
198         /*** nodeb 2 disconnected ***/
199         nodeb2new := *nodeb2
200         nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
201         writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
202
203         nodeb2NotAssociated := *nodeb2
204         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
205         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
206         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
207
208         err := shutdownManager.Shutdown(e2tInstance1)
209
210         assert.Nil(t, err)
211         readerMock.AssertExpectations(t)
212         writerMock.AssertExpectations(t)
213         httpClientMock.AssertExpectations(t)
214 }
215
216 func TestShutdownE2tInstanceAlreadyBeingDeleted(t *testing.T) {
217         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
218
219         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
220         e2tInstance1.State = entities.ToBeDeleted
221         e2tInstance1.AssociatedRanList = []string{"test1"}
222         e2tInstance1.DeletionTimestamp = time.Now().UnixNano()
223
224         err := shutdownManager.Shutdown(e2tInstance1)
225
226         assert.Nil(t, err)
227         readerMock.AssertExpectations(t)
228         writerMock.AssertExpectations(t)
229         httpClientMock.AssertExpectations(t)
230 }
231
232 func TestShutdownFailureMarkInstanceAsToBeDeleted(t *testing.T) {
233         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
234
235         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
236         e2tInstance1.State = entities.Active
237         e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
238         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(e2managererrors.NewRnibDbError())
239
240         err := shutdownManager.Shutdown(e2tInstance1)
241
242         assert.NotNil(t, err)
243         readerMock.AssertExpectations(t)
244         writerMock.AssertExpectations(t)
245         httpClientMock.AssertExpectations(t)
246 }
247
248 func TestShutdownFailureRoutingManagerError(t *testing.T) {
249         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
250
251         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
252         e2tInstance1.State = entities.Active
253         e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
254         e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
255         e2tInstance2.State = entities.Active
256         e2tInstance2.AssociatedRanList = []string{"test3"}
257         e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
258         e2tInstance3.State = entities.Active
259         e2tInstance3.AssociatedRanList = []string{"test4"}
260         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
261
262         nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
263         readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
264         nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
265         readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
266         nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
267         readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
268
269         e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
270         readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
271
272         data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
273         marshaled, _ := json.Marshal(data)
274         body := bytes.NewBuffer(marshaled)
275         respBody := ioutil.NopCloser(bytes.NewBufferString(""))
276         httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusBadRequest, Body: respBody}, nil)
277
278         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
279         writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
280
281         /*** nodeb 1 connected ***/
282         nodeb1connected := *nodeb1
283         nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
284         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1connected, "test1_DISCONNECTED").Return(nil)
285
286         nodeb1NotAssociated := *nodeb1
287         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
288         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
289         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
290
291         /*** nodeb 2 shutting down ***/
292         nodeb2connected := *nodeb2
293         nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
294         writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
295
296         nodeb2NotAssociated := *nodeb2
297         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
298         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
299         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
300
301         /*** nodeb 5 connected ***/
302         nodeb5connected := *nodeb5
303         nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
304         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb5connected, "test5_DISCONNECTED").Return(nil)
305
306         nodeb5NotAssociated := *nodeb5
307         nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
308         nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
309         writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
310
311         err := shutdownManager.Shutdown(e2tInstance1)
312
313         assert.Nil(t, err)
314         readerMock.AssertExpectations(t)
315         writerMock.AssertExpectations(t)
316         httpClientMock.AssertExpectations(t)
317 }
318
319 func TestShutdownFailureInClearNodebsAssociation(t *testing.T) {
320         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
321
322         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
323         e2tInstance1.State = entities.Active
324         e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
325         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
326
327         nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
328         readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
329
330         nodeb1new := *nodeb1
331         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
332         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "test1_DISCONNECTED").Return(nil)
333
334         nodeb1NotAssociated := *nodeb1
335         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
336         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
337         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(common.NewInternalError(fmt.Errorf("for tests")))
338
339         err := shutdownManager.Shutdown(e2tInstance1)
340
341         assert.NotNil(t, err)
342         readerMock.AssertExpectations(t)
343         writerMock.AssertExpectations(t)
344         httpClientMock.AssertExpectations(t)
345 }
346
347 func TestShutdownFailureInClearNodebsAssociation_UpdateConnectionStatus(t *testing.T) {
348         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
349
350         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
351         e2tInstance1.State = entities.Active
352         e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
353         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
354
355         nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
356         readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
357
358         nodeb1new := *nodeb1
359         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
360         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "test1_DISCONNECTED").Return(common.NewInternalError(fmt.Errorf("for tests")))
361
362         err := shutdownManager.Shutdown(e2tInstance1)
363
364         assert.NotNil(t, err)
365         readerMock.AssertExpectations(t)
366         writerMock.AssertExpectations(t)
367         httpClientMock.AssertExpectations(t)
368 }
369
370 func TestShutdownResourceNotFoundErrorInGetNodeb(t *testing.T) {
371         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
372
373         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
374         e2tInstance1.State = entities.Active
375         e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
376         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
377
378         nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
379         readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
380         var nodeb2 *entities.NodebInfo
381         readerMock.On("GetNodeb", "test2").Return(nodeb2, common.NewResourceNotFoundError("for testing"))
382
383         nodeb1new := *nodeb1
384         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
385         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "test1_DISCONNECTED").Return(nil)
386
387         nodeb1NotAssociated := *nodeb1
388         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
389         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
390         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
391
392         err := shutdownManager.Shutdown(e2tInstance1)
393
394         assert.NotNil(t, err)
395         readerMock.AssertExpectations(t)
396         writerMock.AssertExpectations(t)
397         httpClientMock.AssertExpectations(t)
398 }
399
400 func TestShutdownResourceGeneralErrorInGetNodeb(t *testing.T) {
401         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
402
403         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
404         e2tInstance1.State = entities.Active
405         e2tInstance1.AssociatedRanList = []string{"test1", "test2"}
406         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
407
408         var nodeb1 *entities.NodebInfo
409         readerMock.On("GetNodeb", "test1").Return(nodeb1, common.NewInternalError(fmt.Errorf("for testing")))
410         nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_DISCONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
411         readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
412
413         data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, []string{"test1", "test2"}, nil)
414         marshaled, _ := json.Marshal(data)
415         body := bytes.NewBuffer(marshaled)
416         respBody := ioutil.NopCloser(bytes.NewBufferString(""))
417         httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
418
419         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
420         readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
421         writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
422
423         nodeb2new := *nodeb2
424         nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
425         writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
426
427         nodeb2NotAssociated := *nodeb2
428         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
429         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
430         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
431
432         err := shutdownManager.Shutdown(e2tInstance1)
433
434         assert.Nil(t, err)
435         readerMock.AssertExpectations(t)
436         writerMock.AssertExpectations(t)
437         httpClientMock.AssertExpectations(t)
438
439 }
440
441 func TestShutdownFailureInRemoveE2TInstance(t *testing.T) {
442         shutdownManager, readerMock, writerMock, httpClientMock := initE2TShutdownManagerTest(t)
443
444         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
445         e2tInstance1.State = entities.Active
446         e2tInstance1.AssociatedRanList = []string{"test1", "test2", "test5"}
447         e2tInstance2 := entities.NewE2TInstance(E2TAddress2, PodName)
448         e2tInstance2.State = entities.Active
449         e2tInstance2.AssociatedRanList = []string{"test3"}
450         e2tInstance3 := entities.NewE2TInstance(E2TAddress3, PodName)
451         e2tInstance3.State = entities.Active
452         e2tInstance3.AssociatedRanList = []string{"test4"}
453         writerMock.On("SaveE2TInstance", mock.MatchedBy(func(e2tInstance *entities.E2TInstance) bool { return e2tInstance.Address == E2TAddress && e2tInstance.State == entities.ToBeDeleted })).Return(nil)
454
455         nodeb1 := &entities.NodebInfo{RanName: "test1", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
456         readerMock.On("GetNodeb", "test1").Return(nodeb1, nil)
457         nodeb2 := &entities.NodebInfo{RanName: "test2", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_SHUTTING_DOWN, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
458         readerMock.On("GetNodeb", "test2").Return(nodeb2, nil)
459         nodeb5 := &entities.NodebInfo{RanName: "test5", AssociatedE2TInstanceAddress: E2TAddress, ConnectionStatus: entities.ConnectionStatus_CONNECTED, E2ApplicationProtocol: entities.E2ApplicationProtocol_X2_SETUP_REQUEST}
460         readerMock.On("GetNodeb", "test5").Return(nodeb5, nil)
461
462         data := models.NewRoutingManagerDeleteRequestModel(E2TAddress, e2tInstance1.AssociatedRanList, nil)
463         marshaled, _ := json.Marshal(data)
464         body := bytes.NewBuffer(marshaled)
465         respBody := ioutil.NopCloser(bytes.NewBufferString(""))
466         httpClientMock.On("Delete", "e2t", "application/json", body).Return(&http.Response{StatusCode: http.StatusCreated, Body: respBody}, nil)
467
468         writerMock.On("RemoveE2TInstance", E2TAddress).Return(common.NewInternalError(fmt.Errorf("for tests")))
469
470         /*** nodeb 1 connected ***/
471         nodeb1connected := *nodeb1
472         nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
473         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1connected, "test1_DISCONNECTED").Return(nil)
474
475         nodeb1NotAssociated := *nodeb1
476         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
477         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
478         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
479
480         /*** nodeb 2 shutting down ***/
481         nodeb2connected := *nodeb2
482         nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
483         writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
484
485         nodeb2NotAssociated := *nodeb2
486         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
487         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
488         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
489
490         /*** nodeb 5 connected ***/
491         nodeb5connected := *nodeb5
492         nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
493         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb5connected, "test5_DISCONNECTED").Return(nil)
494
495         nodeb5NotAssociated := *nodeb5
496         nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
497         nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
498         writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
499
500         err := shutdownManager.Shutdown(e2tInstance1)
501
502         assert.IsType(t, &e2managererrors.RnibDbError{}, err)
503         readerMock.AssertExpectations(t)
504         writerMock.AssertExpectations(t)
505         httpClientMock.AssertExpectations(t)
506 }