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