| /* |
| * Copyright 2018-present Open Networking Foundation |
| |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| This file contains unit test cases for functions in the file resourcemanager.go. |
| This file also implements the Client interface to mock the kv-client, fields struct to mock OpenOltResourceMgr |
| and few utility functions. |
| */ |
| |
| //Package adaptercore provides the utility for olt devices, flows and statistics |
| package resourcemanager |
| |
| import ( |
| "context" |
| "encoding/json" |
| "errors" |
| "github.com/opencord/voltha-lib-go/v3/pkg/db" |
| "github.com/opencord/voltha-lib-go/v3/pkg/db/kvstore" |
| fu "github.com/opencord/voltha-lib-go/v3/pkg/flows" |
| "github.com/opencord/voltha-lib-go/v3/pkg/log" |
| ponrmgr "github.com/opencord/voltha-lib-go/v3/pkg/ponresourcemanager" |
| ofp "github.com/opencord/voltha-protos/v3/go/openflow_13" |
| "github.com/opencord/voltha-protos/v3/go/openolt" |
| "reflect" |
| "strconv" |
| "strings" |
| "sync" |
| "testing" |
| "time" |
| ) |
| |
| func init() { |
| log.SetDefaultLogger(log.JSON, log.DebugLevel, nil) |
| } |
| |
| const ( |
| // MeterConfig meter to extract meter |
| MeterConfig = "meter_id" |
| // TpIDSuffixPath to extract Techprofile |
| TpIDSuffixPath = "tp_id" |
| // FlowIDInfo to extract flows |
| FlowIDInfo = "flow_id_info" |
| // FlowIds to extract flows |
| FlowIDs = "flow_ids" |
| // GemportIDs to gemport_ids |
| GemportIDs = "gemport_ids" |
| // AllocIDs to extract alloc_ids |
| AllocIDs = "alloc_ids" |
| // GemportIDPool to extract gemport |
| GemportIDPool = "gemport_id_pool" |
| // AllocIDPool to extract allocid |
| AllocIDPool = "alloc_id_pool" |
| // FlowIDpool to extract Flow ids |
| FlowIDpool = "flow_id_pool" |
| ) |
| |
| // fields mocks OpenOltResourceMgr struct. |
| type fields struct { |
| DeviceID string |
| Address string |
| Args string |
| KVStore *db.Backend |
| DeviceType string |
| DevInfo *openolt.DeviceInfo |
| ResourceMgrs map[uint32]*ponrmgr.PONResourceManager |
| NumOfPonPorts uint32 |
| } |
| |
| // MockKVClient mocks the AdapterProxy interface. |
| type MockResKVClient struct { |
| } |
| |
| // getResMgr mocks OpenOltResourceMgr struct. |
| func getResMgr() *fields { |
| var resMgr fields |
| resMgr.KVStore = &db.Backend{ |
| Client: &MockResKVClient{}, |
| } |
| resMgr.ResourceMgrs = make(map[uint32]*ponrmgr.PONResourceManager) |
| ranges := make(map[string]interface{}) |
| sharedIdxByType := make(map[string]string) |
| sharedIdxByType["ALLOC_ID"] = "ALLOC_ID" |
| sharedIdxByType["ONU_ID"] = "ONU_ID" |
| sharedIdxByType["GEMPORT_ID"] = "GEMPORT_ID" |
| sharedIdxByType["FLOW_ID"] = "FLOW_ID" |
| ranges["ONU_ID"] = uint32(0) |
| ranges["GEMPORT_ID"] = uint32(0) |
| ranges["ALLOC_ID"] = uint32(0) |
| ranges["FLOW_ID"] = uint32(0) |
| ranges["onu_id_shared"] = uint32(0) |
| ranges["alloc_id_shared"] = uint32(0) |
| ranges["gemport_id_shared"] = uint32(0) |
| ranges["flow_id_shared"] = uint32(0) |
| resMgr.NumOfPonPorts = 2 |
| ponMgr := &ponrmgr.PONResourceManager{ |
| DeviceID: "onu-1", |
| IntfIDs: []uint32{1, 2}, |
| KVStore: &db.Backend{ |
| Client: &MockResKVClient{}, |
| }, |
| PonResourceRanges: ranges, |
| SharedIdxByType: sharedIdxByType, |
| } |
| resMgr.ResourceMgrs[1] = ponMgr |
| resMgr.ResourceMgrs[2] = ponMgr |
| |
| return &resMgr |
| } |
| |
| // List function implemented for KVClient. |
| func (kvclient *MockResKVClient) List(ctx context.Context, key string) (map[string]*kvstore.KVPair, error) { |
| return nil, errors.New("key didn't find") |
| } |
| |
| // Get mock function implementation for KVClient |
| func (kvclient *MockResKVClient) Get(ctx context.Context, key string) (*kvstore.KVPair, error) { |
| logger.Debugw("Warning Warning Warning: Get of MockKVClient called", log.Fields{"key": key}) |
| if key != "" { |
| if strings.Contains(key, MeterConfig) { |
| var bands []*ofp.OfpMeterBandHeader |
| bands = append(bands, &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DSCP_REMARK, |
| Rate: 1024, Data: &ofp.OfpMeterBandHeader_DscpRemark{DscpRemark: &ofp.OfpMeterBandDscpRemark{PrecLevel: 2}}}) |
| |
| bands = append(bands, &ofp.OfpMeterBandHeader{Type: ofp.OfpMeterBandType_OFPMBT_DSCP_REMARK, |
| Rate: 1024, Data: &ofp.OfpMeterBandHeader_DscpRemark{DscpRemark: &ofp.OfpMeterBandDscpRemark{PrecLevel: 3}}}) |
| |
| sep := strings.Split(key, "/")[1] |
| val, _ := strconv.ParseInt(strings.Split(sep, ",")[1], 10, 32) |
| if uint32(val) > 1 { |
| meterConfig := &ofp.OfpMeterConfig{MeterId: uint32(val), Bands: bands} |
| str, _ := json.Marshal(meterConfig) |
| |
| return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil |
| } |
| return nil, errors.New("invalid meter") |
| } |
| if strings.Contains(key, FlowIDpool) || strings.Contains(key, GemportIDPool) || strings.Contains(key, AllocIDPool) { |
| logger.Debug("Error Error Error Key:", FlowIDpool, GemportIDPool, AllocIDPool) |
| data := make(map[string]interface{}) |
| data["pool"] = "1024" |
| data["start_idx"] = 1 |
| data["end_idx"] = 1024 |
| str, _ := json.Marshal(data) |
| return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil |
| } |
| if strings.Contains(key, FlowIDInfo) || strings.Contains(key, FlowIDs) { |
| logger.Debug("Error Error Error Key:", FlowIDs, FlowIDInfo) |
| str, _ := json.Marshal([]uint32{1, 2}) |
| return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil |
| } |
| if strings.Contains(key, AllocIDs) || strings.Contains(key, GemportIDs) { |
| logger.Debug("Error Error Error Key:", AllocIDs, GemportIDs) |
| str, _ := json.Marshal(1) |
| return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil |
| } |
| if strings.Contains(key, McastQueuesForIntf) { |
| logger.Debug("Error Error Error Key:", McastQueuesForIntf) |
| mcastQueues := make(map[uint32][]uint32) |
| mcastQueues[10] = []uint32{4000, 0} |
| str, _ := json.Marshal(mcastQueues) |
| return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil |
| } |
| if strings.Contains(key, "flow_groups") && !strings.Contains(key, "1000") { |
| groupInfo := GroupInfo{GroupID: 2, OutPorts: []uint32{2}} |
| str, _ := json.Marshal(groupInfo) |
| return kvstore.NewKVPair(key, str, "mock", 3000, 1), nil |
| } |
| |
| maps := make(map[string]*kvstore.KVPair) |
| maps[key] = &kvstore.KVPair{Key: key} |
| return maps[key], nil |
| } |
| return nil, errors.New("key didn't find") |
| } |
| |
| // Put mock function implementation for KVClient |
| func (kvclient *MockResKVClient) Put(ctx context.Context, key string, value interface{}) error { |
| if key != "" { |
| return nil |
| } |
| return errors.New("key didn't find") |
| } |
| |
| // Delete mock function implementation for KVClient |
| func (kvclient *MockResKVClient) Delete(ctx context.Context, key string) error { |
| return nil |
| } |
| |
| // Reserve mock function implementation for KVClient |
| func (kvclient *MockResKVClient) Reserve(ctx context.Context, key string, value interface{}, ttl time.Duration) (interface{}, error) { |
| return nil, errors.New("key didn't find") |
| } |
| |
| // ReleaseReservation mock function implementation for KVClient |
| func (kvclient *MockResKVClient) ReleaseReservation(ctx context.Context, key string) error { |
| return nil |
| } |
| |
| // ReleaseAllReservations mock function implementation for KVClient |
| func (kvclient *MockResKVClient) ReleaseAllReservations(ctx context.Context) error { |
| return nil |
| } |
| |
| // RenewReservation mock function implementation for KVClient |
| func (kvclient *MockResKVClient) RenewReservation(ctx context.Context, key string) error { |
| return nil |
| } |
| |
| // Watch mock function implementation for KVClient |
| func (kvclient *MockResKVClient) Watch(ctx context.Context, key string, withPrefix bool) chan *kvstore.Event { |
| return nil |
| } |
| |
| // AcquireLock mock function implementation for KVClient |
| func (kvclient *MockResKVClient) AcquireLock(ctx context.Context, lockName string, timeout time.Duration) error { |
| return nil |
| } |
| |
| // ReleaseLock mock function implementation for KVClient |
| func (kvclient *MockResKVClient) ReleaseLock(lockName string) error { |
| return nil |
| } |
| |
| // IsConnectionUp mock function implementation for KVClient |
| func (kvclient *MockResKVClient) IsConnectionUp(ctx context.Context) bool { // timeout in second |
| return true |
| } |
| |
| // CloseWatch mock function implementation for KVClient |
| func (kvclient *MockResKVClient) CloseWatch(key string, ch chan *kvstore.Event) { |
| } |
| |
| // Close mock function implementation for KVClient |
| func (kvclient *MockResKVClient) Close() { |
| } |
| |
| // testResMgrObject maps fields type to OpenOltResourceMgr type. |
| func testResMgrObject(testResMgr *fields) *OpenOltResourceMgr { |
| var rsrMgr = OpenOltResourceMgr{ |
| DeviceID: testResMgr.DeviceID, |
| Args: testResMgr.Args, |
| KVStore: testResMgr.KVStore, |
| DeviceType: testResMgr.DeviceType, |
| Address: testResMgr.Address, |
| DevInfo: testResMgr.DevInfo, |
| ResourceMgrs: testResMgr.ResourceMgrs, |
| } |
| |
| rsrMgr.AllocIDMgmtLock = make([]sync.RWMutex, testResMgr.NumOfPonPorts) |
| rsrMgr.GemPortIDMgmtLock = make([]sync.RWMutex, testResMgr.NumOfPonPorts) |
| rsrMgr.OnuIDMgmtLock = make([]sync.RWMutex, testResMgr.NumOfPonPorts) |
| |
| return &rsrMgr |
| } |
| |
| func TestNewResourceMgr(t *testing.T) { |
| type args struct { |
| deviceID string |
| KVStoreAddress string |
| kvStoreType string |
| deviceType string |
| devInfo *openolt.DeviceInfo |
| } |
| tests := []struct { |
| name string |
| args args |
| want *OpenOltResourceMgr |
| }{ |
| {"NewResourceMgr-1", args{"olt1", "1:2", "consul", |
| "onu", &openolt.DeviceInfo{OnuIdStart: 1, OnuIdEnd: 1}}, &OpenOltResourceMgr{}}, |
| {"NewResourceMgr-2", args{"olt2", "3:4", "etcd", |
| "onu", &openolt.DeviceInfo{OnuIdStart: 1, OnuIdEnd: 1}}, &OpenOltResourceMgr{}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if got := NewResourceMgr(ctx, tt.args.deviceID, tt.args.KVStoreAddress, tt.args.kvStoreType, tt.args.deviceType, tt.args.devInfo); reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("NewResourceMgr() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_Delete(t *testing.T) { |
| tests := []struct { |
| name string |
| fields *fields |
| wantErr error |
| }{ |
| {"Delete-1", getResMgr(), errors.New("failed to clear device resource pool")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.Delete(ctx); (err != nil) && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) { |
| t.Errorf("Delete() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_FreeFlowID(t *testing.T) { |
| type args struct { |
| IntfID uint32 |
| onuID int32 |
| uniID int32 |
| FlowID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| }{ |
| {"FreeFlowID-1", getResMgr(), args{1, 2, 2, 2}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| RsrcMgr.FreeFlowID(ctx, tt.args.IntfID, tt.args.onuID, tt.args.uniID, tt.args.FlowID) |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_FreeFlowIDs(t *testing.T) { |
| |
| type args struct { |
| IntfID uint32 |
| onuID uint32 |
| uniID uint32 |
| FlowID []uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| }{ |
| {"FreeFlowIDs-1", getResMgr(), args{1, 2, 2, []uint32{1, 2}}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| RsrcMgr.FreeFlowIDs(ctx, tt.args.IntfID, tt.args.onuID, tt.args.uniID, tt.args.FlowID) |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_FreePONResourcesForONU(t *testing.T) { |
| type args struct { |
| intfID uint32 |
| onuID uint32 |
| uniID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| }{ |
| {"FreePONResourcesForONU-1", getResMgr(), args{1, 0, 2}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| RsrcMgr.FreePONResourcesForONU(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID) |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_FreeonuID(t *testing.T) { |
| type args struct { |
| intfID uint32 |
| onuID []uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| }{ |
| {"FreeOnuID-1", getResMgr(), args{1, []uint32{1, 2}}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| RsrcMgr.FreeonuID(ctx, tt.args.intfID, tt.args.onuID) |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetAllocID(t *testing.T) { |
| |
| type args struct { |
| intfID uint32 |
| onuID uint32 |
| uniID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want uint32 |
| }{ |
| {"GetAllocID-1", getResMgr(), args{1, 2, 2}, 0}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if got := RsrcMgr.GetAllocID(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("GetAllocID() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetCurrentAllocIDForOnu(t *testing.T) { |
| type args struct { |
| intfID uint32 |
| onuID uint32 |
| uniID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want []uint32 |
| }{ |
| {"GetCurrentAllocIDForOnu-1", getResMgr(), args{1, 2, 2}, []uint32{}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if got := RsrcMgr.GetCurrentAllocIDsForOnu(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID); !reflect.DeepEqual(got, tt.want) { |
| t.Errorf("GetCurrentAllocIDsForOnu() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetCurrentFlowIDsForOnu(t *testing.T) { |
| |
| type args struct { |
| PONIntfID uint32 |
| ONUID int32 |
| UNIID int32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want []uint32 |
| }{ |
| {"GetCurrentFlowIDsForOnu-1", getResMgr(), args{1, 2, 2}, []uint32{}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if got := RsrcMgr.GetCurrentFlowIDsForOnu(ctx, tt.args.PONIntfID, tt.args.ONUID, tt.args.UNIID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("GetCurrentFlowIDsForOnu() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetCurrentGEMPortIDsForOnu(t *testing.T) { |
| type args struct { |
| intfID uint32 |
| onuID uint32 |
| uniID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want []uint32 |
| }{ |
| {"GetCurrentGEMPortIDsForOnu-1", getResMgr(), args{1, 2, 2}, []uint32{}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if got := RsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, tt.args.intfID, tt.args.onuID, tt.args.uniID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("GetCurrentGEMPortIDsForOnu() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetFlowID(t *testing.T) { |
| |
| type args struct { |
| ponIntfID uint32 |
| ONUID int32 |
| uniID int32 |
| gemportID uint32 |
| flowStoreCookie uint64 |
| flowCategory string |
| vlanVid uint32 |
| vlanPcp []uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want uint32 |
| wantErr error |
| }{ |
| {"GetFlowID-1", getResMgr(), args{1, 2, 2, 2, 2, |
| "HSIA", 33, nil}, 0, errors.New("failed to get flows")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| got, err := RsrcMgr.GetFlowID(ctx, tt.args.ponIntfID, tt.args.ONUID, tt.args.uniID, tt.args.gemportID, tt.args.flowStoreCookie, tt.args.flowCategory, tt.args.vlanVid, tt.args.vlanPcp...) |
| if err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) { |
| t.Errorf("GetFlowID() error = %v, wantErr %v", err, tt.wantErr) |
| return |
| } |
| if reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("GetFlowID() got = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetGEMPortID(t *testing.T) { |
| type args struct { |
| ponPort uint32 |
| onuID uint32 |
| uniID uint32 |
| NumOfPorts uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want []uint32 |
| wantErr error |
| }{ |
| {"GetGEMPortID-1", getResMgr(), args{1, 2, 2, 2}, []uint32{}, |
| errors.New("failed to get gem port")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| got, err := RsrcMgr.GetGEMPortID(ctx, tt.args.ponPort, tt.args.onuID, tt.args.uniID, tt.args.NumOfPorts) |
| if reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil { |
| t.Errorf("GetGEMPortID() error = %v, wantErr %v", err, tt.wantErr) |
| return |
| } |
| if reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("GetGEMPortID() got = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetMeterIDForOnu(t *testing.T) { |
| type args struct { |
| Direction string |
| IntfID uint32 |
| OnuID uint32 |
| UniID uint32 |
| tpID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want *ofp.OfpMeterConfig |
| wantErr error |
| }{ |
| {"GetMeterIDOnu", getResMgr(), args{"DOWNSTREAM", 0, 1, 1, 64}, |
| &ofp.OfpMeterConfig{}, errors.New("failed to get Meter config from kvstore for path")}, |
| {"GetMeterIDOnu", getResMgr(), args{"DOWNSTREAM", 1, 2, 2, 65}, |
| &ofp.OfpMeterConfig{}, errors.New("failed to get Meter config from kvstore for path")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| got, err := RsrcMgr.GetMeterIDForOnu(ctx, tt.args.Direction, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, tt.args.tpID) |
| if reflect.TypeOf(got) != reflect.TypeOf(tt.want) && err != nil { |
| t.Errorf("GetMeterIDForOnu() got = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetONUID(t *testing.T) { |
| type args struct { |
| ponIntfID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want uint32 |
| wantErr error |
| }{ |
| {"GetONUID-1", getResMgr(), args{1}, uint32(0), errors.New("json errors")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| got, err := RsrcMgr.GetONUID(ctx, tt.args.ponIntfID) |
| if got != tt.want && err != nil { |
| t.Errorf("GetONUID() got = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetTechProfileIDForOnu(t *testing.T) { |
| |
| type args struct { |
| IntfID uint32 |
| OnuID uint32 |
| UniID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want []uint32 |
| }{ |
| {"GetTechProfileIDForOnu-1", getResMgr(), args{1, 2, 2}, |
| []uint32{1}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if got := RsrcMgr.GetTechProfileIDForOnu(ctx, tt.args.IntfID, tt.args.OnuID, tt.args.UniID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("GetTechProfileIDForOnu() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_IsFlowCookieOnKVStore(t *testing.T) { |
| type args struct { |
| ponIntfID uint32 |
| onuID int32 |
| uniID int32 |
| flowStoreCookie uint64 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| want bool |
| }{ |
| {"IsFlowCookieOnKVStore-1", getResMgr(), args{1, 2, 2, 2}, false}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if got := RsrcMgr.IsFlowCookieOnKVStore(ctx, tt.args.ponIntfID, tt.args.onuID, tt.args.uniID, tt.args.flowStoreCookie); got != tt.want { |
| t.Errorf("IsFlowCookieOnKVStore() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_RemoveMeterIDForOnu(t *testing.T) { |
| |
| type args struct { |
| Direction string |
| IntfID uint32 |
| OnuID uint32 |
| UniID uint32 |
| tpID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"RemoveMeterIdForOnu-1", getResMgr(), args{"DOWNSTREAM", 1, 1, 1, 64}, |
| errors.New("failed to delete meter id %s from kvstore")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.RemoveMeterIDForOnu(ctx, tt.args.Direction, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, |
| tt.args.tpID); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil { |
| t.Errorf("RemoveMeterIDForOnu() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_RemoveTechProfileIDForOnu(t *testing.T) { |
| type args struct { |
| IntfID uint32 |
| OnuID uint32 |
| UniID uint32 |
| tpID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"RemoveTechProfileIDForOnu-1", getResMgr(), args{1, 2, 2, 64}, |
| errors.New("failed to delete techprofile id resource %s in KV store")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.RemoveTechProfileIDForOnu(ctx, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, |
| tt.args.tpID); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil { |
| t.Errorf("RemoveTechProfileIDForOnu() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_UpdateAllocIdsForOnu(t *testing.T) { |
| type args struct { |
| ponPort uint32 |
| onuID uint32 |
| uniID uint32 |
| allocID []uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"UpdateAllocIdsForOnu-1", getResMgr(), args{1, 2, 2, []uint32{1, 2}}, |
| errors.New("")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.UpdateAllocIdsForOnu(ctx, tt.args.ponPort, tt.args.onuID, tt.args.uniID, tt.args.allocID); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) { |
| t.Errorf("UpdateAllocIdsForOnu() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_UpdateFlowIDInfo(t *testing.T) { |
| type args struct { |
| ponIntfID int32 |
| onuID int32 |
| uniID int32 |
| flowID uint32 |
| flowData *[]FlowInfo |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"UpdateFlowIDInfo-1", getResMgr(), args{1, 2, 2, 2, &[]FlowInfo{}}, errors.New("")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.UpdateFlowIDInfo(ctx, tt.args.ponIntfID, tt.args.onuID, tt.args.uniID, tt.args.flowID, tt.args.flowData); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) { |
| t.Errorf("UpdateFlowIDInfo() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_UpdateGEMPortIDsForOnu(t *testing.T) { |
| |
| type args struct { |
| ponPort uint32 |
| onuID uint32 |
| uniID uint32 |
| GEMPortList []uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"UpdateGEMPortIDsForOnu-1", getResMgr(), args{1, 2, 2, |
| []uint32{1, 2}}, errors.New("failed to update resource")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.UpdateGEMPortIDsForOnu(ctx, tt.args.ponPort, tt.args.onuID, tt.args.uniID, tt.args.GEMPortList); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) { |
| t.Errorf("UpdateGEMPortIDsForOnu() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_UpdateGEMportsPonportToOnuMapOnKVStore(t *testing.T) { |
| type args struct { |
| gemPorts []uint32 |
| PonPort uint32 |
| onuID uint32 |
| uniID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"UpdateGEMportsPonportToOnuMapOnKVStore-1", getResMgr(), args{[]uint32{1, 2}, |
| 1, 2, 2}, errors.New("failed to update resource")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, tt.args.gemPorts, tt.args.PonPort, |
| tt.args.onuID, tt.args.uniID); err != nil && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) { |
| t.Errorf("UpdateGEMportsPonportToOnuMapOnKVStore() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_UpdateMeterIDForOnu(t *testing.T) { |
| type args struct { |
| Direction string |
| IntfID uint32 |
| OnuID uint32 |
| UniID uint32 |
| tpID uint32 |
| MeterConfig *ofp.OfpMeterConfig |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"UpdateMeterIDForOnu-1", getResMgr(), args{"DOWNSTREAM", 1, 2, |
| 2, 64, &ofp.OfpMeterConfig{}}, errors.New("failed to get Meter config from kvstore for path")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.UpdateMeterIDForOnu(ctx, tt.args.Direction, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, |
| tt.args.tpID, tt.args.MeterConfig); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil { |
| t.Errorf("UpdateMeterIDForOnu() got = %v, want %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_UpdateTechProfileIDForOnu(t *testing.T) { |
| type args struct { |
| IntfID uint32 |
| OnuID uint32 |
| UniID uint32 |
| TpID uint32 |
| } |
| tests := []struct { |
| name string |
| fields *fields |
| args args |
| wantErr error |
| }{ |
| {"UpdateTechProfileIDForOnu-1", getResMgr(), args{1, 2, 2, |
| 2}, errors.New("failed to update resource")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| if err := RsrcMgr.UpdateTechProfileIDForOnu(ctx, tt.args.IntfID, tt.args.OnuID, tt.args.UniID, tt.args.TpID); reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil { |
| t.Errorf("UpdateTechProfileIDForOnu() got = %v, want %v", err, tt.wantErr) |
| } |
| }) |
| } |
| } |
| |
| func TestSetKVClient(t *testing.T) { |
| type args struct { |
| backend string |
| address string |
| DeviceID string |
| } |
| tests := []struct { |
| name string |
| args args |
| want *db.Backend |
| }{ |
| {"setKVClient-1", args{"consul", "1.1.1.1:1", "olt1"}, &db.Backend{}}, |
| {"setKVClient-1", args{"etcd", "2.2.2.2:2", "olt2"}, &db.Backend{}}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| if got := SetKVClient(tt.args.backend, tt.args.address, tt.args.DeviceID); reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("SetKVClient() = %v, want %v", got, tt.want) |
| } |
| }) |
| } |
| } |
| |
| func Test_getFlowIDFromFlowInfo(t *testing.T) { |
| type args struct { |
| FlowInfo *[]FlowInfo |
| flowID uint32 |
| gemportID uint32 |
| flowStoreCookie uint64 |
| flowCategory string |
| vlanVid uint32 |
| vlanPcp []uint32 |
| } |
| flowInfo := &[]FlowInfo{ |
| { |
| &openolt.Flow{ |
| FlowId: 1, |
| GemportId: 1, |
| Classifier: &openolt.Classifier{ |
| OPbits: 1, |
| OVid: 33, |
| }, |
| Action: &openolt.Action{ |
| Cmd: &openolt.ActionCmd{ |
| AddOuterTag: true, |
| }, |
| OVid: 7, |
| }, |
| }, |
| 1, |
| "HSIA_FLOW", |
| 2000, |
| }, |
| { |
| &openolt.Flow{ |
| GemportId: 1, |
| Classifier: &openolt.Classifier{ |
| OVid: 0, |
| }, |
| Action: &openolt.Action{ |
| Cmd: &openolt.ActionCmd{ |
| TrapToHost: true, |
| }, |
| }, |
| }, |
| 1, |
| "EAPOL", |
| 3000, |
| }, |
| } |
| tests := []struct { |
| name string |
| args args |
| wantErr error |
| }{ |
| {"getFlowIdFromFlowInfo-1", args{}, errors.New("invalid flow-info")}, |
| {"getFlowIdFromFlowInfo-2", args{flowInfo, 1, 1, 1, |
| "HSIA_FLOW", 33, []uint32{1, 2}}, errors.New("invalid flow-info")}, |
| {"getFlowIdFromFlowInfo-2", args{flowInfo, 1, 1, 1, |
| "EAPOL", 33, []uint32{1, 2}}, errors.New("invalid flow-info")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| err := getFlowIDFromFlowInfo(tt.args.FlowInfo, tt.args.flowID, tt.args.gemportID, tt.args.flowStoreCookie, tt.args.flowCategory, tt.args.vlanVid, tt.args.vlanPcp...) |
| if reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) && err != nil { |
| t.Errorf("getFlowIDFromFlowInfo() error = %v, wantErr %v", err, tt.wantErr) |
| } |
| if err == nil { |
| t.Log("return'd nil") |
| } |
| }) |
| } |
| } |
| |
| func Test_newKVClient(t *testing.T) { |
| type args struct { |
| storeType string |
| address string |
| timeout time.Duration |
| } |
| var kvClient kvstore.Client |
| tests := []struct { |
| name string |
| args args |
| want kvstore.Client |
| wantErr error |
| }{ |
| {"newKVClient-1", args{"", "3.3.3.3", 1}, kvClient, errors.New("unsupported-kv-store")}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| got, err := newKVClient(tt.args.storeType, tt.args.address, tt.args.timeout) |
| if got != nil && reflect.TypeOf(got) != reflect.TypeOf(tt.want) { |
| t.Errorf("newKVClient() got = %v, want %v", got, tt.want) |
| } |
| if (err != nil) && reflect.TypeOf(err) != reflect.TypeOf(tt.wantErr) { |
| t.Errorf("newKVClient() error = %v, wantErr %v", err, tt.wantErr) |
| return |
| } |
| |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_AddMcastQueueForIntf(t *testing.T) { |
| type args struct { |
| intf uint32 |
| gem uint32 |
| servicePriority uint32 |
| } |
| tests := []struct { |
| name string |
| args args |
| fields *fields |
| }{ |
| {"AddMcastQueueForIntf-1", args{0, 4000, 0}, getResMgr()}, |
| {"AddMcastQueueForIntf-2", args{1, 4000, 1}, getResMgr()}, |
| {"AddMcastQueueForIntf-3", args{2, 4000, 2}, getResMgr()}, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| err := RsrcMgr.AddMcastQueueForIntf(ctx, tt.args.intf, tt.args.gem, tt.args.servicePriority) |
| if err != nil { |
| t.Errorf("%s got err= %s wants nil", tt.name, err) |
| return |
| } |
| }) |
| } |
| } |
| |
| func newGroup(groupID uint32, outPorts []uint32) *ofp.OfpGroupEntry { |
| groupDesc := ofp.OfpGroupDesc{ |
| Type: ofp.OfpGroupType_OFPGT_ALL, |
| GroupId: groupID, |
| } |
| groupEntry := ofp.OfpGroupEntry{ |
| Desc: &groupDesc, |
| } |
| for i := 0; i < len(outPorts); i++ { |
| var acts []*ofp.OfpAction |
| acts = append(acts, fu.Output(outPorts[i])) |
| bucket := ofp.OfpBucket{ |
| Actions: acts, |
| } |
| groupDesc.Buckets = append(groupDesc.Buckets, &bucket) |
| } |
| return &groupEntry |
| } |
| |
| func TestOpenOltResourceMgr_AddFlowGroupToKVStore(t *testing.T) { |
| type args struct { |
| group *ofp.OfpGroupEntry |
| cached bool |
| } |
| //create group 1 |
| group1 := newGroup(1, []uint32{1}) |
| //create group 2 |
| group2 := newGroup(2, []uint32{2}) |
| //define test set |
| tests := []struct { |
| name string |
| args args |
| fields *fields |
| }{ |
| {"AddFlowGroupToKVStore-1", args{group1, true}, getResMgr()}, |
| {"AddFlowGroupToKVStore-2", args{group2, false}, getResMgr()}, |
| } |
| //execute tests |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| err := RsrcMgr.AddFlowGroupToKVStore(ctx, tt.args.group, tt.args.cached) |
| if err != nil { |
| t.Errorf("%s got err= %s wants nil", tt.name, err) |
| return |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_RemoveFlowGroupFromKVStore(t *testing.T) { |
| type args struct { |
| groupID uint32 |
| cached bool |
| } |
| //define test set |
| tests := []struct { |
| name string |
| args args |
| fields *fields |
| }{ |
| {"RemoveFlowGroupFromKVStore-1", args{1, true}, getResMgr()}, |
| {"RemoveFlowGroupFromKVStore-2", args{2, false}, getResMgr()}, |
| } |
| //execute tests |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| success := RsrcMgr.RemoveFlowGroupFromKVStore(ctx, tt.args.groupID, tt.args.cached) |
| if !success { |
| t.Errorf("%s got false but wants true", tt.name) |
| return |
| } |
| }) |
| } |
| } |
| |
| func TestOpenOltResourceMgr_GetFlowGroupFromKVStore(t *testing.T) { |
| type args struct { |
| groupID uint32 |
| cached bool |
| } |
| //define test set |
| tests := []struct { |
| name string |
| args args |
| fields *fields |
| }{ |
| {"GetFlowGroupFromKVStore-1", args{1, true}, getResMgr()}, |
| {"GetFlowGroupFromKVStore-2", args{2, false}, getResMgr()}, |
| {"GetFlowGroupFromKVStore-3", args{1000, false}, getResMgr()}, |
| } |
| //execute tests |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| RsrcMgr := testResMgrObject(tt.fields) |
| ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) |
| defer cancel() |
| exists, groupInfo, err := RsrcMgr.GetFlowGroupFromKVStore(ctx, tt.args.groupID, tt.args.cached) |
| if err != nil { |
| t.Errorf("%s got error but wants nil error", tt.name) |
| return |
| } else if exists && (groupInfo.GroupID == 0) { |
| t.Errorf("%s got true and nil group info but expected not nil group info", tt.name) |
| return |
| } else if tt.args.groupID == 3 && exists { |
| t.Errorf("%s got true but wants false", tt.name) |
| return |
| } |
| }) |
| } |
| } |