Some code and testing improvement 89/2489/1
authorMohamed Abukar <abukar.mohamed@nokia.com>
Wed, 12 Feb 2020 17:08:42 +0000 (19:08 +0200)
committerMohamed Abukar <abukar.mohamed@nokia.com>
Wed, 12 Feb 2020 17:08:49 +0000 (19:08 +0200)
Change-Id: Ic8a52c315db09f9c3f9d73b2c3c50d15ee205555
Signed-off-by: Mohamed Abukar <abukar.mohamed@nokia.com>
README.md
config/config-file.yaml
pkg/xapp/rmr.go
pkg/xapp/xapp_test.go

index 3f91461..7a0cccc 100755 (executable)
--- a/README.md
+++ b/README.md
@@ -169,6 +169,24 @@ Congratulations! You've just built your first **xapp** application.
     Resource.InjectQueryRoute("/ric/v1/user", handler, "GET", "foo", "bar", "id", "mykey")
     ```
 
+* Metrics: registering couple of counters
+    ```
+    metrics := []xapp.CounterOpts{
+               {Name: "RICIndicationsRx", Help: "The total number of RIC inidcation events received"},
+               {Name: "RICExampleMessageRx", Help: "The total number of RIC example messages received"},
+       }
+    xapp.Metric.RegisterCounterGroup(metrics, "MyXApp")
+
+    // Use curl-command to get metrics
+    curl http://localhost:8080/ric/v1/metrics
+    ```
+
+## Running unit tests
+  Unit tests of xApp-framework can be run as following:
+  ```
+  make test
+  ```
+
 ## Documentation
 
 ## Community
index 26dbbae..7678c5a 100755 (executable)
   "protPort": "tcp:4560"
   "maxSize": 2072
   "numWorkers": 1
+  "maxRetryOnFailure": 5
 "subscription":
     "host": "localhost:8088"
     "timeout": 2
 "db":
-  "namespaces": ["sdl", "rnib"]
+  "namespace": "sdl"
+  "waitForSdl": false
 "test":
   "mode": "forwarder"
   "mtype": 10004
index 3a52c97..a25b340 100755 (executable)
@@ -81,6 +81,7 @@ type RMRParams struct {
        SubId      int
        Src        string
        Mbuf       *C.rmr_mbuf_t
+       status     int
 }
 
 func NewRMRClientWithParams(protPort string, maxSize int, numWorkers int, statDesc string) *RMRClient {
@@ -247,13 +248,16 @@ func (m *RMRClient) Send(params *RMRParams, isRts bool) bool {
        }
        C.write_bytes_array(txBuffer.payload, datap, txBuffer.len)
 
-       return m.SendBuf(txBuffer, isRts)
+       params.status = m.SendBuf(txBuffer, isRts)
+       if params.status == int(C.RMR_OK) {
+               return true
+       }
+       return false
 }
 
-func (m *RMRClient) SendBuf(txBuffer *C.rmr_mbuf_t, isRts bool) bool {
+func (m *RMRClient) SendBuf(txBuffer *C.rmr_mbuf_t, isRts bool) int {
        var (
                currBuffer  *C.rmr_mbuf_t
-               state       bool   = true
                counterName string = "Transmitted"
        )
 
@@ -270,7 +274,12 @@ func (m *RMRClient) SendBuf(txBuffer *C.rmr_mbuf_t, isRts bool) bool {
        }
 
        // Just quick retry seems to help for K8s issue
-       for j := 0; j < 3 && currBuffer != nil && currBuffer.state == C.RMR_ERR_RETRY; j++ {
+       maxRetryOnFailure := viper.GetInt("rmr.maxRetryOnFailure")
+       if maxRetryOnFailure == 0 {
+               maxRetryOnFailure = 5
+       }
+
+       for j := 0; j < maxRetryOnFailure && currBuffer != nil && currBuffer.state == C.RMR_ERR_RETRY; j++ {
                if isRts {
                        currBuffer = C.rmr_rts_msg(m.context, currBuffer)
                } else {
@@ -280,12 +289,27 @@ func (m *RMRClient) SendBuf(txBuffer *C.rmr_mbuf_t, isRts bool) bool {
 
        if currBuffer.state != C.RMR_OK {
                counterName = "TransmitError"
-               state = m.LogMBufError("SendBuf failed", currBuffer)
+               m.LogMBufError("SendBuf failed", currBuffer)
        }
 
        m.UpdateStatCounter(counterName)
        m.Free(currBuffer)
-       return state
+
+       return int(currBuffer.state)
+}
+
+func (m *RMRClient) IsRetryError(params *RMRParams) bool {
+       if params.status == int(C.RMR_ERR_RETRY) {
+               return true
+       }
+       return false
+}
+
+func (m *RMRClient) IsNoEndPointError(params *RMRParams) bool {
+       if params.status == int(C.RMR_ERR_NOENDPT) {
+               return true
+       }
+       return false
 }
 
 func (m *RMRClient) UpdateStatCounter(name string) {
@@ -325,9 +349,9 @@ func (m *RMRClient) GetRicMessageName(id int) (s string) {
        return
 }
 
-func (m *RMRClient) LogMBufError(text string, mbuf *C.rmr_mbuf_t) bool {
+func (m *RMRClient) LogMBufError(text string, mbuf *C.rmr_mbuf_t) int {
        Logger.Debug(fmt.Sprintf("rmrClient: %s -> [tp=%v] %v - %s", text, mbuf.tp_state, mbuf.state, RMRErrors[int(mbuf.state)]))
-       return false
+       return int(mbuf.state)
 }
 
 // To be removed ...
index ca858eb..c1a049f 100755 (executable)
@@ -23,6 +23,7 @@ import (
        "github.com/gorilla/mux"
        "net/http"
        "net/http/httptest"
+       "github.com/spf13/viper"
        "os"
        "strings"
        "testing"
@@ -43,7 +44,7 @@ func (m Consumer) Consume(params *RMRParams) (err error) {
 
 // Test cases
 func TestMain(m *testing.M) {
-       go Run(Consumer{})
+       go RunWithParams(Consumer{}, viper.GetBool("db.waitForSdl"))
        time.Sleep(time.Duration(5) * time.Second)
        code := m.Run()
        os.Exit(code)
@@ -114,6 +115,7 @@ func TestMessagesReceivedSuccessfully(t *testing.T) {
        // Allow time to process the messages
        time.Sleep(time.Duration(2) * time.Second)
 
+       waitForSdl := viper.GetBool("db.waitForSdl")
        stats := getMetrics(t)
        if !strings.Contains(stats, "ricxapp_RMR_Transmitted 100") {
                t.Errorf("Error: ricxapp_RMR_Transmitted value incorrect")
@@ -131,16 +133,20 @@ func TestMessagesReceivedSuccessfully(t *testing.T) {
                t.Errorf("Error: ricxapp_RMR_ReceiveError value incorrect")
        }
 
-       if !strings.Contains(stats, "ricxapp_SDL_Stored 100") {
+       if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_Stored 100") {
                t.Errorf("Error: ricxapp_SDL_Stored value incorrect")
        }
 
-       if !strings.Contains(stats, "ricxapp_SDL_StoreError 0") {
+       if waitForSdl && !strings.Contains(stats, "ricxapp_SDL_StoreError 0") {
                t.Errorf("Error: ricxapp_SDL_StoreError value incorrect")
        }
 }
 
 func TestSubscribeChannels(t *testing.T) {
+       if !viper.GetBool("db.waitForSdl") {
+               return
+       }
+
        var NotificationCb = func(ch string, events ...string) {
                if ch != "channel1" {
                        t.Errorf("Error: Callback function called with incorrect params")
@@ -170,14 +176,36 @@ func TestGetRicMessageSuccess(t *testing.T) {
 }
 
 func TestGetRicMessageFails(t *testing.T) {
-       id, ok := Rmr.GetRicMessageId("INVALID")
+       ok := Rmr.IsRetryError(&RMRParams{status: 0})
        if ok {
-               t.Errorf("Error: GetRicMessageId returned invalid value id=%d", id)
+               t.Errorf("Error: IsRetryError returned wrong value")
+       }
+
+       ok = Rmr.IsRetryError(&RMRParams{status: 10})
+       if !ok {
+               t.Errorf("Error: IsRetryError returned wrong value")
+       }
+
+       ok = Rmr.IsNoEndPointError(&RMRParams{status: 5})
+       if ok {
+               t.Errorf("Error: IsNoEndPointError returned wrong value")
+       }
+
+       ok = Rmr.IsNoEndPointError(&RMRParams{status: 2})
+       if !ok {
+               t.Errorf("Error: IsNoEndPointError returned wrong value")
        }
+}
 
-       name := Rmr.GetRicMessageName(123456)
-       if name != "" {
-               t.Errorf("Error: GetRicMessageName returned invalid value: name=%s", name)
+func TestIsErrorFunctions(t *testing.T) {
+       id, ok := Rmr.GetRicMessageId("RIC_SUB_REQ")
+       if !ok || id != 12010 {
+               t.Errorf("Error: GetRicMessageId failed: id=%d", id)
+       }
+
+       name := Rmr.GetRicMessageName(12010)
+       if name != "RIC_SUB_REQ" {
+               t.Errorf("Error: GetRicMessageName failed: name=%s", name)
        }
 }