diff --git a/internal/test/mocks/mock_dbintf.go b/internal/test/mocks/mock_dbintf.go
new file mode 100644
index 0000000..75a22ff
--- /dev/null
+++ b/internal/test/mocks/mock_dbintf.go
@@ -0,0 +1,1914 @@
+/*
+* Copyright 2022-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.
+ */
+
+// Code generated by MockGen. DO NOT EDIT.
+// Source: /home/vinod/go/src/gerrit.opencord.org/voltha-go-controller/database/dbintf.go
+
+// Package mock_database is a generated GoMock package.
+package mocks
+
+import (
+	context "context"
+	net "net"
+	reflect "reflect"
+	of "voltha-go-controller/internal/pkg/of"
+
+	gomock "github.com/golang/mock/gomock"
+	kvstore "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
+)
+
+// MockDBIntf is a mock of DBIntf interface.
+type MockDBIntf struct {
+	ctrl     *gomock.Controller
+	recorder *MockDBIntfMockRecorder
+}
+
+// MockDBIntfMockRecorder is the mock recorder for MockDBIntf.
+type MockDBIntfMockRecorder struct {
+	mock *MockDBIntf
+}
+
+// NewMockDBIntf creates a new mock instance.
+func NewMockDBIntf(ctrl *gomock.Controller) *MockDBIntf {
+	mock := &MockDBIntf{ctrl: ctrl}
+	mock.recorder = &MockDBIntfMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockDBIntf) EXPECT() *MockDBIntfMockRecorder {
+	return m.recorder
+}
+
+// Del mocks base method.
+func (m *MockDBIntf) Del(ctx context.Context, path string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Del", ctx, path)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Del indicates an expected call of Del.
+func (mr *MockDBIntfMockRecorder) Del(ctx, path interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Del", reflect.TypeOf((*MockDBIntf)(nil).Del), ctx, path)
+}
+
+// DelAllGroup mocks base method.
+func (m *MockDBIntf) DelAllGroup(ctx context.Context, deviceID string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllGroup", ctx, deviceID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllGroup indicates an expected call of DelAllGroup.
+func (mr *MockDBIntfMockRecorder) DelAllGroup(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllGroup", reflect.TypeOf((*MockDBIntf)(nil).DelAllGroup), ctx, deviceID)
+}
+
+// DelAllIgmpRcvr mocks base method.
+func (m *MockDBIntf) DelAllIgmpRcvr(ctx context.Context, mvlan of.VlanType, gip net.IP, device string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllIgmpRcvr", ctx, mvlan, gip, device)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllIgmpRcvr indicates an expected call of DelAllIgmpRcvr.
+func (mr *MockDBIntfMockRecorder) DelAllIgmpRcvr(ctx, mvlan, gip, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllIgmpRcvr", reflect.TypeOf((*MockDBIntf)(nil).DelAllIgmpRcvr), ctx, mvlan, gip, device)
+}
+
+// DelAllMeter mocks base method.
+func (m *MockDBIntf) DelAllMeter(ctx context.Context, device string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllMeter", ctx, device)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllMeter indicates an expected call of DelAllMeter.
+func (mr *MockDBIntfMockRecorder) DelAllMeter(ctx, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllMeter", reflect.TypeOf((*MockDBIntf)(nil).DelAllMeter), ctx, device)
+}
+
+// DelAllMigrateServicesReq mocks base method.
+func (m *MockDBIntf) DelAllMigrateServicesReq(ctx context.Context, deviceID string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllMigrateServicesReq", ctx, deviceID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllMigrateServicesReq indicates an expected call of DelAllMigrateServicesReq.
+func (mr *MockDBIntfMockRecorder) DelAllMigrateServicesReq(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllMigrateServicesReq", reflect.TypeOf((*MockDBIntf)(nil).DelAllMigrateServicesReq), ctx, deviceID)
+}
+
+// DelAllPONCounters mocks base method.
+func (m *MockDBIntf) DelAllPONCounters(ctx context.Context, device string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllPONCounters", ctx, device)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllPONCounters indicates an expected call of DelAllPONCounters.
+func (mr *MockDBIntfMockRecorder) DelAllPONCounters(ctx, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllPONCounters", reflect.TypeOf((*MockDBIntf)(nil).DelAllPONCounters), ctx, device)
+}
+
+// DelAllPorts mocks base method.
+func (m *MockDBIntf) DelAllPorts(ctx context.Context, deviceID string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllPorts", ctx, deviceID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllPorts indicates an expected call of DelAllPorts.
+func (mr *MockDBIntfMockRecorder) DelAllPorts(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllPorts", reflect.TypeOf((*MockDBIntf)(nil).DelAllPorts), ctx, deviceID)
+}
+
+// DelAllRoutesForDevice mocks base method.
+func (m *MockDBIntf) DelAllRoutesForDevice(ctx context.Context, device string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllRoutesForDevice", ctx, device)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllRoutesForDevice indicates an expected call of DelAllRoutesForDevice.
+func (mr *MockDBIntfMockRecorder) DelAllRoutesForDevice(ctx, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllRoutesForDevice", reflect.TypeOf((*MockDBIntf)(nil).DelAllRoutesForDevice), ctx, device)
+}
+
+// DelAllServiceChannelCounter mocks base method.
+func (m *MockDBIntf) DelAllServiceChannelCounter(ctx context.Context, serviceName string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelAllServiceChannelCounter", ctx, serviceName)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelAllServiceChannelCounter indicates an expected call of DelAllServiceChannelCounter.
+func (mr *MockDBIntfMockRecorder) DelAllServiceChannelCounter(ctx, serviceName interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelAllServiceChannelCounter", reflect.TypeOf((*MockDBIntf)(nil).DelAllServiceChannelCounter), ctx, serviceName)
+}
+
+// DelDeviceMeter mocks base method.
+func (m *MockDBIntf) DelDeviceMeter(ctx context.Context, deviceID string, meterID uint32) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelDeviceMeter", ctx, deviceID, meterID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelDeviceMeter indicates an expected call of DelDeviceMeter.
+func (mr *MockDBIntfMockRecorder) DelDeviceMeter(ctx, deviceID, meterID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelDeviceMeter", reflect.TypeOf((*MockDBIntf)(nil).DelDeviceMeter), ctx, deviceID, meterID)
+}
+
+// DelFlow mocks base method.
+func (m *MockDBIntf) DelFlow(ctx context.Context, deviceID string, flowID uint64) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelFlow", ctx, deviceID, flowID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelFlow indicates an expected call of DelFlow.
+func (mr *MockDBIntfMockRecorder) DelFlow(ctx, deviceID, flowID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelFlow", reflect.TypeOf((*MockDBIntf)(nil).DelFlow), ctx, deviceID, flowID)
+}
+
+// DelGroup mocks base method.
+func (m *MockDBIntf) DelGroup(ctx context.Context, deviceID string, groupID uint32) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelGroup", ctx, deviceID, groupID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelGroup indicates an expected call of DelGroup.
+func (mr *MockDBIntfMockRecorder) DelGroup(ctx, deviceID, groupID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelGroup", reflect.TypeOf((*MockDBIntf)(nil).DelGroup), ctx, deviceID, groupID)
+}
+
+// DelHealth mocks base method.
+func (m *MockDBIntf) DelHealth(ctx context.Context) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelHealth", ctx)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelHealth indicates an expected call of DelHealth.
+func (mr *MockDBIntfMockRecorder) DelHealth(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelHealth", reflect.TypeOf((*MockDBIntf)(nil).DelHealth), ctx)
+}
+
+// DelIGMPCfg mocks base method.
+func (m *MockDBIntf) DelIGMPCfg(ctx context.Context) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelIGMPCfg", ctx)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelIGMPCfg indicates an expected call of DelIGMPCfg.
+func (mr *MockDBIntfMockRecorder) DelIGMPCfg(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelIGMPCfg", reflect.TypeOf((*MockDBIntf)(nil).DelIGMPCfg), ctx)
+}
+
+// DelIgmpChannel mocks base method.
+func (m *MockDBIntf) DelIgmpChannel(ctx context.Context, mvlan of.VlanType, gName, device string, gip net.IP) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelIgmpChannel", ctx, mvlan, gName, device, gip)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelIgmpChannel indicates an expected call of DelIgmpChannel.
+func (mr *MockDBIntfMockRecorder) DelIgmpChannel(ctx, mvlan, gName, device, gip interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelIgmpChannel", reflect.TypeOf((*MockDBIntf)(nil).DelIgmpChannel), ctx, mvlan, gName, device, gip)
+}
+
+// DelIgmpDevice mocks base method.
+func (m *MockDBIntf) DelIgmpDevice(ctx context.Context, mvlan of.VlanType, gid string, gip net.IP, device string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelIgmpDevice", ctx, mvlan, gid, gip, device)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelIgmpDevice indicates an expected call of DelIgmpDevice.
+func (mr *MockDBIntfMockRecorder) DelIgmpDevice(ctx, mvlan, gid, gip, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelIgmpDevice", reflect.TypeOf((*MockDBIntf)(nil).DelIgmpDevice), ctx, mvlan, gid, gip, device)
+}
+
+// DelIgmpGroup mocks base method.
+func (m *MockDBIntf) DelIgmpGroup(ctx context.Context, id string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelIgmpGroup", ctx, id)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelIgmpGroup indicates an expected call of DelIgmpGroup.
+func (mr *MockDBIntfMockRecorder) DelIgmpGroup(ctx, id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelIgmpGroup", reflect.TypeOf((*MockDBIntf)(nil).DelIgmpGroup), ctx, id)
+}
+
+// DelIgmpProfile mocks base method.
+func (m *MockDBIntf) DelIgmpProfile(ctx context.Context, name string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelIgmpProfile", ctx, name)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelIgmpProfile indicates an expected call of DelIgmpProfile.
+func (mr *MockDBIntfMockRecorder) DelIgmpProfile(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelIgmpProfile", reflect.TypeOf((*MockDBIntf)(nil).DelIgmpProfile), ctx, name)
+}
+
+// DelIgmpRcvr mocks base method.
+func (m *MockDBIntf) DelIgmpRcvr(ctx context.Context, mvlan of.VlanType, gip net.IP, device, rcvr string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelIgmpRcvr", ctx, mvlan, gip, device, rcvr)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelIgmpRcvr indicates an expected call of DelIgmpRcvr.
+func (mr *MockDBIntfMockRecorder) DelIgmpRcvr(ctx, mvlan, gip, device, rcvr interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelIgmpRcvr", reflect.TypeOf((*MockDBIntf)(nil).DelIgmpRcvr), ctx, mvlan, gip, device, rcvr)
+}
+
+// DelMcastConfig mocks base method.
+func (m *MockDBIntf) DelMcastConfig(ctx context.Context, name string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelMcastConfig", ctx, name)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelMcastConfig indicates an expected call of DelMcastConfig.
+func (mr *MockDBIntfMockRecorder) DelMcastConfig(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelMcastConfig", reflect.TypeOf((*MockDBIntf)(nil).DelMcastConfig), ctx, name)
+}
+
+// DelMeter mocks base method.
+func (m *MockDBIntf) DelMeter(ctx context.Context, name string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelMeter", ctx, name)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelMeter indicates an expected call of DelMeter.
+func (mr *MockDBIntfMockRecorder) DelMeter(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelMeter", reflect.TypeOf((*MockDBIntf)(nil).DelMeter), ctx, name)
+}
+
+// DelMigrateServicesReq mocks base method.
+func (m *MockDBIntf) DelMigrateServicesReq(ctx context.Context, deviceID, vlan string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelMigrateServicesReq", ctx, deviceID, vlan)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelMigrateServicesReq indicates an expected call of DelMigrateServicesReq.
+func (mr *MockDBIntfMockRecorder) DelMigrateServicesReq(ctx, deviceID, vlan interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelMigrateServicesReq", reflect.TypeOf((*MockDBIntf)(nil).DelMigrateServicesReq), ctx, deviceID, vlan)
+}
+
+// DelMigrationInfo mocks base method.
+func (m *MockDBIntf) DelMigrationInfo(ctx context.Context) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelMigrationInfo", ctx)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelMigrationInfo indicates an expected call of DelMigrationInfo.
+func (mr *MockDBIntfMockRecorder) DelMigrationInfo(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelMigrationInfo", reflect.TypeOf((*MockDBIntf)(nil).DelMigrationInfo), ctx)
+}
+
+// DelMvlan mocks base method.
+func (m *MockDBIntf) DelMvlan(ctx context.Context, mvlan uint16) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelMvlan", ctx, mvlan)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelMvlan indicates an expected call of DelMvlan.
+func (mr *MockDBIntfMockRecorder) DelMvlan(ctx, mvlan interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelMvlan", reflect.TypeOf((*MockDBIntf)(nil).DelMvlan), ctx, mvlan)
+}
+
+// DelNbDevicePort mocks base method.
+func (m *MockDBIntf) DelNbDevicePort(ctx context.Context, device string, ponPortID uint32) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "DelNbDevicePort", ctx, device, ponPortID)
+}
+
+// DelNbDevicePort indicates an expected call of DelNbDevicePort.
+func (mr *MockDBIntfMockRecorder) DelNbDevicePort(ctx, device, ponPortID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelNbDevicePort", reflect.TypeOf((*MockDBIntf)(nil).DelNbDevicePort), ctx, device, ponPortID)
+}
+
+// DelOlt mocks base method.
+func (m *MockDBIntf) DelOlt(ctx context.Context, deviceID string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelOlt", ctx, deviceID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelOlt indicates an expected call of DelOlt.
+func (mr *MockDBIntfMockRecorder) DelOlt(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelOlt", reflect.TypeOf((*MockDBIntf)(nil).DelOlt), ctx, deviceID)
+}
+
+// DelPONCounters mocks base method.
+func (m *MockDBIntf) DelPONCounters(ctx context.Context, device, ponID string) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "DelPONCounters", ctx, device, ponID)
+}
+
+// DelPONCounters indicates an expected call of DelPONCounters.
+func (mr *MockDBIntfMockRecorder) DelPONCounters(ctx, device, ponID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelPONCounters", reflect.TypeOf((*MockDBIntf)(nil).DelPONCounters), ctx, device, ponID)
+}
+
+// DelPonChannelCounter mocks base method.
+func (m *MockDBIntf) DelPonChannelCounter(ctx context.Context, device, ponID, channel string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelPonChannelCounter", ctx, device, ponID, channel)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelPonChannelCounter indicates an expected call of DelPonChannelCounter.
+func (mr *MockDBIntfMockRecorder) DelPonChannelCounter(ctx, device, ponID, channel interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelPonChannelCounter", reflect.TypeOf((*MockDBIntf)(nil).DelPonChannelCounter), ctx, device, ponID, channel)
+}
+
+// DelPonCounter mocks base method.
+func (m *MockDBIntf) DelPonCounter(ctx context.Context, device, ponID string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelPonCounter", ctx, device, ponID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelPonCounter indicates an expected call of DelPonCounter.
+func (mr *MockDBIntfMockRecorder) DelPonCounter(ctx, device, ponID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelPonCounter", reflect.TypeOf((*MockDBIntf)(nil).DelPonCounter), ctx, device, ponID)
+}
+
+// DelPort mocks base method.
+func (m *MockDBIntf) DelPort(ctx context.Context, deviceID string, portID uint32) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelPort", ctx, deviceID, portID)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelPort indicates an expected call of DelPort.
+func (mr *MockDBIntfMockRecorder) DelPort(ctx, deviceID, portID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelPort", reflect.TypeOf((*MockDBIntf)(nil).DelPort), ctx, deviceID, portID)
+}
+
+// DelPortAlarmData mocks base method.
+func (m *MockDBIntf) DelPortAlarmData(ctx context.Context, deviceID string, portID uint32) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "DelPortAlarmData", ctx, deviceID, portID)
+}
+
+// DelPortAlarmData indicates an expected call of DelPortAlarmData.
+func (mr *MockDBIntfMockRecorder) DelPortAlarmData(ctx, deviceID, portID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelPortAlarmData", reflect.TypeOf((*MockDBIntf)(nil).DelPortAlarmData), ctx, deviceID, portID)
+}
+
+// DelPortAlarmProfile mocks base method.
+func (m *MockDBIntf) DelPortAlarmProfile(ctx context.Context, portAlarmProfileID string) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "DelPortAlarmProfile", ctx, portAlarmProfileID)
+}
+
+// DelPortAlarmProfile indicates an expected call of DelPortAlarmProfile.
+func (mr *MockDBIntfMockRecorder) DelPortAlarmProfile(ctx, portAlarmProfileID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelPortAlarmProfile", reflect.TypeOf((*MockDBIntf)(nil).DelPortAlarmProfile), ctx, portAlarmProfileID)
+}
+
+// DelService mocks base method.
+func (m *MockDBIntf) DelService(ctx context.Context, name string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelService", ctx, name)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelService indicates an expected call of DelService.
+func (mr *MockDBIntfMockRecorder) DelService(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelService", reflect.TypeOf((*MockDBIntf)(nil).DelService), ctx, name)
+}
+
+// DelServiceChannelCounter mocks base method.
+func (m *MockDBIntf) DelServiceChannelCounter(ctx context.Context, serviceName, channel string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelServiceChannelCounter", ctx, serviceName, channel)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelServiceChannelCounter indicates an expected call of DelServiceChannelCounter.
+func (mr *MockDBIntfMockRecorder) DelServiceChannelCounter(ctx, serviceName, channel interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelServiceChannelCounter", reflect.TypeOf((*MockDBIntf)(nil).DelServiceChannelCounter), ctx, serviceName, channel)
+}
+
+// DelSubAlarmData mocks base method.
+func (m *MockDBIntf) DelSubAlarmData(ctx context.Context, deviceID, portName string) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "DelSubAlarmData", ctx, deviceID, portName)
+}
+
+// DelSubAlarmData indicates an expected call of DelSubAlarmData.
+func (mr *MockDBIntfMockRecorder) DelSubAlarmData(ctx, deviceID, portName interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelSubAlarmData", reflect.TypeOf((*MockDBIntf)(nil).DelSubAlarmData), ctx, deviceID, portName)
+}
+
+// DelVnet mocks base method.
+func (m *MockDBIntf) DelVnet(ctx context.Context, name string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelVnet", ctx, name)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelVnet indicates an expected call of DelVnet.
+func (mr *MockDBIntfMockRecorder) DelVnet(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelVnet", reflect.TypeOf((*MockDBIntf)(nil).DelVnet), ctx, name)
+}
+
+// DelVpv mocks base method.
+func (m *MockDBIntf) DelVpv(ctx context.Context, port string, SVlan, CVlan, UniVlan uint16) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DelVpv", ctx, port, SVlan, CVlan, UniVlan)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DelVpv indicates an expected call of DelVpv.
+func (mr *MockDBIntfMockRecorder) DelVpv(ctx, port, SVlan, CVlan, UniVlan interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DelVpv", reflect.TypeOf((*MockDBIntf)(nil).DelVpv), ctx, port, SVlan, CVlan, UniVlan)
+}
+
+// DeleteAll mocks base method.
+func (m *MockDBIntf) DeleteAll(ctx context.Context, path string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteAll", ctx, path)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DeleteAll indicates an expected call of DeleteAll.
+func (mr *MockDBIntfMockRecorder) DeleteAll(ctx, path interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAll", reflect.TypeOf((*MockDBIntf)(nil).DeleteAll), ctx, path)
+}
+
+// DeleteAllUnderHashKey mocks base method.
+func (m *MockDBIntf) DeleteAllUnderHashKey(ctx context.Context, hashKeyPrefix string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteAllUnderHashKey", ctx, hashKeyPrefix)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DeleteAllUnderHashKey indicates an expected call of DeleteAllUnderHashKey.
+func (mr *MockDBIntfMockRecorder) DeleteAllUnderHashKey(ctx, hashKeyPrefix interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllUnderHashKey", reflect.TypeOf((*MockDBIntf)(nil).DeleteAllUnderHashKey), ctx, hashKeyPrefix)
+}
+
+// Get mocks base method.
+func (m *MockDBIntf) Get(ctx context.Context, key string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Get", ctx, key)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Get indicates an expected call of Get.
+func (mr *MockDBIntfMockRecorder) Get(ctx, key interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDBIntf)(nil).Get), ctx, key)
+}
+
+// GetAllIgmpChannels mocks base method.
+func (m *MockDBIntf) GetAllIgmpChannels(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllIgmpChannels", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllIgmpChannels indicates an expected call of GetAllIgmpChannels.
+func (mr *MockDBIntfMockRecorder) GetAllIgmpChannels(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllIgmpChannels", reflect.TypeOf((*MockDBIntf)(nil).GetAllIgmpChannels), ctx)
+}
+
+// GetAllIgmpDevices mocks base method.
+func (m *MockDBIntf) GetAllIgmpDevices(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllIgmpDevices", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllIgmpDevices indicates an expected call of GetAllIgmpDevices.
+func (mr *MockDBIntfMockRecorder) GetAllIgmpDevices(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllIgmpDevices", reflect.TypeOf((*MockDBIntf)(nil).GetAllIgmpDevices), ctx)
+}
+
+// GetAllIgmpRcvrs mocks base method.
+func (m *MockDBIntf) GetAllIgmpRcvrs(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllIgmpRcvrs", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllIgmpRcvrs indicates an expected call of GetAllIgmpRcvrs.
+func (mr *MockDBIntfMockRecorder) GetAllIgmpRcvrs(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllIgmpRcvrs", reflect.TypeOf((*MockDBIntf)(nil).GetAllIgmpRcvrs), ctx)
+}
+
+// GetAllMigrateServicesReq mocks base method.
+func (m *MockDBIntf) GetAllMigrateServicesReq(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllMigrateServicesReq", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllMigrateServicesReq indicates an expected call of GetAllMigrateServicesReq.
+func (mr *MockDBIntfMockRecorder) GetAllMigrateServicesReq(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllMigrateServicesReq", reflect.TypeOf((*MockDBIntf)(nil).GetAllMigrateServicesReq), ctx, deviceID)
+}
+
+// GetAllNbPorts mocks base method.
+func (m *MockDBIntf) GetAllNbPorts(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllNbPorts", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllNbPorts indicates an expected call of GetAllNbPorts.
+func (mr *MockDBIntfMockRecorder) GetAllNbPorts(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllNbPorts", reflect.TypeOf((*MockDBIntf)(nil).GetAllNbPorts), ctx, deviceID)
+}
+
+// GetAllPonChannelCounters mocks base method.
+func (m *MockDBIntf) GetAllPonChannelCounters(ctx context.Context, device, ponID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllPonChannelCounters", ctx, device, ponID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllPonChannelCounters indicates an expected call of GetAllPonChannelCounters.
+func (mr *MockDBIntfMockRecorder) GetAllPonChannelCounters(ctx, device, ponID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllPonChannelCounters", reflect.TypeOf((*MockDBIntf)(nil).GetAllPonChannelCounters), ctx, device, ponID)
+}
+
+// GetAllPonCounters mocks base method.
+func (m *MockDBIntf) GetAllPonCounters(ctx context.Context, device string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllPonCounters", ctx, device)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllPonCounters indicates an expected call of GetAllPonCounters.
+func (mr *MockDBIntfMockRecorder) GetAllPonCounters(ctx, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllPonCounters", reflect.TypeOf((*MockDBIntf)(nil).GetAllPonCounters), ctx, device)
+}
+
+// GetAllPortAlarmData mocks base method.
+func (m *MockDBIntf) GetAllPortAlarmData(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllPortAlarmData", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllPortAlarmData indicates an expected call of GetAllPortAlarmData.
+func (mr *MockDBIntfMockRecorder) GetAllPortAlarmData(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllPortAlarmData", reflect.TypeOf((*MockDBIntf)(nil).GetAllPortAlarmData), ctx, deviceID)
+}
+
+// GetAllServiceChannelCounters mocks base method.
+func (m *MockDBIntf) GetAllServiceChannelCounters(ctx context.Context, serviceName string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllServiceChannelCounters", ctx, serviceName)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllServiceChannelCounters indicates an expected call of GetAllServiceChannelCounters.
+func (mr *MockDBIntfMockRecorder) GetAllServiceChannelCounters(ctx, serviceName interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllServiceChannelCounters", reflect.TypeOf((*MockDBIntf)(nil).GetAllServiceChannelCounters), ctx, serviceName)
+}
+
+// GetAllSubAlarmData mocks base method.
+func (m *MockDBIntf) GetAllSubAlarmData(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAllSubAlarmData", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAllSubAlarmData indicates an expected call of GetAllSubAlarmData.
+func (mr *MockDBIntfMockRecorder) GetAllSubAlarmData(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllSubAlarmData", reflect.TypeOf((*MockDBIntf)(nil).GetAllSubAlarmData), ctx, deviceID)
+}
+
+// GetDeviceConfig mocks base method.
+func (m *MockDBIntf) GetDeviceConfig(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDeviceConfig", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDeviceConfig indicates an expected call of GetDeviceConfig.
+func (mr *MockDBIntfMockRecorder) GetDeviceConfig(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceConfig", reflect.TypeOf((*MockDBIntf)(nil).GetDeviceConfig), ctx)
+}
+
+// GetDeviceMeter mocks base method.
+func (m *MockDBIntf) GetDeviceMeter(ctx context.Context, deviceID string, meterID uint32) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDeviceMeter", ctx, deviceID, meterID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDeviceMeter indicates an expected call of GetDeviceMeter.
+func (mr *MockDBIntfMockRecorder) GetDeviceMeter(ctx, deviceID, meterID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceMeter", reflect.TypeOf((*MockDBIntf)(nil).GetDeviceMeter), ctx, deviceID, meterID)
+}
+
+// GetDeviceMeters mocks base method.
+func (m *MockDBIntf) GetDeviceMeters(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDeviceMeters", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDeviceMeters indicates an expected call of GetDeviceMeters.
+func (mr *MockDBIntfMockRecorder) GetDeviceMeters(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceMeters", reflect.TypeOf((*MockDBIntf)(nil).GetDeviceMeters), ctx, deviceID)
+}
+
+// GetFlow mocks base method.
+func (m *MockDBIntf) GetFlow(ctx context.Context, deviceID string, flowID uint64) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetFlow", ctx, deviceID, flowID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetFlow indicates an expected call of GetFlow.
+func (mr *MockDBIntfMockRecorder) GetFlow(ctx, deviceID, flowID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFlow", reflect.TypeOf((*MockDBIntf)(nil).GetFlow), ctx, deviceID, flowID)
+}
+
+// GetFlowHash mocks base method.
+func (m *MockDBIntf) GetFlowHash(ctx context.Context, deviceID string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetFlowHash", ctx, deviceID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetFlowHash indicates an expected call of GetFlowHash.
+func (mr *MockDBIntfMockRecorder) GetFlowHash(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFlowHash", reflect.TypeOf((*MockDBIntf)(nil).GetFlowHash), ctx, deviceID)
+}
+
+// GetFlows mocks base method.
+func (m *MockDBIntf) GetFlows(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetFlows", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetFlows indicates an expected call of GetFlows.
+func (mr *MockDBIntfMockRecorder) GetFlows(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFlows", reflect.TypeOf((*MockDBIntf)(nil).GetFlows), ctx, deviceID)
+}
+
+// GetGroup mocks base method.
+func (m *MockDBIntf) GetGroup(ctx context.Context, deviceID string, groupID uint32) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetGroup", ctx, deviceID, groupID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetGroup indicates an expected call of GetGroup.
+func (mr *MockDBIntfMockRecorder) GetGroup(ctx, deviceID, groupID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroup", reflect.TypeOf((*MockDBIntf)(nil).GetGroup), ctx, deviceID, groupID)
+}
+
+// GetGroups mocks base method.
+func (m *MockDBIntf) GetGroups(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetGroups", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetGroups indicates an expected call of GetGroups.
+func (mr *MockDBIntfMockRecorder) GetGroups(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetGroups", reflect.TypeOf((*MockDBIntf)(nil).GetGroups), ctx, deviceID)
+}
+
+// GetHealth mocks base method.
+func (m *MockDBIntf) GetHealth(ctx context.Context) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetHealth", ctx)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetHealth indicates an expected call of GetHealth.
+func (mr *MockDBIntfMockRecorder) GetHealth(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealth", reflect.TypeOf((*MockDBIntf)(nil).GetHealth), ctx)
+}
+
+// GetIgmpChannel mocks base method.
+func (m *MockDBIntf) GetIgmpChannel(ctx context.Context, mvlan of.VlanType, gName, device string, gip net.IP) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpChannel", ctx, mvlan, gName, device, gip)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpChannel indicates an expected call of GetIgmpChannel.
+func (mr *MockDBIntfMockRecorder) GetIgmpChannel(ctx, mvlan, gName, device, gip interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpChannel", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpChannel), ctx, mvlan, gName, device, gip)
+}
+
+// GetIgmpChannels mocks base method.
+func (m *MockDBIntf) GetIgmpChannels(ctx context.Context, mvlan of.VlanType, gname, device string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpChannels", ctx, mvlan, gname, device)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpChannels indicates an expected call of GetIgmpChannels.
+func (mr *MockDBIntfMockRecorder) GetIgmpChannels(ctx, mvlan, gname, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpChannels", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpChannels), ctx, mvlan, gname, device)
+}
+
+// GetIgmpDevice mocks base method.
+func (m *MockDBIntf) GetIgmpDevice(ctx context.Context, mvlan of.VlanType, gid string, gip net.IP, device string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpDevice", ctx, mvlan, gid, gip, device)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpDevice indicates an expected call of GetIgmpDevice.
+func (mr *MockDBIntfMockRecorder) GetIgmpDevice(ctx, mvlan, gid, gip, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpDevice", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpDevice), ctx, mvlan, gid, gip, device)
+}
+
+// GetIgmpDevices mocks base method.
+func (m *MockDBIntf) GetIgmpDevices(ctx context.Context, mvlan of.VlanType, gid string, gip net.IP) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpDevices", ctx, mvlan, gid, gip)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpDevices indicates an expected call of GetIgmpDevices.
+func (mr *MockDBIntfMockRecorder) GetIgmpDevices(ctx, mvlan, gid, gip interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpDevices", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpDevices), ctx, mvlan, gid, gip)
+}
+
+// GetIgmpGroup mocks base method.
+func (m *MockDBIntf) GetIgmpGroup(ctx context.Context, id string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpGroup", ctx, id)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpGroup indicates an expected call of GetIgmpGroup.
+func (mr *MockDBIntfMockRecorder) GetIgmpGroup(ctx, id interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpGroup", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpGroup), ctx, id)
+}
+
+// GetIgmpGroups mocks base method.
+func (m *MockDBIntf) GetIgmpGroups(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpGroups", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpGroups indicates an expected call of GetIgmpGroups.
+func (mr *MockDBIntfMockRecorder) GetIgmpGroups(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpGroups", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpGroups), ctx)
+}
+
+// GetIgmpProfile mocks base method.
+func (m *MockDBIntf) GetIgmpProfile(ctx context.Context, name string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpProfile", ctx, name)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpProfile indicates an expected call of GetIgmpProfile.
+func (mr *MockDBIntfMockRecorder) GetIgmpProfile(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpProfile", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpProfile), ctx, name)
+}
+
+// GetIgmpProfiles mocks base method.
+func (m *MockDBIntf) GetIgmpProfiles(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpProfiles", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpProfiles indicates an expected call of GetIgmpProfiles.
+func (mr *MockDBIntfMockRecorder) GetIgmpProfiles(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpProfiles", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpProfiles), ctx)
+}
+
+// GetIgmpRcvr mocks base method.
+func (m *MockDBIntf) GetIgmpRcvr(ctx context.Context, mvlan of.VlanType, gip net.IP, device, rcvr string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpRcvr", ctx, mvlan, gip, device, rcvr)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpRcvr indicates an expected call of GetIgmpRcvr.
+func (mr *MockDBIntfMockRecorder) GetIgmpRcvr(ctx, mvlan, gip, device, rcvr interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpRcvr", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpRcvr), ctx, mvlan, gip, device, rcvr)
+}
+
+// GetIgmpRcvrs mocks base method.
+func (m *MockDBIntf) GetIgmpRcvrs(ctx context.Context, mvlan of.VlanType, gip net.IP, device string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetIgmpRcvrs", ctx, mvlan, gip, device)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetIgmpRcvrs indicates an expected call of GetIgmpRcvrs.
+func (mr *MockDBIntfMockRecorder) GetIgmpRcvrs(ctx, mvlan, gip, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetIgmpRcvrs", reflect.TypeOf((*MockDBIntf)(nil).GetIgmpRcvrs), ctx, mvlan, gip, device)
+}
+
+// GetMcastConfig mocks base method.
+func (m *MockDBIntf) GetMcastConfig(ctx context.Context, name string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMcastConfig", ctx, name)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMcastConfig indicates an expected call of GetMcastConfig.
+func (mr *MockDBIntfMockRecorder) GetMcastConfig(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMcastConfig", reflect.TypeOf((*MockDBIntf)(nil).GetMcastConfig), ctx, name)
+}
+
+// GetMcastConfigs mocks base method.
+func (m *MockDBIntf) GetMcastConfigs(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMcastConfigs", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMcastConfigs indicates an expected call of GetMcastConfigs.
+func (mr *MockDBIntfMockRecorder) GetMcastConfigs(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMcastConfigs", reflect.TypeOf((*MockDBIntf)(nil).GetMcastConfigs), ctx)
+}
+
+// GetMeter mocks base method.
+func (m *MockDBIntf) GetMeter(ctx context.Context, name string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMeter", ctx, name)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMeter indicates an expected call of GetMeter.
+func (mr *MockDBIntfMockRecorder) GetMeter(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMeter", reflect.TypeOf((*MockDBIntf)(nil).GetMeter), ctx, name)
+}
+
+// GetMeters mocks base method.
+func (m *MockDBIntf) GetMeters(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMeters", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMeters indicates an expected call of GetMeters.
+func (mr *MockDBIntfMockRecorder) GetMeters(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMeters", reflect.TypeOf((*MockDBIntf)(nil).GetMeters), ctx)
+}
+
+// GetMigrateServicesReq mocks base method.
+func (m *MockDBIntf) GetMigrateServicesReq(ctx context.Context, deviceID, vlan string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMigrateServicesReq", ctx, deviceID, vlan)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMigrateServicesReq indicates an expected call of GetMigrateServicesReq.
+func (mr *MockDBIntfMockRecorder) GetMigrateServicesReq(ctx, deviceID, vlan interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMigrateServicesReq", reflect.TypeOf((*MockDBIntf)(nil).GetMigrateServicesReq), ctx, deviceID, vlan)
+}
+
+// GetMigrationInfo mocks base method.
+func (m *MockDBIntf) GetMigrationInfo(ctx context.Context) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMigrationInfo", ctx)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMigrationInfo indicates an expected call of GetMigrationInfo.
+func (mr *MockDBIntfMockRecorder) GetMigrationInfo(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMigrationInfo", reflect.TypeOf((*MockDBIntf)(nil).GetMigrationInfo), ctx)
+}
+
+// GetMvlan mocks base method.
+func (m *MockDBIntf) GetMvlan(ctx context.Context, mvlan uint16) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMvlan", ctx, mvlan)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMvlan indicates an expected call of GetMvlan.
+func (mr *MockDBIntfMockRecorder) GetMvlan(ctx, mvlan interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMvlan", reflect.TypeOf((*MockDBIntf)(nil).GetMvlan), ctx, mvlan)
+}
+
+// GetMvlans mocks base method.
+func (m *MockDBIntf) GetMvlans(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMvlans", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMvlans indicates an expected call of GetMvlans.
+func (mr *MockDBIntfMockRecorder) GetMvlans(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMvlans", reflect.TypeOf((*MockDBIntf)(nil).GetMvlans), ctx)
+}
+
+// GetOlt mocks base method.
+func (m *MockDBIntf) GetOlt(ctx context.Context, deviceID string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOlt", ctx, deviceID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOlt indicates an expected call of GetOlt.
+func (mr *MockDBIntfMockRecorder) GetOlt(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOlt", reflect.TypeOf((*MockDBIntf)(nil).GetOlt), ctx, deviceID)
+}
+
+// GetOltFlowService mocks base method.
+func (m *MockDBIntf) GetOltFlowService(ctx context.Context) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOltFlowService", ctx)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOltFlowService indicates an expected call of GetOltFlowService.
+func (mr *MockDBIntfMockRecorder) GetOltFlowService(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOltFlowService", reflect.TypeOf((*MockDBIntf)(nil).GetOltFlowService), ctx)
+}
+
+// GetOltIgmpCounter mocks base method.
+func (m *MockDBIntf) GetOltIgmpCounter(ctx context.Context, device string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOltIgmpCounter", ctx, device)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOltIgmpCounter indicates an expected call of GetOltIgmpCounter.
+func (mr *MockDBIntfMockRecorder) GetOltIgmpCounter(ctx, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOltIgmpCounter", reflect.TypeOf((*MockDBIntf)(nil).GetOltIgmpCounter), ctx, device)
+}
+
+// GetPonChannelCounter mocks base method.
+func (m *MockDBIntf) GetPonChannelCounter(ctx context.Context, device, ponID, channel string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPonChannelCounter", ctx, device, ponID, channel)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPonChannelCounter indicates an expected call of GetPonChannelCounter.
+func (mr *MockDBIntfMockRecorder) GetPonChannelCounter(ctx, device, ponID, channel interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPonChannelCounter", reflect.TypeOf((*MockDBIntf)(nil).GetPonChannelCounter), ctx, device, ponID, channel)
+}
+
+// GetPonCounter mocks base method.
+func (m *MockDBIntf) GetPonCounter(ctx context.Context, device, ponID string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPonCounter", ctx, device, ponID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPonCounter indicates an expected call of GetPonCounter.
+func (mr *MockDBIntfMockRecorder) GetPonCounter(ctx, device, ponID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPonCounter", reflect.TypeOf((*MockDBIntf)(nil).GetPonCounter), ctx, device, ponID)
+}
+
+// GetPort mocks base method.
+func (m *MockDBIntf) GetPort(ctx context.Context, deviceID string, portID uint32) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPort", ctx, deviceID, portID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPort indicates an expected call of GetPort.
+func (mr *MockDBIntfMockRecorder) GetPort(ctx, deviceID, portID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPort", reflect.TypeOf((*MockDBIntf)(nil).GetPort), ctx, deviceID, portID)
+}
+
+// GetPortAlarmData mocks base method.
+func (m *MockDBIntf) GetPortAlarmData(ctx context.Context, deviceID string, portID uint32) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPortAlarmData", ctx, deviceID, portID)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPortAlarmData indicates an expected call of GetPortAlarmData.
+func (mr *MockDBIntfMockRecorder) GetPortAlarmData(ctx, deviceID, portID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPortAlarmData", reflect.TypeOf((*MockDBIntf)(nil).GetPortAlarmData), ctx, deviceID, portID)
+}
+
+// GetPortAlarmProfile mocks base method.
+func (m *MockDBIntf) GetPortAlarmProfile(ctx context.Context, portAlarmProfileID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPortAlarmProfile", ctx, portAlarmProfileID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPortAlarmProfile indicates an expected call of GetPortAlarmProfile.
+func (mr *MockDBIntfMockRecorder) GetPortAlarmProfile(ctx, portAlarmProfileID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPortAlarmProfile", reflect.TypeOf((*MockDBIntf)(nil).GetPortAlarmProfile), ctx, portAlarmProfileID)
+}
+
+// GetPorts mocks base method.
+func (m *MockDBIntf) GetPorts(ctx context.Context, deviceID string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPorts", ctx, deviceID)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPorts indicates an expected call of GetPorts.
+func (mr *MockDBIntfMockRecorder) GetPorts(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPorts", reflect.TypeOf((*MockDBIntf)(nil).GetPorts), ctx, deviceID)
+}
+
+// GetPrevIgmpChannels mocks base method.
+func (m *MockDBIntf) GetPrevIgmpChannels(ctx context.Context, gname, device string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPrevIgmpChannels", ctx, gname, device)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPrevIgmpChannels indicates an expected call of GetPrevIgmpChannels.
+func (mr *MockDBIntfMockRecorder) GetPrevIgmpChannels(ctx, gname, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrevIgmpChannels", reflect.TypeOf((*MockDBIntf)(nil).GetPrevIgmpChannels), ctx, gname, device)
+}
+
+// GetPrevIgmpDevices mocks base method.
+func (m *MockDBIntf) GetPrevIgmpDevices(ctx context.Context, mvlan of.VlanType, gid string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPrevIgmpDevices", ctx, mvlan, gid)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPrevIgmpDevices indicates an expected call of GetPrevIgmpDevices.
+func (mr *MockDBIntfMockRecorder) GetPrevIgmpDevices(ctx, mvlan, gid interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrevIgmpDevices", reflect.TypeOf((*MockDBIntf)(nil).GetPrevIgmpDevices), ctx, mvlan, gid)
+}
+
+// GetPrevIgmpRcvrs mocks base method.
+func (m *MockDBIntf) GetPrevIgmpRcvrs(ctx context.Context, gip net.IP, device string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetPrevIgmpRcvrs", ctx, gip, device)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetPrevIgmpRcvrs indicates an expected call of GetPrevIgmpRcvrs.
+func (mr *MockDBIntfMockRecorder) GetPrevIgmpRcvrs(ctx, gip, device interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPrevIgmpRcvrs", reflect.TypeOf((*MockDBIntf)(nil).GetPrevIgmpRcvrs), ctx, gip, device)
+}
+
+// GetService mocks base method.
+func (m *MockDBIntf) GetService(ctx context.Context, name string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetService", ctx, name)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetService indicates an expected call of GetService.
+func (mr *MockDBIntfMockRecorder) GetService(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetService", reflect.TypeOf((*MockDBIntf)(nil).GetService), ctx, name)
+}
+
+// GetServiceChannelCounter mocks base method.
+func (m *MockDBIntf) GetServiceChannelCounter(ctx context.Context, serviceName, channel string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetServiceChannelCounter", ctx, serviceName, channel)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetServiceChannelCounter indicates an expected call of GetServiceChannelCounter.
+func (mr *MockDBIntfMockRecorder) GetServiceChannelCounter(ctx, serviceName, channel interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetServiceChannelCounter", reflect.TypeOf((*MockDBIntf)(nil).GetServiceChannelCounter), ctx, serviceName, channel)
+}
+
+// GetServices mocks base method.
+func (m *MockDBIntf) GetServices(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetServices", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetServices indicates an expected call of GetServices.
+func (mr *MockDBIntfMockRecorder) GetServices(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetServices", reflect.TypeOf((*MockDBIntf)(nil).GetServices), ctx)
+}
+
+// GetSubAlarmData mocks base method.
+func (m *MockDBIntf) GetSubAlarmData(ctx context.Context, deviceID, portName string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetSubAlarmData", ctx, deviceID, portName)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetSubAlarmData indicates an expected call of GetSubAlarmData.
+func (mr *MockDBIntfMockRecorder) GetSubAlarmData(ctx, deviceID, portName interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSubAlarmData", reflect.TypeOf((*MockDBIntf)(nil).GetSubAlarmData), ctx, deviceID, portName)
+}
+
+// GetVnet mocks base method.
+func (m *MockDBIntf) GetVnet(ctx context.Context, name string) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetVnet", ctx, name)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVnet indicates an expected call of GetVnet.
+func (mr *MockDBIntfMockRecorder) GetVnet(ctx, name interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVnet", reflect.TypeOf((*MockDBIntf)(nil).GetVnet), ctx, name)
+}
+
+// GetVnets mocks base method.
+func (m *MockDBIntf) GetVnets(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetVnets", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVnets indicates an expected call of GetVnets.
+func (mr *MockDBIntfMockRecorder) GetVnets(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVnets", reflect.TypeOf((*MockDBIntf)(nil).GetVnets), ctx)
+}
+
+// GetVpv mocks base method.
+func (m *MockDBIntf) GetVpv(ctx context.Context, port string, SVlan, CVlan, UniVlan uint16) (string, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetVpv", ctx, port, SVlan, CVlan, UniVlan)
+	ret0, _ := ret[0].(string)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVpv indicates an expected call of GetVpv.
+func (mr *MockDBIntfMockRecorder) GetVpv(ctx, port, SVlan, CVlan, UniVlan interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVpv", reflect.TypeOf((*MockDBIntf)(nil).GetVpv), ctx, port, SVlan, CVlan, UniVlan)
+}
+
+// GetVpvs mocks base method.
+func (m *MockDBIntf) GetVpvs(ctx context.Context) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetVpvs", ctx)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVpvs indicates an expected call of GetVpvs.
+func (mr *MockDBIntfMockRecorder) GetVpvs(ctx interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVpvs", reflect.TypeOf((*MockDBIntf)(nil).GetVpvs), ctx)
+}
+
+// List mocks base method.
+func (m *MockDBIntf) List(ctx context.Context, key string) (map[string]*kvstore.KVPair, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "List", ctx, key)
+	ret0, _ := ret[0].(map[string]*kvstore.KVPair)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// List indicates an expected call of List.
+func (mr *MockDBIntfMockRecorder) List(ctx, key interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockDBIntf)(nil).List), ctx, key)
+}
+
+// OltExists mocks base method.
+func (m *MockDBIntf) OltExists(ctx context.Context, deviceID string) bool {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "OltExists", ctx, deviceID)
+	ret0, _ := ret[0].(bool)
+	return ret0
+}
+
+// OltExists indicates an expected call of OltExists.
+func (mr *MockDBIntfMockRecorder) OltExists(ctx, deviceID interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OltExists", reflect.TypeOf((*MockDBIntf)(nil).OltExists), ctx, deviceID)
+}
+
+// Put mocks base method.
+func (m *MockDBIntf) Put(ctx context.Context, fullKeyPath, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Put", ctx, fullKeyPath, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Put indicates an expected call of Put.
+func (mr *MockDBIntfMockRecorder) Put(ctx, fullKeyPath, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockDBIntf)(nil).Put), ctx, fullKeyPath, value)
+}
+
+// PutDeviceConfig mocks base method.
+func (m *MockDBIntf) PutDeviceConfig(ctx context.Context, serialNum, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutDeviceConfig", ctx, serialNum, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutDeviceConfig indicates an expected call of PutDeviceConfig.
+func (mr *MockDBIntfMockRecorder) PutDeviceConfig(ctx, serialNum, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeviceConfig", reflect.TypeOf((*MockDBIntf)(nil).PutDeviceConfig), ctx, serialNum, value)
+}
+
+// PutDeviceMeter mocks base method.
+func (m *MockDBIntf) PutDeviceMeter(ctx context.Context, deviceID string, meterID uint32, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutDeviceMeter", ctx, deviceID, meterID, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutDeviceMeter indicates an expected call of PutDeviceMeter.
+func (mr *MockDBIntfMockRecorder) PutDeviceMeter(ctx, deviceID, meterID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutDeviceMeter", reflect.TypeOf((*MockDBIntf)(nil).PutDeviceMeter), ctx, deviceID, meterID, value)
+}
+
+// PutFlow mocks base method.
+func (m *MockDBIntf) PutFlow(ctx context.Context, deviceID string, flowID uint64, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutFlow", ctx, deviceID, flowID, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutFlow indicates an expected call of PutFlow.
+func (mr *MockDBIntfMockRecorder) PutFlow(ctx, deviceID, flowID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutFlow", reflect.TypeOf((*MockDBIntf)(nil).PutFlow), ctx, deviceID, flowID, value)
+}
+
+// PutFlowHash mocks base method.
+func (m *MockDBIntf) PutFlowHash(ctx context.Context, deviceID, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutFlowHash", ctx, deviceID, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutFlowHash indicates an expected call of PutFlowHash.
+func (mr *MockDBIntfMockRecorder) PutFlowHash(ctx, deviceID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutFlowHash", reflect.TypeOf((*MockDBIntf)(nil).PutFlowHash), ctx, deviceID, value)
+}
+
+// PutGroup mocks base method.
+func (m *MockDBIntf) PutGroup(ctx context.Context, deviceID string, groupID uint32, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutGroup", ctx, deviceID, groupID, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutGroup indicates an expected call of PutGroup.
+func (mr *MockDBIntfMockRecorder) PutGroup(ctx, deviceID, groupID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutGroup", reflect.TypeOf((*MockDBIntf)(nil).PutGroup), ctx, deviceID, groupID, value)
+}
+
+// PutHealth mocks base method.
+func (m *MockDBIntf) PutHealth(ctx context.Context, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutHealth", ctx, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutHealth indicates an expected call of PutHealth.
+func (mr *MockDBIntfMockRecorder) PutHealth(ctx, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutHealth", reflect.TypeOf((*MockDBIntf)(nil).PutHealth), ctx, value)
+}
+
+// PutIgmpChannel mocks base method.
+func (m *MockDBIntf) PutIgmpChannel(ctx context.Context, mvlan of.VlanType, gName, device string, gip net.IP, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutIgmpChannel", ctx, mvlan, gName, device, gip, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutIgmpChannel indicates an expected call of PutIgmpChannel.
+func (mr *MockDBIntfMockRecorder) PutIgmpChannel(ctx, mvlan, gName, device, gip, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutIgmpChannel", reflect.TypeOf((*MockDBIntf)(nil).PutIgmpChannel), ctx, mvlan, gName, device, gip, value)
+}
+
+// PutIgmpDevice mocks base method.
+func (m *MockDBIntf) PutIgmpDevice(ctx context.Context, mvlan of.VlanType, gid string, gip net.IP, device, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutIgmpDevice", ctx, mvlan, gid, gip, device, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutIgmpDevice indicates an expected call of PutIgmpDevice.
+func (mr *MockDBIntfMockRecorder) PutIgmpDevice(ctx, mvlan, gid, gip, device, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutIgmpDevice", reflect.TypeOf((*MockDBIntf)(nil).PutIgmpDevice), ctx, mvlan, gid, gip, device, value)
+}
+
+// PutIgmpGroup mocks base method.
+func (m *MockDBIntf) PutIgmpGroup(ctx context.Context, id, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutIgmpGroup", ctx, id, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutIgmpGroup indicates an expected call of PutIgmpGroup.
+func (mr *MockDBIntfMockRecorder) PutIgmpGroup(ctx, id, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutIgmpGroup", reflect.TypeOf((*MockDBIntf)(nil).PutIgmpGroup), ctx, id, value)
+}
+
+// PutIgmpProfile mocks base method.
+func (m *MockDBIntf) PutIgmpProfile(ctx context.Context, name, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutIgmpProfile", ctx, name, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutIgmpProfile indicates an expected call of PutIgmpProfile.
+func (mr *MockDBIntfMockRecorder) PutIgmpProfile(ctx, name, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutIgmpProfile", reflect.TypeOf((*MockDBIntf)(nil).PutIgmpProfile), ctx, name, value)
+}
+
+// PutIgmpRcvr mocks base method.
+func (m *MockDBIntf) PutIgmpRcvr(ctx context.Context, mvlan of.VlanType, gip net.IP, device, rcvr, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutIgmpRcvr", ctx, mvlan, gip, device, rcvr, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutIgmpRcvr indicates an expected call of PutIgmpRcvr.
+func (mr *MockDBIntfMockRecorder) PutIgmpRcvr(ctx, mvlan, gip, device, rcvr, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutIgmpRcvr", reflect.TypeOf((*MockDBIntf)(nil).PutIgmpRcvr), ctx, mvlan, gip, device, rcvr, value)
+}
+
+// PutMcastConfig mocks base method.
+func (m *MockDBIntf) PutMcastConfig(ctx context.Context, name, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutMcastConfig", ctx, name, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutMcastConfig indicates an expected call of PutMcastConfig.
+func (mr *MockDBIntfMockRecorder) PutMcastConfig(ctx, name, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutMcastConfig", reflect.TypeOf((*MockDBIntf)(nil).PutMcastConfig), ctx, name, value)
+}
+
+// PutMeter mocks base method.
+func (m *MockDBIntf) PutMeter(ctx context.Context, name, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutMeter", ctx, name, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutMeter indicates an expected call of PutMeter.
+func (mr *MockDBIntfMockRecorder) PutMeter(ctx, name, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutMeter", reflect.TypeOf((*MockDBIntf)(nil).PutMeter), ctx, name, value)
+}
+
+// PutMigrateServicesReq mocks base method.
+func (m *MockDBIntf) PutMigrateServicesReq(ctx context.Context, deviceID, vlan, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutMigrateServicesReq", ctx, deviceID, vlan, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutMigrateServicesReq indicates an expected call of PutMigrateServicesReq.
+func (mr *MockDBIntfMockRecorder) PutMigrateServicesReq(ctx, deviceID, vlan, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutMigrateServicesReq", reflect.TypeOf((*MockDBIntf)(nil).PutMigrateServicesReq), ctx, deviceID, vlan, value)
+}
+
+// PutMigrationInfo mocks base method.
+func (m *MockDBIntf) PutMigrationInfo(ctx context.Context, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutMigrationInfo", ctx, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutMigrationInfo indicates an expected call of PutMigrationInfo.
+func (mr *MockDBIntfMockRecorder) PutMigrationInfo(ctx, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutMigrationInfo", reflect.TypeOf((*MockDBIntf)(nil).PutMigrationInfo), ctx, value)
+}
+
+// PutMvlan mocks base method.
+func (m *MockDBIntf) PutMvlan(ctx context.Context, mvlan uint16, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutMvlan", ctx, mvlan, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutMvlan indicates an expected call of PutMvlan.
+func (mr *MockDBIntfMockRecorder) PutMvlan(ctx, mvlan, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutMvlan", reflect.TypeOf((*MockDBIntf)(nil).PutMvlan), ctx, mvlan, value)
+}
+
+// PutNbDevicePort mocks base method.
+func (m *MockDBIntf) PutNbDevicePort(ctx context.Context, device string, ponPortID uint32, value string) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "PutNbDevicePort", ctx, device, ponPortID, value)
+}
+
+// PutNbDevicePort indicates an expected call of PutNbDevicePort.
+func (mr *MockDBIntfMockRecorder) PutNbDevicePort(ctx, device, ponPortID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutNbDevicePort", reflect.TypeOf((*MockDBIntf)(nil).PutNbDevicePort), ctx, device, ponPortID, value)
+}
+
+// PutOlt mocks base method.
+func (m *MockDBIntf) PutOlt(ctx context.Context, deviceID, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutOlt", ctx, deviceID, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutOlt indicates an expected call of PutOlt.
+func (mr *MockDBIntfMockRecorder) PutOlt(ctx, deviceID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutOlt", reflect.TypeOf((*MockDBIntf)(nil).PutOlt), ctx, deviceID, value)
+}
+
+// PutOltFlowService mocks base method.
+func (m *MockDBIntf) PutOltFlowService(ctx context.Context, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutOltFlowService", ctx, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutOltFlowService indicates an expected call of PutOltFlowService.
+func (mr *MockDBIntfMockRecorder) PutOltFlowService(ctx, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutOltFlowService", reflect.TypeOf((*MockDBIntf)(nil).PutOltFlowService), ctx, value)
+}
+
+// PutOltIgmpCounters mocks base method.
+func (m *MockDBIntf) PutOltIgmpCounters(ctx context.Context, device, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutOltIgmpCounters", ctx, device, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutOltIgmpCounters indicates an expected call of PutOltIgmpCounters.
+func (mr *MockDBIntfMockRecorder) PutOltIgmpCounters(ctx, device, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutOltIgmpCounters", reflect.TypeOf((*MockDBIntf)(nil).PutOltIgmpCounters), ctx, device, value)
+}
+
+// PutPonChannelCounter mocks base method.
+func (m *MockDBIntf) PutPonChannelCounter(ctx context.Context, device, ponID, channel, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutPonChannelCounter", ctx, device, ponID, channel, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutPonChannelCounter indicates an expected call of PutPonChannelCounter.
+func (mr *MockDBIntfMockRecorder) PutPonChannelCounter(ctx, device, ponID, channel, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPonChannelCounter", reflect.TypeOf((*MockDBIntf)(nil).PutPonChannelCounter), ctx, device, ponID, channel, value)
+}
+
+// PutPonCounter mocks base method.
+func (m *MockDBIntf) PutPonCounter(ctx context.Context, device, ponID, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutPonCounter", ctx, device, ponID, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutPonCounter indicates an expected call of PutPonCounter.
+func (mr *MockDBIntfMockRecorder) PutPonCounter(ctx, device, ponID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPonCounter", reflect.TypeOf((*MockDBIntf)(nil).PutPonCounter), ctx, device, ponID, value)
+}
+
+// PutPort mocks base method.
+func (m *MockDBIntf) PutPort(ctx context.Context, deviceID string, portID uint32, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutPort", ctx, deviceID, portID, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutPort indicates an expected call of PutPort.
+func (mr *MockDBIntfMockRecorder) PutPort(ctx, deviceID, portID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPort", reflect.TypeOf((*MockDBIntf)(nil).PutPort), ctx, deviceID, portID, value)
+}
+
+// PutPortAlarmData mocks base method.
+func (m *MockDBIntf) PutPortAlarmData(ctx context.Context, deviceID string, portID uint32, value string) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "PutPortAlarmData", ctx, deviceID, portID, value)
+}
+
+// PutPortAlarmData indicates an expected call of PutPortAlarmData.
+func (mr *MockDBIntfMockRecorder) PutPortAlarmData(ctx, deviceID, portID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPortAlarmData", reflect.TypeOf((*MockDBIntf)(nil).PutPortAlarmData), ctx, deviceID, portID, value)
+}
+
+// PutPortAlarmProfile mocks base method.
+func (m *MockDBIntf) PutPortAlarmProfile(ctx context.Context, portAlarmProfileID, value string) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "PutPortAlarmProfile", ctx, portAlarmProfileID, value)
+}
+
+// PutPortAlarmProfile indicates an expected call of PutPortAlarmProfile.
+func (mr *MockDBIntfMockRecorder) PutPortAlarmProfile(ctx, portAlarmProfileID, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutPortAlarmProfile", reflect.TypeOf((*MockDBIntf)(nil).PutPortAlarmProfile), ctx, portAlarmProfileID, value)
+}
+
+// PutService mocks base method.
+func (m *MockDBIntf) PutService(ctx context.Context, name, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutService", ctx, name, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutService indicates an expected call of PutService.
+func (mr *MockDBIntfMockRecorder) PutService(ctx, name, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutService", reflect.TypeOf((*MockDBIntf)(nil).PutService), ctx, name, value)
+}
+
+// PutServiceChannelCounter mocks base method.
+func (m *MockDBIntf) PutServiceChannelCounter(ctx context.Context, serviceName, channel, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutServiceChannelCounter", ctx, serviceName, channel, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutServiceChannelCounter indicates an expected call of PutServiceChannelCounter.
+func (mr *MockDBIntfMockRecorder) PutServiceChannelCounter(ctx, serviceName, channel, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutServiceChannelCounter", reflect.TypeOf((*MockDBIntf)(nil).PutServiceChannelCounter), ctx, serviceName, channel, value)
+}
+
+// PutSubAlarmData mocks base method.
+func (m *MockDBIntf) PutSubAlarmData(ctx context.Context, deviceID, portName, value string) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "PutSubAlarmData", ctx, deviceID, portName, value)
+}
+
+// PutSubAlarmData indicates an expected call of PutSubAlarmData.
+func (mr *MockDBIntfMockRecorder) PutSubAlarmData(ctx, deviceID, portName, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutSubAlarmData", reflect.TypeOf((*MockDBIntf)(nil).PutSubAlarmData), ctx, deviceID, portName, value)
+}
+
+// PutVnet mocks base method.
+func (m *MockDBIntf) PutVnet(ctx context.Context, name, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutVnet", ctx, name, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutVnet indicates an expected call of PutVnet.
+func (mr *MockDBIntfMockRecorder) PutVnet(ctx, name, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutVnet", reflect.TypeOf((*MockDBIntf)(nil).PutVnet), ctx, name, value)
+}
+
+// PutVpv mocks base method.
+func (m *MockDBIntf) PutVpv(ctx context.Context, port string, SVlan, CVlan, UniVlan uint16, value string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "PutVpv", ctx, port, SVlan, CVlan, UniVlan, value)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// PutVpv indicates an expected call of PutVpv.
+func (mr *MockDBIntfMockRecorder) PutVpv(ctx, port, SVlan, CVlan, UniVlan, value interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutVpv", reflect.TypeOf((*MockDBIntf)(nil).PutVpv), ctx, port, SVlan, CVlan, UniVlan, value)
+}
