Some code and testing improvement

Change-Id: Ic8a52c315db09f9c3f9d73b2c3c50d15ee205555
Signed-off-by: Mohamed Abukar <abukar.mohamed@nokia.com>
diff --git a/README.md b/README.md
index 3f91461..7a0cccc 100755
--- a/README.md
+++ b/README.md
@@ -169,6 +169,24 @@
     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
diff --git a/config/config-file.yaml b/config/config-file.yaml
index 26dbbae..7678c5a 100755
--- a/config/config-file.yaml
+++ b/config/config-file.yaml
@@ -21,11 +21,13 @@
   "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
diff --git a/pkg/xapp/rmr.go b/pkg/xapp/rmr.go
index 3a52c97..a25b340 100755
--- a/pkg/xapp/rmr.go
+++ b/pkg/xapp/rmr.go
@@ -81,6 +81,7 @@
 	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 @@
 	}
 	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 @@
 	}
 
 	// 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 @@
 
 	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 @@
 	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 ...
diff --git a/pkg/xapp/xapp_test.go b/pkg/xapp/xapp_test.go
index ca858eb..c1a049f 100755
--- a/pkg/xapp/xapp_test.go
+++ b/pkg/xapp/xapp_test.go
@@ -23,6 +23,7 @@
 	"github.com/gorilla/mux"
 	"net/http"
 	"net/http/httptest"
+	"github.com/spf13/viper"
 	"os"
 	"strings"
 	"testing"
@@ -43,7 +44,7 @@
 
 // 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 @@
 	// 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 @@
 		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 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")
 	}
 
-	name := Rmr.GetRicMessageName(123456)
-	if name != "" {
-		t.Errorf("Error: GetRicMessageName returned invalid value: name=%s", name)
+	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")
+	}
+}
+
+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)
 	}
 }