038c20ac88c7aaf56f670e553423baf9469e87fc
[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         xapp.Logger.Debug("Replacing real db with test db")
59         mainCtrl.c.db = CreateMock() // This overrides real database for testing
60         xapp.SetReadyCB(mainCtrl.ReadyCB, nil)
61         go xapp.RunWithParams(mainCtrl.c, false)
62         mainCtrl.WaitCB()
63         mainCtrl.c.ReadyCB(nil)
64         return mainCtrl
65 }
66
67 func (mc *testingSubmgrControl) SimulateRestart(t *testing.T) {
68         mc.TestLog(t, "Simulating submgr restart")
69         mainCtrl.c.registry.subIds = nil
70         // Initialize subIds slice and subscription map
71         mainCtrl.c.registry.Initialize()
72         // Read subIds and subscriptions from database
73         subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
74         if err != nil {
75                 mc.TestError(t, "%v", err)
76         } else {
77                 mainCtrl.c.registry.register = nil
78                 mainCtrl.c.registry.subIds = subIds
79                 mainCtrl.c.registry.register = register
80
81                 mc.TestLog(t, "register:")
82                 for subId, subs := range register {
83                         mc.TestLog(t, "  subId=%v", subId)
84                         mc.TestLog(t, "  subs.SubRespRcvd=%v", subs.SubRespRcvd)
85                         mc.TestLog(t, "  subs=%v\n", subs)
86                 }
87
88                 mc.TestLog(t, "mainCtrl.c.registry.register:")
89                 for subId, subs := range mainCtrl.c.registry.register {
90                         mc.TestLog(t, "  subId=%v", subId)
91                         mc.TestLog(t, "  subs.SubRespRcvd=%v", subs.SubRespRcvd)
92                         mc.TestLog(t, "  subs=%v\n", subs)
93                 }
94         }
95         go mainCtrl.c.HandleUncompletedSubscriptions(mainCtrl.c.registry.register)
96 }
97
98 func (mc *testingSubmgrControl) SetResetTestFlag(t *testing.T, status bool) {
99         mc.TestLog(t, "ResetTestFlag set to %v=", status)
100         mainCtrl.c.ResetTestFlag = status
101 }
102
103 func (mc *testingSubmgrControl) removeExistingSubscriptions(t *testing.T) {
104
105         mc.TestLog(t, "Removing existing subscriptions")
106         mainCtrl.c.RemoveAllSubscriptionsFromSdl()
107         mainCtrl.c.registry.subIds = nil
108         // Initialize subIds slice and subscription map
109         mainCtrl.c.registry.Initialize()
110 }
111
112 func PringSubscriptionQueryResult(resp models.SubscriptionList) {
113         for _, item := range resp {
114                 fmt.Printf("item.SubscriptionID=%v\n", item.SubscriptionID)
115                 fmt.Printf("item.Meid=%v\n", item.Meid)
116                 fmt.Printf("item.ClientEndpoint=%v\n", item.ClientEndpoint)
117         }
118 }
119
120 func (mc *testingSubmgrControl) wait_registry_empty(t *testing.T, secs int) bool {
121         cnt := int(0)
122         i := 1
123         for ; i <= secs*10; i++ {
124                 cnt = len(mc.c.registry.register)
125                 if cnt == 0 {
126                         return true
127                 }
128                 time.Sleep(100 * time.Millisecond)
129         }
130         mc.TestError(t, "(submgr) no registry empty within %d secs: %d", secs, cnt)
131         return false
132 }
133
134 func (mc *testingSubmgrControl) get_registry_next_subid(t *testing.T) uint32 {
135         mc.c.registry.mutex.Lock()
136         defer mc.c.registry.mutex.Unlock()
137         return mc.c.registry.subIds[0]
138 }
139
140 func (mc *testingSubmgrControl) wait_registry_next_subid_change(t *testing.T, origSubId uint32, secs int) (uint32, bool) {
141         i := 1
142         for ; i <= secs*10; i++ {
143                 mc.c.registry.mutex.Lock()
144                 currSubId := mc.c.registry.subIds[0]
145                 mc.c.registry.mutex.Unlock()
146                 if currSubId != origSubId {
147                         return currSubId, true
148                 }
149                 time.Sleep(100 * time.Millisecond)
150         }
151         mc.TestError(t, "(submgr) no subId change within %d secs", secs)
152         return 0, false
153 }
154
155 func (mc *testingSubmgrControl) wait_subs_clean(t *testing.T, e2SubsId uint32, secs int) bool {
156         var subs *Subscription
157         i := 1
158         for ; i <= secs*10; i++ {
159                 subs = mc.c.registry.GetSubscription(e2SubsId)
160                 if subs == nil {
161                         return true
162                 }
163                 time.Sleep(100 * time.Millisecond)
164         }
165         if subs != nil {
166                 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, subs.String())
167         } else {
168                 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A)", secs)
169         }
170         return false
171 }
172
173 func (mc *testingSubmgrControl) wait_multi_subs_clean(t *testing.T, e2SubsIds []uint32, secs int) bool {
174
175         purgedSubscriptions := 0
176
177         for i := 1; i <= secs*10; i++ {
178                 purgedSubscriptions = 0
179                 for k := 0; k <= len(e2SubsIds); i++ {
180                         subs := mc.c.registry.GetSubscription(e2SubsIds[k])
181                         if subs == nil {
182                                 mc.TestLog(t, "(submgr) subscriber purged for esSubsId %v", e2SubsIds[k])
183                                 purgedSubscriptions += 1
184                                 if purgedSubscriptions == len(e2SubsIds) {
185                                         return true
186                                 }
187                         }
188                 }
189                 mc.TestLog(t, "(submgr) subscriptions pending purging %v/%v after %d msecs", purgedSubscriptions, len(e2SubsIds), i+500)
190                 time.Sleep(100 * time.Millisecond)
191         }
192
193         mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A) - %v/%v subscriptions found still", secs, purgedSubscriptions, len(e2SubsIds))
194
195         return false
196 }
197
198 func (mc *testingSubmgrControl) wait_subs_trans_clean(t *testing.T, e2SubsId uint32, secs int) bool {
199         var trans TransactionIf
200         i := 1
201         for ; i <= secs*10; i++ {
202                 subs := mc.c.registry.GetSubscription(e2SubsId)
203                 if subs == nil {
204                         return true
205                 }
206                 trans = subs.GetTransaction()
207                 if trans == nil {
208                         return true
209                 }
210                 time.Sleep(100 * time.Millisecond)
211         }
212         if trans != nil {
213                 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, trans.String())
214         } else {
215                 mc.TestError(t, "(submgr) no clean within %d secs: trans(N/A)", secs)
216         }
217         return false
218 }
219
220 func (mc *testingSubmgrControl) get_subs_entrypoint_cnt(t *testing.T, origSubId uint32) int {
221         subs := mc.c.registry.GetSubscription(origSubId)
222         if subs == nil {
223                 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt get", origSubId)
224                 return -1
225         }
226         return subs.EpList.Size()
227 }
228
229 func (mc *testingSubmgrControl) wait_subs_entrypoint_cnt_change(t *testing.T, origSubId uint32, orig int, secs int) (int, bool) {
230
231         subs := mc.c.registry.GetSubscription(origSubId)
232         if subs == nil {
233                 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt wait", origSubId)
234                 return -1, true
235         }
236
237         i := 1
238         for ; i <= secs*10; i++ {
239                 curr := subs.EpList.Size()
240                 if curr != orig {
241                         return curr, true
242                 }
243                 time.Sleep(100 * time.Millisecond)
244         }
245         mc.TestError(t, "(submgr) no subs %d entrypoint cnt change within %d secs", origSubId, secs)
246         return 0, false
247 }
248
249 //
250 // Counter check for received message. Note might not be yet handled
251 //
252 func (mc *testingSubmgrControl) get_msgcounter(t *testing.T) uint64 {
253         return mc.c.CntRecvMsg
254 }
255
256 func (mc *testingSubmgrControl) wait_msgcounter_change(t *testing.T, orig uint64, secs int) (uint64, bool) {
257         i := 1
258         for ; i <= secs*10; i++ {
259                 curr := mc.c.CntRecvMsg
260                 if curr != orig {
261                         return curr, true
262                 }
263                 time.Sleep(100 * time.Millisecond)
264         }
265         mc.TestError(t, "(submgr) no msg counter change within %d secs", secs)
266         return 0, false
267 }
268
269 func (mc *testingSubmgrControl) GetMetrics(t *testing.T) (string, error) {
270         req, err := http.NewRequest("GET", "http://localhost:8080/ric/v1/metrics", nil)
271         if err != nil {
272                 return "", fmt.Errorf("Error reading request. %v", err)
273         }
274         client := &http.Client{Timeout: time.Second * 10}
275         resp, err := client.Do(req)
276         if err != nil {
277                 return "", fmt.Errorf("Error reading response. %v", err)
278         }
279         defer resp.Body.Close()
280
281         respBody, err := ioutil.ReadAll(resp.Body)
282         if err != nil {
283                 return "", fmt.Errorf("Error reading body. %v", err)
284         }
285         return string(respBody[:]), nil
286 }
287
288 func (mc *testingSubmgrControl) CounterValuesToBeVeriefied(t *testing.T, countersToBeAdded CountersToBeAdded) {
289
290         if len(toBeAddedCountersMap) == 0 {
291                 toBeAddedCountersMap = make(map[string]Counter)
292         }
293         for _, counter := range countersToBeAdded {
294                 toBeAddedCountersMap[counter.Name] = counter
295         }
296         mc.GetCounterValuesBefore(t)
297 }
298
299 func (mc *testingSubmgrControl) GetCounterValuesBefore(t *testing.T) {
300         countersBeforeMap = make(map[string]Counter)
301         countersBeforeMap = mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
302 }
303
304 func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) {
305         currentCountersMap := mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
306         for _, toBeAddedCounter := range toBeAddedCountersMap {
307                 if currentCounter, ok := currentCountersMap[toBeAddedCounter.Name]; ok == true {
308                         if beforeCounter, ok := countersBeforeMap[toBeAddedCounter.Name]; ok == true {
309                                 if currentCounter.Value != beforeCounter.Value+toBeAddedCounter.Value {
310                                         mc.TestError(t, "Error in expected counter value: counterName %v, current value %v, expected value %v",
311                                                 currentCounter.Name, currentCounter.Value, beforeCounter.Value+toBeAddedCounter.Value)
312
313                                         //fmt.Printf("beforeCounter.Value=%v, toBeAddedCounter.Value=%v, \n",beforeCounter.Value, toBeAddedCounter.Value)
314                                 }
315                         } else {
316                                 mc.TestError(t, "Counter %v not in countersBeforeMap", toBeAddedCounter.Name)
317                         }
318                 } else {
319                         mc.TestError(t, "Counter %v not in currentCountersMap", toBeAddedCounter.Name)
320                 }
321         }
322
323         // Make map empty
324         //fmt.Printf("toBeAddedCountersMap=%v\n",toBeAddedCountersMap)
325         toBeAddedCountersMap = make(map[string]Counter)
326 }
327
328 func (mc *testingSubmgrControl) GetCurrentCounterValues(t *testing.T, chekedCountersMap map[string]Counter) map[string]Counter {
329         countersString, err := mc.GetMetrics(t)
330         if err != nil {
331                 mc.TestError(t, "Error GetMetrics() failed %v", err)
332                 return nil
333         }
334
335         retCounterMap := make(map[string]Counter)
336         stringsTable := strings.Split(countersString, "\n")
337         for _, counter := range chekedCountersMap {
338                 for _, counterString := range stringsTable {
339                         if !strings.Contains(counterString, "#") && strings.Contains(counterString, counter.Name) {
340                                 counterString := strings.Split(counterString, " ")
341                                 if strings.Contains(counterString[0], counter.Name) {
342                                         val, err := strconv.ParseUint(counterString[1], 10, 64)
343                                         if err != nil {
344                                                 mc.TestError(t, "Error: strconv.ParseUint failed %v", err)
345                                         }
346                                         counter.Value = val
347                                         //fmt.Printf("counter=%v\n", counter)
348                                         retCounterMap[counter.Name] = counter
349                                 }
350                         }
351                 }
352         }
353
354         if len(retCounterMap) != len(chekedCountersMap) {
355                 mc.TestError(t, "Error: len(retCounterMap) != len(chekedCountersMap)")
356
357         }
358         return retCounterMap
359 }
360
361 func (mc *testingSubmgrControl) sendGetRequest(t *testing.T, addr string, path string) {
362
363         mc.TestLog(t, "GET http://"+addr+"%v", path)
364         req, err := http.NewRequest("GET", "http://"+addr+path, nil)
365         if err != nil {
366                 mc.TestError(t, "Error reading request. %v", err)
367                 return
368         }
369         req.Header.Set("Cache-Control", "no-cache")
370         client := &http.Client{Timeout: time.Second * 2}
371         resp, err := client.Do(req)
372         if err != nil {
373                 mc.TestError(t, "Error reading response. %v", err)
374                 return
375         }
376         defer resp.Body.Close()
377
378         mc.TestLog(t, "Response status: %v", resp.Status)
379         mc.TestLog(t, "Response Headers: %v", resp.Header)
380         if !strings.Contains(resp.Status, "200 OK") {
381                 mc.TestError(t, "Wrong response status")
382                 return
383         }
384
385         respBody, err := ioutil.ReadAll(resp.Body)
386         if err != nil {
387                 mc.TestError(t, "Error reading body. %v", err)
388                 return
389         }
390         mc.TestLog(t, "%s", respBody)
391         return
392 }
393
394 func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path string) {
395
396         mc.TestLog(t, "POST http://"+addr+"%v", path)
397         req, err := http.NewRequest("POST", "http://"+addr+path, nil)
398         if err != nil {
399                 mc.TestError(t, "Error reading request. %v", err)
400                 return
401         }
402         client := &http.Client{Timeout: time.Second * 2}
403         resp, err := client.Do(req)
404         if err != nil {
405                 mc.TestError(t, "Error reading response. %v", err)
406                 return
407         }
408         defer resp.Body.Close()
409
410         mc.TestLog(t, "Response status: %v", resp.Status)
411         mc.TestLog(t, "Response Headers: %v", resp.Header)
412         if !strings.Contains(resp.Status, "200 OK") {
413                 mc.TestError(t, "Wrong response status")
414                 return
415         }
416
417         respBody, err := ioutil.ReadAll(resp.Body)
418         if err != nil {
419                 mc.TestError(t, "Error reading body. %v", err)
420                 return
421         }
422         mc.TestLog(t, "%s", respBody)
423         return
424 }