E2 restart handling added
[ric-plt/submgr.git] / pkg / control / ut_ctrl_submgr_test.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 AT&T Intellectual Property.
4   Copyright (c) 2019 Nokia
5
6    Licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8    You may obtain a copy of the License at
9
10        http://www.apache.org/licenses/LICENSE-2.0
11
12    Unless required by applicable law or agreed to in writing, software
13    distributed under the License is distributed on an "AS IS" BASIS,
14    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15    See the License for the specific language governing permissions and
16    limitations under the License.
17 ==================================================================================
18 */
19
20 package control
21
22 import (
23         "fmt"
24         "io/ioutil"
25         "net/http"
26         "strconv"
27         "strings"
28         "testing"
29         "time"
30
31         "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststub"
32         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
33         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
34 )
35
36 //-----------------------------------------------------------------------------
37 //
38 //-----------------------------------------------------------------------------
39 type testingSubmgrControl struct {
40         teststub.RmrControl
41         c *Control
42 }
43
44 type Counter struct {
45         Name  string
46         Value uint64
47 }
48
49 type CountersToBeAdded []Counter
50
51 var countersBeforeMap map[string]Counter
52 var toBeAddedCountersMap map[string]Counter
53
54 func createSubmgrControl(srcId teststub.RmrSrcId, rtgSvc teststub.RmrRtgSvc) *testingSubmgrControl {
55         mainCtrl = &testingSubmgrControl{}
56         mainCtrl.RmrControl.Init("SUBMGRCTL", srcId, rtgSvc)
57         mainCtrl.c = NewControl()
58         mainCtrl.c.UTTesting = true
59         mainCtrl.c.LoggerLevel = int(xapp.Logger.GetLevel())
60         xapp.Logger.Debug("Test: LoggerLevel %v", mainCtrl.c.LoggerLevel)
61         xapp.Logger.Debug("Replacing real db with test db")
62         mainCtrl.c.e2SubsDb = CreateMock()              // This overrides real E2 Subscription database for testing
63         mainCtrl.c.restSubsDb = CreateRestSubsDbMock()  // This overrides real REST Subscription database for testing
64         mainCtrl.c.e2IfStateDb = CreateXappRnibIfMock() // This overrides real RNIB database for testing
65         xapp.SetReadyCB(mainCtrl.ReadyCB, nil)
66         go xapp.RunWithParams(mainCtrl.c, false)
67         mainCtrl.WaitCB()
68         mainCtrl.c.ReadyCB(nil)
69         return mainCtrl
70 }
71
72 func (mc *testingSubmgrControl) SimulateRestart(t *testing.T) {
73         mc.TestLog(t, "Simulating submgr restart")
74         mainCtrl.c.registry.subIds = nil
75         // Initialize subIds slice and subscription map
76         mainCtrl.c.registry.Initialize()
77         mainCtrl.c.restDuplicateCtrl.Init()
78         // Read subIds and subscriptions from database
79         subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
80         if err != nil {
81                 mc.TestError(t, "%v", err)
82         } else {
83                 mainCtrl.c.registry.subIds = subIds
84                 mainCtrl.c.registry.register = register
85                 mc.TestLog(t, "mainCtrl.c.registry.register:")
86                 for subId, subs := range mainCtrl.c.registry.register {
87                         mc.TestLog(t, "  subId=%v", subId)
88                         mc.TestLog(t, "  subs.SubRespRcvd=%v", subs.SubRespRcvd)
89                         mc.TestLog(t, "  subs=%v\n", subs)
90                 }
91         }
92         restSubscriptions, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl()
93         if err != nil {
94                 mc.TestError(t, "%v", err)
95         } else {
96                 mainCtrl.c.registry.restSubscriptions = restSubscriptions
97                 mc.TestLog(t, "mainCtrl.c.registry.restSubscriptions:")
98                 for restSubId, restSubs := range mainCtrl.c.registry.restSubscriptions {
99                         mc.TestLog(t, "  restSubId=%v", restSubId)
100                         mc.TestLog(t, "  restSubs=%v\n", restSubs)
101                 }
102         }
103
104         go mainCtrl.c.HandleUncompletedSubscriptions(mainCtrl.c.registry.register)
105 }
106
107 func (mc *testingSubmgrControl) MakeTransactionNil(t *testing.T, subId uint32) {
108
109         mc.TestLog(t, "Makin transaction nil for SubId=%v", subId)
110         subs := mainCtrl.c.registry.GetSubscription(subId)
111         subs.TheTrans = nil
112 }
113
114 func (mc *testingSubmgrControl) SetResetTestFlag(t *testing.T, status bool) {
115         mc.TestLog(t, "ResetTestFlag set to %v", status)
116         mainCtrl.c.ResetTestFlag = status
117 }
118
119 func (mc *testingSubmgrControl) removeExistingSubscriptions(t *testing.T) {
120
121         mc.TestLog(t, "Removing existing subscriptions")
122         mainCtrl.c.RemoveAllSubscriptionsFromSdl()
123         mainCtrl.c.registry.subIds = nil
124         // Initialize subIds slice and subscription map
125         mainCtrl.c.registry.Initialize()
126 }
127
128 func PringSubscriptionQueryResult(resp models.SubscriptionList) {
129         for _, item := range resp {
130                 fmt.Printf("item.SubscriptionID=%v\n", item.SubscriptionID)
131                 fmt.Printf("item.Meid=%v\n", item.Meid)
132                 fmt.Printf("item.ClientEndpoint=%v\n", item.ClientEndpoint)
133         }
134 }
135
136 func (mc *testingSubmgrControl) wait_registry_empty(t *testing.T, secs int) bool {
137         cnt := int(0)
138         i := 1
139         for ; i <= secs*10; i++ {
140                 cnt = len(mc.c.registry.register)
141                 if cnt == 0 {
142                         return true
143                 }
144                 time.Sleep(100 * time.Millisecond)
145         }
146         mc.TestError(t, "(submgr) no registry empty within %d secs: %d, register: %v", secs, cnt, mc.c.registry.register)
147         return false
148 }
149
150 func (mc *testingSubmgrControl) get_registry_next_subid(t *testing.T) uint32 {
151         mc.c.registry.mutex.Lock()
152         defer mc.c.registry.mutex.Unlock()
153         return mc.c.registry.subIds[0]
154 }
155
156 func (mc *testingSubmgrControl) wait_registry_next_subid_change(t *testing.T, origSubId uint32, secs int) (uint32, bool) {
157         i := 1
158         for ; i <= secs*10; i++ {
159                 mc.c.registry.mutex.Lock()
160                 currSubId := mc.c.registry.subIds[0]
161                 mc.c.registry.mutex.Unlock()
162                 if currSubId != origSubId {
163                         return currSubId, true
164                 }
165                 time.Sleep(100 * time.Millisecond)
166         }
167         mc.TestError(t, "(submgr) no subId change within %d secs", secs)
168         return 0, false
169 }
170
171 func (mc *testingSubmgrControl) wait_subs_clean(t *testing.T, e2SubsId uint32, secs int) bool {
172         var subs *Subscription
173         i := 1
174         for ; i <= secs*10; i++ {
175                 subs = mc.c.registry.GetSubscription(e2SubsId)
176                 if subs == nil {
177                         return true
178                 }
179                 time.Sleep(100 * time.Millisecond)
180         }
181         if subs != nil {
182                 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, subs.String())
183         } else {
184                 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A)", secs)
185         }
186         return false
187 }
188
189 func (mc *testingSubmgrControl) wait_multi_subs_clean(t *testing.T, e2SubsIds []uint32, secs int) bool {
190
191         purgedSubscriptions := 0
192
193         for i := 1; i <= secs*10; i++ {
194                 purgedSubscriptions = 0
195                 for k := 0; k <= len(e2SubsIds); i++ {
196                         subs := mc.c.registry.GetSubscription(e2SubsIds[k])
197                         if subs == nil {
198                                 mc.TestLog(t, "(submgr) subscriber purged for esSubsId %v", e2SubsIds[k])
199                                 purgedSubscriptions += 1
200                                 if purgedSubscriptions == len(e2SubsIds) {
201                                         return true
202                                 }
203                         }
204                 }
205                 mc.TestLog(t, "(submgr) subscriptions pending purging %v/%v after %d msecs", purgedSubscriptions, len(e2SubsIds), i+500)
206                 time.Sleep(100 * time.Millisecond)
207         }
208
209         mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A) - %v/%v subscriptions found still", secs, purgedSubscriptions, len(e2SubsIds))
210
211         return false
212 }
213
214 func (mc *testingSubmgrControl) wait_subs_trans_clean(t *testing.T, e2SubsId uint32, secs int) bool {
215         var trans TransactionIf
216         i := 1
217         for ; i <= secs*10; i++ {
218                 subs := mc.c.registry.GetSubscription(e2SubsId)
219                 if subs == nil {
220                         return true
221                 }
222                 trans = subs.GetTransaction()
223                 if trans == nil {
224                         return true
225                 }
226                 time.Sleep(100 * time.Millisecond)
227         }
228         if trans != nil {
229                 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, trans.String())
230         } else {
231                 mc.TestError(t, "(submgr) no clean within %d secs: trans(N/A)", secs)
232         }
233         return false
234 }
235
236 func (mc *testingSubmgrControl) get_subs_entrypoint_cnt(t *testing.T, origSubId uint32) int {
237         subs := mc.c.registry.GetSubscription(origSubId)
238         if subs == nil {
239                 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt get", origSubId)
240                 return -1
241         }
242         return subs.EpList.Size()
243 }
244
245 func (mc *testingSubmgrControl) wait_subs_entrypoint_cnt_change(t *testing.T, origSubId uint32, orig int, secs int) (int, bool) {
246
247         subs := mc.c.registry.GetSubscription(origSubId)
248         if subs == nil {
249                 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt wait", origSubId)
250                 return -1, true
251         }
252
253         i := 1
254         for ; i <= secs*10; i++ {
255                 curr := subs.EpList.Size()
256                 if curr != orig {
257                         return curr, true
258                 }
259                 time.Sleep(100 * time.Millisecond)
260         }
261         mc.TestError(t, "(submgr) no subs %d entrypoint cnt change within %d secs", origSubId, secs)
262         return 0, false
263 }
264
265 //
266 // Counter check for received message. Note might not be yet handled
267 //
268 func (mc *testingSubmgrControl) get_msgcounter(t *testing.T) uint64 {
269         return mc.c.CntRecvMsg
270 }
271
272 func (mc *testingSubmgrControl) wait_msgcounter_change(t *testing.T, orig uint64, secs int) (uint64, bool) {
273         i := 1
274         for ; i <= secs*10; i++ {
275                 curr := mc.c.CntRecvMsg
276                 if curr != orig {
277                         return curr, true
278                 }
279                 time.Sleep(100 * time.Millisecond)
280         }
281         mc.TestError(t, "(submgr) no msg counter change within %d secs", secs)
282         return 0, false
283 }
284
285 func (mc *testingSubmgrControl) GetMetrics(t *testing.T) (string, error) {
286         req, err := http.NewRequest("GET", "http://localhost:8080/ric/v1/metrics", nil)
287         if err != nil {
288                 return "", fmt.Errorf("Error reading request. %v", err)
289         }
290         client := &http.Client{Timeout: time.Second * 10}
291         resp, err := client.Do(req)
292         if err != nil {
293                 return "", fmt.Errorf("Error reading response. %v", err)
294         }
295         defer resp.Body.Close()
296
297         respBody, err := ioutil.ReadAll(resp.Body)
298         if err != nil {
299                 return "", fmt.Errorf("Error reading body. %v", err)
300         }
301         return string(respBody[:]), nil
302 }
303
304 func (mc *testingSubmgrControl) CounterValuesToBeVeriefied(t *testing.T, countersToBeAdded CountersToBeAdded) {
305
306         if len(toBeAddedCountersMap) == 0 {
307                 toBeAddedCountersMap = make(map[string]Counter)
308         }
309         for _, counter := range countersToBeAdded {
310                 toBeAddedCountersMap[counter.Name] = counter
311         }
312         mc.GetCounterValuesBefore(t)
313 }
314
315 func (mc *testingSubmgrControl) GetCounterValuesBefore(t *testing.T) {
316         countersBeforeMap = make(map[string]Counter)
317         countersBeforeMap = mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
318 }
319
320 func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) {
321
322         // Check that expected counters are added ok
323         currentCountersMap := mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
324         for _, toBeAddedCounter := range toBeAddedCountersMap {
325                 if currentCounter, ok := currentCountersMap[toBeAddedCounter.Name]; ok == true {
326                         if beforeCounter, ok := countersBeforeMap[toBeAddedCounter.Name]; ok == true {
327                                 if currentCounter.Value != beforeCounter.Value+toBeAddedCounter.Value {
328                                         mc.TestError(t, "Error in expected counter value: counterName %v, current value %v, expected value %v",
329                                                 currentCounter.Name, currentCounter.Value, beforeCounter.Value+toBeAddedCounter.Value)
330
331                                         //fmt.Printf("beforeCounter.Value=%v, toBeAddedCounter.Value=%v, \n",beforeCounter.Value, toBeAddedCounter.Value)
332                                 }
333                         } else {
334                                 mc.TestError(t, "Counter %v not in countersBeforeMap", toBeAddedCounter.Name)
335                         }
336                 } else {
337                         mc.TestError(t, "Counter %v not in currentCountersMap", toBeAddedCounter.Name)
338                 }
339         }
340
341         // Check that not any unexpected counter are added (this is not working correctly!)
342         for _, currentCounter := range currentCountersMap {
343                 if _, ok := toBeAddedCountersMap[currentCounter.Name]; ok == false {
344                         if beforeCounter, ok := countersBeforeMap[currentCounter.Name]; ok == true {
345                                 if currentCounter.Value != beforeCounter.Value {
346                                         mc.TestError(t, "Error: unexpected counter value added: counterName %v, current value %v, expected value %v",
347                                                 currentCounter.Name, beforeCounter.Value, beforeCounter.Value)
348
349                                         //fmt.Printf("beforeCounter.Value=%v, toBeAddedCounter.Value=%v, \n",beforeCounter.Value, toBeAddedCounter.Value)
350                                 }
351                         } else {
352                                 mc.TestError(t, "Counter %v not in countersBeforeMap", beforeCounter.Name)
353                         }
354                 }
355         }
356
357         // Make map empty
358         //fmt.Printf("toBeAddedCountersMap=%v\n",toBeAddedCountersMap)
359         toBeAddedCountersMap = make(map[string]Counter)
360 }
361
362 func (mc *testingSubmgrControl) GetCurrentCounterValues(t *testing.T, chekedCountersMap map[string]Counter) map[string]Counter {
363         countersString, err := mc.GetMetrics(t)
364         if err != nil {
365                 mc.TestError(t, "Error GetMetrics() failed %v", err)
366                 return nil
367         }
368
369         retCounterMap := make(map[string]Counter)
370         stringsTable := strings.Split(countersString, "\n")
371         for _, counter := range chekedCountersMap {
372                 for _, counterString := range stringsTable {
373                         if !strings.Contains(counterString, "#") && strings.Contains(counterString, counter.Name) {
374                                 counterString := strings.Split(counterString, " ")
375                                 if strings.Contains(counterString[0], counter.Name) {
376                                         val, err := strconv.ParseUint(counterString[1], 10, 64)
377                                         if err != nil {
378                                                 mc.TestError(t, "Error: strconv.ParseUint failed %v", err)
379                                         }
380                                         counter.Value = val
381                                         //fmt.Printf("counter=%v\n", counter)
382                                         retCounterMap[counter.Name] = counter
383                                 }
384                         }
385                 }
386         }
387
388         if len(retCounterMap) != len(chekedCountersMap) {
389                 mc.TestError(t, "Error: len(retCounterMap) != len(chekedCountersMap)")
390
391         }
392         return retCounterMap
393 }
394
395 func (mc *testingSubmgrControl) sendGetRequest(t *testing.T, addr string, path string) {
396
397         mc.TestLog(t, "GET http://"+addr+"%v", path)
398         req, err := http.NewRequest("GET", "http://"+addr+path, nil)
399         if err != nil {
400                 mc.TestError(t, "Error reading request. %v", err)
401                 return
402         }
403         req.Header.Set("Cache-Control", "no-cache")
404         client := &http.Client{Timeout: time.Second * 2}
405         resp, err := client.Do(req)
406         if err != nil {
407                 mc.TestError(t, "Error reading response. %v", err)
408                 return
409         }
410         defer resp.Body.Close()
411
412         mc.TestLog(t, "Response status: %v", resp.Status)
413         mc.TestLog(t, "Response Headers: %v", resp.Header)
414         if !strings.Contains(resp.Status, "200 OK") {
415                 mc.TestError(t, "Wrong response status")
416                 return
417         }
418
419         respBody, err := ioutil.ReadAll(resp.Body)
420         if err != nil {
421                 mc.TestError(t, "Error reading body. %v", err)
422                 return
423         }
424         mc.TestLog(t, "%s", respBody)
425         return
426 }
427
428 func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path string) {
429
430         mc.TestLog(t, "POST http://"+addr+"%v", path)
431         req, err := http.NewRequest("POST", "http://"+addr+path, nil)
432         if err != nil {
433                 mc.TestError(t, "Error reading request. %v", err)
434                 return
435         }
436         client := &http.Client{Timeout: time.Second * 2}
437         resp, err := client.Do(req)
438         if err != nil {
439                 mc.TestError(t, "Error reading response. %v", err)
440                 return
441         }
442         defer resp.Body.Close()
443
444         mc.TestLog(t, "Response status: %v", resp.Status)
445         mc.TestLog(t, "Response Headers: %v", resp.Header)
446         if !strings.Contains(resp.Status, "200 OK") {
447                 mc.TestError(t, "Wrong response status")
448                 return
449         }
450
451         respBody, err := ioutil.ReadAll(resp.Body)
452         if err != nil {
453                 mc.TestError(t, "Error reading body. %v", err)
454                 return
455         }
456         mc.TestLog(t, "%s", respBody)
457         return
458 }
459
460 //-----------------------------------------------------------------------------
461 //
462 //-----------------------------------------------------------------------------
463 func (mc *testingSubmgrControl) SetE2State(t *testing.T, ranNameState string) {
464
465         if err := mc.c.e2IfStateDb.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", ranNameState, "key1", "data1"); err != nil {
466                 t.Errorf("XappRnibStoreAndPublish failed: %v", err)
467         }
468 }