43614918c6406ee4f556bcccb38dd7b146205ac7
[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 }
344
345 func TestPublishConfigChange(t *testing.T) {
346         Logger.Info("CASE: AddConfigChangeListener")
347         PublishConfigChange("testApp", "values")
348 }
349
350 func TestNewSubscriber(t *testing.T) {
351         Logger.Info("CASE: TestNewSubscriber")
352         assert.NotNil(t, NewSubscriber("", 0), "NewSubscriber failed")
353 }
354
355 func TestNewRMRClient(t *testing.T) {
356         c := map[string]interface{} {"protPort": "tcp:4560"}
357         viper.Set("rmr", c)
358         assert.NotNil(t, NewRMRClient(), "NewRMRClient failed")
359
360         params := &RMRParams{}
361         params.Mtype = 1234
362         params.SubId = -1
363         params.Payload = []byte{1, 2, 3, 4, 5, 6}
364         Rmr.SendWithRetry(params, false, 1)
365 }
366
367 func TestInjectRoutePrefix(t *testing.T) {
368         Logger.Info("CASE: TestInjectRoutePrefix")
369         assert.NotNil(t, Resource.InjectRoutePrefix("test", nil), "InjectRoutePrefix failed")
370 }
371
372 func TestInjectStatusCb(t *testing.T) {
373         Logger.Info("CASE: TestInjectStatusCb")
374
375         var f = func() bool {
376                 return true
377         }
378         Resource.InjectStatusCb(f)
379 }
380
381 func TestSdlInterfaces(t *testing.T) {
382         Sdl.Read("myKey")
383         Sdl.MRead([]string{"myKey"})
384         Sdl.ReadAllKeys("myKey")
385         Sdl.Store("myKey", "Values")
386         Sdl.MStore("myKey", "Values")
387         Sdl.RegisterMetrics()
388
389         // Misc.
390         var NotificationCb = func(ch string, events ...string) {}
391         Sdl.Subscribe(NotificationCb, "channel1")
392         Sdl.MSubscribe(NotificationCb, "channel1", "channel2")
393         Sdl.MStoreAndPublish([]string{"channel1"}, "event", "key1", "data1")
394 }
395
396 func TestRnibInterfaces(t *testing.T) {
397         Rnib.GetNodeb("test-gnb")
398         Rnib.GetCellList("test-gnb")
399         Rnib.GetListGnbIds()
400         Rnib.GetListEnbIds()
401         Rnib.GetCountGnbList()
402         Rnib.GetCell("test-gnb", 0)
403         Rnib.GetCell("test-gnb", 0)
404         Rnib.GetCellById(0, "cell-1")
405
406         // Misc.
407         var NotificationCb = func(ch string, events ...string) {}
408         Rnib.Subscribe(NotificationCb, "channel1")
409         Rnib.StoreAndPublish("channel1", "event", "key1", "data1")
410 }
411
412 func TestLogger(t *testing.T) {
413         Logger.Error("CASE: TestNewSubscriber")
414         Logger.Warn("CASE: TestNewSubscriber")
415 }
416
417 func TestConfigHandler(t *testing.T) {
418         Logger.Error("CASE: TestConfigHandler")
419         req, _ := http.NewRequest("POST", "/ric/v1/cm/appname", bytes.NewBuffer([]byte{}))
420         handleFunc := http.HandlerFunc(configHandler)
421         executeRequest(req, handleFunc)
422 }
423
424 func TestMisc(t *testing.T) {
425         Logger.Info("CASE: TestMisc")
426
427         IsReady()
428         SetReadyCB(func(interface{}) {}, "")
429         XappReadyCb("")
430         SetShutdownCB(func() {})
431 }
432
433 func TestTeardown(t *testing.T) {
434         Logger.Info("CASE: TestTeardown")
435         Sdl.Delete([]string{"myKey"})
436         Sdl.Clear()
437         Sdl.IsReady()
438         Sdl.GetStat()
439 }
440
441 // Helper functions
442 func executeRequest(req *http.Request, handleR http.HandlerFunc) *httptest.ResponseRecorder {
443         rr := httptest.NewRecorder()
444         if handleR != nil {
445                 vars := map[string]string{"name": "myxapp"}
446                 req = mux.SetURLVars(req, vars)
447                 handleR.ServeHTTP(rr, req)
448         } else {
449                 vars := map[string]string{"id": "1"}
450                 req = mux.SetURLVars(req, vars)
451                 Resource.router.ServeHTTP(rr, req)
452         }
453         return rr
454 }
455
456 func checkResponseCode(t *testing.T, expected, actual int) {
457         if expected != actual {
458                 t.Errorf("Expected response code %d. Got %d\n", expected, actual)
459         }
460 }
461
462 func getMetrics(t *testing.T) string {
463         req, _ := http.NewRequest("GET", "/ric/v1/metrics", nil)
464         response := executeRequest(req, nil)
465
466         return response.Body.String()
467 }