/*
 * Copyright 2021-present Open Networking Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
// Code generated by MockGen. DO NOT EDIT.
// Source: core.pb.go

package grpc

import (
	context "context"
	reflect "reflect"

	gomock "github.com/golang/mock/gomock"
	empty "github.com/golang/protobuf/ptypes/empty"
	common "github.com/opencord/voltha-protos/v5/go/common"
	inter_container "github.com/opencord/voltha-protos/v5/go/inter_container"
	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
	grpc "google.golang.org/grpc"
)

// MockCoreServiceClient is a mock of CoreServiceClient interface.
type MockCoreServiceClient struct {
	ctrl     *gomock.Controller
	recorder *MockCoreServiceClientMockRecorder
}

// MockCoreServiceClientMockRecorder is the mock recorder for MockCoreServiceClient.
type MockCoreServiceClientMockRecorder struct {
	mock *MockCoreServiceClient
}

// NewMockCoreServiceClient creates a new mock instance.
func NewMockCoreServiceClient(ctrl *gomock.Controller) *MockCoreServiceClient {
	mock := &MockCoreServiceClient{ctrl: ctrl}
	mock.recorder = &MockCoreServiceClientMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockCoreServiceClient) EXPECT() *MockCoreServiceClientMockRecorder {
	return m.recorder
}

// ChildDeviceDetected mocks base method.
func (m *MockCoreServiceClient) ChildDeviceDetected(ctx context.Context, in *inter_container.DeviceDiscovery, 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, "ChildDeviceDetected", varargs...)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildDeviceDetected indicates an expected call of ChildDeviceDetected.
func (mr *MockCoreServiceClientMockRecorder) ChildDeviceDetected(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, "ChildDeviceDetected", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDeviceDetected), varargs...)
}

// ChildDevicesDetected mocks base method.
func (m *MockCoreServiceClient) ChildDevicesDetected(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, "ChildDevicesDetected", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildDevicesDetected indicates an expected call of ChildDevicesDetected.
func (mr *MockCoreServiceClientMockRecorder) ChildDevicesDetected(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, "ChildDevicesDetected", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDevicesDetected), varargs...)
}

// ChildDevicesLost mocks base method.
func (m *MockCoreServiceClient) ChildDevicesLost(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, "ChildDevicesLost", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildDevicesLost indicates an expected call of ChildDevicesLost.
func (mr *MockCoreServiceClientMockRecorder) ChildDevicesLost(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, "ChildDevicesLost", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildDevicesLost), varargs...)
}

// ChildrenStateUpdate mocks base method.
func (m *MockCoreServiceClient) ChildrenStateUpdate(ctx context.Context, in *inter_container.DeviceStateFilter, 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, "ChildrenStateUpdate", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildrenStateUpdate indicates an expected call of ChildrenStateUpdate.
func (mr *MockCoreServiceClientMockRecorder) ChildrenStateUpdate(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, "ChildrenStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).ChildrenStateUpdate), varargs...)
}

// DeleteAllPorts mocks base method.
func (m *MockCoreServiceClient) DeleteAllPorts(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, "DeleteAllPorts", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteAllPorts indicates an expected call of DeleteAllPorts.
func (mr *MockCoreServiceClientMockRecorder) DeleteAllPorts(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, "DeleteAllPorts", reflect.TypeOf((*MockCoreServiceClient)(nil).DeleteAllPorts), varargs...)
}

// DevicePMConfigUpdate mocks base method.
func (m *MockCoreServiceClient) DevicePMConfigUpdate(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, "DevicePMConfigUpdate", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DevicePMConfigUpdate indicates an expected call of DevicePMConfigUpdate.
func (mr *MockCoreServiceClientMockRecorder) DevicePMConfigUpdate(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, "DevicePMConfigUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DevicePMConfigUpdate), varargs...)
}

// DeviceReasonUpdate mocks base method.
func (m *MockCoreServiceClient) DeviceReasonUpdate(ctx context.Context, in *inter_container.DeviceReason, 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, "DeviceReasonUpdate", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeviceReasonUpdate indicates an expected call of DeviceReasonUpdate.
func (mr *MockCoreServiceClientMockRecorder) DeviceReasonUpdate(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, "DeviceReasonUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceReasonUpdate), varargs...)
}

// DeviceStateUpdate mocks base method.
func (m *MockCoreServiceClient) DeviceStateUpdate(ctx context.Context, in *inter_container.DeviceStateFilter, 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, "DeviceStateUpdate", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeviceStateUpdate indicates an expected call of DeviceStateUpdate.
func (mr *MockCoreServiceClientMockRecorder) DeviceStateUpdate(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, "DeviceStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceStateUpdate), varargs...)
}

// DeviceUpdate mocks base method.
func (m *MockCoreServiceClient) DeviceUpdate(ctx context.Context, in *voltha.Device, 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, "DeviceUpdate", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeviceUpdate indicates an expected call of DeviceUpdate.
func (mr *MockCoreServiceClientMockRecorder) DeviceUpdate(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, "DeviceUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).DeviceUpdate), varargs...)
}

// GetChildDevice mocks base method.
func (m *MockCoreServiceClient) GetChildDevice(ctx context.Context, in *inter_container.ChildDeviceFilter, 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, "GetChildDevice", varargs...)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetChildDevice indicates an expected call of GetChildDevice.
func (mr *MockCoreServiceClientMockRecorder) GetChildDevice(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, "GetChildDevice", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDevice), varargs...)
}

// GetChildDeviceWithProxyAddress mocks base method.
func (m *MockCoreServiceClient) GetChildDeviceWithProxyAddress(ctx context.Context, in *voltha.Device_ProxyAddress, 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, "GetChildDeviceWithProxyAddress", varargs...)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetChildDeviceWithProxyAddress indicates an expected call of GetChildDeviceWithProxyAddress.
func (mr *MockCoreServiceClientMockRecorder) GetChildDeviceWithProxyAddress(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, "GetChildDeviceWithProxyAddress", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDeviceWithProxyAddress), varargs...)
}

// GetChildDevices mocks base method.
func (m *MockCoreServiceClient) GetChildDevices(ctx context.Context, in *common.ID, 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, "GetChildDevices", varargs...)
	ret0, _ := ret[0].(*voltha.Devices)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetChildDevices indicates an expected call of GetChildDevices.
func (mr *MockCoreServiceClientMockRecorder) GetChildDevices(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, "GetChildDevices", reflect.TypeOf((*MockCoreServiceClient)(nil).GetChildDevices), varargs...)
}

// GetDevice mocks base method.
func (m *MockCoreServiceClient) 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 *MockCoreServiceClientMockRecorder) 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((*MockCoreServiceClient)(nil).GetDevice), varargs...)
}

// GetDevicePort mocks base method.
func (m *MockCoreServiceClient) GetDevicePort(ctx context.Context, in *inter_container.PortFilter, opts ...grpc.CallOption) (*voltha.Port, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetDevicePort", varargs...)
	ret0, _ := ret[0].(*voltha.Port)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetDevicePort indicates an expected call of GetDevicePort.
func (mr *MockCoreServiceClientMockRecorder) GetDevicePort(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, "GetDevicePort", reflect.TypeOf((*MockCoreServiceClient)(nil).GetDevicePort), varargs...)
}

// GetHealthStatus mocks base method.
func (m *MockCoreServiceClient) GetHealthStatus(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.HealthStatus, error) {
	m.ctrl.T.Helper()
	varargs := []interface{}{ctx, in}
	for _, a := range opts {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetHealthStatus", varargs...)
	ret0, _ := ret[0].(*voltha.HealthStatus)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetHealthStatus indicates an expected call of GetHealthStatus.
func (mr *MockCoreServiceClientMockRecorder) GetHealthStatus(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, "GetHealthStatus", reflect.TypeOf((*MockCoreServiceClient)(nil).GetHealthStatus), varargs...)
}

// GetPorts mocks base method.
func (m *MockCoreServiceClient) GetPorts(ctx context.Context, in *inter_container.PortFilter, 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, "GetPorts", varargs...)
	ret0, _ := ret[0].(*voltha.Ports)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetPorts indicates an expected call of GetPorts.
func (mr *MockCoreServiceClientMockRecorder) GetPorts(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, "GetPorts", reflect.TypeOf((*MockCoreServiceClient)(nil).GetPorts), varargs...)
}

// ListDevicePorts mocks base method.
func (m *MockCoreServiceClient) 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 *MockCoreServiceClientMockRecorder) 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((*MockCoreServiceClient)(nil).ListDevicePorts), varargs...)
}

// PortCreated mocks base method.
func (m *MockCoreServiceClient) PortCreated(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, "PortCreated", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PortCreated indicates an expected call of PortCreated.
func (mr *MockCoreServiceClientMockRecorder) PortCreated(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, "PortCreated", reflect.TypeOf((*MockCoreServiceClient)(nil).PortCreated), varargs...)
}

// PortStateUpdate mocks base method.
func (m *MockCoreServiceClient) PortStateUpdate(ctx context.Context, in *inter_container.PortState, 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, "PortStateUpdate", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PortStateUpdate indicates an expected call of PortStateUpdate.
func (mr *MockCoreServiceClientMockRecorder) PortStateUpdate(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, "PortStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).PortStateUpdate), varargs...)
}

// PortsStateUpdate mocks base method.
func (m *MockCoreServiceClient) PortsStateUpdate(ctx context.Context, in *inter_container.PortStateFilter, 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, "PortsStateUpdate", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PortsStateUpdate indicates an expected call of PortsStateUpdate.
func (mr *MockCoreServiceClientMockRecorder) PortsStateUpdate(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, "PortsStateUpdate", reflect.TypeOf((*MockCoreServiceClient)(nil).PortsStateUpdate), varargs...)
}

// ReconcileChildDevices mocks base method.
func (m *MockCoreServiceClient) ReconcileChildDevices(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, "ReconcileChildDevices", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ReconcileChildDevices indicates an expected call of ReconcileChildDevices.
func (mr *MockCoreServiceClientMockRecorder) ReconcileChildDevices(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, "ReconcileChildDevices", reflect.TypeOf((*MockCoreServiceClient)(nil).ReconcileChildDevices), varargs...)
}

// RegisterAdapter mocks base method.
func (m *MockCoreServiceClient) RegisterAdapter(ctx context.Context, in *inter_container.AdapterRegistration, 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, "RegisterAdapter", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// RegisterAdapter indicates an expected call of RegisterAdapter.
func (mr *MockCoreServiceClientMockRecorder) RegisterAdapter(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, "RegisterAdapter", reflect.TypeOf((*MockCoreServiceClient)(nil).RegisterAdapter), varargs...)
}

// SendPacketIn mocks base method.
func (m *MockCoreServiceClient) SendPacketIn(ctx context.Context, in *inter_container.PacketIn, 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, "SendPacketIn", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// SendPacketIn indicates an expected call of SendPacketIn.
func (mr *MockCoreServiceClientMockRecorder) SendPacketIn(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, "SendPacketIn", reflect.TypeOf((*MockCoreServiceClient)(nil).SendPacketIn), varargs...)
}

// UpdateImageDownload mocks base method.
func (m *MockCoreServiceClient) UpdateImageDownload(ctx context.Context, in *voltha.ImageDownload, 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, "UpdateImageDownload", varargs...)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateImageDownload indicates an expected call of UpdateImageDownload.
func (mr *MockCoreServiceClientMockRecorder) UpdateImageDownload(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, "UpdateImageDownload", reflect.TypeOf((*MockCoreServiceClient)(nil).UpdateImageDownload), varargs...)
}

// MockCoreServiceServer is a mock of CoreServiceServer interface.
type MockCoreServiceServer struct {
	ctrl     *gomock.Controller
	recorder *MockCoreServiceServerMockRecorder
}

// MockCoreServiceServerMockRecorder is the mock recorder for MockCoreServiceServer.
type MockCoreServiceServerMockRecorder struct {
	mock *MockCoreServiceServer
}

// NewMockCoreServiceServer creates a new mock instance.
func NewMockCoreServiceServer(ctrl *gomock.Controller) *MockCoreServiceServer {
	mock := &MockCoreServiceServer{ctrl: ctrl}
	mock.recorder = &MockCoreServiceServerMockRecorder{mock}
	return mock
}

// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockCoreServiceServer) EXPECT() *MockCoreServiceServerMockRecorder {
	return m.recorder
}

// ChildDeviceDetected mocks base method.
func (m *MockCoreServiceServer) ChildDeviceDetected(arg0 context.Context, arg1 *inter_container.DeviceDiscovery) (*voltha.Device, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ChildDeviceDetected", arg0, arg1)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildDeviceDetected indicates an expected call of ChildDeviceDetected.
func (mr *MockCoreServiceServerMockRecorder) ChildDeviceDetected(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDeviceDetected", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDeviceDetected), arg0, arg1)
}

// ChildDevicesDetected mocks base method.
func (m *MockCoreServiceServer) ChildDevicesDetected(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ChildDevicesDetected", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildDevicesDetected indicates an expected call of ChildDevicesDetected.
func (mr *MockCoreServiceServerMockRecorder) ChildDevicesDetected(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesDetected", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDevicesDetected), arg0, arg1)
}

// ChildDevicesLost mocks base method.
func (m *MockCoreServiceServer) ChildDevicesLost(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ChildDevicesLost", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildDevicesLost indicates an expected call of ChildDevicesLost.
func (mr *MockCoreServiceServerMockRecorder) ChildDevicesLost(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildDevicesLost", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildDevicesLost), arg0, arg1)
}

// ChildrenStateUpdate mocks base method.
func (m *MockCoreServiceServer) ChildrenStateUpdate(arg0 context.Context, arg1 *inter_container.DeviceStateFilter) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ChildrenStateUpdate", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ChildrenStateUpdate indicates an expected call of ChildrenStateUpdate.
func (mr *MockCoreServiceServerMockRecorder) ChildrenStateUpdate(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChildrenStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).ChildrenStateUpdate), arg0, arg1)
}

// DeleteAllPorts mocks base method.
func (m *MockCoreServiceServer) DeleteAllPorts(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeleteAllPorts", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeleteAllPorts indicates an expected call of DeleteAllPorts.
func (mr *MockCoreServiceServerMockRecorder) DeleteAllPorts(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAllPorts", reflect.TypeOf((*MockCoreServiceServer)(nil).DeleteAllPorts), arg0, arg1)
}

// DevicePMConfigUpdate mocks base method.
func (m *MockCoreServiceServer) DevicePMConfigUpdate(arg0 context.Context, arg1 *voltha.PmConfigs) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DevicePMConfigUpdate", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DevicePMConfigUpdate indicates an expected call of DevicePMConfigUpdate.
func (mr *MockCoreServiceServerMockRecorder) DevicePMConfigUpdate(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DevicePMConfigUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DevicePMConfigUpdate), arg0, arg1)
}

// DeviceReasonUpdate mocks base method.
func (m *MockCoreServiceServer) DeviceReasonUpdate(arg0 context.Context, arg1 *inter_container.DeviceReason) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeviceReasonUpdate", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeviceReasonUpdate indicates an expected call of DeviceReasonUpdate.
func (mr *MockCoreServiceServerMockRecorder) DeviceReasonUpdate(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceReasonUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceReasonUpdate), arg0, arg1)
}

// DeviceStateUpdate mocks base method.
func (m *MockCoreServiceServer) DeviceStateUpdate(arg0 context.Context, arg1 *inter_container.DeviceStateFilter) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeviceStateUpdate", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeviceStateUpdate indicates an expected call of DeviceStateUpdate.
func (mr *MockCoreServiceServerMockRecorder) DeviceStateUpdate(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceStateUpdate), arg0, arg1)
}

// DeviceUpdate mocks base method.
func (m *MockCoreServiceServer) DeviceUpdate(arg0 context.Context, arg1 *voltha.Device) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "DeviceUpdate", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// DeviceUpdate indicates an expected call of DeviceUpdate.
func (mr *MockCoreServiceServerMockRecorder) DeviceUpdate(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeviceUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).DeviceUpdate), arg0, arg1)
}

// GetChildDevice mocks base method.
func (m *MockCoreServiceServer) GetChildDevice(arg0 context.Context, arg1 *inter_container.ChildDeviceFilter) (*voltha.Device, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetChildDevice", arg0, arg1)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetChildDevice indicates an expected call of GetChildDevice.
func (mr *MockCoreServiceServerMockRecorder) GetChildDevice(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevice", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDevice), arg0, arg1)
}

// GetChildDeviceWithProxyAddress mocks base method.
func (m *MockCoreServiceServer) GetChildDeviceWithProxyAddress(arg0 context.Context, arg1 *voltha.Device_ProxyAddress) (*voltha.Device, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetChildDeviceWithProxyAddress", arg0, arg1)
	ret0, _ := ret[0].(*voltha.Device)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetChildDeviceWithProxyAddress indicates an expected call of GetChildDeviceWithProxyAddress.
func (mr *MockCoreServiceServerMockRecorder) GetChildDeviceWithProxyAddress(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDeviceWithProxyAddress", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDeviceWithProxyAddress), arg0, arg1)
}

// GetChildDevices mocks base method.
func (m *MockCoreServiceServer) GetChildDevices(arg0 context.Context, arg1 *common.ID) (*voltha.Devices, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetChildDevices", arg0, arg1)
	ret0, _ := ret[0].(*voltha.Devices)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetChildDevices indicates an expected call of GetChildDevices.
func (mr *MockCoreServiceServerMockRecorder) GetChildDevices(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetChildDevices", reflect.TypeOf((*MockCoreServiceServer)(nil).GetChildDevices), arg0, arg1)
}

// GetDevice mocks base method.
func (m *MockCoreServiceServer) 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 *MockCoreServiceServerMockRecorder) GetDevice(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockCoreServiceServer)(nil).GetDevice), arg0, arg1)
}

// GetDevicePort mocks base method.
func (m *MockCoreServiceServer) GetDevicePort(arg0 context.Context, arg1 *inter_container.PortFilter) (*voltha.Port, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetDevicePort", arg0, arg1)
	ret0, _ := ret[0].(*voltha.Port)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetDevicePort indicates an expected call of GetDevicePort.
func (mr *MockCoreServiceServerMockRecorder) GetDevicePort(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevicePort", reflect.TypeOf((*MockCoreServiceServer)(nil).GetDevicePort), arg0, arg1)
}

// GetHealthStatus mocks base method.
func (m *MockCoreServiceServer) GetHealthStatus(arg0 context.Context, arg1 *empty.Empty) (*voltha.HealthStatus, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetHealthStatus", arg0, arg1)
	ret0, _ := ret[0].(*voltha.HealthStatus)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetHealthStatus indicates an expected call of GetHealthStatus.
func (mr *MockCoreServiceServerMockRecorder) GetHealthStatus(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetHealthStatus", reflect.TypeOf((*MockCoreServiceServer)(nil).GetHealthStatus), arg0, arg1)
}

// GetPorts mocks base method.
func (m *MockCoreServiceServer) GetPorts(arg0 context.Context, arg1 *inter_container.PortFilter) (*voltha.Ports, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "GetPorts", arg0, arg1)
	ret0, _ := ret[0].(*voltha.Ports)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// GetPorts indicates an expected call of GetPorts.
func (mr *MockCoreServiceServerMockRecorder) GetPorts(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetPorts", reflect.TypeOf((*MockCoreServiceServer)(nil).GetPorts), arg0, arg1)
}

// ListDevicePorts mocks base method.
func (m *MockCoreServiceServer) 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 *MockCoreServiceServerMockRecorder) ListDevicePorts(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockCoreServiceServer)(nil).ListDevicePorts), arg0, arg1)
}

// PortCreated mocks base method.
func (m *MockCoreServiceServer) PortCreated(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "PortCreated", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PortCreated indicates an expected call of PortCreated.
func (mr *MockCoreServiceServerMockRecorder) PortCreated(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortCreated", reflect.TypeOf((*MockCoreServiceServer)(nil).PortCreated), arg0, arg1)
}

// PortStateUpdate mocks base method.
func (m *MockCoreServiceServer) PortStateUpdate(arg0 context.Context, arg1 *inter_container.PortState) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "PortStateUpdate", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PortStateUpdate indicates an expected call of PortStateUpdate.
func (mr *MockCoreServiceServerMockRecorder) PortStateUpdate(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).PortStateUpdate), arg0, arg1)
}

// PortsStateUpdate mocks base method.
func (m *MockCoreServiceServer) PortsStateUpdate(arg0 context.Context, arg1 *inter_container.PortStateFilter) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "PortsStateUpdate", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// PortsStateUpdate indicates an expected call of PortsStateUpdate.
func (mr *MockCoreServiceServerMockRecorder) PortsStateUpdate(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PortsStateUpdate", reflect.TypeOf((*MockCoreServiceServer)(nil).PortsStateUpdate), arg0, arg1)
}

// ReconcileChildDevices mocks base method.
func (m *MockCoreServiceServer) ReconcileChildDevices(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "ReconcileChildDevices", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// ReconcileChildDevices indicates an expected call of ReconcileChildDevices.
func (mr *MockCoreServiceServerMockRecorder) ReconcileChildDevices(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileChildDevices", reflect.TypeOf((*MockCoreServiceServer)(nil).ReconcileChildDevices), arg0, arg1)
}

// RegisterAdapter mocks base method.
func (m *MockCoreServiceServer) RegisterAdapter(arg0 context.Context, arg1 *inter_container.AdapterRegistration) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "RegisterAdapter", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// RegisterAdapter indicates an expected call of RegisterAdapter.
func (mr *MockCoreServiceServerMockRecorder) RegisterAdapter(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterAdapter", reflect.TypeOf((*MockCoreServiceServer)(nil).RegisterAdapter), arg0, arg1)
}

// SendPacketIn mocks base method.
func (m *MockCoreServiceServer) SendPacketIn(arg0 context.Context, arg1 *inter_container.PacketIn) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "SendPacketIn", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// SendPacketIn indicates an expected call of SendPacketIn.
func (mr *MockCoreServiceServerMockRecorder) SendPacketIn(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendPacketIn", reflect.TypeOf((*MockCoreServiceServer)(nil).SendPacketIn), arg0, arg1)
}

// UpdateImageDownload mocks base method.
func (m *MockCoreServiceServer) UpdateImageDownload(arg0 context.Context, arg1 *voltha.ImageDownload) (*empty.Empty, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "UpdateImageDownload", arg0, arg1)
	ret0, _ := ret[0].(*empty.Empty)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

// UpdateImageDownload indicates an expected call of UpdateImageDownload.
func (mr *MockCoreServiceServerMockRecorder) UpdateImageDownload(arg0, arg1 interface{}) *gomock.Call {
	mr.mock.ctrl.T.Helper()
	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateImageDownload", reflect.TypeOf((*MockCoreServiceServer)(nil).UpdateImageDownload), arg0, arg1)
}
