diff --git a/vendor/github.com/opencord/voltha-lib-go/v7/pkg/mocks/grpc/mock_core_services.go b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/mocks/grpc/mock_core_services.go
new file mode 100644
index 0000000..49abae7
--- /dev/null
+++ b/vendor/github.com/opencord/voltha-lib-go/v7/pkg/mocks/grpc/mock_core_services.go
@@ -0,0 +1,917 @@
+/*
+ * 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)
+}
