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