RIC:1060: Change in PTL
[ric-plt/xapp-frame.git] / pkg / xapp / subscription_test.go
1 /*
2 ==================================================================================
3   Copyright (c) 2019 Nokia
4 ==================================================================================
5 */
6
7 package xapp
8
9 import (
10         "bytes"
11         "fmt"
12         "net/http"
13         "net/http/httptest"
14         "testing"
15         "time"
16
17         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/clientmodel"
18         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/models"
19         "gerrit.o-ran-sc.org/r/ric-plt/xapp-frame/pkg/restapi/operations/common"
20         "github.com/stretchr/testify/assert"
21 )
22
23 var (
24         suite *testing.T
25
26         meid                = "gnb123456"
27         xappEventInstanceId = int64(1)
28         eventInstanceId     = int64(1)
29         funId               = int64(1)
30         actionId            = int64(1)
31         actionType          = "report"
32         subsequestActioType = "continue"
33         timeToWait          = "w10ms"
34         direction           = int64(0)
35         procedureCode       = int64(27)
36         typeOfMessage       = int64(1)
37         subscriptionId      = ""
38         hPort               = int64(8086) // See log: "Xapp started, listening on: :8086"
39         rPort               = int64(4560)
40         clientEndpoint      = clientmodel.SubscriptionParamsClientEndpoint{Host: "localhost", HTTPPort: &hPort, RMRPort: &rPort}
41 )
42
43 // Test cases
44 func TestSetup(t *testing.T) {
45         suite = t
46
47         // Start the server to simulate SubManager
48         go Subscription.Listen(subscriptionHandler, queryHandler, deleteHandler)
49         time.Sleep(time.Duration(2) * time.Second)
50 }
51
52 func TestSubscriptionQueryHandling(t *testing.T) {
53         resp, err := Subscription.QuerySubscriptions()
54
55         assert.Equal(t, err, nil)
56         assert.Equal(t, resp[0].SubscriptionID, int64(11))
57         assert.Equal(t, resp[0].Meid, "Test-Gnb")
58         assert.Equal(t, resp[0].ClientEndpoint, []string{"127.0.0.1:4056"})
59         <-time.After(1 * time.Second)
60 }
61
62 func TestSubscriptionHandling(t *testing.T) {
63         subscriptionParams := GetSubscriptionparams()
64
65         Subscription.SetResponseCB(func(resp *clientmodel.SubscriptionResponse) {
66                 fmt.Println("TestSubscriptionHandling: notification received")
67                 assert.Equal(t, len(resp.SubscriptionInstances), 1)
68                 assert.Equal(t, *resp.SubscriptionInstances[0].XappEventInstanceID, int64(11))
69                 assert.Equal(t, *resp.SubscriptionInstances[0].E2EventInstanceID, int64(22))
70         })
71
72         _, err := Subscription.Subscribe(subscriptionParams)
73         assert.Equal(t, err, nil)
74         <-time.After(1 * time.Second)
75 }
76
77 func TestSubscriptionWithClientProvidedIdHandling(t *testing.T) {
78         subscriptionParams := GetSubscriptionparams()
79         subscriptionParams.SubscriptionID = "myxapp"
80
81         Subscription.SetResponseCB(func(resp *clientmodel.SubscriptionResponse) {
82                 fmt.Println("TestSubscriptionWithClientProvidedIdHandling: notification received")
83                 assert.Equal(t, len(resp.SubscriptionInstances), 1)
84                 assert.Equal(t, *resp.SubscriptionInstances[0].XappEventInstanceID, int64(11))
85                 assert.Equal(t, *resp.SubscriptionInstances[0].E2EventInstanceID, int64(22))
86         })
87
88         _, err := Subscription.Subscribe(subscriptionParams)
89         assert.Equal(t, err, nil)
90         <-time.After(1 * time.Second)
91 }
92
93 func TestFailureNotificationHandling(t *testing.T) {
94         subscriptionParams := GetSubscriptionparams()
95         subscriptionParams.SubscriptionID = "send_failure_notification"
96
97         Subscription.SetResponseCB(func(resp *clientmodel.SubscriptionResponse) {
98                 assert.Equal(t, len(resp.SubscriptionInstances), 1)
99                 assert.Equal(t, *resp.SubscriptionInstances[0].XappEventInstanceID, int64(11))
100                 assert.Equal(t, *resp.SubscriptionInstances[0].E2EventInstanceID, int64(0))
101                 assert.Equal(t, resp.SubscriptionInstances[0].ErrorCause, "Some error")
102                 assert.Equal(t, resp.SubscriptionInstances[0].ErrorSource, "SUBMGR")
103                 assert.Equal(t, resp.SubscriptionInstances[0].TimeoutType, "E2-Timeout")
104         })
105
106         _, err := Subscription.Subscribe(subscriptionParams)
107         assert.Equal(t, err, nil)
108         <-time.After(1 * time.Second)
109 }
110
111 func TestBadRequestSubscriptionHandling(t *testing.T) {
112         subscriptionParams := GetSubscriptionparams()
113         subscriptionParams.SubscriptionID = "send_400_bad_request_response"
114
115         // Notification is not coming
116
117         _, err := Subscription.Subscribe(subscriptionParams)
118         assert.Equal(t, err.Error(), "[POST /subscriptions][400] subscribeBadRequest ")
119         fmt.Println("Error:", err)
120 }
121
122 func TestNotFoundRequestSubscriptionHandling(t *testing.T) {
123         subscriptionParams := GetSubscriptionparams()
124         subscriptionParams.SubscriptionID = "send_404_not_found_response"
125
126         // Notification is not coming
127
128         _, err := Subscription.Subscribe(subscriptionParams)
129         assert.Equal(t, err.Error(), "[POST /subscriptions][404] subscribeNotFound ")
130         fmt.Println("Error:", err)
131 }
132
133 func TestInternalServerErrorSubscriptionHandling(t *testing.T) {
134         subscriptionParams := GetSubscriptionparams()
135         subscriptionParams.SubscriptionID = "send_500_internal_server_error_response"
136
137         // Notification is not coming
138
139         _, err := Subscription.Subscribe(subscriptionParams)
140         assert.Equal(t, err.Error(), "[POST /subscriptions][500] subscribeInternalServerError ")
141         fmt.Println("Error:", err)
142 }
143
144 func TestServiceUnavailableSubscriptionHandling(t *testing.T) {
145         subscriptionParams := GetSubscriptionparams()
146         subscriptionParams.SubscriptionID = "send_503_Service_Unavailable_response"
147
148         // Notification is not coming
149
150         _, err := Subscription.Subscribe(subscriptionParams)
151         assert.Equal(t, err.Error(), "[POST /subscriptions][503] subscribeServiceUnavailable ")
152         fmt.Println("Error:", err)
153 }
154
155 func GetSubscriptionparams() *clientmodel.SubscriptionParams {
156         return &clientmodel.SubscriptionParams{
157                 SubscriptionID: "",
158                 Meid:           &meid,
159                 RANFunctionID:  &funId,
160                 ClientEndpoint: &clientEndpoint,
161                 SubscriptionDetails: clientmodel.SubscriptionDetailsList{
162                         &clientmodel.SubscriptionDetail{
163                                 XappEventInstanceID: &eventInstanceId,
164                                 EventTriggers:       clientmodel.EventTriggerDefinition{00, 0x11, 0x12, 0x13, 0x00, 0x21, 0x22, 0x24, 0x1B, 0x80},
165                                 ActionToBeSetupList: clientmodel.ActionsToBeSetup{
166                                         &clientmodel.ActionToBeSetup{
167                                                 ActionID:         &actionId,
168                                                 ActionType:       &actionType,
169                                                 ActionDefinition: clientmodel.ActionDefinition{5, 6, 7, 8},
170                                                 SubsequentAction: &clientmodel.SubsequentAction{
171                                                         SubsequentActionType: &subsequestActioType,
172                                                         TimeToWait:           &timeToWait,
173                                                 },
174                                         },
175                                 },
176                         },
177                 },
178         }
179 }
180
181 func TestSuccessfulSubscriptionDeleteHandling(t *testing.T) {
182         subscriptionId = "send_201_successful_response"
183         err := Subscription.Unsubscribe(subscriptionId)
184         assert.Equal(t, err, nil)
185         fmt.Println("Error:", err)
186 }
187
188 func TestBadRequestSubscriptionDeleteHandling(t *testing.T) {
189         subscriptionId = "send_400_bad_request_response"
190         err := Subscription.Unsubscribe(subscriptionId)
191         assert.NotEqual(t, err, nil)
192         fmt.Println("Error:", err.Error())
193         assert.Equal(t, err.Error(), "[DELETE /subscriptions/{subscriptionId}][400] unsubscribeBadRequest ")
194 }
195
196 func TestInternalServerErrorSubscriptionDeleteHandling(t *testing.T) {
197         subscriptionId = "send_500_internal_server_error_response"
198         err := Subscription.Unsubscribe(subscriptionId)
199         assert.NotEqual(t, err, nil)
200         fmt.Println("Error:", err.Error())
201         assert.Equal(t, err.Error(), "[DELETE /subscriptions/{subscriptionId}][500] unsubscribeInternalServerError ")
202 }
203
204 func TestResponseHandler(t *testing.T) {
205         Subscription.SetResponseCB(SubscriptionRespHandler)
206
207         payload := []byte(`{"SubscriptionInstances":[{"tXappEventInstanceID": 1}]`)
208         req, err := http.NewRequest("POST", "/ric/v1/subscriptions/response", bytes.NewBuffer(payload))
209         if err != nil {
210                 t.Fatal(err)
211         }
212
213         rr := httptest.NewRecorder()
214         handler := http.HandlerFunc(Subscription.ResponseHandler)
215         handler.ServeHTTP(rr, req)
216
217         if status := rr.Code; status != http.StatusOK {
218                 t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
219         }
220         time.Sleep(time.Duration(2) * time.Second)
221 }
222
223 // Helper functions
224 func SubscriptionRespHandler(resp *clientmodel.SubscriptionResponse) {
225 }
226
227 func processSubscriptions(subscriptionId string) {
228
229         // Generate xappInstanceId
230         xappInstanceId := int64(11)
231
232         if subscriptionId == "send_failure_notification" {
233                 fmt.Println("Sending error notification")
234
235                 // Generate e2InstanceId
236                 e2InstanceId := int64(0)
237                 resp := &models.SubscriptionResponse{
238                         SubscriptionID: &subscriptionId,
239                         SubscriptionInstances: []*models.SubscriptionInstance{
240                                 {
241                                         XappEventInstanceID: &xappInstanceId,
242                                         E2EventInstanceID:   &e2InstanceId,
243                                         ErrorCause:          "Some error",
244                                         ErrorSource:         "SUBMGR",
245                                         TimeoutType:         "E2-Timeout",
246                                 },
247                         },
248                 }
249
250                 Subscription.Notify(resp, models.SubscriptionParamsClientEndpoint{Host: "localhost", HTTPPort: &hPort, RMRPort: &rPort})
251                 return
252         } else {
253
254                 fmt.Println("Sending successful notification")
255
256                 // Generate e2InstanceId
257                 e2InstanceId := int64(22)
258
259                 resp := &models.SubscriptionResponse{
260                         SubscriptionID: &subscriptionId,
261                         SubscriptionInstances: []*models.SubscriptionInstance{
262                                 {
263                                         XappEventInstanceID: &xappInstanceId,
264                                         E2EventInstanceID:   &e2InstanceId,
265                                 },
266                         },
267                 }
268
269                 // Notify the client: don't worry about errors ... Notify() will handle retries, etc.
270                 Subscription.Notify(resp, models.SubscriptionParamsClientEndpoint{Host: "localhost", HTTPPort: &hPort, RMRPort: &rPort})
271                 return
272         }
273 }
274
275 func subscriptionHandler(params interface{}) (*models.SubscriptionResponse, int) {
276         p := params.(*models.SubscriptionParams)
277
278         assert.Equal(suite, meid, *p.Meid)
279         assert.Equal(suite, funId, *p.RANFunctionID)
280         assert.Equal(suite, clientEndpoint.Host, p.ClientEndpoint.Host)
281         assert.Equal(suite, clientEndpoint.HTTPPort, p.ClientEndpoint.HTTPPort)
282         assert.Equal(suite, clientEndpoint.RMRPort, p.ClientEndpoint.RMRPort)
283
284         assert.Equal(suite, xappEventInstanceId, *p.SubscriptionDetails[0].XappEventInstanceID)
285         et := []int64{00, 0x11, 0x12, 0x13, 0x00, 0x21, 0x22, 0x24, 0x1B, 0x80}
286         assert.ElementsMatch(suite, et, p.SubscriptionDetails[0].EventTriggers)
287         assert.Equal(suite, actionId, *p.SubscriptionDetails[0].ActionToBeSetupList[0].ActionID)
288         assert.Equal(suite, actionType, *p.SubscriptionDetails[0].ActionToBeSetupList[0].ActionType)
289
290         assert.Equal(suite, subsequestActioType, *p.SubscriptionDetails[0].ActionToBeSetupList[0].SubsequentAction.SubsequentActionType)
291         assert.Equal(suite, timeToWait, *p.SubscriptionDetails[0].ActionToBeSetupList[0].SubsequentAction.TimeToWait)
292         assert.ElementsMatch(suite, []int64{5, 6, 7, 8}, p.SubscriptionDetails[0].ActionToBeSetupList[0].ActionDefinition)
293
294         if p.SubscriptionID != "send_failure_notification" {
295                 // Generate a unique subscriptionId
296                 subscriptionId = fmt.Sprintf("%s-%s", meid, clientEndpoint.Host)
297         } else {
298                 subscriptionId = "send_failure_notification"
299         }
300         if p.SubscriptionID == "send_400_bad_request_response" {
301                 fmt.Println("send_400_bad_request_response")
302                 return &models.SubscriptionResponse{}, common.SubscribeBadRequestCode
303         }
304         if p.SubscriptionID == "send_404_not_found_response" {
305                 fmt.Println("send_404_not_found_response")
306                 return &models.SubscriptionResponse{}, common.SubscribeNotFoundCode
307         }
308         if p.SubscriptionID == "send_500_internal_server_error_response" {
309                 fmt.Println("send_500_internal_server_error_response")
310                 return &models.SubscriptionResponse{}, common.SubscribeInternalServerErrorCode
311         }
312         if p.SubscriptionID == "send_503_Service_Unavailable_response" {
313                 fmt.Println("send_503_Service_Unavailable_response")
314                 return &models.SubscriptionResponse{}, common.SubscribeServiceUnavailableCode
315         }
316
317         // Process subscriptions on the background
318         go processSubscriptions(subscriptionId)
319
320         // and send response immediately
321         return &models.SubscriptionResponse{
322                 SubscriptionID: &subscriptionId,
323         }, common.SubscribeCreatedCode
324 }
325
326 func queryHandler() (models.SubscriptionList, error) {
327         resp := models.SubscriptionList{
328                 &models.SubscriptionData{
329                         SubscriptionID: 11,
330                         Meid:           "Test-Gnb",
331                         ClientEndpoint: []string{"127.0.0.1:4056"},
332                 },
333         }
334         return resp, nil
335 }
336
337 func deleteHandler(ep string) int {
338         assert.Equal(suite, subscriptionId, ep)
339         if subscriptionId == "send_201_successful_response" {
340                 return common.UnsubscribeNoContentCode
341         } else if subscriptionId == "send_400_bad_request_response" {
342                 return common.UnsubscribeBadRequestCode
343         } else if subscriptionId == "send_500_internal_server_error_response" {
344                 return common.UnsubscribeInternalServerErrorCode
345         } else {
346                 fmt.Println("Unknown subscriptionId:", subscriptionId)
347                 return 0
348         }
349 }