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