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 mc.TestLog(t, "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) GetMetrics(t *testing.T) (string, error) {
317 req, err := http.NewRequest("GET", "http://localhost:8080/ric/v1/metrics", nil)
319 return "", fmt.Errorf("Error reading request. %v", err)
321 client := &http.Client{Timeout: time.Second * 10}
322 resp, err := client.Do(req)
324 return "", fmt.Errorf("Error reading response. %v", err)
326 defer resp.Body.Close()
328 respBody, err := ioutil.ReadAll(resp.Body)
330 return "", fmt.Errorf("Error reading body. %v", err)
332 return string(respBody[:]), nil
335 func (mc *testingSubmgrControl) InitAllCounterMap() {
336 counterOpts := GetMetricsOpts()
338 allCountersMap = make(map[string]Counter)
339 for _, counterOpt := range counterOpts {
340 //fmt.Printf("counterOpt.Name: '%v'\n", counterOpt.Name)
341 counter := Counter{counterOpt.Name, 0}
342 allCountersMap[counterOpt.Name] = counter
346 func (mc *testingSubmgrControl) CounterValuesToBeVeriefied(t *testing.T, countersToBeAdded CountersToBeAdded) {
348 if len(toBeAddedCountersMap) == 0 {
349 toBeAddedCountersMap = make(map[string]Counter)
351 for _, counter := range countersToBeAdded {
352 toBeAddedCountersMap[counter.Name] = counter
354 mc.GetCounterValuesBefore(t)
357 func (mc *testingSubmgrControl) GetCounterValuesBefore(t *testing.T) {
358 toBeAddedCountersBeforeMap = make(map[string]Counter)
359 toBeAddedCountersBeforeMap = mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
360 allCountersBeforeMap = make(map[string]Counter)
361 allCountersBeforeMap = mc.GetCurrentCounterValues(t, allCountersMap)
364 func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) {
366 // Check that expected counters are added ok
367 // Get current values of counters exected to be added
368 currentCountersMap := mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
369 for _, toBeAddedCounter := range toBeAddedCountersMap {
370 if currentCounter, ok := currentCountersMap[toBeAddedCounter.Name]; ok == true {
371 if beforeCounter, ok := toBeAddedCountersBeforeMap[toBeAddedCounter.Name]; ok == true {
372 if currentCounter.Value != beforeCounter.Value+toBeAddedCounter.Value {
373 mc.TestError(t, "Error in expected counter value: counterName %v, current value %v, expected value %v",
374 currentCounter.Name, currentCounter.Value, beforeCounter.Value+toBeAddedCounter.Value)
377 mc.TestError(t, "Counter %v not in toBeAddedCountersBeforeMap", toBeAddedCounter.Name)
380 mc.TestError(t, "Counter %v not in currentCountersMap", toBeAddedCounter.Name)
384 // Check that not any unexpected counter are added
385 // Get current values of all counters
386 currentCountersMap = mc.GetCurrentCounterValues(t, allCountersMap)
387 for _, currentCounter := range currentCountersMap {
388 if _, ok := toBeAddedCountersMap[currentCounter.Name]; ok == false {
389 if beforeCounter, ok := allCountersBeforeMap[currentCounter.Name]; ok == true {
390 if currentCounter.Value != beforeCounter.Value {
391 mc.TestError(t, "Error: unexpected counter added: counterName %v, current value %v, expected value %v",
392 currentCounter.Name, currentCounter.Value, beforeCounter.Value)
399 toBeAddedCountersMap = make(map[string]Counter)
400 allCountersBeforeMap = make(map[string]Counter)
403 func (mc *testingSubmgrControl) GetCurrentCounterValues(t *testing.T, chekedCountersMap map[string]Counter) map[string]Counter {
404 countersString, err := mc.GetMetrics(t)
406 mc.TestError(t, "Error GetMetrics() failed %v", err)
410 retCounterMap := make(map[string]Counter)
411 stringsTable := strings.Split(countersString, "\n")
412 for _, counter := range chekedCountersMap {
413 for _, counterString := range stringsTable {
414 if !strings.Contains(counterString, "#") && strings.Contains(counterString, counter.Name) {
415 counterString := strings.Split(counterString, " ")
416 if strings.Contains(counterString[0], counter.Name) {
417 val, err := strconv.ParseUint(counterString[1], 10, 64)
419 mc.TestError(t, "Error: strconv.ParseUint failed %v", err)
422 //fmt.Printf("counter=%v\n", counter)
423 retCounterMap[counter.Name] = counter
429 if len(retCounterMap) != len(chekedCountersMap) {
430 mc.TestError(t, "Error: len(retCounterMap) != len(chekedCountersMap)")
435 func (mc *testingSubmgrControl) sendGetRequest(t *testing.T, addr string, path string) {
437 mc.TestLog(t, "GET http://"+addr+"%v", path)
438 req, err := http.NewRequest("GET", "http://"+addr+path, nil)
440 mc.TestError(t, "Error reading request. %v", err)
443 req.Header.Set("Cache-Control", "no-cache")
444 client := &http.Client{Timeout: time.Second * 2}
445 resp, err := client.Do(req)
447 mc.TestError(t, "Error reading response. %v", err)
450 defer resp.Body.Close()
452 mc.TestLog(t, "Response status: %v", resp.Status)
453 mc.TestLog(t, "Response Headers: %v", resp.Header)
454 if !strings.Contains(resp.Status, "200 OK") {
455 mc.TestError(t, "Wrong response status")
459 respBody, err := ioutil.ReadAll(resp.Body)
461 mc.TestError(t, "Error reading body. %v", err)
464 mc.TestLog(t, "%s", respBody)
468 func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path string) {
470 mc.TestLog(t, "POST http://"+addr+"%v", path)
471 req, err := http.NewRequest("POST", "http://"+addr+path, nil)
473 mc.TestError(t, "Error reading request. %v", err)
476 client := &http.Client{Timeout: time.Second * 2}
477 resp, err := client.Do(req)
479 mc.TestError(t, "Error reading response. %v", err)
482 defer resp.Body.Close()
484 mc.TestLog(t, "Response status: %v", resp.Status)
485 mc.TestLog(t, "Response Headers: %v", resp.Header)
486 if !strings.Contains(resp.Status, "200 OK") {
487 mc.TestError(t, "Wrong response status")
491 respBody, err := ioutil.ReadAll(resp.Body)
493 mc.TestError(t, "Error reading body. %v", err)
496 mc.TestLog(t, "%s", respBody)
500 //-----------------------------------------------------------------------------
502 //-----------------------------------------------------------------------------
503 func (mc *testingSubmgrControl) SetE2State(t *testing.T, ranNameState string) {
505 if err := mc.c.e2IfStateDb.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", ranNameState, "key1", "data1"); err != nil {
506 t.Errorf("XappRnibStoreAndPublish failed: %v", err)