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 ==================================================================================
32 "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
33 "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststube2ap"
34 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
35 "github.com/stretchr/testify/assert"
38 var sdlShouldReturnError bool = false
40 const sdlTestErrorString string = "Test sdl returned error on purpose"
49 e2SubsDb map[string]string // Store information as a string like real db does.
50 register map[uint32]*Subscription
52 lastAllocatedSubId uint32
53 marshalLock sync.Mutex
58 func CreateMock() *Mock {
59 fmt.Println("Test CreateMock()")
61 mock.ResetTestSettings()
65 func (m *Mock) ResetTestSettings() {
66 m.e2SubsDb = make(map[string]string)
67 m.register = make(map[uint32]*Subscription)
69 for i = 1; i < 65535; i++ {
70 m.subIds = append(m.subIds, i)
74 func (m *Mock) AllocNextSubId() uint32 {
75 m.lastAllocatedSubId = m.subIds[0]
76 return m.lastAllocatedSubId
79 func TestWait(t *testing.T) {
80 // Wait to test settings to complete
81 <-time.After(1 * time.Second)
84 func GetSubscription(t *testing.T, e2SubId uint32, responseType int, srcEndPoint, ranName string, xId string) *Subscription {
85 t.Log("TEST: Getting subscription")
87 subs := &Subscription{}
89 // Create unpacked e2SubReqMsg
90 subReqParams := &teststube2ap.E2StubSubsReqParams{}
93 meid := xapp.RMRMeid{}
94 meid.RanName = ranName
96 params := &xapp.RMRParams{}
97 params.Src = srcEndPoint
101 // Create xApp transaction
102 trans := mainCtrl.c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subReqParams.Req.RequestId, params.Meid)
104 t.Errorf("TEST: %s", idstring(fmt.Errorf("transaction not created"), params))
108 // Allocate E2 instanceId/subId
109 subReqParams.Req.RequestId.InstanceId = e2SubId
112 subs.ReqId.InstanceId = subReqParams.Req.RequestId.InstanceId
114 subs.EpList.AddEndpoint(trans.GetEndpoint())
115 subs.SubReqMsg = subReqParams.Req
116 // subs.SubRFMsg contains received/cached SubscriptionResponse or SubscriptionFailure, nil in no response received
117 if responseType == subsResponse {
118 subs.SubRFMsg = GetSubsResponse(t, subReqParams.Req)
120 } else if responseType == subsFailure {
121 subs.SubRFMsg = GetSubsFailure(t, subReqParams.Req)
123 } else if responseType == noResponse {
130 func GetSubsResponse(t *testing.T, req *e2ap.E2APSubscriptionRequest) *e2ap.E2APSubscriptionResponse {
131 t.Log("TEST: Getting ricSubscriptionResponse")
133 // Create e2SubRespMsg
134 resp := &e2ap.E2APSubscriptionResponse{}
135 resp.RequestId.Id = 123
136 resp.RequestId.InstanceId = req.RequestId.InstanceId
137 resp.FunctionId = req.FunctionId
139 resp.ActionAdmittedList.Items = make([]e2ap.ActionAdmittedItem, len(req.ActionSetups))
140 for index := int(0); index < len(req.ActionSetups); index++ {
141 resp.ActionAdmittedList.Items[index].ActionId = req.ActionSetups[index].ActionId
144 for index := uint64(0); index < 1; index++ {
145 item := e2ap.ActionNotAdmittedItem{}
146 item.ActionId = index
147 item.Cause.Content = 1
149 resp.ActionNotAdmittedList.Items = append(resp.ActionNotAdmittedList.Items, item)
154 func GetSubsFailure(t *testing.T, req *e2ap.E2APSubscriptionRequest) *e2ap.E2APSubscriptionFailure {
155 t.Log("TEST: Getting ricSubscriptionFailure")
157 fail := &e2ap.E2APSubscriptionFailure{}
158 fail.RequestId.Id = req.RequestId.Id
159 fail.RequestId.InstanceId = req.RequestId.InstanceId
160 fail.FunctionId = req.FunctionId
164 func PrintSubscriptionData(t *testing.T, subs *Subscription) {
165 t.Log("TEST: subscription data")
166 t.Logf("TEST: subs.mutex = %v", subs.mutex)
167 t.Logf("TEST: subs.ReqId.InstanceId = %v", subs.ReqId.InstanceId)
168 t.Logf("TEST: subs.ReqId.Id = %v", subs.ReqId.Id)
169 t.Logf("TEST: subs.EpList = %v", subs.EpList)
170 t.Logf("TEST: subs.Meid.RanName = %v", subs.Meid.RanName)
171 t.Logf("TEST: subs.SubReqMsg = %v", subs.SubReqMsg.String())
172 t.Logf("TEST: subs.valid = %v", subs.valid)
174 if subs.SubRFMsg != nil {
175 switch typeofSubsMessage(subs.SubRFMsg) {
177 t.Logf("TEST: subs.SubRFMsg == SubResp")
178 subResp := subs.SubRFMsg.(*e2ap.E2APSubscriptionResponse)
179 t.Logf("TEST: subResp = %+v", subResp)
181 t.Logf("TEST: subs.SubRFMsg == SubFail")
182 subFail := subs.SubRFMsg.(*e2ap.E2APSubscriptionFailure)
183 t.Logf("TEST: subFail = %+v", subFail)
186 t.Logf("TEST: subs.SubRFMsg == nil")
190 func TestWriteSubscriptionToSdl(t *testing.T) {
192 // Write one subscription
193 subId := mock.AllocNextSubId()
194 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
195 PrintSubscriptionData(t, subs)
196 t.Logf("TEST: Writing subId = %v\n", subId)
197 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
199 t.Errorf("TEST: %s", err.Error())
201 verifyE2KeyCount(t, 1)
204 func verifyE2KeyCount(t *testing.T, expectedCount int) {
206 count, err := mainCtrl.c.GetE2KeyCount()
208 t.Errorf("TEST: %s", err.Error())
210 assert.Equal(t, expectedCount, count)
214 func TestReadSubscriptionFromSdl(t *testing.T) {
216 subId := mock.lastAllocatedSubId
217 t.Logf("Reading subId = %v\n", subId)
218 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
220 t.Errorf("TEST: %s", err.Error())
223 PrintSubscriptionData(t, subs)
224 assert.Equal(t, mock.register[subId].SubReqMsg, subs.SubReqMsg)
227 func TestRemoveSubscriptionFromSdl(t *testing.T) {
229 subId := mock.lastAllocatedSubId
230 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
232 t.Errorf("TEST: %s", err.Error())
235 delete(mock.register, subId)
236 mock.subIds = append(mock.subIds, subId)
237 t.Logf("TEST: subscription removed from db. subId = %v", subId)
240 func TestReadNotExistingSubscriptionFromSdl(t *testing.T) {
243 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
245 t.Logf("TEST: subscription not found from db. subId = %v", subId)
248 t.Errorf("TEST: subscription read from db. %v", subs.String())
249 PrintSubscriptionData(t, subs)
252 func TestReadNotExistingSubscriptionFromSdl2(t *testing.T) {
255 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
257 t.Logf("TEST: subscription not found from db. subId = %v", subId)
260 t.Errorf("TEST: subscription read from db. %v", subs.String())
261 PrintSubscriptionData(t, subs)
264 func TestRemoveNotExistingSubscriptionFromSdl(t *testing.T) {
267 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
269 t.Logf("TEST: %s", err.Error())
272 t.Logf("TEST: subscription removed from db. subId = %v", subId)
275 func TestWriteSubscriptionsToSdl(t *testing.T) {
277 // Write 1st subscription
278 subId := mock.AllocNextSubId()
279 t.Logf("TEST: Writing subId = %v\n", subId)
280 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
281 PrintSubscriptionData(t, subs)
282 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
284 t.Errorf("TEST: %s", err.Error())
287 t.Logf("TEST: subscription written in db = %v", subs.String())
289 // Write 2nd subscription
290 subId = mock.AllocNextSubId()
291 t.Logf("TEST:Writing subId = %v\n", subId)
292 subs = GetSubscription(t, subId, subsFailure, "localhost:13560", "RAN_NAME_2", "123457")
293 PrintSubscriptionData(t, subs)
294 err = mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
296 t.Errorf("TEST: %s", err.Error())
299 t.Logf("TEST: subscription written in db = %v", subs.String())
301 // Write 3rd subscription
302 subId = mock.AllocNextSubId()
303 t.Logf("TEST:Writing subId = %v\n", subId)
304 subs = GetSubscription(t, subId, noResponse, "localhost:13560", "RAN_NAME_3", "123458")
305 PrintSubscriptionData(t, subs)
306 err = mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
308 t.Errorf("TEST: %s", err.Error())
311 t.Logf("TEST: subscription written in db = %v", subs.String())
314 func TestReadSubscriptionsFromSdl(t *testing.T) {
316 // Subscription with subId 1 was added and and removed above. Then subscriptions with subIds 2, 3 and 4 was added
317 // Db subscriptions should now contain subIDs 2, 3 and 4
319 for subId = 2; subId <= 4; subId++ {
320 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
322 t.Errorf("TEST: %s", err.Error())
325 PrintSubscriptionData(t, subs)
329 func TestReadAllSubscriptionsFromSdl(t *testing.T) {
331 // This test cases simulates submgr restart. SubIds and subscriptions are restored from db
332 // after initializing mock.subIds and mock.register
334 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
336 t.Errorf("TEST: %s", err.Error())
339 // for _, subs := range mock.register {
340 for _, subs := range register {
341 PrintSubscriptionData(t, subs)
343 // SubIds slices before and after restart can't be directly compared as original slice is not stored
344 // in the db. SubId values 1, 2, 3, 4 are already removed from the beginning of subIds slice above
345 // so far. Next free subId is 5 in the beginning of mock.subIds slice. The db contains now however only
346 // 3 subscriptions with subIds 2, 3 and 4, so only subId values 2, 3, 4 are removed from the returned
347 // subIds slice and there next free value is 1
348 assert.Equal(t, uint32(0x1), subIds[0])
351 func TestRemoveAllSubscriptionsFromSdl(t *testing.T) {
353 err := mainCtrl.c.RemoveAllSubscriptionsFromSdl()
355 t.Errorf("TEST: %s", err.Error())
358 t.Log("TEST: All subscription removed from db")
361 func TestReadAllSubscriptionsFromSdl2(t *testing.T) {
363 // This test cases simulates submgr startup. SubIds and subscriptions are restored from empty db
364 // after initializing mock.subIds and mock.register
365 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
367 t.Errorf("TEST: %s", err.Error())
370 for _, subs := range mock.register {
371 PrintSubscriptionData(t, subs)
373 assert.Equal(t, len(subIds), 65534)
374 assert.Equal(t, len(register), 0)
377 func TestWriteSubscriptionToSdlFail(t *testing.T) {
379 // Try to write one subscription. Test db should return test error string
380 MakeNextSdlCallFail()
381 subId := mock.AllocNextSubId()
382 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
383 PrintSubscriptionData(t, subs)
384 t.Logf("TEST: Writing subId = %v\n", subId)
385 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
387 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
388 t.Errorf("TEST: %s", err.Error())
391 t.Errorf("TEST: This test case should return error")
395 func TestReadSubscriptionFromSdlFail(t *testing.T) {
397 // Try to read one subscription. Test db should return test error string
398 MakeNextSdlCallFail()
399 subId := mock.lastAllocatedSubId
400 t.Logf("Reading subId = %v\n", subId)
401 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
403 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
404 t.Errorf("TEST: %s", err.Error())
408 t.Errorf("TEST: This test case should return error")
410 PrintSubscriptionData(t, subs)
411 assert.Equal(t, mock.register[subId].SubReqMsg, subs.SubReqMsg)
414 func TestRemoveSubscriptionFromSdlFail(t *testing.T) {
416 // Try to remove one subscription. Test db should return test error string
417 MakeNextSdlCallFail()
418 subId := mock.lastAllocatedSubId
419 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
421 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
422 t.Errorf("TEST: %s", err.Error())
426 t.Errorf("TEST: This test case should return error")
428 delete(mock.register, subId)
429 mock.subIds = append(mock.subIds, subId)
430 t.Logf("TEST: subscription removed from db. subId = %v", subId)
433 func TestReadAllSubscriptionsFromSdlFail(t *testing.T) {
435 // Try to read all subscriptions. Test db should return test error string
436 MakeNextSdlCallFail()
437 // This test cases simulates submgr restart. SubIds and subscriptions are restored from db
438 // after initializing mock.subIds and mock.register
440 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
442 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
443 t.Errorf("TEST: %s", err.Error())
447 t.Errorf("TEST: This test case should return error")
449 // for _, subs := range mock.register {
450 for _, subs := range register {
451 PrintSubscriptionData(t, subs)
453 // SubIds slices before and after restart can't be directly compared as original slice is not stored
454 // in the db. SubId values 1, 2, 3, 4 are already removed from the beginning of subIds slice above
455 // so far. Next free subId is 5 in the beginning of mock.subIds slice. The db contains now however only
456 // 3 subscriptions with subIds 2, 3 and 4, so only subId values 2, 3, 4 are removed from the returned
457 // subIds slice and there next free value is 1
458 assert.Equal(t, uint32(0x1), subIds[0])
461 func TestRemoveAllSubscriptionsFromSdlFail(t *testing.T) {
463 // Try to remove all subscriptions. Test db should return test error string
464 MakeNextSdlCallFail()
465 err := mainCtrl.c.RemoveAllSubscriptionsFromSdl()
467 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
468 t.Errorf("TEST: %s", err.Error())
472 t.Errorf("TEST: This test case should return error")
474 t.Log("TEST: All subscription removed from db")
477 func (m *Mock) Set(ns string, pairs ...interface{}) error {
482 defer m.marshalLock.Unlock()
484 if ns != e2SubSdlNs {
485 return fmt.Errorf("Unexpected namespace '%s' error\n", ns)
488 if sdlShouldReturnError == true {
492 for _, v := range pairs {
493 reflectType := reflect.TypeOf(v)
494 switch reflectType.Kind() {
496 val = fmt.Sprintf("%s", v.([]uint8))
502 return fmt.Errorf("Set() error: Unexpected type\n")
508 m.e2SubsDb[key] = val
510 subscriptionInfo := &SubscriptionInfo{}
511 err := json.Unmarshal([]byte(val), subscriptionInfo)
513 return fmt.Errorf("Set() json.unmarshal error: %s\n", err.Error())
516 subs := mainCtrl.c.CreateSubscription(subscriptionInfo, &val)
517 m.register[subId] = subs
518 m.subIds = m.subIds[1:]
520 return fmt.Errorf("Set() error: key == ''\n")
525 func (m *Mock) Get(ns string, keys []string) (map[string]interface{}, error) {
526 retMap := make(map[string]interface{})
528 if ns != e2SubSdlNs {
529 return nil, fmt.Errorf("Unexpected namespace '%s' error\n", ns)
533 return nil, fmt.Errorf("Get() error: len(key) == 0\n")
536 if sdlShouldReturnError == true {
537 return nil, GetSdlError()
540 for _, key := range keys {
542 retMap[key] = m.e2SubsDb[key]
544 return nil, fmt.Errorf("Get() error: key == ''\n")
550 func (m *Mock) GetAll(ns string) ([]string, error) {
552 if ns != e2SubSdlNs {
553 return nil, fmt.Errorf("Unexpected namespace '%s' error\n", ns)
556 if sdlShouldReturnError == true {
557 return nil, GetSdlError()
561 for key, _ := range m.e2SubsDb {
562 keys = append(keys, key)
567 func (m *Mock) Remove(ns string, keys []string) error {
569 if ns != e2SubSdlNs {
570 return fmt.Errorf("Unexpected namespace '%s' error\n", ns)
574 return fmt.Errorf("Remove() error: len(key) == 0\n")
576 subId64, err := strconv.ParseUint(keys[0], 10, 64)
578 return fmt.Errorf("Remove() ParseUint() error: %s\n", err.Error())
581 if sdlShouldReturnError == true {
585 subId := uint32(subId64)
586 delete(m.e2SubsDb, keys[0])
587 delete(m.register, subId)
588 m.subIds = append(m.subIds, subId)
592 func (m *Mock) RemoveAll(ns string) error {
594 if ns != e2SubSdlNs {
595 return fmt.Errorf("Unexpected namespace '%s' error\n", ns)
598 for key := range m.e2SubsDb {
599 subId64, err := strconv.ParseUint(key, 10, 64)
601 return fmt.Errorf("RemoveAll() ParseUint() error: %s\n", err.Error())
604 subId := uint32(subId64)
605 delete(m.e2SubsDb, key)
606 delete(m.register, subId)
607 m.subIds = append(m.subIds, subId)
610 if sdlShouldReturnError == true {
617 func MakeNextSdlCallFail() {
618 sdlShouldReturnError = true
621 func GetSdlError() error {
622 sdlShouldReturnError = false
623 return fmt.Errorf(sdlTestErrorString)