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 xapp.Logger.Debug("VerifyAllClean. Adding 100ms more delay to complete")
301 <-time.After(time.Millisecond * 100)
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. Adding 100ms more delay to complete")
325 func (mc *testingSubmgrControl) WaitRESTSubscriptionDelete(restSubsId string) {
326 for i := 0; i < 100; i++ {
327 restSubscription, _ := mainCtrl.c.registry.GetRESTSubscription(restSubsId, false)
328 if restSubscription != nil {
329 xapp.Logger.Debug("WaitRESTSubscriptionDelete. Adding 100ms more delay to complete")
330 <-time.After(time.Millisecond * 100)
335 func (mc *testingSubmgrControl) GetMetrics(t *testing.T) (string, error) {
336 req, err := http.NewRequest("GET", "http://localhost:8080/ric/v1/metrics", nil)
338 return "", fmt.Errorf("Error reading request. %v", err)
340 client := &http.Client{Timeout: time.Second * 10}
341 resp, err := client.Do(req)
343 return "", fmt.Errorf("Error reading response. %v", err)
345 defer resp.Body.Close()
347 respBody, err := ioutil.ReadAll(resp.Body)
349 return "", fmt.Errorf("Error reading body. %v", err)
351 return string(respBody[:]), nil
354 func (mc *testingSubmgrControl) InitAllCounterMap() {
355 counterOpts := GetMetricsOpts()
357 allCountersMap = make(map[string]Counter)
358 for _, counterOpt := range counterOpts {
359 //fmt.Printf("counterOpt.Name: '%v'\n", counterOpt.Name)
360 counter := Counter{counterOpt.Name, 0}
361 allCountersMap[counterOpt.Name] = counter
365 func (mc *testingSubmgrControl) CounterValuesToBeVeriefied(t *testing.T, countersToBeAdded CountersToBeAdded) {
367 if len(toBeAddedCountersMap) == 0 {
368 toBeAddedCountersMap = make(map[string]Counter)
370 for _, counter := range countersToBeAdded {
371 toBeAddedCountersMap[counter.Name] = counter
373 mc.GetCounterValuesBefore(t)
376 func (mc *testingSubmgrControl) GetCounterValuesBefore(t *testing.T) {
377 toBeAddedCountersBeforeMap = make(map[string]Counter)
378 toBeAddedCountersBeforeMap = mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
379 allCountersBeforeMap = make(map[string]Counter)
380 allCountersBeforeMap = mc.GetCurrentCounterValues(t, allCountersMap)
383 func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) {
385 // Check that expected counters are added ok
386 // Get current values of counters exected to be added
387 currentCountersMap := mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
388 for _, toBeAddedCounter := range toBeAddedCountersMap {
389 if currentCounter, ok := currentCountersMap[toBeAddedCounter.Name]; ok == true {
390 if beforeCounter, ok := toBeAddedCountersBeforeMap[toBeAddedCounter.Name]; ok == true {
391 if currentCounter.Value != beforeCounter.Value+toBeAddedCounter.Value {
392 mc.TestError(t, "Error in expected counter value: counterName %v, current value %v, expected value %v",
393 currentCounter.Name, currentCounter.Value, beforeCounter.Value+toBeAddedCounter.Value)
396 mc.TestError(t, "Counter %v not in toBeAddedCountersBeforeMap", toBeAddedCounter.Name)
399 mc.TestError(t, "Counter %v not in currentCountersMap", toBeAddedCounter.Name)
403 // Check that not any unexpected counter are added
404 // Get current values of all counters
405 currentCountersMap = mc.GetCurrentCounterValues(t, allCountersMap)
406 for _, currentCounter := range currentCountersMap {
407 if _, ok := toBeAddedCountersMap[currentCounter.Name]; ok == false {
408 if beforeCounter, ok := allCountersBeforeMap[currentCounter.Name]; ok == true {
409 if currentCounter.Value != beforeCounter.Value {
410 mc.TestError(t, "Error: unexpected counter added: counterName %v, current value %v, expected value %v",
411 currentCounter.Name, currentCounter.Value, beforeCounter.Value)
418 toBeAddedCountersMap = make(map[string]Counter)
419 allCountersBeforeMap = make(map[string]Counter)
422 func (mc *testingSubmgrControl) GetCurrentCounterValues(t *testing.T, chekedCountersMap map[string]Counter) map[string]Counter {
423 countersString, err := mc.GetMetrics(t)
425 mc.TestError(t, "Error GetMetrics() failed %v", err)
429 retCounterMap := make(map[string]Counter)
430 stringsTable := strings.Split(countersString, "\n")
431 for _, counter := range chekedCountersMap {
432 for _, counterString := range stringsTable {
433 if !strings.Contains(counterString, "#") && strings.Contains(counterString, counter.Name) {
434 counterString := strings.Split(counterString, " ")
435 if strings.Contains(counterString[0], counter.Name) {
436 val, err := strconv.ParseUint(counterString[1], 10, 64)
438 mc.TestError(t, "Error: strconv.ParseUint failed %v", err)
441 //fmt.Printf("counter=%v\n", counter)
442 retCounterMap[counter.Name] = counter
448 if len(retCounterMap) != len(chekedCountersMap) {
449 mc.TestError(t, "Error: len(retCounterMap) != len(chekedCountersMap)")
454 func (mc *testingSubmgrControl) sendGetRequest(t *testing.T, addr string, path string) {
456 mc.TestLog(t, "GET http://"+addr+"%v", path)
457 req, err := http.NewRequest("GET", "http://"+addr+path, nil)
459 mc.TestError(t, "Error reading request. %v", err)
462 req.Header.Set("Cache-Control", "no-cache")
463 client := &http.Client{Timeout: time.Second * 2}
464 resp, err := client.Do(req)
466 mc.TestError(t, "Error reading response. %v", err)
469 defer resp.Body.Close()
471 mc.TestLog(t, "Response status: %v", resp.Status)
472 mc.TestLog(t, "Response Headers: %v", resp.Header)
473 if !strings.Contains(resp.Status, "200 OK") {
474 mc.TestError(t, "Wrong response status")
478 respBody, err := ioutil.ReadAll(resp.Body)
480 mc.TestError(t, "Error reading body. %v", err)
483 mc.TestLog(t, "%s", respBody)
487 func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path string) {
489 mc.TestLog(t, "POST http://"+addr+"%v", path)
490 req, err := http.NewRequest("POST", "http://"+addr+path, nil)
492 mc.TestError(t, "Error reading request. %v", err)
495 client := &http.Client{Timeout: time.Second * 2}
496 resp, err := client.Do(req)
498 mc.TestError(t, "Error reading response. %v", err)
501 defer resp.Body.Close()
503 mc.TestLog(t, "Response status: %v", resp.Status)
504 mc.TestLog(t, "Response Headers: %v", resp.Header)
505 if !strings.Contains(resp.Status, "200 OK") {
506 mc.TestError(t, "Wrong response status")
510 respBody, err := ioutil.ReadAll(resp.Body)
512 mc.TestError(t, "Error reading body. %v", err)
515 mc.TestLog(t, "%s", respBody)
519 //-----------------------------------------------------------------------------
521 //-----------------------------------------------------------------------------
522 func (mc *testingSubmgrControl) SetE2State(t *testing.T, ranNameState string) {
524 if err := mc.c.e2IfStateDb.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", ranNameState, "key1", "data1"); err != nil {
525 t.Errorf("XappRnibStoreAndPublish failed: %v", err)