diff --git a/internal/test/mocks/mock_voltha.pb.go b/internal/test/mocks/mock_voltha.pb.go
new file mode 100644
index 0000000..03309bd
--- /dev/null
+++ b/internal/test/mocks/mock_voltha.pb.go
@@ -0,0 +1,3058 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: /home/vinod/go/src/gerrit.opencord.org/voltha-go-controller/vendor/github.com/opencord/voltha-protos/v5/go/voltha/voltha.pb.go
+
+// Package mock_voltha is a generated GoMock package.
+package mocks
+
+import (
+	context "context"
+	reflect "reflect"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+
+	gomock "github.com/golang/mock/gomock"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	extension "github.com/opencord/voltha-protos/v5/go/extension"
+	omci "github.com/opencord/voltha-protos/v5/go/omci"
+	openflow_13 "github.com/opencord/voltha-protos/v5/go/openflow_13"
+	grpc "google.golang.org/grpc"
+	metadata "google.golang.org/grpc/metadata"
+)
+
+// MockVolthaServiceClient is a mock of VolthaServiceClient interface.
+type MockVolthaServiceClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaServiceClientMockRecorder
+}
+
+// MockVolthaServiceClientMockRecorder is the mock recorder for MockVolthaServiceClient.
+type MockVolthaServiceClientMockRecorder struct {
+	mock *MockVolthaServiceClient
+}
+
+// NewMockVolthaServiceClient creates a new mock instance.
+func NewMockVolthaServiceClient(ctrl *gomock.Controller) *MockVolthaServiceClient {
+	mock := &MockVolthaServiceClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaServiceClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaServiceClient) EXPECT() *MockVolthaServiceClientMockRecorder {
+	return m.recorder
+}
+
+// AbortImageUpgradeToDevice mocks base method.
+func (m *MockVolthaServiceClient) AbortImageUpgradeToDevice(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "AbortImageUpgradeToDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AbortImageUpgradeToDevice indicates an expected call of AbortImageUpgradeToDevice.
+func (mr *MockVolthaServiceClientMockRecorder) AbortImageUpgradeToDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortImageUpgradeToDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).AbortImageUpgradeToDevice), varargs...)
+}
+
+// ActivateImage mocks base method.
+func (m *MockVolthaServiceClient) ActivateImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ActivateImage", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImage indicates an expected call of ActivateImage.
+func (mr *MockVolthaServiceClientMockRecorder) ActivateImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).ActivateImage), varargs...)
+}
+
+// ActivateImageUpdate mocks base method.
+func (m *MockVolthaServiceClient) ActivateImageUpdate(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ActivateImageUpdate", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
+func (mr *MockVolthaServiceClientMockRecorder) ActivateImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockVolthaServiceClient)(nil).ActivateImageUpdate), varargs...)
+}
+
+// CancelImageDownload mocks base method.
+func (m *MockVolthaServiceClient) CancelImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CancelImageDownload", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CancelImageDownload indicates an expected call of CancelImageDownload.
+func (mr *MockVolthaServiceClientMockRecorder) CancelImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockVolthaServiceClient)(nil).CancelImageDownload), varargs...)
+}
+
+// CommitImage mocks base method.
+func (m *MockVolthaServiceClient) CommitImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CommitImage", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CommitImage indicates an expected call of CommitImage.
+func (mr *MockVolthaServiceClientMockRecorder) CommitImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).CommitImage), varargs...)
+}
+
+// CreateDevice mocks base method.
+func (m *MockVolthaServiceClient) CreateDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CreateDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateDevice indicates an expected call of CreateDevice.
+func (mr *MockVolthaServiceClientMockRecorder) CreateDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).CreateDevice), varargs...)
+}
+
+// CreateEventFilter mocks base method.
+func (m *MockVolthaServiceClient) CreateEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CreateEventFilter", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateEventFilter indicates an expected call of CreateEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) CreateEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).CreateEventFilter), varargs...)
+}
+
+// DeleteDevice mocks base method.
+func (m *MockVolthaServiceClient) DeleteDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteDevice indicates an expected call of DeleteDevice.
+func (mr *MockVolthaServiceClientMockRecorder) DeleteDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteDevice), varargs...)
+}
+
+// DeleteEventFilter mocks base method.
+func (m *MockVolthaServiceClient) DeleteEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteEventFilter", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteEventFilter indicates an expected call of DeleteEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) DeleteEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteEventFilter), varargs...)
+}
+
+// DisableDevice mocks base method.
+func (m *MockVolthaServiceClient) DisableDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisableDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableDevice indicates an expected call of DisableDevice.
+func (mr *MockVolthaServiceClientMockRecorder) DisableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableDevice), varargs...)
+}
+
+// DisableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceClient) DisableLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisableLogicalDevicePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableLogicalDevicePort indicates an expected call of DisableLogicalDevicePort.
+func (mr *MockVolthaServiceClientMockRecorder) DisableLogicalDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableLogicalDevicePort), varargs...)
+}
+
+// DisablePort mocks base method.
+func (m *MockVolthaServiceClient) DisablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisablePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisablePort indicates an expected call of DisablePort.
+func (mr *MockVolthaServiceClientMockRecorder) DisablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisablePort), varargs...)
+}
+
+// DownloadImage mocks base method.
+func (m *MockVolthaServiceClient) DownloadImage(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DownloadImage", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImage indicates an expected call of DownloadImage.
+func (mr *MockVolthaServiceClientMockRecorder) DownloadImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).DownloadImage), varargs...)
+}
+
+// DownloadImageToDevice mocks base method.
+func (m *MockVolthaServiceClient) DownloadImageToDevice(ctx context.Context, in *voltha.DeviceImageDownloadRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DownloadImageToDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImageToDevice indicates an expected call of DownloadImageToDevice.
+func (mr *MockVolthaServiceClientMockRecorder) DownloadImageToDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImageToDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DownloadImageToDevice), varargs...)
+}
+
+// EnableDevice mocks base method.
+func (m *MockVolthaServiceClient) EnableDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "EnableDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableDevice indicates an expected call of EnableDevice.
+func (mr *MockVolthaServiceClientMockRecorder) EnableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableDevice), varargs...)
+}
+
+// EnableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceClient) EnableLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "EnableLogicalDevicePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableLogicalDevicePort indicates an expected call of EnableLogicalDevicePort.
+func (mr *MockVolthaServiceClientMockRecorder) EnableLogicalDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableLogicalDevicePort), varargs...)
+}
+
+// EnablePort mocks base method.
+func (m *MockVolthaServiceClient) EnablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "EnablePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnablePort indicates an expected call of EnablePort.
+func (mr *MockVolthaServiceClientMockRecorder) EnablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnablePort), varargs...)
+}
+
+// ForceDeleteDevice mocks base method.
+func (m *MockVolthaServiceClient) ForceDeleteDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ForceDeleteDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ForceDeleteDevice indicates an expected call of ForceDeleteDevice.
+func (mr *MockVolthaServiceClientMockRecorder) ForceDeleteDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForceDeleteDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).ForceDeleteDevice), varargs...)
+}
+
+// GetAlarmDeviceData mocks base method.
+func (m *MockVolthaServiceClient) GetAlarmDeviceData(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*omci.AlarmDeviceData, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetAlarmDeviceData", varargs...)
+	ret0, _ := ret[0].(*omci.AlarmDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAlarmDeviceData indicates an expected call of GetAlarmDeviceData.
+func (mr *MockVolthaServiceClientMockRecorder) GetAlarmDeviceData(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmDeviceData", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetAlarmDeviceData), varargs...)
+}
+
+// GetCoreInstance mocks base method.
+func (m *MockVolthaServiceClient) GetCoreInstance(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.CoreInstance, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetCoreInstance", varargs...)
+	ret0, _ := ret[0].(*voltha.CoreInstance)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetCoreInstance indicates an expected call of GetCoreInstance.
+func (mr *MockVolthaServiceClientMockRecorder) GetCoreInstance(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreInstance", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetCoreInstance), varargs...)
+}
+
+// GetDevice mocks base method.
+func (m *MockVolthaServiceClient) GetDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevice indicates an expected call of GetDevice.
+func (mr *MockVolthaServiceClientMockRecorder) GetDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetDevice), varargs...)
+}
+
+// GetDeviceType mocks base method.
+func (m *MockVolthaServiceClient) GetDeviceType(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.DeviceType, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetDeviceType", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceType)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDeviceType indicates an expected call of GetDeviceType.
+func (mr *MockVolthaServiceClientMockRecorder) GetDeviceType(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceType", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetDeviceType), varargs...)
+}
+
+// GetEventFilter mocks base method.
+func (m *MockVolthaServiceClient) GetEventFilter(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetEventFilter", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetEventFilter indicates an expected call of GetEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) GetEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetEventFilter), varargs...)
+}
+
+// GetExtValue mocks base method.
+func (m *MockVolthaServiceClient) GetExtValue(ctx context.Context, in *extension.ValueSpecifier, opts ...grpc.CallOption) (*extension.ReturnValues, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetExtValue", varargs...)
+	ret0, _ := ret[0].(*extension.ReturnValues)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetExtValue indicates an expected call of GetExtValue.
+func (mr *MockVolthaServiceClientMockRecorder) GetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetExtValue), varargs...)
+}
+
+// GetImageDownload mocks base method.
+func (m *MockVolthaServiceClient) GetImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImageDownload", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownload indicates an expected call of GetImageDownload.
+func (mr *MockVolthaServiceClientMockRecorder) GetImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownload", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageDownload), varargs...)
+}
+
+// GetImageDownloadStatus mocks base method.
+func (m *MockVolthaServiceClient) GetImageDownloadStatus(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImageDownloadStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
+func (mr *MockVolthaServiceClientMockRecorder) GetImageDownloadStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageDownloadStatus), varargs...)
+}
+
+// GetImageStatus mocks base method.
+func (m *MockVolthaServiceClient) GetImageStatus(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImageStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageStatus indicates an expected call of GetImageStatus.
+func (mr *MockVolthaServiceClientMockRecorder) GetImageStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStatus", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageStatus), varargs...)
+}
+
+// GetImages mocks base method.
+func (m *MockVolthaServiceClient) GetImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Images, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImages", varargs...)
+	ret0, _ := ret[0].(*voltha.Images)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImages indicates an expected call of GetImages.
+func (mr *MockVolthaServiceClientMockRecorder) GetImages(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImages", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImages), varargs...)
+}
+
+// GetLogicalDevice mocks base method.
+func (m *MockVolthaServiceClient) GetLogicalDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.LogicalDevice, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetLogicalDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalDevice)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevice indicates an expected call of GetLogicalDevice.
+func (mr *MockVolthaServiceClientMockRecorder) GetLogicalDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetLogicalDevice), varargs...)
+}
+
+// GetLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceClient) GetLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*voltha.LogicalPort, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetLogicalDevicePort", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalPort)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevicePort indicates an expected call of GetLogicalDevicePort.
+func (mr *MockVolthaServiceClientMockRecorder) GetLogicalDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetLogicalDevicePort), varargs...)
+}
+
+// GetMibDeviceData mocks base method.
+func (m *MockVolthaServiceClient) GetMibDeviceData(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*omci.MibDeviceData, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetMibDeviceData", varargs...)
+	ret0, _ := ret[0].(*omci.MibDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMibDeviceData indicates an expected call of GetMibDeviceData.
+func (mr *MockVolthaServiceClientMockRecorder) GetMibDeviceData(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMibDeviceData", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetMibDeviceData), varargs...)
+}
+
+// GetOnuImages mocks base method.
+func (m *MockVolthaServiceClient) GetOnuImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.OnuImages, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetOnuImages", varargs...)
+	ret0, _ := ret[0].(*voltha.OnuImages)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImages indicates an expected call of GetOnuImages.
+func (mr *MockVolthaServiceClientMockRecorder) GetOnuImages(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetOnuImages), varargs...)
+}
+
+// GetVoltha mocks base method.
+func (m *MockVolthaServiceClient) GetVoltha(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.Voltha, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetVoltha", varargs...)
+	ret0, _ := ret[0].(*voltha.Voltha)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVoltha indicates an expected call of GetVoltha.
+func (mr *MockVolthaServiceClientMockRecorder) GetVoltha(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVoltha", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetVoltha), varargs...)
+}
+
+// ListAdapters mocks base method.
+func (m *MockVolthaServiceClient) ListAdapters(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.Adapters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListAdapters", varargs...)
+	ret0, _ := ret[0].(*voltha.Adapters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListAdapters indicates an expected call of ListAdapters.
+func (mr *MockVolthaServiceClientMockRecorder) ListAdapters(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAdapters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListAdapters), varargs...)
+}
+
+// ListCoreInstances mocks base method.
+func (m *MockVolthaServiceClient) ListCoreInstances(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.CoreInstances, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListCoreInstances", varargs...)
+	ret0, _ := ret[0].(*voltha.CoreInstances)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListCoreInstances indicates an expected call of ListCoreInstances.
+func (mr *MockVolthaServiceClientMockRecorder) ListCoreInstances(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCoreInstances", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListCoreInstances), varargs...)
+}
+
+// ListDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceFlowGroups(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceFlowGroups", varargs...)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlowGroups indicates an expected call of ListDeviceFlowGroups.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceFlowGroups(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceFlowGroups), varargs...)
+}
+
+// ListDeviceFlows mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceFlows(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceFlows", varargs...)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlows indicates an expected call of ListDeviceFlows.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceFlows(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlows", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceFlows), varargs...)
+}
+
+// ListDeviceIds mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceIds(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*common.IDs, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceIds", varargs...)
+	ret0, _ := ret[0].(*common.IDs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceIds indicates an expected call of ListDeviceIds.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceIds(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceIds", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceIds), varargs...)
+}
+
+// ListDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceClient) ListDevicePmConfigs(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.PmConfigs, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDevicePmConfigs", varargs...)
+	ret0, _ := ret[0].(*voltha.PmConfigs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePmConfigs indicates an expected call of ListDevicePmConfigs.
+func (mr *MockVolthaServiceClientMockRecorder) ListDevicePmConfigs(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevicePmConfigs), varargs...)
+}
+
+// ListDevicePorts mocks base method.
+func (m *MockVolthaServiceClient) ListDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDevicePorts", varargs...)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePorts indicates an expected call of ListDevicePorts.
+func (mr *MockVolthaServiceClientMockRecorder) ListDevicePorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevicePorts), varargs...)
+}
+
+// ListDeviceTypes mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceTypes(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.DeviceTypes, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceTypes", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceTypes)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceTypes indicates an expected call of ListDeviceTypes.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceTypes(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceTypes", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceTypes), varargs...)
+}
+
+// ListDevices mocks base method.
+func (m *MockVolthaServiceClient) ListDevices(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.Devices, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDevices", varargs...)
+	ret0, _ := ret[0].(*voltha.Devices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevices indicates an expected call of ListDevices.
+func (mr *MockVolthaServiceClientMockRecorder) ListDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevices), varargs...)
+}
+
+// ListEventFilters mocks base method.
+func (m *MockVolthaServiceClient) ListEventFilters(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListEventFilters", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListEventFilters indicates an expected call of ListEventFilters.
+func (mr *MockVolthaServiceClientMockRecorder) ListEventFilters(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEventFilters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListEventFilters), varargs...)
+}
+
+// ListImageDownloads mocks base method.
+func (m *MockVolthaServiceClient) ListImageDownloads(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.ImageDownloads, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListImageDownloads", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownloads)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListImageDownloads indicates an expected call of ListImageDownloads.
+func (mr *MockVolthaServiceClientMockRecorder) ListImageDownloads(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImageDownloads", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListImageDownloads), varargs...)
+}
+
+// ListLogicalDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDeviceFlowGroups(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlowGroups", varargs...)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlowGroups indicates an expected call of ListLogicalDeviceFlowGroups.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceFlowGroups(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceFlowGroups), varargs...)
+}
+
+// ListLogicalDeviceFlows mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDeviceFlows(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlows", varargs...)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlows indicates an expected call of ListLogicalDeviceFlows.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceFlows(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlows", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceFlows), varargs...)
+}
+
+// ListLogicalDeviceMeters mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDeviceMeters(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Meters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDeviceMeters", varargs...)
+	ret0, _ := ret[0].(*openflow_13.Meters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceMeters indicates an expected call of ListLogicalDeviceMeters.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceMeters(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceMeters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceMeters), varargs...)
+}
+
+// ListLogicalDevicePorts mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.LogicalPorts, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDevicePorts", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalPorts)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevicePorts indicates an expected call of ListLogicalDevicePorts.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDevicePorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevicePorts", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDevicePorts), varargs...)
+}
+
+// ListLogicalDevices mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDevices(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.LogicalDevices, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDevices", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalDevices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevices indicates an expected call of ListLogicalDevices.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDevices), varargs...)
+}
+
+// RebootDevice mocks base method.
+func (m *MockVolthaServiceClient) RebootDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "RebootDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RebootDevice indicates an expected call of RebootDevice.
+func (mr *MockVolthaServiceClientMockRecorder) RebootDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).RebootDevice), varargs...)
+}
+
+// ReceiveChangeEvents mocks base method.
+func (m *MockVolthaServiceClient) ReceiveChangeEvents(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (voltha.VolthaService_ReceiveChangeEventsClient, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReceiveChangeEvents", varargs...)
+	ret0, _ := ret[0].(voltha.VolthaService_ReceiveChangeEventsClient)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReceiveChangeEvents indicates an expected call of ReceiveChangeEvents.
+func (mr *MockVolthaServiceClientMockRecorder) ReceiveChangeEvents(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveChangeEvents", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReceiveChangeEvents), varargs...)
+}
+
+// ReceivePacketsIn mocks base method.
+func (m *MockVolthaServiceClient) ReceivePacketsIn(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (voltha.VolthaService_ReceivePacketsInClient, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReceivePacketsIn", varargs...)
+	ret0, _ := ret[0].(voltha.VolthaService_ReceivePacketsInClient)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReceivePacketsIn indicates an expected call of ReceivePacketsIn.
+func (mr *MockVolthaServiceClientMockRecorder) ReceivePacketsIn(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivePacketsIn", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReceivePacketsIn), varargs...)
+}
+
+// ReconcileDevices mocks base method.
+func (m *MockVolthaServiceClient) ReconcileDevices(ctx context.Context, in *common.IDs, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReconcileDevices", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileDevices indicates an expected call of ReconcileDevices.
+func (mr *MockVolthaServiceClientMockRecorder) ReconcileDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReconcileDevices), varargs...)
+}
+
+// RevertImageUpdate mocks base method.
+func (m *MockVolthaServiceClient) RevertImageUpdate(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "RevertImageUpdate", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RevertImageUpdate indicates an expected call of RevertImageUpdate.
+func (mr *MockVolthaServiceClientMockRecorder) RevertImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockVolthaServiceClient)(nil).RevertImageUpdate), varargs...)
+}
+
+// SelfTest mocks base method.
+func (m *MockVolthaServiceClient) SelfTest(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.SelfTestResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SelfTest", varargs...)
+	ret0, _ := ret[0].(*voltha.SelfTestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SelfTest indicates an expected call of SelfTest.
+func (mr *MockVolthaServiceClientMockRecorder) SelfTest(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTest", reflect.TypeOf((*MockVolthaServiceClient)(nil).SelfTest), varargs...)
+}
+
+// SetExtValue mocks base method.
+func (m *MockVolthaServiceClient) SetExtValue(ctx context.Context, in *extension.ValueSet, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SetExtValue", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetExtValue indicates an expected call of SetExtValue.
+func (mr *MockVolthaServiceClientMockRecorder) SetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockVolthaServiceClient)(nil).SetExtValue), varargs...)
+}
+
+// SimulateAlarm mocks base method.
+func (m *MockVolthaServiceClient) SimulateAlarm(ctx context.Context, in *voltha.SimulateAlarmRequest, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SimulateAlarm", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SimulateAlarm indicates an expected call of SimulateAlarm.
+func (mr *MockVolthaServiceClientMockRecorder) SimulateAlarm(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockVolthaServiceClient)(nil).SimulateAlarm), varargs...)
+}
+
+// StartOmciTestAction mocks base method.
+func (m *MockVolthaServiceClient) StartOmciTestAction(ctx context.Context, in *omci.OmciTestRequest, opts ...grpc.CallOption) (*omci.TestResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "StartOmciTestAction", varargs...)
+	ret0, _ := ret[0].(*omci.TestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StartOmciTestAction indicates an expected call of StartOmciTestAction.
+func (mr *MockVolthaServiceClientMockRecorder) StartOmciTestAction(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTestAction", reflect.TypeOf((*MockVolthaServiceClient)(nil).StartOmciTestAction), varargs...)
+}
+
+// StreamPacketsOut mocks base method.
+func (m *MockVolthaServiceClient) StreamPacketsOut(ctx context.Context, opts ...grpc.CallOption) (voltha.VolthaService_StreamPacketsOutClient, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "StreamPacketsOut", varargs...)
+	ret0, _ := ret[0].(voltha.VolthaService_StreamPacketsOutClient)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StreamPacketsOut indicates an expected call of StreamPacketsOut.
+func (mr *MockVolthaServiceClientMockRecorder) StreamPacketsOut(ctx interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamPacketsOut", reflect.TypeOf((*MockVolthaServiceClient)(nil).StreamPacketsOut), varargs...)
+}
+
+// UpdateDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceClient) UpdateDevicePmConfigs(ctx context.Context, in *voltha.PmConfigs, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateDevicePmConfigs", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateDevicePmConfigs indicates an expected call of UpdateDevicePmConfigs.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateDevicePmConfigs(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateDevicePmConfigs), varargs...)
+}
+
+// UpdateEventFilter mocks base method.
+func (m *MockVolthaServiceClient) UpdateEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateEventFilter", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateEventFilter indicates an expected call of UpdateEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateEventFilter), varargs...)
+}
+
+// UpdateLogicalDeviceFlowGroupTable mocks base method.
+func (m *MockVolthaServiceClient) UpdateLogicalDeviceFlowGroupTable(ctx context.Context, in *openflow_13.FlowGroupTableUpdate, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowGroupTable", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowGroupTable indicates an expected call of UpdateLogicalDeviceFlowGroupTable.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceFlowGroupTable(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowGroupTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceFlowGroupTable), varargs...)
+}
+
+// UpdateLogicalDeviceFlowTable mocks base method.
+func (m *MockVolthaServiceClient) UpdateLogicalDeviceFlowTable(ctx context.Context, in *openflow_13.FlowTableUpdate, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowTable", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowTable indicates an expected call of UpdateLogicalDeviceFlowTable.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceFlowTable(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceFlowTable), varargs...)
+}
+
+// UpdateLogicalDeviceMeterTable mocks base method.
+func (m *MockVolthaServiceClient) UpdateLogicalDeviceMeterTable(ctx context.Context, in *openflow_13.MeterModUpdate, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceMeterTable", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceMeterTable indicates an expected call of UpdateLogicalDeviceMeterTable.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceMeterTable(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceMeterTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceMeterTable), varargs...)
+}
+
+// MockVolthaService_StreamPacketsOutClient is a mock of VolthaService_StreamPacketsOutClient interface.
+type MockVolthaService_StreamPacketsOutClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_StreamPacketsOutClientMockRecorder
+}
+
+// MockVolthaService_StreamPacketsOutClientMockRecorder is the mock recorder for MockVolthaService_StreamPacketsOutClient.
+type MockVolthaService_StreamPacketsOutClientMockRecorder struct {
+	mock *MockVolthaService_StreamPacketsOutClient
+}
+
+// NewMockVolthaService_StreamPacketsOutClient creates a new mock instance.
+func NewMockVolthaService_StreamPacketsOutClient(ctrl *gomock.Controller) *MockVolthaService_StreamPacketsOutClient {
+	mock := &MockVolthaService_StreamPacketsOutClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_StreamPacketsOutClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_StreamPacketsOutClient) EXPECT() *MockVolthaService_StreamPacketsOutClientMockRecorder {
+	return m.recorder
+}
+
+// CloseAndRecv mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) CloseAndRecv() (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseAndRecv")
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CloseAndRecv indicates an expected call of CloseAndRecv.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) CloseAndRecv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseAndRecv", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).CloseAndRecv))
+}
+
+// CloseSend mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) CloseSend() error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseSend")
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CloseSend indicates an expected call of CloseSend.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) CloseSend() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).CloseSend))
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Context))
+}
+
+// Header mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Header() (metadata.MD, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Header")
+	ret0, _ := ret[0].(metadata.MD)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Header indicates an expected call of Header.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Header() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Header))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutClient) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).RecvMsg), m)
+}
+
+// Send mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Send(arg0 *openflow_13.PacketOut) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Send", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Send indicates an expected call of Send.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Send(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Send), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutClient) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).SendMsg), m)
+}
+
+// Trailer mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Trailer() metadata.MD {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Trailer")
+	ret0, _ := ret[0].(metadata.MD)
+	return ret0
+}
+
+// Trailer indicates an expected call of Trailer.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Trailer() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Trailer))
+}
+
+// MockVolthaService_ReceivePacketsInClient is a mock of VolthaService_ReceivePacketsInClient interface.
+type MockVolthaService_ReceivePacketsInClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceivePacketsInClientMockRecorder
+}
+
+// MockVolthaService_ReceivePacketsInClientMockRecorder is the mock recorder for MockVolthaService_ReceivePacketsInClient.
+type MockVolthaService_ReceivePacketsInClientMockRecorder struct {
+	mock *MockVolthaService_ReceivePacketsInClient
+}
+
+// NewMockVolthaService_ReceivePacketsInClient creates a new mock instance.
+func NewMockVolthaService_ReceivePacketsInClient(ctrl *gomock.Controller) *MockVolthaService_ReceivePacketsInClient {
+	mock := &MockVolthaService_ReceivePacketsInClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceivePacketsInClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceivePacketsInClient) EXPECT() *MockVolthaService_ReceivePacketsInClientMockRecorder {
+	return m.recorder
+}
+
+// CloseSend mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) CloseSend() error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseSend")
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CloseSend indicates an expected call of CloseSend.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) CloseSend() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).CloseSend))
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Context))
+}
+
+// Header mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Header() (metadata.MD, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Header")
+	ret0, _ := ret[0].(metadata.MD)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Header indicates an expected call of Header.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Header() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Header))
+}
+
+// Recv mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Recv() (*openflow_13.PacketIn, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Recv")
+	ret0, _ := ret[0].(*openflow_13.PacketIn)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Recv indicates an expected call of Recv.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Recv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Recv))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInClient) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).RecvMsg), m)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInClient) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).SendMsg), m)
+}
+
+// Trailer mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Trailer() metadata.MD {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Trailer")
+	ret0, _ := ret[0].(metadata.MD)
+	return ret0
+}
+
+// Trailer indicates an expected call of Trailer.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Trailer() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Trailer))
+}
+
+// MockVolthaService_ReceiveChangeEventsClient is a mock of VolthaService_ReceiveChangeEventsClient interface.
+type MockVolthaService_ReceiveChangeEventsClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceiveChangeEventsClientMockRecorder
+}
+
+// MockVolthaService_ReceiveChangeEventsClientMockRecorder is the mock recorder for MockVolthaService_ReceiveChangeEventsClient.
+type MockVolthaService_ReceiveChangeEventsClientMockRecorder struct {
+	mock *MockVolthaService_ReceiveChangeEventsClient
+}
+
+// NewMockVolthaService_ReceiveChangeEventsClient creates a new mock instance.
+func NewMockVolthaService_ReceiveChangeEventsClient(ctrl *gomock.Controller) *MockVolthaService_ReceiveChangeEventsClient {
+	mock := &MockVolthaService_ReceiveChangeEventsClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceiveChangeEventsClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceiveChangeEventsClient) EXPECT() *MockVolthaService_ReceiveChangeEventsClientMockRecorder {
+	return m.recorder
+}
+
+// CloseSend mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) CloseSend() error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseSend")
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CloseSend indicates an expected call of CloseSend.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) CloseSend() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).CloseSend))
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Context))
+}
+
+// Header mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Header() (metadata.MD, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Header")
+	ret0, _ := ret[0].(metadata.MD)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Header indicates an expected call of Header.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Header() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Header))
+}
+
+// Recv mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Recv() (*openflow_13.ChangeEvent, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Recv")
+	ret0, _ := ret[0].(*openflow_13.ChangeEvent)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Recv indicates an expected call of Recv.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Recv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Recv))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsClient) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).RecvMsg), m)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsClient) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).SendMsg), m)
+}
+
+// Trailer mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Trailer() metadata.MD {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Trailer")
+	ret0, _ := ret[0].(metadata.MD)
+	return ret0
+}
+
+// Trailer indicates an expected call of Trailer.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Trailer() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Trailer))
+}
+
+// MockVolthaServiceServer is a mock of VolthaServiceServer interface.
+type MockVolthaServiceServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaServiceServerMockRecorder
+}
+
+// MockVolthaServiceServerMockRecorder is the mock recorder for MockVolthaServiceServer.
+type MockVolthaServiceServerMockRecorder struct {
+	mock *MockVolthaServiceServer
+}
+
+// NewMockVolthaServiceServer creates a new mock instance.
+func NewMockVolthaServiceServer(ctrl *gomock.Controller) *MockVolthaServiceServer {
+	mock := &MockVolthaServiceServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaServiceServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaServiceServer) EXPECT() *MockVolthaServiceServerMockRecorder {
+	return m.recorder
+}
+
+// AbortImageUpgradeToDevice mocks base method.
+func (m *MockVolthaServiceServer) AbortImageUpgradeToDevice(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AbortImageUpgradeToDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AbortImageUpgradeToDevice indicates an expected call of AbortImageUpgradeToDevice.
+func (mr *MockVolthaServiceServerMockRecorder) AbortImageUpgradeToDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortImageUpgradeToDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).AbortImageUpgradeToDevice), arg0, arg1)
+}
+
+// ActivateImage mocks base method.
+func (m *MockVolthaServiceServer) ActivateImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ActivateImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImage indicates an expected call of ActivateImage.
+func (mr *MockVolthaServiceServerMockRecorder) ActivateImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImage", reflect.TypeOf((*MockVolthaServiceServer)(nil).ActivateImage), arg0, arg1)
+}
+
+// ActivateImageUpdate mocks base method.
+func (m *MockVolthaServiceServer) ActivateImageUpdate(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ActivateImageUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
+func (mr *MockVolthaServiceServerMockRecorder) ActivateImageUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockVolthaServiceServer)(nil).ActivateImageUpdate), arg0, arg1)
+}
+
+// CancelImageDownload mocks base method.
+func (m *MockVolthaServiceServer) CancelImageDownload(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CancelImageDownload", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CancelImageDownload indicates an expected call of CancelImageDownload.
+func (mr *MockVolthaServiceServerMockRecorder) CancelImageDownload(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockVolthaServiceServer)(nil).CancelImageDownload), arg0, arg1)
+}
+
+// CommitImage mocks base method.
+func (m *MockVolthaServiceServer) CommitImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CommitImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CommitImage indicates an expected call of CommitImage.
+func (mr *MockVolthaServiceServerMockRecorder) CommitImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitImage", reflect.TypeOf((*MockVolthaServiceServer)(nil).CommitImage), arg0, arg1)
+}
+
+// CreateDevice mocks base method.
+func (m *MockVolthaServiceServer) CreateDevice(arg0 context.Context, arg1 *voltha.Device) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CreateDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateDevice indicates an expected call of CreateDevice.
+func (mr *MockVolthaServiceServerMockRecorder) CreateDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).CreateDevice), arg0, arg1)
+}
+
+// CreateEventFilter mocks base method.
+func (m *MockVolthaServiceServer) CreateEventFilter(arg0 context.Context, arg1 *voltha.EventFilter) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CreateEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateEventFilter indicates an expected call of CreateEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) CreateEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).CreateEventFilter), arg0, arg1)
+}
+
+// DeleteDevice mocks base method.
+func (m *MockVolthaServiceServer) DeleteDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteDevice indicates an expected call of DeleteDevice.
+func (mr *MockVolthaServiceServerMockRecorder) DeleteDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).DeleteDevice), arg0, arg1)
+}
+
+// DeleteEventFilter mocks base method.
+func (m *MockVolthaServiceServer) DeleteEventFilter(arg0 context.Context, arg1 *voltha.EventFilter) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteEventFilter indicates an expected call of DeleteEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) DeleteEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).DeleteEventFilter), arg0, arg1)
+}
+
+// DisableDevice mocks base method.
+func (m *MockVolthaServiceServer) DisableDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisableDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableDevice indicates an expected call of DisableDevice.
+func (mr *MockVolthaServiceServerMockRecorder) DisableDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).DisableDevice), arg0, arg1)
+}
+
+// DisableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceServer) DisableLogicalDevicePort(arg0 context.Context, arg1 *voltha.LogicalPortId) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisableLogicalDevicePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableLogicalDevicePort indicates an expected call of DisableLogicalDevicePort.
+func (mr *MockVolthaServiceServerMockRecorder) DisableLogicalDevicePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).DisableLogicalDevicePort), arg0, arg1)
+}
+
+// DisablePort mocks base method.
+func (m *MockVolthaServiceServer) DisablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisablePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisablePort indicates an expected call of DisablePort.
+func (mr *MockVolthaServiceServerMockRecorder) DisablePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).DisablePort), arg0, arg1)
+}
+
+// DownloadImage mocks base method.
+func (m *MockVolthaServiceServer) DownloadImage(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DownloadImage", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImage indicates an expected call of DownloadImage.
+func (mr *MockVolthaServiceServerMockRecorder) DownloadImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockVolthaServiceServer)(nil).DownloadImage), arg0, arg1)
+}
+
+// DownloadImageToDevice mocks base method.
+func (m *MockVolthaServiceServer) DownloadImageToDevice(arg0 context.Context, arg1 *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DownloadImageToDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImageToDevice indicates an expected call of DownloadImageToDevice.
+func (mr *MockVolthaServiceServerMockRecorder) DownloadImageToDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImageToDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).DownloadImageToDevice), arg0, arg1)
+}
+
+// EnableDevice mocks base method.
+func (m *MockVolthaServiceServer) EnableDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "EnableDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableDevice indicates an expected call of EnableDevice.
+func (mr *MockVolthaServiceServerMockRecorder) EnableDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).EnableDevice), arg0, arg1)
+}
+
+// EnableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceServer) EnableLogicalDevicePort(arg0 context.Context, arg1 *voltha.LogicalPortId) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "EnableLogicalDevicePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableLogicalDevicePort indicates an expected call of EnableLogicalDevicePort.
+func (mr *MockVolthaServiceServerMockRecorder) EnableLogicalDevicePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).EnableLogicalDevicePort), arg0, arg1)
+}
+
+// EnablePort mocks base method.
+func (m *MockVolthaServiceServer) EnablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "EnablePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnablePort indicates an expected call of EnablePort.
+func (mr *MockVolthaServiceServerMockRecorder) EnablePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).EnablePort), arg0, arg1)
+}
+
+// ForceDeleteDevice mocks base method.
+func (m *MockVolthaServiceServer) ForceDeleteDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ForceDeleteDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ForceDeleteDevice indicates an expected call of ForceDeleteDevice.
+func (mr *MockVolthaServiceServerMockRecorder) ForceDeleteDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForceDeleteDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).ForceDeleteDevice), arg0, arg1)
+}
+
+// GetAlarmDeviceData mocks base method.
+func (m *MockVolthaServiceServer) GetAlarmDeviceData(arg0 context.Context, arg1 *common.ID) (*omci.AlarmDeviceData, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAlarmDeviceData", arg0, arg1)
+	ret0, _ := ret[0].(*omci.AlarmDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAlarmDeviceData indicates an expected call of GetAlarmDeviceData.
+func (mr *MockVolthaServiceServerMockRecorder) GetAlarmDeviceData(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmDeviceData", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetAlarmDeviceData), arg0, arg1)
+}
+
+// GetCoreInstance mocks base method.
+func (m *MockVolthaServiceServer) GetCoreInstance(arg0 context.Context, arg1 *common.ID) (*voltha.CoreInstance, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetCoreInstance", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.CoreInstance)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetCoreInstance indicates an expected call of GetCoreInstance.
+func (mr *MockVolthaServiceServerMockRecorder) GetCoreInstance(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreInstance", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetCoreInstance), arg0, arg1)
+}
+
+// GetDevice mocks base method.
+func (m *MockVolthaServiceServer) GetDevice(arg0 context.Context, arg1 *common.ID) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevice indicates an expected call of GetDevice.
+func (mr *MockVolthaServiceServerMockRecorder) GetDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetDevice), arg0, arg1)
+}
+
+// GetDeviceType mocks base method.
+func (m *MockVolthaServiceServer) GetDeviceType(arg0 context.Context, arg1 *common.ID) (*voltha.DeviceType, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDeviceType", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceType)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDeviceType indicates an expected call of GetDeviceType.
+func (mr *MockVolthaServiceServerMockRecorder) GetDeviceType(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceType", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetDeviceType), arg0, arg1)
+}
+
+// GetEventFilter mocks base method.
+func (m *MockVolthaServiceServer) GetEventFilter(arg0 context.Context, arg1 *common.ID) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetEventFilter indicates an expected call of GetEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) GetEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetEventFilter), arg0, arg1)
+}
+
+// GetExtValue mocks base method.
+func (m *MockVolthaServiceServer) GetExtValue(arg0 context.Context, arg1 *extension.ValueSpecifier) (*extension.ReturnValues, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetExtValue", arg0, arg1)
+	ret0, _ := ret[0].(*extension.ReturnValues)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetExtValue indicates an expected call of GetExtValue.
+func (mr *MockVolthaServiceServerMockRecorder) GetExtValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetExtValue), arg0, arg1)
+}
+
+// GetImageDownload mocks base method.
+func (m *MockVolthaServiceServer) GetImageDownload(arg0 context.Context, arg1 *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImageDownload", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownload indicates an expected call of GetImageDownload.
+func (mr *MockVolthaServiceServerMockRecorder) GetImageDownload(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownload", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImageDownload), arg0, arg1)
+}
+
+// GetImageDownloadStatus mocks base method.
+func (m *MockVolthaServiceServer) GetImageDownloadStatus(arg0 context.Context, arg1 *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImageDownloadStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
+func (mr *MockVolthaServiceServerMockRecorder) GetImageDownloadStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImageDownloadStatus), arg0, arg1)
+}
+
+// GetImageStatus mocks base method.
+func (m *MockVolthaServiceServer) GetImageStatus(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImageStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageStatus indicates an expected call of GetImageStatus.
+func (mr *MockVolthaServiceServerMockRecorder) GetImageStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStatus", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImageStatus), arg0, arg1)
+}
+
+// GetImages mocks base method.
+func (m *MockVolthaServiceServer) GetImages(arg0 context.Context, arg1 *common.ID) (*voltha.Images, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImages", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Images)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImages indicates an expected call of GetImages.
+func (mr *MockVolthaServiceServerMockRecorder) GetImages(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImages", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImages), arg0, arg1)
+}
+
+// GetLogicalDevice mocks base method.
+func (m *MockVolthaServiceServer) GetLogicalDevice(arg0 context.Context, arg1 *common.ID) (*voltha.LogicalDevice, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetLogicalDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalDevice)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevice indicates an expected call of GetLogicalDevice.
+func (mr *MockVolthaServiceServerMockRecorder) GetLogicalDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetLogicalDevice), arg0, arg1)
+}
+
+// GetLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceServer) GetLogicalDevicePort(arg0 context.Context, arg1 *voltha.LogicalPortId) (*voltha.LogicalPort, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetLogicalDevicePort", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalPort)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevicePort indicates an expected call of GetLogicalDevicePort.
+func (mr *MockVolthaServiceServerMockRecorder) GetLogicalDevicePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetLogicalDevicePort), arg0, arg1)
+}
+
+// GetMibDeviceData mocks base method.
+func (m *MockVolthaServiceServer) GetMibDeviceData(arg0 context.Context, arg1 *common.ID) (*omci.MibDeviceData, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMibDeviceData", arg0, arg1)
+	ret0, _ := ret[0].(*omci.MibDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMibDeviceData indicates an expected call of GetMibDeviceData.
+func (mr *MockVolthaServiceServerMockRecorder) GetMibDeviceData(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMibDeviceData", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetMibDeviceData), arg0, arg1)
+}
+
+// GetOnuImages mocks base method.
+func (m *MockVolthaServiceServer) GetOnuImages(arg0 context.Context, arg1 *common.ID) (*voltha.OnuImages, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOnuImages", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.OnuImages)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImages indicates an expected call of GetOnuImages.
+func (mr *MockVolthaServiceServerMockRecorder) GetOnuImages(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetOnuImages), arg0, arg1)
+}
+
+// GetVoltha mocks base method.
+func (m *MockVolthaServiceServer) GetVoltha(arg0 context.Context, arg1 *empty.Empty) (*voltha.Voltha, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetVoltha", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Voltha)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVoltha indicates an expected call of GetVoltha.
+func (mr *MockVolthaServiceServerMockRecorder) GetVoltha(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVoltha", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetVoltha), arg0, arg1)
+}
+
+// ListAdapters mocks base method.
+func (m *MockVolthaServiceServer) ListAdapters(arg0 context.Context, arg1 *empty.Empty) (*voltha.Adapters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListAdapters", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Adapters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListAdapters indicates an expected call of ListAdapters.
+func (mr *MockVolthaServiceServerMockRecorder) ListAdapters(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAdapters", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListAdapters), arg0, arg1)
+}
+
+// ListCoreInstances mocks base method.
+func (m *MockVolthaServiceServer) ListCoreInstances(arg0 context.Context, arg1 *empty.Empty) (*voltha.CoreInstances, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListCoreInstances", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.CoreInstances)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListCoreInstances indicates an expected call of ListCoreInstances.
+func (mr *MockVolthaServiceServerMockRecorder) ListCoreInstances(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCoreInstances", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListCoreInstances), arg0, arg1)
+}
+
+// ListDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceFlowGroups(arg0 context.Context, arg1 *common.ID) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceFlowGroups", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlowGroups indicates an expected call of ListDeviceFlowGroups.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceFlowGroups(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceFlowGroups), arg0, arg1)
+}
+
+// ListDeviceFlows mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceFlows(arg0 context.Context, arg1 *common.ID) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceFlows", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlows indicates an expected call of ListDeviceFlows.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceFlows(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlows", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceFlows), arg0, arg1)
+}
+
+// ListDeviceIds mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceIds(arg0 context.Context, arg1 *empty.Empty) (*common.IDs, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceIds", arg0, arg1)
+	ret0, _ := ret[0].(*common.IDs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceIds indicates an expected call of ListDeviceIds.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceIds(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceIds", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceIds), arg0, arg1)
+}
+
+// ListDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceServer) ListDevicePmConfigs(arg0 context.Context, arg1 *common.ID) (*voltha.PmConfigs, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDevicePmConfigs", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.PmConfigs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePmConfigs indicates an expected call of ListDevicePmConfigs.
+func (mr *MockVolthaServiceServerMockRecorder) ListDevicePmConfigs(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDevicePmConfigs), arg0, arg1)
+}
+
+// ListDevicePorts mocks base method.
+func (m *MockVolthaServiceServer) ListDevicePorts(arg0 context.Context, arg1 *common.ID) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDevicePorts", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePorts indicates an expected call of ListDevicePorts.
+func (mr *MockVolthaServiceServerMockRecorder) ListDevicePorts(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDevicePorts), arg0, arg1)
+}
+
+// ListDeviceTypes mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceTypes(arg0 context.Context, arg1 *empty.Empty) (*voltha.DeviceTypes, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceTypes", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceTypes)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceTypes indicates an expected call of ListDeviceTypes.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceTypes(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceTypes", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceTypes), arg0, arg1)
+}
+
+// ListDevices mocks base method.
+func (m *MockVolthaServiceServer) ListDevices(arg0 context.Context, arg1 *empty.Empty) (*voltha.Devices, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDevices", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Devices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevices indicates an expected call of ListDevices.
+func (mr *MockVolthaServiceServerMockRecorder) ListDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevices", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDevices), arg0, arg1)
+}
+
+// ListEventFilters mocks base method.
+func (m *MockVolthaServiceServer) ListEventFilters(arg0 context.Context, arg1 *empty.Empty) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListEventFilters", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListEventFilters indicates an expected call of ListEventFilters.
+func (mr *MockVolthaServiceServerMockRecorder) ListEventFilters(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEventFilters", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListEventFilters), arg0, arg1)
+}
+
+// ListImageDownloads mocks base method.
+func (m *MockVolthaServiceServer) ListImageDownloads(arg0 context.Context, arg1 *common.ID) (*voltha.ImageDownloads, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListImageDownloads", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownloads)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListImageDownloads indicates an expected call of ListImageDownloads.
+func (mr *MockVolthaServiceServerMockRecorder) ListImageDownloads(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImageDownloads", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListImageDownloads), arg0, arg1)
+}
+
+// ListLogicalDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDeviceFlowGroups(arg0 context.Context, arg1 *common.ID) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlowGroups", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlowGroups indicates an expected call of ListLogicalDeviceFlowGroups.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDeviceFlowGroups(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDeviceFlowGroups), arg0, arg1)
+}
+
+// ListLogicalDeviceFlows mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDeviceFlows(arg0 context.Context, arg1 *common.ID) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlows", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlows indicates an expected call of ListLogicalDeviceFlows.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDeviceFlows(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlows", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDeviceFlows), arg0, arg1)
+}
+
+// ListLogicalDeviceMeters mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDeviceMeters(arg0 context.Context, arg1 *common.ID) (*openflow_13.Meters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDeviceMeters", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.Meters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceMeters indicates an expected call of ListLogicalDeviceMeters.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDeviceMeters(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceMeters", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDeviceMeters), arg0, arg1)
+}
+
+// ListLogicalDevicePorts mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDevicePorts(arg0 context.Context, arg1 *common.ID) (*voltha.LogicalPorts, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDevicePorts", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalPorts)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevicePorts indicates an expected call of ListLogicalDevicePorts.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDevicePorts(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevicePorts", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDevicePorts), arg0, arg1)
+}
+
+// ListLogicalDevices mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDevices(arg0 context.Context, arg1 *empty.Empty) (*voltha.LogicalDevices, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDevices", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalDevices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevices indicates an expected call of ListLogicalDevices.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevices", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDevices), arg0, arg1)
+}
+
+// RebootDevice mocks base method.
+func (m *MockVolthaServiceServer) RebootDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RebootDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RebootDevice indicates an expected call of RebootDevice.
+func (mr *MockVolthaServiceServerMockRecorder) RebootDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).RebootDevice), arg0, arg1)
+}
+
+// ReceiveChangeEvents mocks base method.
+func (m *MockVolthaServiceServer) ReceiveChangeEvents(arg0 *empty.Empty, arg1 voltha.VolthaService_ReceiveChangeEventsServer) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReceiveChangeEvents", arg0, arg1)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// ReceiveChangeEvents indicates an expected call of ReceiveChangeEvents.
+func (mr *MockVolthaServiceServerMockRecorder) ReceiveChangeEvents(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveChangeEvents", reflect.TypeOf((*MockVolthaServiceServer)(nil).ReceiveChangeEvents), arg0, arg1)
+}
+
+// ReceivePacketsIn mocks base method.
+func (m *MockVolthaServiceServer) ReceivePacketsIn(arg0 *empty.Empty, arg1 voltha.VolthaService_ReceivePacketsInServer) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReceivePacketsIn", arg0, arg1)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// ReceivePacketsIn indicates an expected call of ReceivePacketsIn.
+func (mr *MockVolthaServiceServerMockRecorder) ReceivePacketsIn(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivePacketsIn", reflect.TypeOf((*MockVolthaServiceServer)(nil).ReceivePacketsIn), arg0, arg1)
+}
+
+// ReconcileDevices mocks base method.
+func (m *MockVolthaServiceServer) ReconcileDevices(arg0 context.Context, arg1 *common.IDs) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReconcileDevices", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileDevices indicates an expected call of ReconcileDevices.
+func (mr *MockVolthaServiceServerMockRecorder) ReconcileDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevices", reflect.TypeOf((*MockVolthaServiceServer)(nil).ReconcileDevices), arg0, arg1)
+}
+
+// RevertImageUpdate mocks base method.
+func (m *MockVolthaServiceServer) RevertImageUpdate(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RevertImageUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RevertImageUpdate indicates an expected call of RevertImageUpdate.
+func (mr *MockVolthaServiceServerMockRecorder) RevertImageUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockVolthaServiceServer)(nil).RevertImageUpdate), arg0, arg1)
+}
+
+// SelfTest mocks base method.
+func (m *MockVolthaServiceServer) SelfTest(arg0 context.Context, arg1 *common.ID) (*voltha.SelfTestResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SelfTest", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.SelfTestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SelfTest indicates an expected call of SelfTest.
+func (mr *MockVolthaServiceServerMockRecorder) SelfTest(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTest", reflect.TypeOf((*MockVolthaServiceServer)(nil).SelfTest), arg0, arg1)
+}
+
+// SetExtValue mocks base method.
+func (m *MockVolthaServiceServer) SetExtValue(arg0 context.Context, arg1 *extension.ValueSet) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetExtValue", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetExtValue indicates an expected call of SetExtValue.
+func (mr *MockVolthaServiceServerMockRecorder) SetExtValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockVolthaServiceServer)(nil).SetExtValue), arg0, arg1)
+}
+
+// SimulateAlarm mocks base method.
+func (m *MockVolthaServiceServer) SimulateAlarm(arg0 context.Context, arg1 *voltha.SimulateAlarmRequest) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SimulateAlarm", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SimulateAlarm indicates an expected call of SimulateAlarm.
+func (mr *MockVolthaServiceServerMockRecorder) SimulateAlarm(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockVolthaServiceServer)(nil).SimulateAlarm), arg0, arg1)
+}
+
+// StartOmciTestAction mocks base method.
+func (m *MockVolthaServiceServer) StartOmciTestAction(arg0 context.Context, arg1 *omci.OmciTestRequest) (*omci.TestResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StartOmciTestAction", arg0, arg1)
+	ret0, _ := ret[0].(*omci.TestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StartOmciTestAction indicates an expected call of StartOmciTestAction.
+func (mr *MockVolthaServiceServerMockRecorder) StartOmciTestAction(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTestAction", reflect.TypeOf((*MockVolthaServiceServer)(nil).StartOmciTestAction), arg0, arg1)
+}
+
+// StreamPacketsOut mocks base method.
+func (m *MockVolthaServiceServer) StreamPacketsOut(arg0 voltha.VolthaService_StreamPacketsOutServer) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StreamPacketsOut", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// StreamPacketsOut indicates an expected call of StreamPacketsOut.
+func (mr *MockVolthaServiceServerMockRecorder) StreamPacketsOut(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamPacketsOut", reflect.TypeOf((*MockVolthaServiceServer)(nil).StreamPacketsOut), arg0)
+}
+
+// UpdateDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceServer) UpdateDevicePmConfigs(arg0 context.Context, arg1 *voltha.PmConfigs) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateDevicePmConfigs", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateDevicePmConfigs indicates an expected call of UpdateDevicePmConfigs.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateDevicePmConfigs(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateDevicePmConfigs), arg0, arg1)
+}
+
+// UpdateEventFilter mocks base method.
+func (m *MockVolthaServiceServer) UpdateEventFilter(arg0 context.Context, arg1 *voltha.EventFilter) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateEventFilter indicates an expected call of UpdateEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateEventFilter), arg0, arg1)
+}
+
+// UpdateLogicalDeviceFlowGroupTable mocks base method.
+func (m *MockVolthaServiceServer) UpdateLogicalDeviceFlowGroupTable(arg0 context.Context, arg1 *openflow_13.FlowGroupTableUpdate) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowGroupTable", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowGroupTable indicates an expected call of UpdateLogicalDeviceFlowGroupTable.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateLogicalDeviceFlowGroupTable(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowGroupTable", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateLogicalDeviceFlowGroupTable), arg0, arg1)
+}
+
+// UpdateLogicalDeviceFlowTable mocks base method.
+func (m *MockVolthaServiceServer) UpdateLogicalDeviceFlowTable(arg0 context.Context, arg1 *openflow_13.FlowTableUpdate) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowTable", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowTable indicates an expected call of UpdateLogicalDeviceFlowTable.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateLogicalDeviceFlowTable(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowTable", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateLogicalDeviceFlowTable), arg0, arg1)
+}
+
+// UpdateLogicalDeviceMeterTable mocks base method.
+func (m *MockVolthaServiceServer) UpdateLogicalDeviceMeterTable(arg0 context.Context, arg1 *openflow_13.MeterModUpdate) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceMeterTable", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceMeterTable indicates an expected call of UpdateLogicalDeviceMeterTable.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateLogicalDeviceMeterTable(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceMeterTable", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateLogicalDeviceMeterTable), arg0, arg1)
+}
+
+// MockVolthaService_StreamPacketsOutServer is a mock of VolthaService_StreamPacketsOutServer interface.
+type MockVolthaService_StreamPacketsOutServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_StreamPacketsOutServerMockRecorder
+}
+
+// MockVolthaService_StreamPacketsOutServerMockRecorder is the mock recorder for MockVolthaService_StreamPacketsOutServer.
+type MockVolthaService_StreamPacketsOutServerMockRecorder struct {
+	mock *MockVolthaService_StreamPacketsOutServer
+}
+
+// NewMockVolthaService_StreamPacketsOutServer creates a new mock instance.
+func NewMockVolthaService_StreamPacketsOutServer(ctrl *gomock.Controller) *MockVolthaService_StreamPacketsOutServer {
+	mock := &MockVolthaService_StreamPacketsOutServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_StreamPacketsOutServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_StreamPacketsOutServer) EXPECT() *MockVolthaService_StreamPacketsOutServerMockRecorder {
+	return m.recorder
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).Context))
+}
+
+// Recv mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) Recv() (*openflow_13.PacketOut, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Recv")
+	ret0, _ := ret[0].(*openflow_13.PacketOut)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Recv indicates an expected call of Recv.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) Recv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).Recv))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutServer) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).RecvMsg), m)
+}
+
+// SendAndClose mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SendAndClose(arg0 *empty.Empty) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendAndClose", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendAndClose indicates an expected call of SendAndClose.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SendAndClose(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAndClose", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SendAndClose), arg0)
+}
+
+// SendHeader mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SendHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendHeader indicates an expected call of SendHeader.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SendHeader), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutServer) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SendMsg), m)
+}
+
+// SetHeader mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SetHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SetHeader indicates an expected call of SetHeader.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SetHeader), arg0)
+}
+
+// SetTrailer mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SetTrailer(arg0 metadata.MD) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "SetTrailer", arg0)
+}
+
+// SetTrailer indicates an expected call of SetTrailer.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SetTrailer), arg0)
+}
+
+// MockVolthaService_ReceivePacketsInServer is a mock of VolthaService_ReceivePacketsInServer interface.
+type MockVolthaService_ReceivePacketsInServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceivePacketsInServerMockRecorder
+}
+
+// MockVolthaService_ReceivePacketsInServerMockRecorder is the mock recorder for MockVolthaService_ReceivePacketsInServer.
+type MockVolthaService_ReceivePacketsInServerMockRecorder struct {
+	mock *MockVolthaService_ReceivePacketsInServer
+}
+
+// NewMockVolthaService_ReceivePacketsInServer creates a new mock instance.
+func NewMockVolthaService_ReceivePacketsInServer(ctrl *gomock.Controller) *MockVolthaService_ReceivePacketsInServer {
+	mock := &MockVolthaService_ReceivePacketsInServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceivePacketsInServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceivePacketsInServer) EXPECT() *MockVolthaService_ReceivePacketsInServerMockRecorder {
+	return m.recorder
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).Context))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInServer) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).RecvMsg), m)
+}
+
+// Send mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) Send(arg0 *openflow_13.PacketIn) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Send", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Send indicates an expected call of Send.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) Send(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).Send), arg0)
+}
+
+// SendHeader mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) SendHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendHeader indicates an expected call of SendHeader.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SendHeader), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInServer) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SendMsg), m)
+}
+
+// SetHeader mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) SetHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SetHeader indicates an expected call of SetHeader.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SetHeader), arg0)
+}
+
+// SetTrailer mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) SetTrailer(arg0 metadata.MD) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "SetTrailer", arg0)
+}
+
+// SetTrailer indicates an expected call of SetTrailer.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SetTrailer), arg0)
+}
+
+// MockVolthaService_ReceiveChangeEventsServer is a mock of VolthaService_ReceiveChangeEventsServer interface.
+type MockVolthaService_ReceiveChangeEventsServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceiveChangeEventsServerMockRecorder
+}
+
+// MockVolthaService_ReceiveChangeEventsServerMockRecorder is the mock recorder for MockVolthaService_ReceiveChangeEventsServer.
+type MockVolthaService_ReceiveChangeEventsServerMockRecorder struct {
+	mock *MockVolthaService_ReceiveChangeEventsServer
+}
+
+// NewMockVolthaService_ReceiveChangeEventsServer creates a new mock instance.
+func NewMockVolthaService_ReceiveChangeEventsServer(ctrl *gomock.Controller) *MockVolthaService_ReceiveChangeEventsServer {
+	mock := &MockVolthaService_ReceiveChangeEventsServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceiveChangeEventsServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceiveChangeEventsServer) EXPECT() *MockVolthaService_ReceiveChangeEventsServerMockRecorder {
+	return m.recorder
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).Context))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsServer) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).RecvMsg), m)
+}
+
+// Send mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) Send(arg0 *openflow_13.ChangeEvent) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Send", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Send indicates an expected call of Send.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) Send(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).Send), arg0)
+}
+
+// SendHeader mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) SendHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendHeader indicates an expected call of SendHeader.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SendHeader), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsServer) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SendMsg), m)
+}
+
+// SetHeader mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) SetHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SetHeader indicates an expected call of SetHeader.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SetHeader), arg0)
+}
+
+// SetTrailer mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) SetTrailer(arg0 metadata.MD) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "SetTrailer", arg0)
+}
+
+// SetTrailer indicates an expected call of SetTrailer.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SetTrailer), arg0)
+}
