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")
79 mainCtrl.c.registry.subIds = nil
80 // Initialize subIds slice and subscription map
81 mainCtrl.c.registry.Initialize()
82 mainCtrl.c.restDuplicateCtrl.Init()
83 // Read subIds and subscriptions from database
84 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
86 mc.TestError(t, "%v", err)
88 mainCtrl.c.registry.subIds = subIds
89 mainCtrl.c.registry.register = register
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)
97 restSubscriptions, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl()
99 mc.TestError(t, "%v", err)
101 mainCtrl.c.registry.restSubscriptions = restSubscriptions
102 mc.TestLog(t, "mainCtrl.c.registry.restSubscriptions:")
103 for restSubId, restSubs := range mainCtrl.c.registry.restSubscriptions {
104 mc.TestLog(t, " restSubId=%v", restSubId)
105 mc.TestLog(t, " restSubs=%v\n", restSubs)
109 go mainCtrl.c.HandleUncompletedSubscriptions(mainCtrl.c.registry.register)
112 func (mc *testingSubmgrControl) MakeTransactionNil(t *testing.T, subId uint32) {
114 mc.TestLog(t, "Makin transaction nil for SubId=%v", subId)
115 subs := mainCtrl.c.registry.GetSubscription(subId)
119 func (mc *testingSubmgrControl) SetResetTestFlag(t *testing.T, status bool) {
120 mc.TestLog(t, "ResetTestFlag set to %v", status)
121 mainCtrl.c.ResetTestFlag = status
124 func (mc *testingSubmgrControl) removeExistingSubscriptions(t *testing.T) {
126 mc.TestLog(t, "Removing existing subscriptions")
127 mainCtrl.c.RemoveAllSubscriptionsFromSdl()
128 mainCtrl.c.registry.subIds = nil
129 // Initialize subIds slice and subscription map
130 mainCtrl.c.registry.Initialize()
133 func PringSubscriptionQueryResult(resp models.SubscriptionList) {
134 for _, item := range resp {
135 fmt.Printf("item.SubscriptionID=%v\n", item.SubscriptionID)
136 fmt.Printf("item.Meid=%v\n", item.Meid)
137 fmt.Printf("item.ClientEndpoint=%v\n", item.ClientEndpoint)
141 func (mc *testingSubmgrControl) wait_registry_empty(t *testing.T, secs int) bool {
144 for ; i <= secs*10; i++ {
145 cnt = len(mc.c.registry.register)
149 time.Sleep(100 * time.Millisecond)
151 mc.TestError(t, "(submgr) no registry empty within %d secs: %d, register: %v", secs, cnt, mc.c.registry.register)
155 func (mc *testingSubmgrControl) get_registry_next_subid(t *testing.T) uint32 {
156 mc.c.registry.mutex.Lock()
157 defer mc.c.registry.mutex.Unlock()
158 return mc.c.registry.subIds[0]
161 func (mc *testingSubmgrControl) wait_registry_next_subid_change(t *testing.T, origSubId uint32, secs int) (uint32, bool) {
163 for ; i <= secs*10; i++ {
164 mc.c.registry.mutex.Lock()
165 currSubId := mc.c.registry.subIds[0]
166 mc.c.registry.mutex.Unlock()
167 if currSubId != origSubId {
168 return currSubId, true
170 time.Sleep(100 * time.Millisecond)
172 mc.TestError(t, "(submgr) no subId change within %d secs", secs)
176 func (mc *testingSubmgrControl) wait_subs_clean(t *testing.T, e2SubsId uint32, secs int) bool {
177 var subs *Subscription
179 for ; i <= secs*10; i++ {
180 subs = mc.c.registry.GetSubscription(e2SubsId)
184 time.Sleep(100 * time.Millisecond)
187 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, subs.String())
189 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A)", secs)
194 func (mc *testingSubmgrControl) wait_multi_subs_clean(t *testing.T, e2SubsIds []uint32, secs int) bool {
196 purgedSubscriptions := 0
198 for i := 1; i <= secs*10; i++ {
199 purgedSubscriptions = 0
200 for k := 0; k <= len(e2SubsIds); i++ {
201 subs := mc.c.registry.GetSubscription(e2SubsIds[k])
203 mc.TestLog(t, "(submgr) subscriber purged for esSubsId %v", e2SubsIds[k])
204 purgedSubscriptions += 1
205 if purgedSubscriptions == len(e2SubsIds) {
210 mc.TestLog(t, "(submgr) subscriptions pending purging %v/%v after %d msecs", purgedSubscriptions, len(e2SubsIds), i+500)
211 time.Sleep(100 * time.Millisecond)
214 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A) - %v/%v subscriptions found still", secs, purgedSubscriptions, len(e2SubsIds))
219 func (mc *testingSubmgrControl) wait_subs_trans_clean(t *testing.T, e2SubsId uint32, secs int) bool {
220 var trans TransactionIf
222 for ; i <= secs*10; i++ {
223 subs := mc.c.registry.GetSubscription(e2SubsId)
227 trans = subs.GetTransaction()
231 time.Sleep(100 * time.Millisecond)
234 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, trans.String())
236 mc.TestError(t, "(submgr) no clean within %d secs: trans(N/A)", secs)
241 func (mc *testingSubmgrControl) get_subs_entrypoint_cnt(t *testing.T, origSubId uint32) int {
242 subs := mc.c.registry.GetSubscription(origSubId)
244 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt get", origSubId)
247 return subs.EpList.Size()
250 func (mc *testingSubmgrControl) wait_subs_entrypoint_cnt_change(t *testing.T, origSubId uint32, orig int, secs int) (int, bool) {
252 subs := mc.c.registry.GetSubscription(origSubId)
254 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt wait", origSubId)
259 for ; i <= secs*10; i++ {
260 curr := subs.EpList.Size()
264 time.Sleep(100 * time.Millisecond)
266 mc.TestError(t, "(submgr) no subs %d entrypoint cnt change within %d secs", origSubId, secs)
271 // Counter check for received message. Note might not be yet handled
273 func (mc *testingSubmgrControl) get_msgcounter(t *testing.T) uint64 {
274 return mc.c.CntRecvMsg
277 func (mc *testingSubmgrControl) wait_msgcounter_change(t *testing.T, orig uint64, secs int) (uint64, bool) {
279 for ; i <= secs*10; i++ {
280 curr := mc.c.CntRecvMsg
284 time.Sleep(100 * time.Millisecond)
286 mc.TestError(t, "(submgr) no msg counter change within %d secs", secs)
290 func (mc *testingSubmgrControl) VerifyAllClean(t *testing.T) {
291 // Verify that all resources are freed
292 assert.Equal(t, 0, len(mainCtrl.c.registry.register))
293 if len(mainCtrl.c.registry.register) > 0 {
294 fmt.Printf("registry.register: %v\n", mainCtrl.c.registry.register)
296 assert.Equal(t, 0, len(mainCtrl.c.registry.restSubscriptions))
297 if len(mainCtrl.c.registry.restSubscriptions) > 0 {
298 fmt.Printf("registry.restSubscriptions: %v\n", mainCtrl.c.registry.restSubscriptions)
300 verifyRESTKeyCount(t, 0)
301 verifyE2KeyCount(t, 0)
304 func (mc *testingSubmgrControl) GetMetrics(t *testing.T) (string, error) {
305 req, err := http.NewRequest("GET", "http://localhost:8080/ric/v1/metrics", nil)
307 return "", fmt.Errorf("Error reading request. %v", err)
309 client := &http.Client{Timeout: time.Second * 10}
310 resp, err := client.Do(req)
312 return "", fmt.Errorf("Error reading response. %v", err)
314 defer resp.Body.Close()
316 respBody, err := ioutil.ReadAll(resp.Body)
318 return "", fmt.Errorf("Error reading body. %v", err)
320 return string(respBody[:]), nil
323 func (mc *testingSubmgrControl) InitAllCounterMap() {
324 counterOpts := GetMetricsOpts()
326 allCountersMap = make(map[string]Counter)
327 for _, counterOpt := range counterOpts {
328 //fmt.Printf("counterOpt.Name: '%v'\n", counterOpt.Name)
329 counter := Counter{counterOpt.Name, 0}
330 allCountersMap[counterOpt.Name] = counter
334 func (mc *testingSubmgrControl) CounterValuesToBeVeriefied(t *testing.T, countersToBeAdded CountersToBeAdded) {
336 if len(toBeAddedCountersMap) == 0 {
337 toBeAddedCountersMap = make(map[string]Counter)
339 for _, counter := range countersToBeAdded {
340 toBeAddedCountersMap[counter.Name] = counter
342 mc.GetCounterValuesBefore(t)
345 func (mc *testingSubmgrControl) GetCounterValuesBefore(t *testing.T) {
346 toBeAddedCountersBeforeMap = make(map[string]Counter)
347 toBeAddedCountersBeforeMap = mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
348 allCountersBeforeMap = make(map[string]Counter)
349 allCountersBeforeMap = mc.GetCurrentCounterValues(t, allCountersMap)
352 func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) {
354 // Check that expected counters are added ok
355 // Get current values of counters exected to be added
356 currentCountersMap := mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
357 for _, toBeAddedCounter := range toBeAddedCountersMap {
358 if currentCounter, ok := currentCountersMap[toBeAddedCounter.Name]; ok == true {
359 if beforeCounter, ok := toBeAddedCountersBeforeMap[toBeAddedCounter.Name]; ok == true {
360 if currentCounter.Value != beforeCounter.Value+toBeAddedCounter.Value {
361 mc.TestError(t, "Error in expected counter value: counterName %v, current value %v, expected value %v",
362 currentCounter.Name, currentCounter.Value, beforeCounter.Value+toBeAddedCounter.Value)
365 mc.TestError(t, "Counter %v not in toBeAddedCountersBeforeMap", toBeAddedCounter.Name)
368 mc.TestError(t, "Counter %v not in currentCountersMap", toBeAddedCounter.Name)
372 // Check that not any unexpected counter are added (this is not working correctly!)
373 // Get current values of all counters
374 currentCountersMap = mc.GetCurrentCounterValues(t, allCountersMap)
375 for _, currentCounter := range currentCountersMap {
376 if _, ok := toBeAddedCountersMap[currentCounter.Name]; ok == false {
377 if beforeCounter, ok := allCountersBeforeMap[currentCounter.Name]; ok == true {
378 if currentCounter.Value != beforeCounter.Value {
379 mc.TestError(t, "Error: unexpected counter added: counterName %v, current value %v, expected value %v",
380 currentCounter.Name, currentCounter.Value, beforeCounter.Value)
387 toBeAddedCountersMap = make(map[string]Counter)
388 allCountersBeforeMap = make(map[string]Counter)
391 func (mc *testingSubmgrControl) GetCurrentCounterValues(t *testing.T, chekedCountersMap map[string]Counter) map[string]Counter {
392 countersString, err := mc.GetMetrics(t)
394 mc.TestError(t, "Error GetMetrics() failed %v", err)
398 retCounterMap := make(map[string]Counter)
399 stringsTable := strings.Split(countersString, "\n")
400 for _, counter := range chekedCountersMap {
401 for _, counterString := range stringsTable {
402 if !strings.Contains(counterString, "#") && strings.Contains(counterString, counter.Name) {
403 counterString := strings.Split(counterString, " ")
404 if strings.Contains(counterString[0], counter.Name) {
405 val, err := strconv.ParseUint(counterString[1], 10, 64)
407 mc.TestError(t, "Error: strconv.ParseUint failed %v", err)
410 //fmt.Printf("counter=%v\n", counter)
411 retCounterMap[counter.Name] = counter
417 if len(retCounterMap) != len(chekedCountersMap) {
418 mc.TestError(t, "Error: len(retCounterMap) != len(chekedCountersMap)")
423 func (mc *testingSubmgrControl) sendGetRequest(t *testing.T, addr string, path string) {
425 mc.TestLog(t, "GET http://"+addr+"%v", path)
426 req, err := http.NewRequest("GET", "http://"+addr+path, nil)
428 mc.TestError(t, "Error reading request. %v", err)
431 req.Header.Set("Cache-Control", "no-cache")
432 client := &http.Client{Timeout: time.Second * 2}
433 resp, err := client.Do(req)
435 mc.TestError(t, "Error reading response. %v", err)
438 defer resp.Body.Close()
440 mc.TestLog(t, "Response status: %v", resp.Status)
441 mc.TestLog(t, "Response Headers: %v", resp.Header)
442 if !strings.Contains(resp.Status, "200 OK") {
443 mc.TestError(t, "Wrong response status")
447 respBody, err := ioutil.ReadAll(resp.Body)
449 mc.TestError(t, "Error reading body. %v", err)
452 mc.TestLog(t, "%s", respBody)
456 func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path string) {
458 mc.TestLog(t, "POST http://"+addr+"%v", path)
459 req, err := http.NewRequest("POST", "http://"+addr+path, nil)
461 mc.TestError(t, "Error reading request. %v", err)
464 client := &http.Client{Timeout: time.Second * 2}
465 resp, err := client.Do(req)
467 mc.TestError(t, "Error reading response. %v", err)
470 defer resp.Body.Close()
472 mc.TestLog(t, "Response status: %v", resp.Status)
473 mc.TestLog(t, "Response Headers: %v", resp.Header)
474 if !strings.Contains(resp.Status, "200 OK") {
475 mc.TestError(t, "Wrong response status")
479 respBody, err := ioutil.ReadAll(resp.Body)
481 mc.TestError(t, "Error reading body. %v", err)
484 mc.TestLog(t, "%s", respBody)
488 //-----------------------------------------------------------------------------
490 //-----------------------------------------------------------------------------
491 func (mc *testingSubmgrControl) SetE2State(t *testing.T, ranNameState string) {
493 if err := mc.c.e2IfStateDb.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", ranNameState, "key1", "data1"); err != nil {
494 t.Errorf("XappRnibStoreAndPublish failed: %v", err)