2 ==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
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
10 http://www.apache.org/licenses/LICENSE-2.0
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 ==================================================================================
31 "github.com/stretchr/testify/assert"
33 "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststub"
34 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
35 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
38 //-----------------------------------------------------------------------------
40 //-----------------------------------------------------------------------------
41 type testingSubmgrControl struct {
51 type CountersToBeAdded []Counter
53 var allCountersMap map[string]Counter
54 var allCountersBeforeMap map[string]Counter
55 var toBeAddedCountersBeforeMap map[string]Counter
56 var toBeAddedCountersMap map[string]Counter
58 func createSubmgrControl(srcId teststub.RmrSrcId, rtgSvc teststub.RmrRtgSvc) *testingSubmgrControl {
59 mainCtrl = &testingSubmgrControl{}
60 mainCtrl.RmrControl.Init("SUBMGRCTL", srcId, rtgSvc)
61 mainCtrl.c = NewControl()
62 mainCtrl.c.UTTesting = true
63 mainCtrl.c.LoggerLevel = 4
64 mainCtrl.c.e2ap.SetASN1DebugPrintStatus(mainCtrl.c.LoggerLevel)
65 xapp.Logger.Debug("Test: LoggerLevel %v", mainCtrl.c.LoggerLevel)
66 xapp.Logger.Debug("Replacing real db with test db")
67 mainCtrl.c.e2SubsDb = CreateMock() // This overrides real E2 Subscription database for testing
68 mainCtrl.c.restSubsDb = CreateRestSubsDbMock() // This overrides real REST Subscription database for testing
69 mainCtrl.c.e2IfStateDb = CreateXappRnibIfMock() // This overrides real RNIB database for testing
70 xapp.SetReadyCB(mainCtrl.ReadyCB, nil)
71 go xapp.RunWithParams(mainCtrl.c, false)
73 mainCtrl.c.ReadyCB(nil)
77 func (mc *testingSubmgrControl) SimulateRestart(t *testing.T) {
78 mc.TestLog(t, "Simulating submgr restart")
80 // Initialize subIds slice and subscription map
81 mainCtrl.c.registry.subIds = nil
82 mainCtrl.c.registry.Initialize()
83 mainCtrl.c.restDuplicateCtrl.Init()
85 // Read subIds and subscriptions from database
86 go mainCtrl.c.ReadE2Subscriptions() // This needs to be run in own go routine when called from here <<--- improve this
87 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)
95 // Read REST subIds and REST subscriptions from database
96 mainCtrl.c.ReadRESTSubscriptions()
97 mc.TestLog(t, "mainCtrl.c.registry.restSubscriptions:")
98 for restSubId, restSubs := range mainCtrl.c.registry.restSubscriptions {
99 mc.TestLog(t, " restSubId=%v", restSubId)
100 mc.TestLog(t, " restSubs=%v\n", restSubs)
102 //go mainCtrl.c.HandleUncompletedSubscriptions(mainCtrl.c.registry.register) // This needs to be run in own go routine when called from here
105 func (mc *testingSubmgrControl) MakeTransactionNil(t *testing.T, subId uint32) {
107 mc.TestLog(t, "Makin transaction nil for SubId=%v", subId)
108 subs := mainCtrl.c.registry.GetSubscription(subId)
112 func (mc *testingSubmgrControl) SetResetTestFlag(t *testing.T, status bool) {
113 mc.TestLog(t, "ResetTestFlag set to %v", status)
114 mainCtrl.c.ResetTestFlag = status
117 func (mc *testingSubmgrControl) removeExistingSubscriptions(t *testing.T) {
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()
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)
134 func (mc *testingSubmgrControl) wait_registry_empty(t *testing.T, secs int) bool {
137 for ; i <= secs*10; i++ {
138 cnt = len(mc.c.registry.register)
142 time.Sleep(100 * time.Millisecond)
144 mc.TestError(t, "(submgr) no registry empty within %d secs: %d, register: %v", secs, cnt, mc.c.registry.register)
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]
154 func (mc *testingSubmgrControl) wait_registry_next_subid_change(t *testing.T, origSubId uint32, secs int) (uint32, bool) {
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
163 time.Sleep(100 * time.Millisecond)
165 mc.TestError(t, "(submgr) no subId change within %d secs", secs)
169 func (mc *testingSubmgrControl) wait_subs_clean(t *testing.T, e2SubsId uint32, secs int) bool {
170 var subs *Subscription
172 for ; i <= secs*10; i++ {
173 subs = mc.c.registry.GetSubscription(e2SubsId)
177 time.Sleep(100 * time.Millisecond)
180 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, subs.String())
182 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A)", secs)
187 func (mc *testingSubmgrControl) wait_multi_subs_clean(t *testing.T, e2SubsIds []uint32, secs int) bool {
189 purgedSubscriptions := 0
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])
196 mc.TestLog(t, "(submgr) subscriber purged for esSubsId %v", e2SubsIds[k])
197 purgedSubscriptions += 1
198 if purgedSubscriptions == len(e2SubsIds) {
203 mc.TestLog(t, "(submgr) subscriptions pending purging %v/%v after %d msecs", purgedSubscriptions, len(e2SubsIds), i+500)
204 time.Sleep(100 * time.Millisecond)
207 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A) - %v/%v subscriptions found still", secs, purgedSubscriptions, len(e2SubsIds))
212 func (mc *testingSubmgrControl) wait_subs_trans_clean(t *testing.T, e2SubsId uint32, secs int) bool {
213 var trans TransactionIf
215 for ; i <= secs*10; i++ {
216 subs := mc.c.registry.GetSubscription(e2SubsId)
220 trans = subs.GetTransaction()
224 time.Sleep(100 * time.Millisecond)
227 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, trans.String())
229 mc.TestError(t, "(submgr) no clean within %d secs: trans(N/A)", secs)
234 func (mc *testingSubmgrControl) get_subs_entrypoint_cnt(t *testing.T, origSubId uint32) int {
235 subs := mc.c.registry.GetSubscription(origSubId)
237 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt get", origSubId)
240 return subs.EpList.Size()
243 func (mc *testingSubmgrControl) wait_subs_entrypoint_cnt_change(t *testing.T, origSubId uint32, orig int, secs int) (int, bool) {
245 subs := mc.c.registry.GetSubscription(origSubId)
247 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt wait", origSubId)
252 for ; i <= secs*10; i++ {
253 curr := subs.EpList.Size()
257 time.Sleep(100 * time.Millisecond)
259 mc.TestError(t, "(submgr) no subs %d entrypoint cnt change within %d secs", origSubId, secs)
264 // Counter check for received message. Note might not be yet handled
266 func (mc *testingSubmgrControl) get_msgcounter(t *testing.T) uint64 {
267 return mc.c.CntRecvMsg
270 func (mc *testingSubmgrControl) wait_msgcounter_change(t *testing.T, orig uint64, secs int) (uint64, bool) {
272 for ; i <= secs*10; i++ {
273 curr := mc.c.CntRecvMsg
277 time.Sleep(100 * time.Millisecond)
279 mc.TestError(t, "(submgr) no msg counter change within %d secs", secs)
283 func (mc *testingSubmgrControl) VerifyAllClean(t *testing.T) {
285 // Verify that all resources are freed. Wait cleaning up to 10 seconds
286 for i := 0; i < 100; i++ {
287 if len(mainCtrl.c.registry.register) == 0 && len(mainCtrl.c.registry.restSubscriptions) == 0 {
288 RESTKeyCount, err := mainCtrl.c.GetRESTKeyCount()
290 t.Errorf("TEST: %s", err.Error())
292 E2KeyCount, err := mainCtrl.c.GetE2KeyCount()
294 t.Errorf("TEST: %s", err.Error())
296 if RESTKeyCount == 0 && E2KeyCount == 0 {
300 <-time.After(time.Millisecond * 100)
301 xapp.Logger.Debug("VerifyAllClean delay plus 100ms")
304 assert.Equal(t, 0, len(mainCtrl.c.registry.register))
305 if len(mainCtrl.c.registry.register) > 0 {
306 fmt.Printf("registry.register: %v\n", mainCtrl.c.registry.register)
308 assert.Equal(t, 0, len(mainCtrl.c.registry.restSubscriptions))
309 if len(mainCtrl.c.registry.restSubscriptions) > 0 {
310 fmt.Printf("registry.restSubscriptions: %v\n", mainCtrl.c.registry.restSubscriptions)
312 verifyRESTKeyCount(t, 0)
313 verifyE2KeyCount(t, 0)
316 func (mc *testingSubmgrControl) WaitOngoingRequestMapEmpty() {
317 for i := 0; i < 100; i++ {
318 if len(mainCtrl.c.restDuplicateCtrl.ongoingRequestMap) != 0 {
319 <-time.After(time.Millisecond * 100)
320 xapp.Logger.Debug("WaitOngoingRequestMapEmpty delay plus 100ms")
325 func (mc *testingSubmgrControl) GetMetrics(t *testing.T) (string, error) {
326 req, err := http.NewRequest("GET", "http://localhost:8080/ric/v1/metrics", nil)
328 return "", fmt.Errorf("Error reading request. %v", err)
330 client := &http.Client{Timeout: time.Second * 10}
331 resp, err := client.Do(req)
333 return "", fmt.Errorf("Error reading response. %v", err)
335 defer resp.Body.Close()
337 respBody, err := ioutil.ReadAll(resp.Body)
339 return "", fmt.Errorf("Error reading body. %v", err)
341 return string(respBody[:]), nil
344 func (mc *testingSubmgrControl) InitAllCounterMap() {
345 counterOpts := GetMetricsOpts()
347 allCountersMap = make(map[string]Counter)
348 for _, counterOpt := range counterOpts {
349 //fmt.Printf("counterOpt.Name: '%v'\n", counterOpt.Name)
350 counter := Counter{counterOpt.Name, 0}
351 allCountersMap[counterOpt.Name] = counter
355 func (mc *testingSubmgrControl) CounterValuesToBeVeriefied(t *testing.T, countersToBeAdded CountersToBeAdded) {
357 if len(toBeAddedCountersMap) == 0 {
358 toBeAddedCountersMap = make(map[string]Counter)
360 for _, counter := range countersToBeAdded {
361 toBeAddedCountersMap[counter.Name] = counter
363 mc.GetCounterValuesBefore(t)
366 func (mc *testingSubmgrControl) GetCounterValuesBefore(t *testing.T) {
367 toBeAddedCountersBeforeMap = make(map[string]Counter)
368 toBeAddedCountersBeforeMap = mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
369 allCountersBeforeMap = make(map[string]Counter)
370 allCountersBeforeMap = mc.GetCurrentCounterValues(t, allCountersMap)
373 func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) {
375 // Check that expected counters are added ok
376 // Get current values of counters exected to be added
377 currentCountersMap := mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
378 for _, toBeAddedCounter := range toBeAddedCountersMap {
379 if currentCounter, ok := currentCountersMap[toBeAddedCounter.Name]; ok == true {
380 if beforeCounter, ok := toBeAddedCountersBeforeMap[toBeAddedCounter.Name]; ok == true {
381 if currentCounter.Value != beforeCounter.Value+toBeAddedCounter.Value {
382 mc.TestError(t, "Error in expected counter value: counterName %v, current value %v, expected value %v",
383 currentCounter.Name, currentCounter.Value, beforeCounter.Value+toBeAddedCounter.Value)
386 mc.TestError(t, "Counter %v not in toBeAddedCountersBeforeMap", toBeAddedCounter.Name)
389 mc.TestError(t, "Counter %v not in currentCountersMap", toBeAddedCounter.Name)
393 // Check that not any unexpected counter are added
394 // Get current values of all counters
395 currentCountersMap = mc.GetCurrentCounterValues(t, allCountersMap)
396 for _, currentCounter := range currentCountersMap {
397 if _, ok := toBeAddedCountersMap[currentCounter.Name]; ok == false {
398 if beforeCounter, ok := allCountersBeforeMap[currentCounter.Name]; ok == true {
399 if currentCounter.Value != beforeCounter.Value {
400 mc.TestError(t, "Error: unexpected counter added: counterName %v, current value %v, expected value %v",
401 currentCounter.Name, currentCounter.Value, beforeCounter.Value)
408 toBeAddedCountersMap = make(map[string]Counter)
409 allCountersBeforeMap = make(map[string]Counter)
412 func (mc *testingSubmgrControl) GetCurrentCounterValues(t *testing.T, chekedCountersMap map[string]Counter) map[string]Counter {
413 countersString, err := mc.GetMetrics(t)
415 mc.TestError(t, "Error GetMetrics() failed %v", err)
419 retCounterMap := make(map[string]Counter)
420 stringsTable := strings.Split(countersString, "\n")
421 for _, counter := range chekedCountersMap {
422 for _, counterString := range stringsTable {
423 if !strings.Contains(counterString, "#") && strings.Contains(counterString, counter.Name) {
424 counterString := strings.Split(counterString, " ")
425 if strings.Contains(counterString[0], counter.Name) {
426 val, err := strconv.ParseUint(counterString[1], 10, 64)
428 mc.TestError(t, "Error: strconv.ParseUint failed %v", err)
431 //fmt.Printf("counter=%v\n", counter)
432 retCounterMap[counter.Name] = counter
438 if len(retCounterMap) != len(chekedCountersMap) {
439 mc.TestError(t, "Error: len(retCounterMap) != len(chekedCountersMap)")
444 func (mc *testingSubmgrControl) sendGetRequest(t *testing.T, addr string, path string) {
446 mc.TestLog(t, "GET http://"+addr+"%v", path)
447 req, err := http.NewRequest("GET", "http://"+addr+path, nil)
449 mc.TestError(t, "Error reading request. %v", err)
452 req.Header.Set("Cache-Control", "no-cache")
453 client := &http.Client{Timeout: time.Second * 2}
454 resp, err := client.Do(req)
456 mc.TestError(t, "Error reading response. %v", err)
459 defer resp.Body.Close()
461 mc.TestLog(t, "Response status: %v", resp.Status)
462 mc.TestLog(t, "Response Headers: %v", resp.Header)
463 if !strings.Contains(resp.Status, "200 OK") {
464 mc.TestError(t, "Wrong response status")
468 respBody, err := ioutil.ReadAll(resp.Body)
470 mc.TestError(t, "Error reading body. %v", err)
473 mc.TestLog(t, "%s", respBody)
477 func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path string) {
479 mc.TestLog(t, "POST http://"+addr+"%v", path)
480 req, err := http.NewRequest("POST", "http://"+addr+path, nil)
482 mc.TestError(t, "Error reading request. %v", err)
485 client := &http.Client{Timeout: time.Second * 2}
486 resp, err := client.Do(req)
488 mc.TestError(t, "Error reading response. %v", err)
491 defer resp.Body.Close()
493 mc.TestLog(t, "Response status: %v", resp.Status)
494 mc.TestLog(t, "Response Headers: %v", resp.Header)
495 if !strings.Contains(resp.Status, "200 OK") {
496 mc.TestError(t, "Wrong response status")
500 respBody, err := ioutil.ReadAll(resp.Body)
502 mc.TestError(t, "Error reading body. %v", err)
505 mc.TestLog(t, "%s", respBody)
509 //-----------------------------------------------------------------------------
511 //-----------------------------------------------------------------------------
512 func (mc *testingSubmgrControl) SetE2State(t *testing.T, ranNameState string) {
514 if err := mc.c.e2IfStateDb.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", ranNameState, "key1", "data1"); err != nil {
515 t.Errorf("XappRnibStoreAndPublish failed: %v", err)