Prepare for SdlInstance usage removal in xapp-frame
[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: TestConfigAccess")
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: TestPublishConfigChange")
352         PublishConfigChange("testApp", "values")
353         ReadConfig("testApp")
354 }
355
356 func TestNewSubscriber(t *testing.T) {
357         Logger.Info("CASE: TestNewSubscriber")
358         assert.NotNil(t, NewSubscriber("", 0), "NewSubscriber failed")
359 }
360
361 func TestNewRMRClient(t *testing.T) {
362         c := map[string]interface{}{"protPort": "tcp:4560"}
363         viper.Set("rmr", c)
364         assert.NotNil(t, NewRMRClient(), "NewRMRClient failed")
365
366         params := &RMRParams{}
367         params.Mtype = 1234
368         params.SubId = -1
369         params.Payload = []byte{1, 2, 3, 4, 5, 6}
370         Rmr.SendWithRetry(params, false, 1)
371 }
372
373 func TestInjectRoutePrefix(t *testing.T) {
374         Logger.Info("CASE: TestInjectRoutePrefix")
375         assert.NotNil(t, Resource.InjectRoutePrefix("test", nil), "InjectRoutePrefix failed")
376 }
377
378 func TestInjectStatusCb(t *testing.T) {
379         Logger.Info("CASE: TestInjectStatusCb")
380
381         var f = func() bool {
382                 return true
383         }
384         Resource.InjectStatusCb(f)
385         Resource.CheckStatus()
386 }
387
388 func TestSdlInterfaces(t *testing.T) {
389         Sdl.Read("myKey")
390         Sdl.MRead([]string{"myKey"})
391         Sdl.ReadAllKeys("myKey")
392         Sdl.Store("myKey", "Values")
393         Sdl.MStore("myKey", "Values")
394         Sdl.RegisterMetrics()
395         Sdl.UpdateStatCounter("Stored")
396
397         // Misc.
398         var NotificationCb = func(ch string, events ...string) {}
399         Sdl.Subscribe(NotificationCb, "channel1")
400         Sdl.MSubscribe(NotificationCb, "channel1", "channel2")
401         Sdl.StoreAndPublish("channel1", "event", "key1", "data1")
402         Sdl.MStoreAndPublish([]string{"channel1"}, "event", "key1", "data1")
403 }
404
405 func TestRnibInterfaces(t *testing.T) {
406         Rnib.GetNodeb("test-gnb")
407         Rnib.GetCellList("test-gnb")
408         Rnib.GetListGnbIds()
409         Rnib.GetListEnbIds()
410         Rnib.GetCountGnbList()
411         Rnib.GetCell("test-gnb", 0)
412         Rnib.GetCell("test-gnb", 0)
413         Rnib.GetCellById(0, "cell-1")
414
415         // Misc.
416         var NotificationCb = func(ch string, events ...string) {}
417         Rnib.Subscribe(NotificationCb, "channel1")
418         Rnib.StoreAndPublish("channel1", "event", "key1", "data1")
419 }
420
421 func TestLogger(t *testing.T) {
422         Logger.Error("CASE: TestNewSubscriber")
423         Logger.Warn("CASE: TestNewSubscriber")
424         Logger.GetLevel()
425 }
426
427 func TestConfigHandler(t *testing.T) {
428         Logger.Error("CASE: TestConfigHandler")
429         req, _ := http.NewRequest("POST", "/ric/v1/cm/appname", bytes.NewBuffer([]byte{}))
430         handleFunc := http.HandlerFunc(configHandler)
431         executeRequest(req, handleFunc)
432 }
433
434 func TestappconfigHandler(t *testing.T) {
435         Logger.Error("CASE: TestappconfigHandler")
436         req, _ := http.NewRequest("POST", "/ric/v1/config", bytes.NewBuffer([]byte{}))
437         handleFunc := http.HandlerFunc(appconfigHandler)
438         executeRequest(req, handleFunc)
439 }
440
441 func TestConfigChange(t *testing.T) {
442         Logger.Error("CASE: TestConfigChange: %s", os.Getenv("CFG_FILE"))
443
444         input, err := ioutil.ReadFile(os.Getenv("CFG_FILE"))
445         assert.Equal(t, err, nil)
446
447         err = ioutil.WriteFile(os.Getenv("CFG_FILE"), input, 0644)
448         assert.Equal(t, err, nil)
449 }
450
451 func TestRegisterXapp(t *testing.T) {
452         Logger.Error("CASE: TestRegisterXapp")
453         doRegister()
454 }
455
456 func TestDeregisterXapp(t *testing.T) {
457         Logger.Error("CASE: TestDeregisterXapp")
458         doDeregister()
459 }
460
461 func TestMisc(t *testing.T) {
462         Logger.Info("CASE: TestMisc")
463         var cb = func() {}
464         IsReady()
465         SetReadyCB(func(interface{}) {}, "")
466         XappReadyCb("")
467         SetShutdownCB(cb)
468         XappShutdownCb()
469         getService("ueec", SERVICE_HTTP)
470
471         Logger.SetFormat(1)
472         Logger.SetLevel(0)
473         Logger.Error("...")
474         Logger.Warn("...")
475         Logger.Info("...")
476
477         mb := Rmr.Allocate(100)
478         Rmr.ReAllocate(mb, 200)
479
480         NewMetrics("", "", Resource.router)
481 }
482
483 func TestTeardown(t *testing.T) {
484         Logger.Info("CASE: TestTeardown")
485         Sdl.Delete([]string{"myKey"})
486         Sdl.Clear()
487         Sdl.IsReady()
488         Sdl.GetStat()
489         Rnib.GetNodebByGlobalNbId(1, &RNIBGlobalNbId{})
490         Rnib.SaveNodeb(&RNIBNbIdentity{}, &RNIBNodebInfo{})
491         go Sdl.TestConnection()
492         time.Sleep(time.Duration(2) * time.Second)
493 }
494
495 // Helper functions
496 func executeRequest(req *http.Request, handleR http.HandlerFunc) *httptest.ResponseRecorder {
497         rr := httptest.NewRecorder()
498         if handleR != nil {
499                 vars := map[string]string{"name": "myxapp"}
500                 req = mux.SetURLVars(req, vars)
501                 handleR.ServeHTTP(rr, req)
502         } else {
503                 vars := map[string]string{"id": "1"}
504                 req = mux.SetURLVars(req, vars)
505                 Resource.router.ServeHTTP(rr, req)
506         }
507         return rr
508 }
509
510 func checkResponseCode(t *testing.T, expected, actual int) {
511         if expected != actual {
512                 t.Errorf("Expected response code %d. Got %d\n", expected, actual)
513         }
514 }
515
516 func getMetrics(t *testing.T) string {
517         req, _ := http.NewRequest("GET", "/ric/v1/metrics", nil)
518         response := executeRequest(req, nil)
519
520         return response.Body.String()
521 }