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