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 "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"
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
39 type testingSubmgrControl struct {
49 type CountersToBeAdded []Counter
51 var countersBeforeMap map[string]Counter
52 var toBeAddedCountersMap map[string]Counter
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.UTTesting = true
59 mainCtrl.c.LoggerLevel = 4
60 mainCtrl.c.e2ap.SetASN1DebugPrintStatus(mainCtrl.c.LoggerLevel)
61 xapp.Logger.Debug("Test: LoggerLevel %v", mainCtrl.c.LoggerLevel)
62 xapp.Logger.Debug("Replacing real db with test db")
63 mainCtrl.c.e2SubsDb = CreateMock() // This overrides real E2 Subscription database for testing
64 mainCtrl.c.restSubsDb = CreateRestSubsDbMock() // This overrides real REST Subscription database for testing
65 mainCtrl.c.e2IfStateDb = CreateXappRnibIfMock() // This overrides real RNIB database for testing
66 xapp.SetReadyCB(mainCtrl.ReadyCB, nil)
67 go xapp.RunWithParams(mainCtrl.c, false)
69 mainCtrl.c.ReadyCB(nil)
73 func (mc *testingSubmgrControl) SimulateRestart(t *testing.T) {
74 mc.TestLog(t, "Simulating submgr restart")
75 mainCtrl.c.registry.subIds = nil
76 // Initialize subIds slice and subscription map
77 mainCtrl.c.registry.Initialize()
78 mainCtrl.c.restDuplicateCtrl.Init()
79 // Read subIds and subscriptions from database
80 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
82 mc.TestError(t, "%v", err)
84 mainCtrl.c.registry.subIds = subIds
85 mainCtrl.c.registry.register = register
86 mc.TestLog(t, "mainCtrl.c.registry.register:")
87 for subId, subs := range mainCtrl.c.registry.register {
88 mc.TestLog(t, " subId=%v", subId)
89 mc.TestLog(t, " subs.SubRespRcvd=%v", subs.SubRespRcvd)
90 mc.TestLog(t, " subs=%v\n", subs)
93 restSubscriptions, err := mainCtrl.c.ReadAllRESTSubscriptionsFromSdl()
95 mc.TestError(t, "%v", err)
97 mainCtrl.c.registry.restSubscriptions = restSubscriptions
98 mc.TestLog(t, "mainCtrl.c.registry.restSubscriptions:")
99 for restSubId, restSubs := range mainCtrl.c.registry.restSubscriptions {
100 mc.TestLog(t, " restSubId=%v", restSubId)
101 mc.TestLog(t, " restSubs=%v\n", restSubs)
105 go mainCtrl.c.HandleUncompletedSubscriptions(mainCtrl.c.registry.register)
108 func (mc *testingSubmgrControl) MakeTransactionNil(t *testing.T, subId uint32) {
110 mc.TestLog(t, "Makin transaction nil for SubId=%v", subId)
111 subs := mainCtrl.c.registry.GetSubscription(subId)
115 func (mc *testingSubmgrControl) SetResetTestFlag(t *testing.T, status bool) {
116 mc.TestLog(t, "ResetTestFlag set to %v", status)
117 mainCtrl.c.ResetTestFlag = status
120 func (mc *testingSubmgrControl) removeExistingSubscriptions(t *testing.T) {
122 mc.TestLog(t, "Removing existing subscriptions")
123 mainCtrl.c.RemoveAllSubscriptionsFromSdl()
124 mainCtrl.c.registry.subIds = nil
125 // Initialize subIds slice and subscription map
126 mainCtrl.c.registry.Initialize()
129 func PringSubscriptionQueryResult(resp models.SubscriptionList) {
130 for _, item := range resp {
131 fmt.Printf("item.SubscriptionID=%v\n", item.SubscriptionID)
132 fmt.Printf("item.Meid=%v\n", item.Meid)
133 fmt.Printf("item.ClientEndpoint=%v\n", item.ClientEndpoint)
137 func (mc *testingSubmgrControl) wait_registry_empty(t *testing.T, secs int) bool {
140 for ; i <= secs*10; i++ {
141 cnt = len(mc.c.registry.register)
145 time.Sleep(100 * time.Millisecond)
147 mc.TestError(t, "(submgr) no registry empty within %d secs: %d, register: %v", secs, cnt, mc.c.registry.register)
151 func (mc *testingSubmgrControl) get_registry_next_subid(t *testing.T) uint32 {
152 mc.c.registry.mutex.Lock()
153 defer mc.c.registry.mutex.Unlock()
154 return mc.c.registry.subIds[0]
157 func (mc *testingSubmgrControl) wait_registry_next_subid_change(t *testing.T, origSubId uint32, secs int) (uint32, bool) {
159 for ; i <= secs*10; i++ {
160 mc.c.registry.mutex.Lock()
161 currSubId := mc.c.registry.subIds[0]
162 mc.c.registry.mutex.Unlock()
163 if currSubId != origSubId {
164 return currSubId, true
166 time.Sleep(100 * time.Millisecond)
168 mc.TestError(t, "(submgr) no subId change within %d secs", secs)
172 func (mc *testingSubmgrControl) wait_subs_clean(t *testing.T, e2SubsId uint32, secs int) bool {
173 var subs *Subscription
175 for ; i <= secs*10; i++ {
176 subs = mc.c.registry.GetSubscription(e2SubsId)
180 time.Sleep(100 * time.Millisecond)
183 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, subs.String())
185 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A)", secs)
190 func (mc *testingSubmgrControl) wait_multi_subs_clean(t *testing.T, e2SubsIds []uint32, secs int) bool {
192 purgedSubscriptions := 0
194 for i := 1; i <= secs*10; i++ {
195 purgedSubscriptions = 0
196 for k := 0; k <= len(e2SubsIds); i++ {
197 subs := mc.c.registry.GetSubscription(e2SubsIds[k])
199 mc.TestLog(t, "(submgr) subscriber purged for esSubsId %v", e2SubsIds[k])
200 purgedSubscriptions += 1
201 if purgedSubscriptions == len(e2SubsIds) {
206 mc.TestLog(t, "(submgr) subscriptions pending purging %v/%v after %d msecs", purgedSubscriptions, len(e2SubsIds), i+500)
207 time.Sleep(100 * time.Millisecond)
210 mc.TestError(t, "(submgr) no clean within %d secs: subs(N/A) - %v/%v subscriptions found still", secs, purgedSubscriptions, len(e2SubsIds))
215 func (mc *testingSubmgrControl) wait_subs_trans_clean(t *testing.T, e2SubsId uint32, secs int) bool {
216 var trans TransactionIf
218 for ; i <= secs*10; i++ {
219 subs := mc.c.registry.GetSubscription(e2SubsId)
223 trans = subs.GetTransaction()
227 time.Sleep(100 * time.Millisecond)
230 mc.TestError(t, "(submgr) no clean within %d secs: %s", secs, trans.String())
232 mc.TestError(t, "(submgr) no clean within %d secs: trans(N/A)", secs)
237 func (mc *testingSubmgrControl) get_subs_entrypoint_cnt(t *testing.T, origSubId uint32) int {
238 subs := mc.c.registry.GetSubscription(origSubId)
240 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt get", origSubId)
243 return subs.EpList.Size()
246 func (mc *testingSubmgrControl) wait_subs_entrypoint_cnt_change(t *testing.T, origSubId uint32, orig int, secs int) (int, bool) {
248 subs := mc.c.registry.GetSubscription(origSubId)
250 mc.TestError(t, "(submgr) no subs %d exists during entrypoint cnt wait", origSubId)
255 for ; i <= secs*10; i++ {
256 curr := subs.EpList.Size()
260 time.Sleep(100 * time.Millisecond)
262 mc.TestError(t, "(submgr) no subs %d entrypoint cnt change within %d secs", origSubId, secs)
267 // Counter check for received message. Note might not be yet handled
269 func (mc *testingSubmgrControl) get_msgcounter(t *testing.T) uint64 {
270 return mc.c.CntRecvMsg
273 func (mc *testingSubmgrControl) wait_msgcounter_change(t *testing.T, orig uint64, secs int) (uint64, bool) {
275 for ; i <= secs*10; i++ {
276 curr := mc.c.CntRecvMsg
280 time.Sleep(100 * time.Millisecond)
282 mc.TestError(t, "(submgr) no msg counter change within %d secs", secs)
286 func (mc *testingSubmgrControl) GetMetrics(t *testing.T) (string, error) {
287 req, err := http.NewRequest("GET", "http://localhost:8080/ric/v1/metrics", nil)
289 return "", fmt.Errorf("Error reading request. %v", err)
291 client := &http.Client{Timeout: time.Second * 10}
292 resp, err := client.Do(req)
294 return "", fmt.Errorf("Error reading response. %v", err)
296 defer resp.Body.Close()
298 respBody, err := ioutil.ReadAll(resp.Body)
300 return "", fmt.Errorf("Error reading body. %v", err)
302 return string(respBody[:]), nil
305 func (mc *testingSubmgrControl) CounterValuesToBeVeriefied(t *testing.T, countersToBeAdded CountersToBeAdded) {
307 if len(toBeAddedCountersMap) == 0 {
308 toBeAddedCountersMap = make(map[string]Counter)
310 for _, counter := range countersToBeAdded {
311 toBeAddedCountersMap[counter.Name] = counter
313 mc.GetCounterValuesBefore(t)
316 func (mc *testingSubmgrControl) GetCounterValuesBefore(t *testing.T) {
317 countersBeforeMap = make(map[string]Counter)
318 countersBeforeMap = mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
321 func (mc *testingSubmgrControl) VerifyCounterValues(t *testing.T) {
323 // Check that expected counters are added ok
324 currentCountersMap := mc.GetCurrentCounterValues(t, toBeAddedCountersMap)
325 for _, toBeAddedCounter := range toBeAddedCountersMap {
326 if currentCounter, ok := currentCountersMap[toBeAddedCounter.Name]; ok == true {
327 if beforeCounter, ok := countersBeforeMap[toBeAddedCounter.Name]; ok == true {
328 if currentCounter.Value != beforeCounter.Value+toBeAddedCounter.Value {
329 mc.TestError(t, "Error in expected counter value: counterName %v, current value %v, expected value %v",
330 currentCounter.Name, currentCounter.Value, beforeCounter.Value+toBeAddedCounter.Value)
332 //fmt.Printf("beforeCounter.Value=%v, toBeAddedCounter.Value=%v, \n",beforeCounter.Value, toBeAddedCounter.Value)
335 mc.TestError(t, "Counter %v not in countersBeforeMap", toBeAddedCounter.Name)
338 mc.TestError(t, "Counter %v not in currentCountersMap", toBeAddedCounter.Name)
342 // Check that not any unexpected counter are added (this is not working correctly!)
343 for _, currentCounter := range currentCountersMap {
344 if _, ok := toBeAddedCountersMap[currentCounter.Name]; ok == false {
345 if beforeCounter, ok := countersBeforeMap[currentCounter.Name]; ok == true {
346 if currentCounter.Value != beforeCounter.Value {
347 mc.TestError(t, "Error: unexpected counter value added: counterName %v, current value %v, expected value %v",
348 currentCounter.Name, beforeCounter.Value, beforeCounter.Value)
350 //fmt.Printf("beforeCounter.Value=%v, toBeAddedCounter.Value=%v, \n",beforeCounter.Value, toBeAddedCounter.Value)
353 mc.TestError(t, "Counter %v not in countersBeforeMap", beforeCounter.Name)
359 //fmt.Printf("toBeAddedCountersMap=%v\n",toBeAddedCountersMap)
360 toBeAddedCountersMap = make(map[string]Counter)
363 func (mc *testingSubmgrControl) GetCurrentCounterValues(t *testing.T, chekedCountersMap map[string]Counter) map[string]Counter {
364 countersString, err := mc.GetMetrics(t)
366 mc.TestError(t, "Error GetMetrics() failed %v", err)
370 retCounterMap := make(map[string]Counter)
371 stringsTable := strings.Split(countersString, "\n")
372 for _, counter := range chekedCountersMap {
373 for _, counterString := range stringsTable {
374 if !strings.Contains(counterString, "#") && strings.Contains(counterString, counter.Name) {
375 counterString := strings.Split(counterString, " ")
376 if strings.Contains(counterString[0], counter.Name) {
377 val, err := strconv.ParseUint(counterString[1], 10, 64)
379 mc.TestError(t, "Error: strconv.ParseUint failed %v", err)
382 //fmt.Printf("counter=%v\n", counter)
383 retCounterMap[counter.Name] = counter
389 if len(retCounterMap) != len(chekedCountersMap) {
390 mc.TestError(t, "Error: len(retCounterMap) != len(chekedCountersMap)")
396 func (mc *testingSubmgrControl) sendGetRequest(t *testing.T, addr string, path string) {
398 mc.TestLog(t, "GET http://"+addr+"%v", path)
399 req, err := http.NewRequest("GET", "http://"+addr+path, nil)
401 mc.TestError(t, "Error reading request. %v", err)
404 req.Header.Set("Cache-Control", "no-cache")
405 client := &http.Client{Timeout: time.Second * 2}
406 resp, err := client.Do(req)
408 mc.TestError(t, "Error reading response. %v", err)
411 defer resp.Body.Close()
413 mc.TestLog(t, "Response status: %v", resp.Status)
414 mc.TestLog(t, "Response Headers: %v", resp.Header)
415 if !strings.Contains(resp.Status, "200 OK") {
416 mc.TestError(t, "Wrong response status")
420 respBody, err := ioutil.ReadAll(resp.Body)
422 mc.TestError(t, "Error reading body. %v", err)
425 mc.TestLog(t, "%s", respBody)
429 func (mc *testingSubmgrControl) sendPostRequest(t *testing.T, addr string, path string) {
431 mc.TestLog(t, "POST http://"+addr+"%v", path)
432 req, err := http.NewRequest("POST", "http://"+addr+path, nil)
434 mc.TestError(t, "Error reading request. %v", err)
437 client := &http.Client{Timeout: time.Second * 2}
438 resp, err := client.Do(req)
440 mc.TestError(t, "Error reading response. %v", err)
443 defer resp.Body.Close()
445 mc.TestLog(t, "Response status: %v", resp.Status)
446 mc.TestLog(t, "Response Headers: %v", resp.Header)
447 if !strings.Contains(resp.Status, "200 OK") {
448 mc.TestError(t, "Wrong response status")
452 respBody, err := ioutil.ReadAll(resp.Body)
454 mc.TestError(t, "Error reading body. %v", err)
457 mc.TestLog(t, "%s", respBody)
461 //-----------------------------------------------------------------------------
463 //-----------------------------------------------------------------------------
464 func (mc *testingSubmgrControl) SetE2State(t *testing.T, ranNameState string) {
466 if err := mc.c.e2IfStateDb.XappRnibStoreAndPublish("RAN_CONNECTION_STATUS_CHANGE", ranNameState, "key1", "data1"); err != nil {
467 t.Errorf("XappRnibStoreAndPublish failed: %v", err)