API update
[ric-plt/xapp-frame.git] / pkg / xapp / xapp_test.go
1 /*
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
20 package xapp
21
22 import (
23         "github.com/gorilla/mux"
24         "github.com/spf13/viper"
25         "net/http"
26         "net/http/httptest"
27         "github.com/stretchr/testify/assert"
28         "os"
29         "strings"
30         "testing"
31         "time"
32         "bytes"
33 )
34
35 //var _ = func() bool {
36 //      testing.Init()
37 //      return true
38 //}()
39
40 type Consumer struct{}
41
42 func (m Consumer) Consume(params *RMRParams) (err error) {
43         Sdl.Store("myKey", params.Payload)
44         return nil
45 }
46
47 // Test cases
48 func TestMain(m *testing.M) {
49         go RunWithParams(Consumer{}, viper.GetBool("controls.waitForSdl"))
50         time.Sleep(time.Duration(5) * time.Second)
51         code := m.Run()
52         os.Exit(code)
53 }
54
55 func TestGetHealthCheckRetursServiceUnavailableError(t *testing.T) {
56         Logger.Info("CASE: TestGetHealthCheckRetursServiceUnavailableError")
57         req, _ := http.NewRequest("GET", "/ric/v1/health/ready", nil)
58         /*response :=*/ executeRequest(req, nil)
59
60         //checkResponseCode(t, http.StatusServiceUnavailable, response.Code)
61 }
62
63 func TestGetHealthCheckReturnsSuccess(t *testing.T) {
64         Logger.Info("CASE: TestGetHealthCheckReturnsSuccess")
65         for Rmr.IsReady() == false {
66                 time.Sleep(time.Duration(2) * time.Second)
67         }
68
69         req, _ := http.NewRequest("GET", "/ric/v1/health/ready", nil)
70         response := executeRequest(req, nil)
71
72         checkResponseCode(t, http.StatusOK, response.Code)
73 }
74
75 func TestInjectQuerySinglePath(t *testing.T) {
76         Logger.Info("CASE: TestInjectQuerySinglePath")
77         var handler = func(w http.ResponseWriter, r *http.Request) {
78         }
79
80         Resource.InjectQueryRoute("/ric/v1/user", handler, "GET", "foo", "bar")
81
82         req, _ := http.NewRequest("GET", "/ric/v1/user?foo=bar", nil)
83         response := executeRequest(req, nil)
84         checkResponseCode(t, http.StatusOK, response.Code)
85 }
86
87 func TestInjectQueryMultiplePaths(t *testing.T) {
88         Logger.Info("CASE: TestInjectQueryMultiplePaths")
89         var handler = func(w http.ResponseWriter, r *http.Request) {
90         }
91
92         Resource.InjectQueryRoute("/ric/v1/user", handler, "GET", "foo", "bar", "id", "mykey")
93
94         req, _ := http.NewRequest("GET", "/ric/v1/user?foo=bar&id=mykey", nil)
95         response := executeRequest(req, nil)
96         checkResponseCode(t, http.StatusOK, response.Code)
97 }
98
99 func TestInjectQueryFailures(t *testing.T) {
100         Logger.Info("CASE: TestInjectQueryFailures")
101         var handler = func(w http.ResponseWriter, r *http.Request) {
102         }
103
104         Resource.InjectQueryRoute("/ric/v1/user", handler, "GET", "foo", "bar", "id", "mykey")
105
106         req, _ := http.NewRequest("GET", "/ric/v1/user?invalid=bar&no=mykey", nil)
107         response := executeRequest(req, nil)
108         checkResponseCode(t, http.StatusNotFound, response.Code)
109 }
110
111 func TestMessagesReceivedSuccessfully(t *testing.T) {
112         Logger.Info("CASE: TestMessagesReceivedSuccessfully")
113         time.Sleep(time.Duration(5) * time.Second)
114         for i := 0; i < 100; i++ {
115                 params := &RMRParams{}
116                 params.Mtype = 10004
117                 params.SubId = -1
118                 params.Payload = []byte{1, 2, 3, 4, 5, 6}
119                 params.Meid = &RMRMeid{PlmnID: "1234", EnbID: "7788", RanName: "RanName-1234"}
120                 params.Xid = "TestXID"
121                 
122                 if i % 2 == 0 {
123                         Rmr.SendMsg(params)
124                 } else {
125                         Rmr.SendWithRetry(params, false, 1)
126                 }
127         }
128         Rmr.RegisterMetrics()
129
130         // Allow time to process the messages
131         time.Sleep(time.Duration(5) * time.Second)
132
133         waitForSdl := viper.GetBool("controls.waitForSdl")
134         stats := getMetrics(t)
135         if !strings.Contains(stats, "ricxapp_RMR_Transmitted 100") {
136                 t.Errorf("Error: ricxapp_RMR_Transmitted value incorrect: %v", stats)
137         }
138
139         if !strings.Contains(stats, "ricxapp_RMR_Received 100") {
140                 t.Errorf("Error: ricxapp_RMR_Received value incorrect: %v", stats)
141         }
142
143         if !strings.Contains(stats, "ricxapp_RMR_TransmitError 0") {
144                 t.Errorf("Error: ricxapp_RMR_TransmitError value incorrect")
145         }
146
147         if !strings.Contains(stats, "ricxapp_RMR_ReceiveError 0") {
148                 t.Errorf("Error: ricxapp_RMR_ReceiveError value incorrect")
149         }
150
151         if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_Stored 100") {
152                 t.Errorf("Error: ricxapp_SDL_Stored value incorrect")
153         }
154
155         if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_StoreError 0") {
156                 t.Errorf("Error: ricxapp_SDL_StoreError value incorrect")
157         }
158 }
159
160 func TestMessagesReceivedSuccessfullyUsingWh(t *testing.T) {
161         Logger.Info("CASE: TestMessagesReceivedSuccessfullyUsingWh")
162         time.Sleep(time.Duration(5) * time.Second)
163         whid := Rmr.Openwh("localhost:4560")
164         time.Sleep(time.Duration(1) * time.Second)
165         for i := 0; i < 100; i++ {
166                 params := &RMRParams{}
167                 params.Mtype = 10004
168                 params.SubId = -1
169                 params.Payload = []byte{1, 2, 3, 4, 5, 6}
170                 params.Meid = &RMRMeid{PlmnID: "1234", EnbID: "7788", RanName: "RanName-1234"}
171                 params.Xid = "TestXID"
172                 params.Whid = int(whid)
173
174                 if i == 0 {
175                         Logger.Info("%+v", params.String())
176                 }
177
178                 Rmr.SendMsg(params)
179         }
180
181         // Allow time to process the messages
182         time.Sleep(time.Duration(5) * time.Second)
183
184         waitForSdl := viper.GetBool("controls.waitForSdl")
185         stats := getMetrics(t)
186         if !strings.Contains(stats, "ricxapp_RMR_Transmitted 200") {
187                 t.Errorf("Error: ricxapp_RMR_Transmitted value incorrect: %v", stats)
188         }
189
190         if !strings.Contains(stats, "ricxapp_RMR_Received 200") {
191                 t.Errorf("Error: ricxapp_RMR_Received value incorrect: %v", stats)
192         }
193
194         if !strings.Contains(stats, "ricxapp_RMR_TransmitError 0") {
195                 t.Errorf("Error: ricxapp_RMR_TransmitError value incorrect")
196         }
197
198         if !strings.Contains(stats, "ricxapp_RMR_ReceiveError 0") {
199                 t.Errorf("Error: ricxapp_RMR_ReceiveError value incorrect")
200         }
201
202         if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_Stored 200") {
203                 t.Errorf("Error: ricxapp_SDL_Stored value incorrect")
204         }
205
206         if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_StoreError 0") {
207                 t.Errorf("Error: ricxapp_SDL_StoreError value incorrect")
208         }
209         Rmr.Closewh(int(whid))
210 }
211
212 func TestMessagesReceivedSuccessfullyUsingWhCall(t *testing.T) {
213         Logger.Info("CASE: TestMessagesReceivedSuccessfullyUsingWhCall")
214         time.Sleep(time.Duration(5) * time.Second)
215         whid := Rmr.Openwh("localhost:4560")
216         params := &RMRParams{}
217         params.Payload = []byte("newrt|start\nnewrt|end\n")
218         params.Whid = int(whid)
219         params.Callid = 4
220         params.Timeout = 1000
221         Rmr.SendCallMsg(params)
222
223         // Allow time to process the messages
224         time.Sleep(time.Duration(2) * time.Second)
225
226         waitForSdl := viper.GetBool("controls.waitForSdl")
227         stats := getMetrics(t)
228         if !strings.Contains(stats, "ricxapp_RMR_Transmitted 200") {
229                 t.Errorf("Error: ricxapp_RMR_Transmitted value incorrect: %v", stats)
230         }
231
232         if !strings.Contains(stats, "ricxapp_RMR_Received 201") {
233                 t.Errorf("Error: ricxapp_RMR_Received value incorrect: %v", stats)
234         }
235
236         if !strings.Contains(stats, "ricxapp_RMR_TransmitError 1") {
237                 t.Errorf("Error: ricxapp_RMR_TransmitError value incorrect")
238         }
239
240         if !strings.Contains(stats, "ricxapp_RMR_ReceiveError 0") {
241                 t.Errorf("Error: ricxapp_RMR_ReceiveError value incorrect")
242         }
243
244         if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_Stored 201") {
245                 t.Errorf("Error: ricxapp_SDL_Stored value incorrect")
246         }
247
248         if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_StoreError 0") {
249                 t.Errorf("Error: ricxapp_SDL_StoreError value incorrect")
250         }
251         Rmr.Closewh(int(whid))
252 }
253
254 func TestSubscribeChannels(t *testing.T) {
255         Logger.Info("CASE: TestSubscribeChannels")
256         if !viper.GetBool("controls.waitForSdl") {
257                 return
258         }
259
260         var NotificationCb = func(ch string, events ...string) {
261                 if ch != "channel1" {
262                         t.Errorf("Error: Callback function called with incorrect params")
263                 }
264         }
265
266         if err := Sdl.Subscribe(NotificationCb, "channel1"); err != nil {
267                 t.Errorf("Error: Subscribe failed: %v", err)
268         }
269         time.Sleep(time.Duration(2) * time.Second)
270
271         if err := Sdl.StoreAndPublish("channel1", "event", "key1", "data1"); err != nil {
272                 t.Errorf("Error: Publish failed: %v", err)
273         }
274
275         // Misc.
276         Sdl.MStoreAndPublish([]string{"channel1"}, "event", "key1", "data1")
277 }
278
279 func TestGetRicMessageSuccess(t *testing.T) {
280         Logger.Info("CASE: TestGetRicMessageSuccess")
281         id, ok := Rmr.GetRicMessageId("RIC_SUB_REQ")
282         if !ok || id != 12010 {
283                 t.Errorf("Error: GetRicMessageId failed: id=%d", id)
284         }
285
286         name := Rmr.GetRicMessageName(12010)
287         if name != "RIC_SUB_REQ" {
288                 t.Errorf("Error: GetRicMessageName failed: name=%s", name)
289         }
290 }
291
292 func TestGetRicMessageFails(t *testing.T) {
293         Logger.Info("CASE: TestGetRicMessageFails")
294         ok := Rmr.IsRetryError(&RMRParams{status: 0})
295         if ok {
296                 t.Errorf("Error: IsRetryError returned wrong value")
297         }
298
299         ok = Rmr.IsRetryError(&RMRParams{status: 10})
300         if !ok {
301                 t.Errorf("Error: IsRetryError returned wrong value")
302         }
303
304         ok = Rmr.IsNoEndPointError(&RMRParams{status: 5})
305         if ok {
306                 t.Errorf("Error: IsNoEndPointError returned wrong value")
307         }
308
309         ok = Rmr.IsNoEndPointError(&RMRParams{status: 2})
310         if !ok {
311                 t.Errorf("Error: IsNoEndPointError returned wrong value")
312         }
313 }
314
315 func TestIsErrorFunctions(t *testing.T) {
316         Logger.Info("CASE: TestIsErrorFunctions")
317         id, ok := Rmr.GetRicMessageId("RIC_SUB_REQ")
318         if !ok || id != 12010 {
319                 t.Errorf("Error: GetRicMessageId failed: id=%d", id)
320         }
321
322         name := Rmr.GetRicMessageName(12010)
323         if name != "RIC_SUB_REQ" {
324                 t.Errorf("Error: GetRicMessageName failed: name=%s", name)
325         }
326 }
327
328 func TestAddConfigChangeListener(t *testing.T) {
329         Logger.Info("CASE: AddConfigChangeListener")
330         AddConfigChangeListener(func(f string) {})
331 }
332
333 func TestConfigAccess(t *testing.T) {
334         Logger.Info("CASE: AddConfigChangeListener")
335         
336         assert.Equal(t,  Config.GetString("name"), "xapp")
337         assert.Equal(t,  Config.GetInt("controls.logger.level"), 3)
338         assert.Equal(t,  Config.GetUint32("controls.logger.level"), uint32(3))
339         assert.Equal(t,  Config.GetBool("controls.waitForSdl"), false)
340         Config.Get("controls")
341         Config.GetStringSlice("messaging.ports")
342         Config.GetStringMap("messaging.ports")
343         Config.IsSet("messaging")
344 }
345
346 func TestPublishConfigChange(t *testing.T) {
347         Logger.Info("CASE: AddConfigChangeListener")
348         PublishConfigChange("testApp", "values")
349 }
350
351 func TestNewSubscriber(t *testing.T) {
352         Logger.Info("CASE: TestNewSubscriber")
353         assert.NotNil(t, NewSubscriber("", 0), "NewSubscriber failed")
354 }
355
356 func TestNewRMRClient(t *testing.T) {
357         c := map[string]interface{} {"protPort": "tcp:4560"}
358         viper.Set("rmr", c)
359         assert.NotNil(t, NewRMRClient(), "NewRMRClient failed")
360
361         params := &RMRParams{}
362         params.Mtype = 1234
363         params.SubId = -1
364         params.Payload = []byte{1, 2, 3, 4, 5, 6}
365         Rmr.SendWithRetry(params, false, 1)
366 }
367
368 func TestInjectRoutePrefix(t *testing.T) {
369         Logger.Info("CASE: TestInjectRoutePrefix")
370         assert.NotNil(t, Resource.InjectRoutePrefix("test", nil), "InjectRoutePrefix failed")
371 }
372
373 func TestInjectStatusCb(t *testing.T) {
374         Logger.Info("CASE: TestInjectStatusCb")
375
376         var f = func() bool {
377                 return true
378         }
379         Resource.InjectStatusCb(f)
380 }
381
382 func TestSdlInterfaces(t *testing.T) {
383         Sdl.Read("myKey")
384         Sdl.MRead([]string{"myKey"})
385         Sdl.ReadAllKeys("myKey")
386         Sdl.Store("myKey", "Values")
387         Sdl.MStore("myKey", "Values")
388         Sdl.RegisterMetrics()
389
390         // Misc.
391         var NotificationCb = func(ch string, events ...string) {}
392         Sdl.Subscribe(NotificationCb, "channel1")
393         Sdl.MSubscribe(NotificationCb, "channel1", "channel2")
394         Sdl.MStoreAndPublish([]string{"channel1"}, "event", "key1", "data1")
395 }
396
397 func TestRnibInterfaces(t *testing.T) {
398         Rnib.GetNodeb("test-gnb")
399         Rnib.GetCellList("test-gnb")
400         Rnib.GetListGnbIds()
401         Rnib.GetListEnbIds()
402         Rnib.GetCountGnbList()
403         Rnib.GetCell("test-gnb", 0)
404         Rnib.GetCell("test-gnb", 0)
405         Rnib.GetCellById(0, "cell-1")
406
407         // Misc.
408         var NotificationCb = func(ch string, events ...string) {}
409         Rnib.Subscribe(NotificationCb, "channel1")
410         Rnib.StoreAndPublish("channel1", "event", "key1", "data1")
411 }
412
413 func TestLogger(t *testing.T) {
414         Logger.Error("CASE: TestNewSubscriber")
415         Logger.Warn("CASE: TestNewSubscriber")
416         Logger.GetLevel()
417 }
418
419 func TestConfigHandler(t *testing.T) {
420         Logger.Error("CASE: TestConfigHandler")
421         req, _ := http.NewRequest("POST", "/ric/v1/cm/appname", bytes.NewBuffer([]byte{}))
422         handleFunc := http.HandlerFunc(configHandler)
423         executeRequest(req, handleFunc)
424 }
425
426 func TestMisc(t *testing.T) {
427         Logger.Info("CASE: TestMisc")
428
429         IsReady()
430         SetReadyCB(func(interface{}) {}, "")
431         XappReadyCb("")
432         SetShutdownCB(func() {})
433 }
434
435 func TestTeardown(t *testing.T) {
436         Logger.Info("CASE: TestTeardown")
437         Sdl.Delete([]string{"myKey"})
438         Sdl.Clear()
439         Sdl.IsReady()
440         Sdl.GetStat()
441 }
442
443 // Helper functions
444 func executeRequest(req *http.Request, handleR http.HandlerFunc) *httptest.ResponseRecorder {
445         rr := httptest.NewRecorder()
446         if handleR != nil {
447                 vars := map[string]string{"name": "myxapp"}
448                 req = mux.SetURLVars(req, vars)
449                 handleR.ServeHTTP(rr, req)
450         } else {
451                 vars := map[string]string{"id": "1"}
452                 req = mux.SetURLVars(req, vars)
453                 Resource.router.ServeHTTP(rr, req)
454         }
455         return rr
456 }
457
458 func checkResponseCode(t *testing.T, expected, actual int) {
459         if expected != actual {
460                 t.Errorf("Expected response code %d. Got %d\n", expected, actual)
461         }
462 }
463
464 func getMetrics(t *testing.T) string {
465         req, _ := http.NewRequest("GET", "/ric/v1/metrics", nil)
466         response := executeRequest(req, nil)
467
468         return response.Body.String()
469 }