[RICPLT-1740] - Get Ran Load Information API 63/663/1
authorns019t <ns019t@intl.att.com>
Thu, 8 Aug 2019 12:00:21 +0000 (15:00 +0300)
committerns019t <ns019t@intl.att.com>
Thu, 8 Aug 2019 12:00:30 +0000 (15:00 +0300)
Change-Id: Ib14fa36f3c5bcd8ab0c4e47363263cd4819294ab
Signed-off-by: ns019t <ns019t@intl.att.com>
common/rNibPool_test.go
reader/rNibReader.go
reader/rNibReader_test.go

index c8f0c00..e3bffa5 100644 (file)
@@ -68,8 +68,8 @@ func validateMaxLimit(size int, iterations int, t *testing.T) {
        )
        group := sync.WaitGroup{}
        for i := 0; i < iterations; i++ {
+               group.Add(1)
                go func() {
-                       group.Add(1)
                        getPutInstance()
                        group.Done()
                }()
index ae9dcf3..0509326 100644 (file)
@@ -22,6 +22,7 @@ import (
        "gerrit.o-ran-sc.org/r/ric-plt/sdlgo"
        "github.com/golang/protobuf/proto"
        "github.com/pkg/errors"
+       "reflect"
 )
 
 var readerPool *common.Pool
@@ -53,6 +54,8 @@ type RNibReader interface {
        GetCellById(cellType entities.Cell_Type, cellId string) (*entities.Cell, common.IRNibError)
        // GetListNodebIds returns the full list of Nodeb identity entities
        GetListNodebIds()([]*entities.NbIdentity, common.IRNibError)
+       // GetRanLoadInformation retrieves nodeb load information entity from redis DB by nodeb inventory name
+       GetRanLoadInformation(inventoryName string) (*entities.RanLoadInformation, common.IRNibError)
 }
 
 const(
@@ -180,6 +183,34 @@ func (w *rNibReaderInstance) GetListNodebIds()([]*entities.NbIdentity, common.IR
        return *data, rnibErr
 }
 
+func (w *rNibReaderInstance) GetRanLoadInformation(inventoryName string) (*entities.RanLoadInformation, common.IRNibError){
+       key, rNibErr := common.ValidateAndBuildRanLoadInformationKey(inventoryName)
+       if rNibErr != nil {
+               return nil, rNibErr
+       }
+       loadInfo := &entities.RanLoadInformation{}
+       err := w.getByKeyAndUnmarshal(key, loadInfo)
+       if err!= nil{
+               return nil, err
+       }
+       return loadInfo, err
+}
+
+func (w *rNibReaderInstance) getByKeyAndUnmarshal(key string, entity proto.Message)common.IRNibError{
+       data, err := (*w.sdl).Get([]string{key})
+       if err != nil {
+               return common.NewInternalError(err)
+       }
+       if data != nil && data[key] != nil {
+               err = proto.Unmarshal([]byte(data[key].(string)), entity)
+               if err != nil {
+                       return common.NewInternalError(err)
+               }
+               return nil
+       }
+       return common.NewResourceNotFoundError(errors.Errorf("#rNibReader.getByKeyAndUnmarshal - entity of type %s not found. Key: %s", reflect.TypeOf(entity).String(), key))
+}
+
 func (w *rNibReaderInstance) getNodeb(key string) (*entities.NodebInfo, common.IRNibError) {
        data, err := (*w.sdl).Get([]string{key})
        if err != nil {
index 35e9cb9..ad19ab4 100644 (file)
 package reader
 
 import (
+       "encoding/json"
        "errors"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/common"
        "gerrit.o-ran-sc.org/r/ric-plt/nodeb-rnib.git/entities"
        "github.com/golang/protobuf/proto"
        "github.com/stretchr/testify/assert"
        "testing"
+       "time"
 )
 
 var namespace = "namespace"
@@ -86,8 +88,12 @@ func TestGetNodeB(t *testing.T) {
        if err != nil {
                t.Errorf("#rNibReader_test.TestGetNb - Failed to marshal ENB instance. Error: %v", err)
        }
-       ret := map[string]interface{}{"RAN:" + name: string(data)}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeB - failed to validate key parameter")
+       }
+       ret := map[string]interface{}{redisKey: string(data)}
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        getNb, er := w.GetNodeb(name)
        assert.Nil(t, er)
        assert.Equal(t, getNb.Ip, nb.Ip)
@@ -104,7 +110,11 @@ func TestGetNodeBNotFoundFailure(t *testing.T) {
        w := GetRNibReader()
        var e error
        var ret map[string]interface{}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBNotFoundFailure - failed to validate key parameter")
+       }
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        getNb, er := w.GetNodeb(name)
        assert.NotNil(t, er)
        assert.Nil(t, getNb)
@@ -119,8 +129,12 @@ func TestGetNodeBUnmarshalFailure(t *testing.T) {
        w := GetRNibReader()
        var e error
        ret := make(map[string]interface{}, 1)
-       ret["RAN:"+name] = "data"
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBUnmarshalFailure - failed to validate key parameter")
+       }
+       ret[redisKey] = "data"
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        getNb, er := w.GetNodeb(name)
        assert.NotNil(t, er)
        assert.Nil(t, getNb)
@@ -137,7 +151,11 @@ func TestGetNodeBSdlgoFailure(t *testing.T) {
        w := GetRNibReader()
        e := errors.New(errMsg)
        var ret map[string]interface{}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBSdlgoFailure - failed to validate key parameter")
+       }
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        getNb, er := w.GetNodeb(name)
        assert.NotNil(t, er)
        assert.Nil(t, getNb)
@@ -163,8 +181,12 @@ func TestGetNodeBCellsListEnb(t *testing.T) {
        if err != nil {
                t.Errorf("#rNibReader_test.GetNodeBCellsList - Failed to marshal ENB instance. Error: %v", err)
        }
-       ret := map[string]interface{}{"RAN:" + name: string(data)}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBCellsListEnb - failed to validate key parameter")
+       }
+       ret := map[string]interface{}{redisKey: string(data)}
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        cells, er := w.GetCellList(name)
        assert.Nil(t, er)
        assert.NotNil(t, cells)
@@ -192,8 +214,12 @@ func TestGetNodeBCellsListGnb(t *testing.T) {
        if err != nil {
                t.Errorf("#rNibReader_test.GetNodeBCellsList - Failed to marshal GNB instance. Error: %v", err)
        }
-       ret := map[string]interface{}{"RAN:" + name: string(data)}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBCellsListGnb - failed to validate key parameter")
+       }
+       ret := map[string]interface{}{redisKey: string(data)}
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        cells, er := w.GetCellList(name)
        assert.Nil(t, er)
        assert.NotNil(t, cells)
@@ -209,8 +235,12 @@ func TestGetNodeBCellsListNodeUnmarshalFailure(t *testing.T) {
        w := GetRNibReader()
        var e error
        ret := make(map[string]interface{}, 1)
-       ret["RAN:"+name] = "data"
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBCellsListNodeUnmarshalFailure - failed to validate key parameter")
+       }
+       ret[redisKey] = "data"
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        cells, er := w.GetCellList(name)
        assert.NotNil(t, er)
        assert.Nil(t, cells)
@@ -225,7 +255,11 @@ func TestGetNodeBCellsListNodeNotFoundFailure(t *testing.T) {
        w := GetRNibReader()
        var e error
        var ret map[string]interface{}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBCellsListNodeNotFoundFailure - failed to validate key parameter")
+       }
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        cells, er := w.GetCellList(name)
        assert.NotNil(t, er)
        assert.Nil(t, cells)
@@ -249,8 +283,12 @@ func TestGetNodeBCellsListNotFoundFailureEnb(t *testing.T) {
        if err != nil {
                t.Errorf("#rNibReader_test.TestGetNbCellsListNotFoundFailure - Failed to marshal ENB instance. Error: %v", err)
        }
-       ret := map[string]interface{}{"RAN:" + name: string(data)}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBCellsListNotFoundFailureEnb - failed to validate key parameter")
+       }
+       ret := map[string]interface{}{redisKey: string(data)}
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        _, er := w.GetCellList(name)
        assert.NotNil(t, er)
        assert.EqualValues(t, "1 RESOURCE_NOT_FOUND - #rNibReader.GetCellList - served cells not found. Responding node RAN name: name.", er.Error())
@@ -270,10 +308,14 @@ func TestGetNodeBCellsListNotFoundFailureGnb(t *testing.T) {
        var e error
        data, err := proto.Marshal(&nb)
        if err != nil {
-               t.Errorf("#rNibReader_test.TestGetNbCellsListNotFoundFailure - Failed to marshal ENB instance. Error: %v", err)
+               t.Errorf("#rNibReader_test.TestGetNodeBCellsListNotFoundFailureGnb - Failed to marshal ENB instance. Error: %v", err)
+       }
+       redisKey, rNibErr := common.ValidateAndBuildNodeBNameKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetNodeBCellsListNotFoundFailureGnb - failed to validate key parameter")
        }
-       ret := map[string]interface{}{"RAN:" + name: string(data)}
-       sdlInstanceMock.On("Get", []string{"RAN:" + name}).Return(ret, e)
+       ret := map[string]interface{}{redisKey: string(data)}
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
        _, er := w.GetCellList(name)
        assert.NotNil(t, er)
        assert.EqualValues(t, "1 RESOURCE_NOT_FOUND - #rNibReader.GetCellList - served cells not found. Responding node RAN name: name.", er.Error())
@@ -929,6 +971,170 @@ func TestGetCellByIdValidationFailureEnb(t *testing.T) {
        assert.EqualValues(t, "3 VALIDATION_ERROR - #utils.ValidateAndBuildCellIdKey - an empty cell id received", er.Error())
 }
 
+func TestGetRanLoadInformation(t *testing.T) {
+       name := "name"
+       readerPool = nil
+       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
+       w := GetRNibReader()
+       loadInfo := generateRanLoadInformation()
+       var e error
+       data, err := proto.Marshal(loadInfo)
+       if err != nil {
+               t.Errorf("#rNibReader_test.TestGetRanLoadInformation - Failed to marshal RanLoadInformation entity. Error: %v", err)
+       }
+       redisKey, rNibErr := common.ValidateAndBuildRanLoadInformationKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetRanLoadInformationNotFoundFailure - failed to validate key parameter")
+       }
+       ret := map[string]interface{}{redisKey: string(data)}
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
+       getLoadInfo, er := w.GetRanLoadInformation(name)
+       assert.Nil(t, er)
+       assert.NotNil(t, getLoadInfo)
+       expected, err := json.Marshal(loadInfo)
+       if err != nil {
+               t.Errorf("#rNibReader_test.TestGetRanLoadInformation - Failed to marshal RanLoadInformation entity. Error: %v", err)
+       }
+       actual, err := json.Marshal(getLoadInfo)
+       if err != nil {
+               t.Errorf("#rNibReader_test.TestGetRanLoadInformation - Failed to marshal RanLoadInformation entity. Error: %v", err)
+       }
+       assert.EqualValues(t, expected, actual)
+}
+
+func TestGetRanLoadInformationNotFoundFailure(t *testing.T) {
+       name := "name"
+       readerPool = nil
+       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
+       w := GetRNibReader()
+       var e error
+       var ret map[string]interface{}
+       redisKey, rNibErr := common.ValidateAndBuildRanLoadInformationKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetRanLoadInformationNotFoundFailure - failed to validate key parameter")
+       }
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
+       getNb, er := w.GetRanLoadInformation(name)
+       assert.NotNil(t, er)
+       assert.Nil(t, getNb)
+       assert.Equal(t, 1, er.GetCode())
+       assert.EqualValues(t, "1 RESOURCE_NOT_FOUND - #rNibReader.getByKeyAndUnmarshal - entity of type *entities.RanLoadInformation not found. Key: LOAD:name", er.Error())
+}
+
+func TestGetRanLoadInformationUnmarshalFailure(t *testing.T) {
+       name := "name"
+       readerPool = nil
+       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
+       w := GetRNibReader()
+       var e error
+       ret := make(map[string]interface{}, 1)
+       redisKey, rNibErr := common.ValidateAndBuildRanLoadInformationKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetRanLoadInformationUnmarshalFailure - failed to validate key parameter")
+       }
+       ret[redisKey] = "data"
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
+       getNb, er := w.GetRanLoadInformation(name)
+       assert.NotNil(t, er)
+       assert.Nil(t, getNb)
+       assert.Equal(t, 2, er.GetCode())
+       assert.EqualValues(t, "2 INTERNAL_ERROR - proto: can't skip unknown wire type 4", er.Error())
+}
+
+func TestGetRanLoadInformationSdlgoFailure(t *testing.T) {
+       name := "name"
+       errMsg := "expected Sdlgo error"
+       errMsgExpected := "2 INTERNAL_ERROR - expected Sdlgo error"
+       readerPool = nil
+       sdlInstanceMock := initSdlInstanceMock(namespace, 1)
+       w := GetRNibReader()
+       e := errors.New(errMsg)
+       var ret map[string]interface{}
+       redisKey, rNibErr := common.ValidateAndBuildRanLoadInformationKey(name)
+       if rNibErr != nil {
+               t.Errorf("#rNibReader_test.TestGetRanLoadInformationSdlgoFailure - failed to validate key parameter")
+       }
+       sdlInstanceMock.On("Get", []string{redisKey}).Return(ret, e)
+       getNb, er := w.GetRanLoadInformation(name)
+       assert.NotNil(t, er)
+       assert.Nil(t, getNb)
+       assert.Equal(t, 2, er.GetCode())
+       assert.EqualValues(t, errMsgExpected, er.Error())
+}
+
+func generateCellLoadInformation() *entities.CellLoadInformation {
+       cellLoadInformation := entities.CellLoadInformation{}
+
+       cellLoadInformation.CellId = "123"
+
+       ulInterferenceOverloadIndication := entities.UlInterferenceOverloadIndication_HIGH_INTERFERENCE
+       cellLoadInformation.UlInterferenceOverloadIndications = []entities.UlInterferenceOverloadIndication{ulInterferenceOverloadIndication}
+
+       ulHighInterferenceInformation := entities.UlHighInterferenceInformation{
+               TargetCellId:"456",
+               UlHighInterferenceIndication:"xxx",
+       }
+
+       cellLoadInformation.UlHighInterferenceInfos = []*entities.UlHighInterferenceInformation{&ulHighInterferenceInformation }
+
+       cellLoadInformation.RelativeNarrowbandTxPower = &entities.RelativeNarrowbandTxPower{
+               RntpPerPrb:"xxx",
+               RntpThreshold:entities.RntpThreshold_NEG_4,
+               NumberOfCellSpecificAntennaPorts: entities.NumberOfCellSpecificAntennaPorts_V1_ANT_PRT,
+               PB: 1,
+               PdcchInterferenceImpact:2,
+               EnhancedRntp: &entities.EnhancedRntp{
+                       EnhancedRntpBitmap:"xxx",
+                       RntpHighPowerThreshold:entities.RntpThreshold_NEG_2,
+                       EnhancedRntpStartTime: &entities.StartTime{StartSfn:500,StartSubframeNumber:5},
+               },
+       }
+
+       cellLoadInformation.AbsInformation = &entities.AbsInformation{
+               Mode: entities.AbsInformationMode_ABS_INFO_FDD,
+               AbsPatternInfo:"xxx",
+               NumberOfCellSpecificAntennaPorts:entities.NumberOfCellSpecificAntennaPorts_V2_ANT_PRT,
+               MeasurementSubset:"xxx",
+       }
+
+       cellLoadInformation.InvokeIndication = entities.InvokeIndication_ABS_INFORMATION
+
+       cellLoadInformation.ExtendedUlInterferenceOverloadInfo = &entities.ExtendedUlInterferenceOverloadInfo{
+               AssociatedSubframes:"xxx",
+               ExtendedUlInterferenceOverloadIndications:cellLoadInformation.UlInterferenceOverloadIndications,
+       }
+
+       compInformationItem := &entities.CompInformationItem{
+               CompHypothesisSets: []*entities.CompHypothesisSet{&entities.CompHypothesisSet{CellId: "789", CompHypothesis:"xxx"}},
+               BenefitMetric:50,
+       }
+
+       cellLoadInformation.CompInformation = &entities.CompInformation{
+               CompInformationItems:[]*entities.CompInformationItem{compInformationItem},
+               CompInformationStartTime:&entities.StartTime{StartSfn:123,StartSubframeNumber:456},
+       }
+
+       cellLoadInformation.DynamicDlTransmissionInformation = &entities.DynamicDlTransmissionInformation{
+               State: entities.NaicsState_NAICS_ACTIVE,
+               TransmissionModes:"xxx",
+               PB: 2,
+               PAList:[]entities.PA{entities.PA_DB_NEG_3},
+       }
+
+       return &cellLoadInformation
+}
+
+func generateRanLoadInformation() *entities.RanLoadInformation {
+       ranLoadInformation := entities.RanLoadInformation{}
+
+       ranLoadInformation.LoadTimestamp = uint64(time.Now().UnixNano())
+
+       cellLoadInformation := generateCellLoadInformation()
+       ranLoadInformation.CellLoadInfos = []*entities.CellLoadInformation{cellLoadInformation}
+
+       return &ranLoadInformation
+}
+
 //integration tests
 
 //func TestGetEnbInteg(t *testing.T){