blob: 9198e5c567ec4ec5befafd3334caa8fd03258556 [file] [log] [blame]
Anssi Mannilac92b4212020-12-07 14:59:34 +02001/*
2==================================================================================
3 Copyright (c) 2019 AT&T Intellectual Property.
4 Copyright (c) 2019 Nokia
5
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
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
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==================================================================================
18*/
19
20package control
21
22import (
23 "encoding/json"
24 "fmt"
25 "gerrit.o-ran-sc.org/r/ric-plt/e2ap/pkg/e2ap"
26 "gerrit.o-ran-sc.org/r/ric-plt/submgr/pkg/teststube2ap"
27 "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/xapp"
28 "github.com/stretchr/testify/assert"
29 "reflect"
30 "strconv"
31 "testing"
32 "time"
33)
34
35const (
36 subsResponse = 1
37 subsFailure = 2
38 noResponse = 3
39)
40
41type Mock struct {
42 subsDB map[string]string // Store information as a string like real db does.
43 register map[uint32]*Subscription
44 subIds []uint32
45 lastAllocatedSubId uint32
46}
47
48var mock *Mock
49
50func CreateMock() *Mock {
51 fmt.Println("Test CreateMock()")
52 mock = new(Mock)
53 mock.ResetTestSettings()
54 return mock
55}
56
57func (m *Mock) ResetTestSettings() {
58 m.subsDB = make(map[string]string)
59 m.register = make(map[uint32]*Subscription)
60 var i uint32
61 for i = 1; i < 65535; i++ {
62 m.subIds = append(m.subIds, i)
63 }
64}
65
66func (m *Mock) AllocNextSubId() uint32 {
67 m.lastAllocatedSubId = m.subIds[0]
68 return m.lastAllocatedSubId
69}
70
71func TestWait(t *testing.T) {
72 // Wait to test settings to complete
73 <-time.After(1 * time.Second)
74}
75
76func GetSubscription(t *testing.T, e2SubId uint32, responseType int, srcEndPoint, ranName string, xId string) *Subscription {
77 t.Log("TEST: Getting subscription")
78
79 subs := &Subscription{}
80
81 // Create unpacked e2SubReqMsg
82 subReqParams := &teststube2ap.E2StubSubsReqParams{}
83 subReqParams.Init()
84
85 meid := xapp.RMRMeid{}
86 meid.RanName = ranName
87
88 params := &xapp.RMRParams{}
89 params.Src = srcEndPoint
90 params.Xid = xId
91 params.Meid = &meid
92
93 // Create xApp transaction
94 trans := mainCtrl.c.tracker.NewXappTransaction(xapp.NewRmrEndpoint(params.Src), params.Xid, subReqParams.Req.RequestId.InstanceId, params.Meid)
95 if trans == nil {
96 t.Errorf("TEST: %s", idstring(fmt.Errorf("transaction not created"), params))
97 return nil
98 }
99
100 // Allocate E2 instanceId/subId
101 subReqParams.Req.RequestId.InstanceId = e2SubId
102
103 subs.ReqId.Id = 123
104 subs.ReqId.InstanceId = subReqParams.Req.RequestId.InstanceId
105 subs.Meid = &meid
106 subs.EpList.AddEndpoint(trans.GetEndpoint())
107 subs.SubReqMsg = subReqParams.Req
108 // subs.SubRFMsg contains received/cached SubscriptionResponse or SubscriptionFailure, nil in no response received
109 if responseType == subsResponse {
110 subs.SubRFMsg = GetSubsResponse(t, subReqParams.Req)
111 subs.valid = true
112 } else if responseType == subsFailure {
113 subs.SubRFMsg = GetSubsFailure(t, subReqParams.Req)
114 subs.valid = false
115 } else if responseType == noResponse {
116 subs.SubRFMsg = nil
117 subs.valid = false
118 }
119 return subs
120}
121
122func GetSubsResponse(t *testing.T, req *e2ap.E2APSubscriptionRequest) *e2ap.E2APSubscriptionResponse {
123 t.Log("TEST: Getting ricSubscriptionResponse")
124
125 // Create e2SubRespMsg
126 resp := &e2ap.E2APSubscriptionResponse{}
127 resp.RequestId.Id = 123
128 resp.RequestId.InstanceId = req.RequestId.InstanceId
129 resp.FunctionId = req.FunctionId
130
131 resp.ActionAdmittedList.Items = make([]e2ap.ActionAdmittedItem, len(req.ActionSetups))
132 for index := int(0); index < len(req.ActionSetups); index++ {
133 resp.ActionAdmittedList.Items[index].ActionId = req.ActionSetups[index].ActionId
134 }
135
136 for index := uint64(0); index < 1; index++ {
137 item := e2ap.ActionNotAdmittedItem{}
138 item.ActionId = index
139 item.Cause.Content = 1
140 item.Cause.Value = 1
141 resp.ActionNotAdmittedList.Items = append(resp.ActionNotAdmittedList.Items, item)
142 }
143 return resp
144}
145
146func GetSubsFailure(t *testing.T, req *e2ap.E2APSubscriptionRequest) *e2ap.E2APSubscriptionFailure {
147 t.Log("TEST: Getting ricSubscriptionFailure")
148
149 fail := &e2ap.E2APSubscriptionFailure{}
150 fail.RequestId.Id = req.RequestId.Id
151 fail.RequestId.InstanceId = req.RequestId.InstanceId
152 fail.FunctionId = req.FunctionId
153 return fail
154}
155
156func PrintSubscriptionData(t *testing.T, subs *Subscription) {
157 t.Log("TEST: subscription data")
158 t.Logf("TEST: subs.mutex = %v", subs.mutex)
159 t.Logf("TEST: subs.ReqId.InstanceId = %v", subs.ReqId.InstanceId)
160 t.Logf("TEST: subs.ReqId.Id = %v", subs.ReqId.Id)
161 t.Logf("TEST: subs.EpList = %v", subs.EpList)
162 t.Logf("TEST: subs.Meid.RanName = %v", subs.Meid.RanName)
163 t.Logf("TEST: subs.SubReqMsg = %v", subs.SubReqMsg.String())
164 t.Logf("TEST: subs.valid = %v", subs.valid)
165
166 if subs.SubRFMsg != nil {
167 switch typeofSubsMessage(subs.SubRFMsg) {
168 case "SubResp":
169 t.Logf("TEST: subs.SubRFMsg == SubResp")
170 subResp := subs.SubRFMsg.(*e2ap.E2APSubscriptionResponse)
171 t.Logf("TEST: subResp = %+v", subResp)
172 case "SubFail":
173 t.Logf("TEST: subs.SubRFMsg == SubFail")
174 subFail := subs.SubRFMsg.(*e2ap.E2APSubscriptionFailure)
175 t.Logf("TEST: subFail = %+v", subFail)
176 }
177 } else {
178 t.Logf("TEST: subs.SubRFMsg == nil")
179 }
180}
181
182func TestWriteSubscriptionToSdl(t *testing.T) {
183 t.Log("TestWriteSubscriptionToSdl")
184
185 // Write one subscription
186 subId := mock.AllocNextSubId()
187 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
188 PrintSubscriptionData(t, subs)
189 t.Logf("TEST: Writing subId = %v\n", subId)
190 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
191 if err != nil {
192 t.Errorf("TEST: %s", err.Error())
193 return
194 }
195}
196
197func TestReadSubscriptionFromSdl(t *testing.T) {
198 t.Log("TestReadSubscriptionFromSdl")
199
200 subId := mock.lastAllocatedSubId
201 t.Logf("Reading subId = %v\n", subId)
202 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
203 if err != nil {
204 t.Errorf("TEST: %s", err.Error())
205 return
206 }
207 PrintSubscriptionData(t, subs)
208 assert.Equal(t, mock.register[subId].SubReqMsg, subs.SubReqMsg)
209}
210
211func TestRemoveSubscriptionFromSdl(t *testing.T) {
212 t.Log("TestRemoveSubscriptionFromSdl")
213
214 subId := mock.lastAllocatedSubId
215 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
216 if err != nil {
217 t.Errorf("TEST: %s", err.Error())
218 return
219 }
220 delete(mock.register, subId)
221 mock.subIds = append(mock.subIds, subId)
222 t.Logf("TEST: subscription removed from db. subId = %v", subId)
223}
224
225func TestReadNotExistingSubscriptionFromSdl(t *testing.T) {
226 t.Log("TestReadNotExistingSubscriptionFromSdl")
227
228 var subId uint32 = 0
229 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
230 if err != nil {
231 t.Logf("TEST: subscription not found from db. subId = %v", subId)
232 return
233 }
234 t.Errorf("TEST: subscription read from db. %v", subs.String())
235 PrintSubscriptionData(t, subs)
236}
237
238func TestReadNotExistingSubscriptionFromSdl2(t *testing.T) {
239 t.Log("TestReadNotExistingSubscriptionFromSdl")
240
241 var subId uint32 = 7
242 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
243 if err != nil {
244 t.Logf("TEST: subscription not found from db. subId = %v", subId)
245 return
246 }
247 t.Errorf("TEST: subscription read from db. %v", subs.String())
248 PrintSubscriptionData(t, subs)
249}
250
251func TestRemoveNotExistingSubscriptionFromSdl(t *testing.T) {
252 t.Log("TestRemoveNotExistingSubscriptionFromSdl")
253
254 var subId uint32 = 0
255 err := mainCtrl.c.RemoveSubscriptionFromSdl(subId)
256 if err != nil {
257 t.Logf("TEST: %s", err.Error())
258 return
259 }
260 t.Logf("TEST: subscription removed from db. subId = %v", subId)
261}
262
263func TestWriteSubscriptionsToSdl(t *testing.T) {
264 t.Log("TestWriteSubscriptionsToSdl")
265
266 // Write 1st subscription
267 subId := mock.AllocNextSubId()
268 t.Logf("TEST: Writing subId = %v\n", subId)
269 subs := GetSubscription(t, subId, subsResponse, "localhost:13560", "RAN_NAME_1", "123456")
270 PrintSubscriptionData(t, subs)
271 err := mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
272 if err != nil {
273 t.Errorf("TEST: %s", err.Error())
274 return
275 }
276 t.Logf("TEST: subscription written in db = %v", subs.String())
277
278 // Write 2nd subscription
279 subId = mock.AllocNextSubId()
280 t.Logf("TEST:Writing subId = %v\n", subId)
281 subs = GetSubscription(t, subId, subsFailure, "localhost:13560", "RAN_NAME_2", "123457")
282 PrintSubscriptionData(t, subs)
283 err = mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
284 if err != nil {
285 t.Errorf("TEST: %s", err.Error())
286 return
287 }
288 t.Logf("TEST: subscription written in db = %v", subs.String())
289
290 // Write 3rd subscription
291 subId = mock.AllocNextSubId()
292 t.Logf("TEST:Writing subId = %v\n", subId)
293 subs = GetSubscription(t, subId, noResponse, "localhost:13560", "RAN_NAME_3", "123458")
294 PrintSubscriptionData(t, subs)
295 err = mainCtrl.c.WriteSubscriptionToSdl(subId, subs)
296 if err != nil {
297 t.Errorf("TEST: %s", err.Error())
298 return
299 }
300 t.Logf("TEST: subscription written in db = %v", subs.String())
301}
302
303func TestReadSubscriptionsFromSdl(t *testing.T) {
304 t.Log("TestReadSubscriptionsFromSdl")
305
306 // Subscription with subId 1 was added and and removed above. Then subscriptions with subIds 2, 3 and 4 was added
307 // Db subscriptions should now contain subIDs 2, 3 and 4
308 var subId uint32
309 for subId = 2; subId <= 4; subId++ {
310 subs, err := mainCtrl.c.ReadSubscriptionFromSdl(subId)
311 if err != nil {
312 t.Errorf("TEST: %s", err.Error())
313 return
314 }
315 PrintSubscriptionData(t, subs)
316 }
317}
318
319func TestReadAllSubscriptionsFromSdl(t *testing.T) {
320 t.Log("TestReadAllSubscriptionsFromSdl")
321
322 // This test cases simulates submgr restart. SubIds and subscriptions are restored from db
323 // after initializing mock.subIds and mock.register
324 // var err error
325 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
326 if err != nil {
327 t.Errorf("TEST: %s", err.Error())
328 return
329 }
330 // for _, subs := range mock.register {
331 for _, subs := range register {
332 PrintSubscriptionData(t, subs)
333 }
334 // SubIds slices before and after restart can't be directly compared as original slice is not stored
335 // in the db. SubId values 1, 2, 3, 4 are already removed from the beginning of subIds slice above
336 // so far. Next free subId is 5 in the beginning of mock.subIds slice. The db contains now however only
337 // 3 subscriptions with subIds 2, 3 and 4, so only subId values 2, 3, 4 are removed from the returned
338 // subIds slice and there next free value is 1
339 assert.Equal(t, uint32(0x1), subIds[0])
340}
341
342func TestRemoveAllSubscriptionsFromSdl(t *testing.T) {
343 t.Log("TestRemoveAllSubscriptionsFromSdl")
344
345 err := mainCtrl.c.RemoveAllSubscriptionsFromSdl()
346 if err != nil {
347 t.Errorf("TEST: %s", err.Error())
348 return
349 }
350 t.Log("TEST: All subscription removed from db")
351}
352
353func TestReadAllSubscriptionsFromSdl2(t *testing.T) {
354 t.Log("TestReadAllSubscriptionsFromSdl2")
355
356 // This test cases simulates submgr startup. SubIds and subscriptions are restored from empty db
357 // after initializing mock.subIds and mock.register
358 subIds, register, err := mainCtrl.c.ReadAllSubscriptionsFromSdl()
359 if err != nil {
360 t.Errorf("TEST: %s", err.Error())
361 return
362 }
363 for _, subs := range mock.register {
364 PrintSubscriptionData(t, subs)
365 }
366 assert.Equal(t, len(subIds), 65534)
367 assert.Equal(t, len(register), 0)
368}
369
370func (m *Mock) Set(pairs ...interface{}) error {
371 var key string
372 var val string
373
374 for _, v := range pairs {
375 reflectType := reflect.TypeOf(v)
376 switch reflectType.Kind() {
377 case reflect.Slice:
378 val = fmt.Sprintf("%s", v.([]uint8))
379 default:
380 switch v.(type) {
381 case string:
382 key = v.(string)
383 default:
384 return fmt.Errorf("Set() error: Unexpected type\n")
385 }
386 }
387 }
388
389 if key != "" {
390 m.subsDB[key] = val
391 subId := m.subIds[0]
392 subscriptionInfo := &SubscriptionInfo{}
393 err := json.Unmarshal([]byte(val), subscriptionInfo)
394 if err != nil {
395 return fmt.Errorf("Set() json.unmarshal error: %s\n", err.Error())
396 }
397
398 subs := mainCtrl.c.CreateSubscription(subscriptionInfo, &val)
399 m.register[subId] = subs
400 m.subIds = m.subIds[1:]
401 } else {
402 return fmt.Errorf("Set() error: key == ''\n")
403 }
404 return nil
405}
406
407func (m *Mock) Get(keys []string) (map[string]interface{}, error) {
408 retMap := make(map[string]interface{})
409 if len(keys) == 0 {
410 return nil, fmt.Errorf("Get() error: len(key) == 0\n")
411 }
412
413 for _, key := range keys {
414 if key != "" {
415 retMap[key] = m.subsDB[key]
416 } else {
417 return nil, fmt.Errorf("Get() error: key == ''\n")
418 }
419 }
420 return retMap, nil
421}
422
423func (m *Mock) GetAll() ([]string, error) {
424
425 keys := []string{}
426 for key, _ := range m.subsDB {
427 keys = append(keys, key)
428 }
429 return keys, nil
430}
431
432func (m *Mock) Remove(keys []string) error {
433 if len(keys) == 0 {
434 return fmt.Errorf("Remove() error: len(key) == 0\n")
435 }
436 subId64, err := strconv.ParseUint(keys[0], 10, 64)
437 if err != nil {
438 return fmt.Errorf("Remove() ParseUint() error: %s\n", err.Error())
439 }
440 subId := uint32(subId64)
441 delete(m.subsDB, keys[0])
442 delete(m.register, subId)
443 m.subIds = append(m.subIds, subId)
444 return nil
445}
446
447func (m *Mock) RemoveAll() error {
448 for key := range m.subsDB {
449 subId64, err := strconv.ParseUint(key, 10, 64)
450 if err != nil {
451 return fmt.Errorf("RemoveAll() ParseUint() error: %s\n", err.Error())
452 }
453 subId := uint32(subId64)
454 delete(m.subsDB, key)
455 delete(m.register, subId)
456 m.subIds = append(m.subIds, subId)
457 }
458 return nil
459}