diff --git a/internal/pkg/resourcemanager/resourcemanager_test.go b/internal/pkg/resourcemanager/resourcemanager_test.go
new file mode 100644
index 0000000..81e0fa4
--- /dev/null
+++ b/internal/pkg/resourcemanager/resourcemanager_test.go
@@ -0,0 +1,1188 @@
+/*
+ * 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_id"
+	FlowIDInfo = "flow_id_info"
+	FlowIDs = "flow_ids"
+	GemportIDs = "gemport_ids"
+	AllocIDs = "alloc_ids"
+	GemportIDPool = "gemport_id_pool"
+	AllocIDPool = "alloc_id_pool"
+	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(ctx, "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(ctx, "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(ctx, "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(ctx, "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(ctx, "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(ctx context.Context, key string, ch chan *kvstore.Event) {
+}
+
+// Close mock function implementation for KVClient
+func (kvclient *MockResKVClient) Close(ctx context.Context) {
+}
+
+// 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(context.Background(), 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(context.Background(), 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(context.Background(), 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
+	}
+	group1 := newGroup(1, []uint32{1})
+	group2 := newGroup(2, []uint32{2})
+	tests := []struct {
+		name   string
+		args   args
+		fields *fields
+	}{
+		{"AddFlowGroupToKVStore-1", args{group1, true}, getResMgr()},
+		{"AddFlowGroupToKVStore-2", args{group2, false}, 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.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
+	}
+	tests := []struct {
+		name   string
+		args   args
+		fields *fields
+	}{
+		{"RemoveFlowGroupFromKVStore-1", args{1, true}, getResMgr()},
+		{"RemoveFlowGroupFromKVStore-2", args{2, false}, 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.RemoveFlowGroupFromKVStore(ctx, tt.args.groupID, tt.args.cached)
+			if err != nil {
+				t.Errorf("%s got false but wants true", tt.name)
+				return
+			}
+		})
+	}
+}
+
+func TestOpenOltResourceMgr_GetFlowGroupFromKVStore(t *testing.T) {
+	type args struct {
+		groupID uint32
+		cached  bool
+	}
+	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()},
+	}
+	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
+			}
+		})
+	}
+}
