[RIC-431] Add Enb | Configuration changes | Some refactoring | K8S yamls
[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, *KubernetesManager) {
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)
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)
64
65         /*shutdownManager := NewE2TShutdownManager(log, config, rnibDataService, e2tInstancesManager, associationManager, kubernetesManager)
66
67         return shutdownManager, readerMock, writerMock, httpClientMock, kubernetesManager*/
68         shutdownManager := NewE2TShutdownManager(log, config, rnibDataService, e2tInstancesManager, associationManager, nil, ranConnectStatusChangeManager)
69
70         return shutdownManager, readerMock, writerMock, httpClientMock, nil
71 }
72
73 func TestShutdownSuccess1OutOf3Instances(t *testing.T) {
74         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
75
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)
86
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)
93
94         e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
95         readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
96
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)
102
103         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
104         writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
105
106         /*** nodeb 1 ***/
107         nodeb1connected := *nodeb1
108         nodeb1connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
109         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1connected, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
110
111         nodeb1NotAssociated := *nodeb1
112         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
113         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
114         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
115
116         /*** nodeb 2 ***/
117         nodeb2connected := *nodeb2
118         nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
119         writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
120
121         nodeb2NotAssociated := *nodeb2
122         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
123         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
124         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
125
126         /*** nodeb 5 ***/
127         nodeb5connected := *nodeb5
128         nodeb5connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
129         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb5connected, "RAN_CONNECTION_STATUS_CHANGE", "test5_DISCONNECTED").Return(nil)
130
131         nodeb5NotAssociated := *nodeb5
132         nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
133         nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
134         writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
135
136         err := shutdownManager.Shutdown(e2tInstance1)
137
138         assert.Nil(t, err)
139         readerMock.AssertExpectations(t)
140         writerMock.AssertExpectations(t)
141         httpClientMock.AssertExpectations(t)
142 }
143
144 func TestShutdownSuccess1InstanceWithoutRans(t *testing.T) {
145         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
146
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)
151
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)
157
158         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
159         readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
160         writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
161
162         err := shutdownManager.Shutdown(e2tInstance1)
163
164         assert.Nil(t, err)
165         readerMock.AssertExpectations(t)
166         writerMock.AssertExpectations(t)
167         httpClientMock.AssertExpectations(t)
168 }
169
170 func TestShutdownSuccess1Instance2Rans(t *testing.T) {
171         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
172
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)
177
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)
182
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)
188
189         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
190         readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
191         writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
192
193         /*** nodeb 1 connected ***/
194         nodeb1new := *nodeb1
195         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
196         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
197
198         nodeb1NotAssociated := *nodeb1
199         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
200         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
201         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
202
203         /*** nodeb 2 disconnected ***/
204         nodeb2new := *nodeb2
205         nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
206         writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
207
208         nodeb2NotAssociated := *nodeb2
209         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
210         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
211         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
212
213         err := shutdownManager.Shutdown(e2tInstance1)
214
215         assert.Nil(t, err)
216         readerMock.AssertExpectations(t)
217         writerMock.AssertExpectations(t)
218         httpClientMock.AssertExpectations(t)
219 }
220
221 func TestShutdownE2tInstanceAlreadyBeingDeleted(t *testing.T) {
222         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
223
224         e2tInstance1 := entities.NewE2TInstance(E2TAddress, PodName)
225         e2tInstance1.State = entities.ToBeDeleted
226         e2tInstance1.AssociatedRanList = []string{"test1"}
227         e2tInstance1.DeletionTimestamp = time.Now().UnixNano()
228
229         err := shutdownManager.Shutdown(e2tInstance1)
230
231         assert.Nil(t, err)
232         readerMock.AssertExpectations(t)
233         writerMock.AssertExpectations(t)
234         httpClientMock.AssertExpectations(t)
235 }
236
237 func TestShutdownFailureMarkInstanceAsToBeDeleted(t *testing.T) {
238         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
239
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())
244
245         err := shutdownManager.Shutdown(e2tInstance1)
246
247         assert.NotNil(t, err)
248         readerMock.AssertExpectations(t)
249         writerMock.AssertExpectations(t)
250         httpClientMock.AssertExpectations(t)
251 }
252
253 func TestShutdownFailureRoutingManagerError(t *testing.T) {
254         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
255
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)
266
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)
273
274         e2tAddresses := []string{E2TAddress, E2TAddress2, E2TAddress3}
275         readerMock.On("GetE2TAddresses").Return(e2tAddresses, nil)
276
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)
282
283         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
284         writerMock.On("SaveE2TAddresses", []string{E2TAddress2, E2TAddress3}).Return(nil)
285
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)
290
291         nodeb1NotAssociated := *nodeb1
292         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
293         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
294         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
295
296         /*** nodeb 2 shutting down ***/
297         nodeb2connected := *nodeb2
298         nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
299         writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
300
301         nodeb2NotAssociated := *nodeb2
302         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
303         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
304         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
305
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)
310
311         nodeb5NotAssociated := *nodeb5
312         nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
313         nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
314         writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
315
316         err := shutdownManager.Shutdown(e2tInstance1)
317
318         assert.Nil(t, err)
319         readerMock.AssertExpectations(t)
320         writerMock.AssertExpectations(t)
321         httpClientMock.AssertExpectations(t)
322 }
323
324 func TestShutdownFailureInClearNodebsAssociation(t *testing.T) {
325         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
326
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)
331
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)
334
335         nodeb1new := *nodeb1
336         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
337         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
338
339         nodeb1NotAssociated := *nodeb1
340         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
341         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
342         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(common.NewInternalError(fmt.Errorf("for tests")))
343
344         err := shutdownManager.Shutdown(e2tInstance1)
345
346         assert.NotNil(t, err)
347         readerMock.AssertExpectations(t)
348         writerMock.AssertExpectations(t)
349         httpClientMock.AssertExpectations(t)
350 }
351
352 func TestShutdownFailureInClearNodebsAssociation_UpdateConnectionStatus(t *testing.T) {
353         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
354
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)
359
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)
362
363         nodeb1new := *nodeb1
364         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
365         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(common.NewInternalError(fmt.Errorf("for tests")))
366
367         err := shutdownManager.Shutdown(e2tInstance1)
368
369         assert.NotNil(t, err)
370         readerMock.AssertExpectations(t)
371         writerMock.AssertExpectations(t)
372         httpClientMock.AssertExpectations(t)
373 }
374
375 func TestShutdownResourceNotFoundErrorInGetNodeb(t *testing.T) {
376         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
377
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)
382
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"))
387
388         nodeb1new := *nodeb1
389         nodeb1new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
390         writerMock.On("UpdateNodebInfoOnConnectionStatusInversion", &nodeb1new, "RAN_CONNECTION_STATUS_CHANGE", "test1_DISCONNECTED").Return(nil)
391
392         nodeb1NotAssociated := *nodeb1
393         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
394         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
395         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
396
397         err := shutdownManager.Shutdown(e2tInstance1)
398
399         assert.NotNil(t, err)
400         readerMock.AssertExpectations(t)
401         writerMock.AssertExpectations(t)
402         httpClientMock.AssertExpectations(t)
403 }
404
405 func TestShutdownResourceGeneralErrorInGetNodeb(t *testing.T) {
406         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
407
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)
412
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)
417
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)
423
424         writerMock.On("RemoveE2TInstance", E2TAddress).Return(nil)
425         readerMock.On("GetE2TAddresses").Return([]string{E2TAddress}, nil)
426         writerMock.On("SaveE2TAddresses", []string{}).Return(nil)
427
428         nodeb2new := *nodeb2
429         nodeb2new.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
430         writerMock.On("UpdateNodebInfo", &nodeb2new).Return(nil)
431
432         nodeb2NotAssociated := *nodeb2
433         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
434         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
435         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
436
437         err := shutdownManager.Shutdown(e2tInstance1)
438
439         assert.Nil(t, err)
440         readerMock.AssertExpectations(t)
441         writerMock.AssertExpectations(t)
442         httpClientMock.AssertExpectations(t)
443
444 }
445
446 func TestShutdownFailureInRemoveE2TInstance(t *testing.T) {
447         shutdownManager, readerMock, writerMock, httpClientMock, _ := initE2TShutdownManagerTest(t)
448
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)
459
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)
466
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)
472
473         writerMock.On("RemoveE2TInstance", E2TAddress).Return(common.NewInternalError(fmt.Errorf("for tests")))
474
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)
479
480         nodeb1NotAssociated := *nodeb1
481         nodeb1NotAssociated.AssociatedE2TInstanceAddress = ""
482         nodeb1NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
483         writerMock.On("UpdateNodebInfo", &nodeb1NotAssociated).Return(nil)
484
485         /*** nodeb 2 shutting down ***/
486         nodeb2connected := *nodeb2
487         nodeb2connected.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
488         writerMock.On("UpdateNodebInfo", &nodeb2connected).Return(nil)
489
490         nodeb2NotAssociated := *nodeb2
491         nodeb2NotAssociated.AssociatedE2TInstanceAddress = ""
492         nodeb2NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
493         writerMock.On("UpdateNodebInfo", &nodeb2NotAssociated).Return(nil)
494
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)
499
500         nodeb5NotAssociated := *nodeb5
501         nodeb5NotAssociated.AssociatedE2TInstanceAddress = ""
502         nodeb5NotAssociated.ConnectionStatus = entities.ConnectionStatus_DISCONNECTED
503         writerMock.On("UpdateNodebInfo", &nodeb5NotAssociated).Return(nil)
504
505         err := shutdownManager.Shutdown(e2tInstance1)
506
507         assert.IsType(t, &e2managererrors.RnibDbError{}, err)
508         readerMock.AssertExpectations(t)
509         writerMock.AssertExpectations(t)
510         httpClientMock.AssertExpectations(t)
511 }