11afe470af6e1b8192e993d5f8874cf98670de17
[ric-plt/a1.git] / pkg / resthooks / resthooks_test.go
1 /*
2 ==================================================================================
3   Copyright (c) 2021 Samsung
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17    This source code is part of the near-RT RIC (RAN Intelligent Controller)
18    platform project (RICP).
19 ==================================================================================
20 */
21 package resthooks
22
23 import (
24         "encoding/json"
25         "os"
26         "strconv"
27         "testing"
28         "time"
29
30         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/a1"
31         "gerrit.o-ran-sc.org/r/ric-plt/a1/pkg/models"
32         "github.com/stretchr/testify/assert"
33         "github.com/stretchr/testify/mock"
34 )
35
36 type RmrSenderMock struct {
37         mock.Mock
38 }
39
40 var rh *Resthook
41 var sdlInst *SdlMock
42 var rmrSenderInst *RmrSenderMock
43
44 func TestMain(m *testing.M) {
45         sdlInst = new(SdlMock)
46
47         sdlInst.On("GetAll", "A1m_ns").Return([]string{"a1.policy_instance.1006001.qos",
48                 "a1.policy_instance.20005.123456",
49                 "a1.policy_instance.20005.234567",
50                 "a1.policy_type.1006001",
51                 "a1.policy_type.20000",
52                 "a1.policy_inst_metadata.1006001.qos",
53         }, nil)
54         rmrSenderInst = new(RmrSenderMock)
55         a1.Init()
56         rh = createResthook(sdlInst, rmrSenderInst)
57         code := m.Run()
58         os.Exit(code)
59 }
60
61 func TestHealth(t *testing.T) {
62         resp := rh.GetA1Health()
63         if resp == true {
64                 a1.Logger.Debug("A1 is healthy ")
65                 assert.Equal(t, true, resp)
66         } else {
67                 a1.Logger.Debug("A1 is unhealthy")
68                 assert.Equal(t, false, resp)
69         }
70 }
71
72 func TestGetAllPolicyType(t *testing.T) {
73         resp := rh.GetAllPolicyType()
74         assert.Equal(t, 2, len(resp))
75 }
76
77 func TestGetPolicyType(t *testing.T) {
78
79         policyTypeId := models.PolicyTypeID(20001)
80
81         var policyTypeSchema models.PolicyTypeSchema
82         name := "admission_control_policy_mine"
83         policyTypeSchema.Name = &name
84         policytypeid := int64(20001)
85         policyTypeSchema.PolicyTypeID = &policytypeid
86         description := "various parameters to control admission of dual connection"
87         policyTypeSchema.Description = &description
88         schema := `{"$schema": "http://json-schema.org/draft-07/schema#","type":"object","properties": {"enforce": {"type":"boolean","default":"true",},"window_length": {"type":        "integer","default":1,"minimum":1,"maximum":60,"description": "Sliding window length (in minutes)",},
89 "blocking_rate": {"type":"number","default":10,"minimum":1,"maximum":100,"description": "% Connections to block",},"additionalProperties": false,},}`
90         policyTypeSchema.CreateSchema = schema
91         key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
92         var keys [1]string
93         keys[0] = key
94         //Setup Expectations
95         sdlInst.On("Get", a1MediatorNs, keys[:]).Return(map[string]interface{}{key: policyTypeSchema}, nil)
96         resp := rh.GetPolicyType(policyTypeId)
97         assert.NotNil(t, resp)
98
99         sdlInst.AssertExpectations(t)
100
101 }
102
103 func TestCreatePolicyType(t *testing.T) {
104         var policyTypeId models.PolicyTypeID
105         policyTypeId = 20001
106         var policyTypeSchema models.PolicyTypeSchema
107         name := "admission_control_policy_mine"
108         policyTypeSchema.Name = &name
109         policytypeid := int64(20001)
110         policyTypeSchema.PolicyTypeID = &policytypeid
111         description := "various parameters to control admission of dual connection"
112         policyTypeSchema.Description = &description
113         policyTypeSchema.CreateSchema = `{"$schema": "http://json-schema.org/draft-07/schema#","type":"object","properties": {"enforce": {"type":"boolean","default":"true",},"window_length": {"type":        "integer","default":1,"minimum":1,"maximum":60,"description": "Sliding window length (in minutes)",},
114 "blocking_rate": {"type":"number","default":10,"minimum":1,"maximum":100,"description": "% Connections to block",},"additionalProperties": false,},}`
115
116         data, err := policyTypeSchema.MarshalBinary()
117         a1.Logger.Debug("error : %+v ", err)
118         a1.Logger.Debug("data : %+v ", data)
119         key := a1PolicyPrefix + strconv.FormatInt(20001, 10)
120         a1.Logger.Debug("key : %+v ", key)
121         //Setup Expectations
122         sdlInst.On("SetIfNotExists", a1MediatorNs, key, string(data)).Return(true, nil)
123
124         errresp := rh.CreatePolicyType(policyTypeId, policyTypeSchema)
125         //Data Assertion
126         assert.Nil(t, errresp)
127         //Mock Assertion :Behavioral
128         sdlInst.AssertExpectations(t)
129 }
130
131 func TestCreatePolicyTypeInstance(t *testing.T) {
132         var policyInstanceID models.PolicyInstanceID
133         policyInstanceID = "123456"
134         var httpBody = `{"enforce":true,"window_length":20,"blocking_rate":20,"trigger_threshold":10}`
135         instancekey := a1InstancePrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
136         var policyTypeId models.PolicyTypeID
137         policyTypeId = 20001
138
139         var instancedata map[string]interface{}
140
141         json.Unmarshal([]byte(httpBody), &instancedata)
142
143         data, _ := json.Marshal(instancedata)
144         a1.Logger.Debug("Marshaled data : %+v", string(data))
145         a1.Logger.Debug("instancekey   : %+v", instancekey)
146         instancearr := []interface{}{instancekey, string(data)}
147         sdlInst.On("Set", "A1m_ns", instancearr).Return(nil)
148
149         metadatainstancekey := a1InstanceMetadataPrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
150         creation_timestamp := time.Now()
151         var metadatajson []interface{}
152         metadatajson = append(metadatajson, map[string]string{"created_at": creation_timestamp.Format("2006-01-02 15:04:05"), "has_been_deleted": "False"})
153         metadata, _ := json.Marshal(metadatajson)
154         a1.Logger.Debug("Marshaled Metadata : %+v", string(metadata))
155         a1.Logger.Debug("metadatainstancekey   : %+v", metadatainstancekey)
156         metadatainstancearr := []interface{}{metadatainstancekey, string(metadata)}
157         sdlInst.On("Set", "A1m_ns", metadatainstancearr).Return(nil)
158         rmrSenderInst.On("RmrSendToXapp", "httpBodyString", 20010, int(policyTypeId)).Return(true)
159
160         errresp := rh.CreatePolicyInstance(policyTypeId, policyInstanceID, instancedata)
161
162         assert.Nil(t, errresp)
163         sdlInst.AssertExpectations(t)
164 }
165
166 func TestGetPolicyInstance(t *testing.T) {
167
168         var policyTypeId models.PolicyTypeID
169         policyTypeId = 20001
170         var policyInstanceID models.PolicyInstanceID
171         policyInstanceID = "123456"
172         httpBody := `{
173                 "enforce":true,
174                 "window_length":20,
175            "blocking_rate":20,
176                 "trigger_threshold":10
177                 }`
178         instancekey := a1InstancePrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
179         a1.Logger.Debug("httpBody String : %+v", httpBody)
180         a1.Logger.Debug("key   : %+v", instancekey)
181         var keys [1]string
182         keys[0] = instancekey
183         //Setup Expectations
184         sdlInst.On("Get", a1MediatorNs, keys[:]).Return(httpBody, nil)
185
186         resp, err := rh.GetPolicyInstance(policyTypeId, policyInstanceID)
187         a1.Logger.Error("err : %+v", err)
188         assert.NotNil(t, resp)
189
190         sdlInst.AssertExpectations(t)
191 }
192
193 func TestGetAllPolicyIntances(t *testing.T) {
194         var policyTypeId models.PolicyTypeID
195         policyTypeId = 20005
196         resp, err := rh.GetAllPolicyInstance(policyTypeId)
197         a1.Logger.Error("err : %+v", err)
198         assert.Equal(t, 2, len(resp))
199 }
200
201 func TestDeletePolicyType(t *testing.T) {
202
203         policyTypeId := models.PolicyTypeID(20001)
204         key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
205         var keys [1]string
206         keys[0] = key
207
208         //Setup Expectations
209         sdlInst.On("Remove", a1MediatorNs, keys[:]).Return(nil)
210
211         errresp := rh.DeletePolicyType(policyTypeId)
212
213         assert.Nil(t, errresp)
214         sdlInst.AssertExpectations(t)
215 }
216
217 func TestGetPolicyInstanceStatus(t *testing.T) {
218         var policyTypeId models.PolicyTypeID
219         policyTypeId = 20001
220         var policyInstanceID models.PolicyInstanceID
221         policyInstanceID = "123456"
222         httpBody := `{
223                 "created_at":"0001-01-01T00:00:00.000Z",
224                 "instance_status":"NOT IN EFFECT"
225                 }`
226         instancekey := a1InstanceMetadataPrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
227         a1.Logger.Debug("httpBody String : %+v", httpBody)
228         a1.Logger.Debug("key   : %+v", instancekey)
229         var keys [1]string
230         keys[0] = instancekey
231         sdlInst.On("Get", a1MediatorNs, keys[:]).Return(httpBody)
232         instancekey = a1HandlerPrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
233         var instancekeys [1]string
234         instancekeys[0] = instancekey
235         instancearr := []interface{}{instancekey, "OK"}
236         sdlInst.On("Get", a1MediatorNs, instancekeys[:]).Return(instancearr, nil)
237         resp, errresp := rh.GetPolicyInstanceStatus(policyTypeId, policyInstanceID)
238
239         assert.Nil(t, errresp)
240         assert.NotNil(t, resp)
241         sdlInst.AssertExpectations(t)
242 }
243
244 func TestDeletePolicyInstance(t *testing.T) {
245         var policyTypeId models.PolicyTypeID
246         policyTypeId = 20001
247         var policyInstanceID models.PolicyInstanceID
248         policyInstanceID = "123456"
249         var policyTypeSchema models.PolicyTypeSchema
250         name := "admission_control_policy_mine"
251         policyTypeSchema.Name = &name
252         policytypeid := int64(20001)
253         policyTypeSchema.PolicyTypeID = &policytypeid
254         description := "various parameters to control admission of dual connection"
255         policyTypeSchema.Description = &description
256         schema := `{"$schema": "http://json-schema.org/draft-07/schema#","type":"object","properties": {"enforce": {"type":"boolean","default":"true",},"window_length": {"type":        "integer","default":1,"minimum":1,"maximum":60,"description": "Sliding window length (in minutes)",},
257 "blocking_rate": {"type":"number","default":10,"minimum":1,"maximum":100,"description": "% Connections to block",},"additionalProperties": false,},}`
258         policyTypeSchema.CreateSchema = schema
259
260         key := a1PolicyPrefix + strconv.FormatInt((int64(policyTypeId)), 10)
261         var policytypekeys [1]string
262         policytypekeys[0] = key
263
264         sdlInst.On("Get", a1MediatorNs, policytypekeys[:]).Return(map[string]interface{}{key: policyTypeSchema}, nil)
265
266         httpBody := `{
267                 "enforce":true,
268                 "window_length":20,
269            "blocking_rate":20,
270                 "trigger_threshold":10
271                 }`
272         instancekey := a1InstancePrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
273         var instancekeys [1]string
274         instancekeys[0] = instancekey
275
276         sdlInst.On("Get", a1MediatorNs, instancekeys[:]).Return(httpBody, nil)
277
278         var instanceMetadataKeys [1]string
279         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
280         instanceMetadataKeys[0] = instanceMetadataKey
281         httpBody = `{
282                 "created_at":"2022-11-02 10:30:20",
283                         "instance_status":"NOT IN EFFECT"
284                 }`
285
286         sdlInst.On("Get", a1MediatorNs, instanceMetadataKeys[:]).Return(httpBody, nil)
287
288         sdlInst.On("Remove", a1MediatorNs, instanceMetadataKeys[:]).Return(nil)
289
290         var metadatainstancekeys [1]string
291         metadatainstancekeys[0] = instancekey
292
293         sdlInst.On("Remove", a1MediatorNs, metadatainstancekeys[:]).Return(nil)
294
295         metadatainstancekey := a1InstanceMetadataPrefix + strconv.FormatInt(20001, 10) + "." + string(policyInstanceID)
296         deleted_timestamp := time.Now()
297         var metadatajson interface{}
298         metadatajson = map[string]string{"created_at": "2022-11-02 10:30:20", "deleted_at": deleted_timestamp.Format("2006-01-02 15:04:05"), "has_been_deleted": "True"}
299         metadata, _ := json.Marshal(metadatajson)
300         metadatainstancearr := []interface{}{metadatainstancekey, string(metadata)}
301
302         sdlInst.On("Set", "A1m_ns", metadatainstancearr).Return(nil)
303
304         httpBodyString := `{"operation":"DELETE","payload":"","policy_instance_id":"123456","policy_type_id":"20001"}`
305
306         rmrSenderInst.On("RmrSendToXapp", httpBodyString, 20010, int(policyTypeId)).Return(true)
307
308         errresp := rh.DeletePolicyInstance(policyTypeId, policyInstanceID)
309
310         assert.Nil(t, errresp)
311         sdlInst.AssertExpectations(t)
312 }
313 func TestDataDelivery(t *testing.T) {
314
315         httpBody := `{
316                 "job":"1",
317                 "payload":"payload"
318                 }
319                 `
320         var instancedata interface{}
321
322         json.Unmarshal([]byte(httpBody), &instancedata)
323         a1.Logger.Debug("Marshaled data : %+v", (instancedata))
324         httpBodyString := `{"ei_job_id":"1","payload":"payload"}`
325         rmrSenderInst.On("RmrSendToXapp", httpBodyString, 20017, -1).Return(true)
326         errresp := rh.DataDelivery(instancedata)
327
328         assert.Nil(t, errresp)
329         sdlInst.AssertExpectations(t)
330 }
331
332 func TestGetMetaData(t *testing.T) {
333         var policyTypeId models.PolicyTypeID
334         policyTypeId = 20001
335         var policyInstanceID models.PolicyInstanceID
336         policyInstanceID = "123456"
337         instanceMetadataKey := a1InstanceMetadataPrefix + strconv.FormatInt((int64(policyTypeId)), 10) + "." + string(policyInstanceID)
338         a1.Logger.Debug("key : %+v", instanceMetadataKey)
339
340         var keys [1]string
341         keys[0] = instanceMetadataKey
342
343         policySchemaString := `{
344                 "created_at":"2022-11-02 10:30:20",
345                 "instance_status":"NOT IN EFFECT"
346                 }`
347
348         sdlInst.On("Get", a1MediatorNs, keys[:]).Return(map[string]interface{}{instanceMetadataKey: policySchemaString}, nil)
349
350         resp, errresp := rh.getMetaData(policyTypeId, policyInstanceID)
351
352         assert.Nil(t, errresp)
353         assert.NotNil(t, resp)
354         sdlInst.AssertExpectations(t)
355 }
356
357 type SdlMock struct {
358         mock.Mock
359 }
360
361 func (s *SdlMock) GetAll(ns string) ([]string, error) {
362         args := s.MethodCalled("GetAll", ns)
363         return args.Get(0).([]string), nil
364 }
365
366 func (s *SdlMock) Get(ns string, keys []string) (map[string]interface{}, error) {
367         a1.Logger.Debug("Get Called ")
368         args := s.MethodCalled("Get", ns, keys)
369         a1.Logger.Debug("ns :%+v", args.Get(0))
370         policytypeid := int64(20001)
371         policyInstanceID := "123456"
372         var policySchemaString string
373         var key string
374         if keys[0] == "a1.policy_instance.20001.123456" {
375                 policySchemaString = `{
376                         "enforce":true,
377                         "window_length":20,
378                    "blocking_rate":20,
379                         "trigger_threshold":10
380                         }`
381                 key = a1InstancePrefix + strconv.FormatInt(policytypeid, 10) + "." + string(policyInstanceID)
382         } else if keys[0] == "a1.policy_type.20001" {
383                 policySchemaString = `{"create_schema":{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"additionalProperties":false,"blocking_rate":{"default":10,"description":"% Connections to block","maximum":1001,"minimum":1,"type":"number"},"enforce":{"default":"true","type":"boolean"},"window_length":{"default":1,"description":"Sliding window length (in minutes)","maximum":60,"minimum":1,"type":"integer"}},"type":"object"},"description":"various parameters to control admission of dual connection","name":"admission_control_policy_mine","policy_type_id":20001}`
384                 key = a1PolicyPrefix + strconv.FormatInt((policytypeid), 10)
385         } else if keys[0] == "a1.policy_inst_metadata.20001.123456" {
386                 policySchemaString = `{
387                         "created_at":"2022-11-02 10:30:20",
388                         "instance_status":"NOT IN EFFECT"
389                         }`
390                 key = a1InstanceMetadataPrefix + strconv.FormatInt(policytypeid, 10) + "." + string(policyInstanceID)
391         }
392         a1.Logger.Debug(" policy SchemaString %+v", policySchemaString)
393         policyTypeSchema, _ := json.Marshal((policySchemaString))
394         a1.Logger.Debug(" policyTypeSchema %+v", string(policyTypeSchema))
395
396         a1.Logger.Debug(" key for policy type %+v", key)
397         mp := map[string]interface{}{key: string(policySchemaString)}
398         a1.Logger.Debug("Get Called and mp return %+v ", mp)
399         return mp, nil
400 }
401 func (s *SdlMock) SetIfNotExists(ns string, key string, data interface{}) (bool, error) {
402         args := s.MethodCalled("SetIfNotExists", ns, key, data)
403         return args.Bool(0), args.Error(1)
404 }
405
406 func (s *SdlMock) Set(ns string, pairs ...interface{}) error {
407         args := s.MethodCalled("Set", ns, pairs)
408         return args.Error(0)
409 }
410 func (s *SdlMock) SetIf(ns string, key string, oldData, newData interface{}) (bool, error) {
411         args := s.MethodCalled("SetIfNotExists", ns, key, oldData, newData)
412         return args.Bool(0), args.Error(1)
413 }
414
415 func (rmr *RmrSenderMock) RmrSendToXapp(httpBodyString string, mtype int, subid int) bool {
416         if httpBodyString == `{"blocking_rate":20,"enforce":true,"trigger_threshold":10,"window_length":20}` {
417                 args := rmr.MethodCalled("RmrSendToXapp", httpBodyString, mtype, subid)
418                 return args.Bool(0)
419         } else if httpBodyString == `{"ei_job_id":"1","payload":"payload"}` {
420                 args := rmr.MethodCalled("RmrSendToXapp", httpBodyString, mtype, subid)
421                 return args.Bool(0)
422         }
423         return true
424 }
425
426 func (s *SdlMock) Remove(ns string, keys []string) error {
427         args := s.MethodCalled("Remove", ns, keys)
428         return args.Error(0)
429 }