// 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)
}
