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