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