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
161 fail.Cause.Content = e2ap.E2AP_CauseContent_RICrequest
162 fail.Cause.Value = e2ap.E2AP_CauseValue_RICrequest_control_message_invalid
166 func PrintSubscriptionData(t *testing.T, subs *Subscription) {
167 t.Log("TEST: subscription data")
168 t.Logf("TEST: subs.mutex = %v", subs.mutex)
169 t.Logf("TEST: subs.ReqId.InstanceId = %v", subs.ReqId.InstanceId)
170 t.Logf("TEST: subs.ReqId.Id = %v", subs.ReqId.Id)
171 t.Logf("TEST: subs.EpList = %v", subs.EpList)
172 t.Logf("TEST: subs.Meid.RanName = %v", subs.Meid.RanName)
173 t.Logf("TEST: subs.SubReqMsg = %v", subs.SubReqMsg.String())
174 t.Logf("TEST: subs.valid = %v", subs.valid)
176 if subs.SubRFMsg != nil {
177 switch typeofSubsMessage(subs.SubRFMsg) {
179 t.Logf("TEST: subs.SubRFMsg == SubResp")
180 subResp := subs.SubRFMsg.(*e2ap.E2APSubscriptionResponse)
181 t.Logf("TEST: subResp = %+v", subResp)
183 t.Logf("TEST: subs.SubRFMsg == SubFail")
184 subFail := subs.SubRFMsg.(*e2ap.E2APSubscriptionFailure)
185 t.Logf("TEST: subFail = %+v", subFail)
188 t.Logf("TEST: subs.SubRFMsg == nil")
192 func TestWriteSubscriptionToSdl(t *testing.T) {
194 // Write one subscription
195 subId := mock.AllocNextSubId()
196 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
197 PrintSubscriptionData(t, subs)
198 t.Logf("TEST: Writing subId = %v\n", subId)
199 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
201 t.Errorf("TEST: %s", err.Error())
203 verifyE2KeyCount(t, 1)
206 func verifyE2KeyCount(t *testing.T, expectedCount int) {
208 count, err := mainCtrl.c.GetE2KeyCount()
210 t.Errorf("TEST: %s", err.Error())
212 assert.Equal(t, expectedCount, count)
216 func TestReadSubscriptionFromSdl(t *testing.T) {
218 subId := mock.lastAllocatedSubId
219 t.Logf("Reading subId = %v\n", subId)
220 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
222 t.Errorf("TEST: %s", err.Error())
225 PrintSubscriptionData(t, subs)
226 assert.Equal(t, mock.register[subId].SubReqMsg, subs.SubReqMsg)
229 func TestRemoveSubscriptionFromSdl(t *testing.T) {
231 subId := mock.lastAllocatedSubId
232 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
234 t.Errorf("TEST: %s", err.Error())
237 delete(mock.register, subId)
238 mock.subIds = append(mock.subIds, subId)
239 t.Logf("TEST: subscription removed from db. subId = %v", subId)
242 func TestReadNotExistingSubscriptionFromSdl(t *testing.T) {
245 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
247 t.Logf("TEST: subscription not found from db. subId = %v", subId)
250 t.Errorf("TEST: subscription read from db. %v", subs.String())
251 PrintSubscriptionData(t, subs)
254 func TestReadNotExistingSubscriptionFromSdl2(t *testing.T) {
257 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
259 t.Logf("TEST: subscription not found from db. subId = %v", subId)
262 t.Errorf("TEST: subscription read from db. %v", subs.String())
263 PrintSubscriptionData(t, subs)
266 func TestRemoveNotExistingSubscriptionFromSdl(t *testing.T) {
269 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
271 t.Logf("TEST: %s", err.Error())
274 t.Logf("TEST: subscription removed from db. subId = %v", subId)
277 func TestWriteSubscriptionsToSdl(t *testing.T) {
279 // Write 1st subscription
280 subId := mock.AllocNextSubId()
281 t.Logf("TEST: Writing subId = %v\n", subId)
282 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
283 PrintSubscriptionData(t, subs)
284 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
286 t.Errorf("TEST: %s", err.Error())
289 t.Logf("TEST: subscription written in db = %v", subs.String())
291 // Write 2nd subscription
292 subId = mock.AllocNextSubId()
293 t.Logf("TEST:Writing subId = %v\n", subId)
294 subs = GetSubscription(t, subId, subsFailure, "localhost:13560", "RAN_NAME_2", "123457")
295 PrintSubscriptionData(t, subs)
296 err = mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
298 t.Errorf("TEST: %s", err.Error())
301 t.Logf("TEST: subscription written in db = %v", subs.String())
303 // Write 3rd subscription
304 subId = mock.AllocNextSubId()
305 t.Logf("TEST:Writing subId = %v\n", subId)
306 subs = GetSubscription(t, subId, noResponse, "localhost:13560", "RAN_NAME_3", "123458")
307 PrintSubscriptionData(t, subs)
308 err = mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
310 t.Errorf("TEST: %s", err.Error())
313 t.Logf("TEST: subscription written in db = %v", subs.String())
316 func TestReadSubscriptionsFromSdl(t *testing.T) {
318 // Subscription with subId 1 was added and and removed above. Then subscriptions with subIds 2, 3 and 4 was added
319 // Db subscriptions should now contain subIDs 2, 3 and 4
321 for subId = 2; subId <= 4; subId++ {
322 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
324 t.Errorf("TEST: %s", err.Error())
327 PrintSubscriptionData(t, subs)
331 func TestReadAllSubscriptionsFromSdl(t *testing.T) {
333 // This test cases simulates submgr restart. SubIds and subscriptions are restored from db
334 // after initializing mock.subIds and mock.register
336 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
338 t.Errorf("TEST: %s", err.Error())
341 // for _, subs := range mock.register {
342 for _, subs := range register {
343 PrintSubscriptionData(t, subs)
345 // SubIds slices before and after restart can't be directly compared as original slice is not stored
346 // in the db. SubId values 1, 2, 3, 4 are already removed from the beginning of subIds slice above
347 // so far. Next free subId is 5 in the beginning of mock.subIds slice. The db contains now however only
348 // 3 subscriptions with subIds 2, 3 and 4, so only subId values 2, 3, 4 are removed from the returned
349 // subIds slice and there next free value is 1
350 assert.Equal(t, uint32(0x1), subIds[0])
353 func TestRemoveAllSubscriptionsFromSdl(t *testing.T) {
355 err := mainCtrl.c.RemoveAllSubscriptionsFromSdl()
357 t.Errorf("TEST: %s", err.Error())
360 t.Log("TEST: All subscription removed from db")
363 func TestReadAllSubscriptionsFromSdl2(t *testing.T) {
365 // This test cases simulates submgr startup. SubIds and subscriptions are restored from empty db
366 // after initializing mock.subIds and mock.register
367 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
369 t.Errorf("TEST: %s", err.Error())
372 for _, subs := range mock.register {
373 PrintSubscriptionData(t, subs)
375 assert.Equal(t, len(subIds), 65534)
376 assert.Equal(t, len(register), 0)
379 func TestWriteSubscriptionToSdlFail(t *testing.T) {
381 // Try to write one subscription. Test db should return test error string
382 MakeNextSdlCallFail()
383 subId := mock.AllocNextSubId()
384 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
385 PrintSubscriptionData(t, subs)
386 t.Logf("TEST: Writing subId = %v\n", subId)
387 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
389 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
390 t.Errorf("TEST: %s", err.Error())
393 t.Errorf("TEST: This test case should return error")
397 func TestReadSubscriptionFromSdlFail(t *testing.T) {
399 // Try to read one subscription. Test db should return test error string
400 MakeNextSdlCallFail()
401 subId := mock.lastAllocatedSubId
402 t.Logf("Reading subId = %v\n", subId)
403 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
405 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
406 t.Errorf("TEST: %s", err.Error())
410 t.Errorf("TEST: This test case should return error")
412 PrintSubscriptionData(t, subs)
413 assert.Equal(t, mock.register[subId].SubReqMsg, subs.SubReqMsg)
416 func TestRemoveSubscriptionFromSdlFail(t *testing.T) {
418 // Try to remove one subscription. Test db should return test error string
419 MakeNextSdlCallFail()
420 subId := mock.lastAllocatedSubId
421 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
423 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
424 t.Errorf("TEST: %s", err.Error())
428 t.Errorf("TEST: This test case should return error")
430 delete(mock.register, subId)
431 mock.subIds = append(mock.subIds, subId)
432 t.Logf("TEST: subscription removed from db. subId = %v", subId)
435 func TestReadAllSubscriptionsFromSdlFail(t *testing.T) {
437 // Try to read all subscriptions. Test db should return test error string
438 MakeNextSdlCallFail()
439 // This test cases simulates submgr restart. SubIds and subscriptions are restored from db
440 // after initializing mock.subIds and mock.register
442 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
444 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
445 t.Errorf("TEST: %s", err.Error())
449 t.Errorf("TEST: This test case should return error")
451 // for _, subs := range mock.register {
452 for _, subs := range register {
453 PrintSubscriptionData(t, subs)
455 // SubIds slices before and after restart can't be directly compared as original slice is not stored
456 // in the db. SubId values 1, 2, 3, 4 are already removed from the beginning of subIds slice above
457 // so far. Next free subId is 5 in the beginning of mock.subIds slice. The db contains now however only
458 // 3 subscriptions with subIds 2, 3 and 4, so only subId values 2, 3, 4 are removed from the returned
459 // subIds slice and there next free value is 1
460 assert.Equal(t, uint32(0x1), subIds[0])
463 func TestRemoveAllSubscriptionsFromSdlFail(t *testing.T) {
465 // Try to remove all subscriptions. Test db should return test error string
466 MakeNextSdlCallFail()
467 err := mainCtrl.c.RemoveAllSubscriptionsFromSdl()
469 if !strings.Contains(fmt.Sprintf("%s", err), sdlTestErrorString) {
470 t.Errorf("TEST: %s", err.Error())
474 t.Errorf("TEST: This test case should return error")
476 t.Log("TEST: All subscription removed from db")
479 func (m *Mock) Set(ns string, pairs ...interface{}) error {
484 defer m.marshalLock.Unlock()
486 if ns != e2SubSdlNs {
487 return fmt.Errorf("Unexpected namespace '%s' error\n", ns)
490 if sdlShouldReturnError == true {
494 for _, v := range pairs {
495 reflectType := reflect.TypeOf(v)
496 switch reflectType.Kind() {
498 val = fmt.Sprintf("%s", v.([]uint8))
504 return fmt.Errorf("Set() error: Unexpected type\n")
510 m.e2SubsDb[key] = val
512 subscriptionInfo := &SubscriptionInfo{}
513 err := json.Unmarshal([]byte(val), subscriptionInfo)
515 return fmt.Errorf("Set() json.unmarshal error: %s\n", err.Error())
518 subs := mainCtrl.c.CreateSubscription(subscriptionInfo, &val)
519 m.register[subId] = subs
520 m.subIds = m.subIds[1:]
522 return fmt.Errorf("Set() error: key == ''\n")
527 func (m *Mock) Get(ns string, keys []string) (map[string]interface{}, error) {
528 retMap := make(map[string]interface{})
530 if ns != e2SubSdlNs {
531 return nil, fmt.Errorf("Unexpected namespace '%s' error\n", ns)
535 return nil, fmt.Errorf("Get() error: len(key) == 0\n")
538 if sdlShouldReturnError == true {
539 return nil, GetSdlError()
542 for _, key := range keys {
544 retMap[key] = m.e2SubsDb[key]
546 return nil, fmt.Errorf("Get() error: key == ''\n")
552 func (m *Mock) GetAll(ns string) ([]string, error) {
554 if ns != e2SubSdlNs {
555 return nil, fmt.Errorf("Unexpected namespace '%s' error\n", ns)
558 if sdlShouldReturnError == true {
559 return nil, GetSdlError()
563 for key, _ := range m.e2SubsDb {
564 keys = append(keys, key)
569 func (m *Mock) Remove(ns string, keys []string) error {
571 if ns != e2SubSdlNs {
572 return fmt.Errorf("Unexpected namespace '%s' error\n", ns)
576 return fmt.Errorf("Remove() error: len(key) == 0\n")
578 subId64, err := strconv.ParseUint(keys[0], 10, 64)
580 return fmt.Errorf("Remove() ParseUint() error: %s\n", err.Error())
583 if sdlShouldReturnError == true {
587 subId := uint32(subId64)
588 delete(m.e2SubsDb, keys[0])
589 delete(m.register, subId)
590 m.subIds = append(m.subIds, subId)
594 func (m *Mock) RemoveAll(ns string) error {
596 if ns != e2SubSdlNs {
597 return fmt.Errorf("Unexpected namespace '%s' error\n", ns)
600 for key := range m.e2SubsDb {
601 subId64, err := strconv.ParseUint(key, 10, 64)
603 return fmt.Errorf("RemoveAll() ParseUint() error: %s\n", err.Error())
606 subId := uint32(subId64)
607 delete(m.e2SubsDb, key)
608 delete(m.register, subId)
609 m.subIds = append(m.subIds, subId)
612 if sdlShouldReturnError == true {
619 func MakeNextSdlCallFail() {
620 sdlShouldReturnError = true
623 func GetSdlError() error {
624 sdlShouldReturnError = false
625 return fmt.Errorf(sdlTestErrorString)