diff --git a/internal/pkg/application/application_test.go b/internal/pkg/application/application_test.go
index 15071e3..7d92230 100644
--- a/internal/pkg/application/application_test.go
+++ b/internal/pkg/application/application_test.go
@@ -22,6 +22,7 @@
 	"reflect"
 	"sync"
 	"testing"
+	"time"
 	"voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/internal/pkg/intf"
 	"voltha-go-controller/internal/pkg/of"
@@ -2697,3 +2698,241 @@
 		})
 	}
 }
+
+func TestVoltApplication_DeleteMacInPortMap(t *testing.T) {
+	type args struct {
+		macAddr net.HardwareAddr
+	}
+
+	macAdd, _ := net.ParseMAC("ff:ff:ff:ff:ff:ff")
+	macPort := map[string]string{}
+	macPort[macAdd.String()] = test_data
+
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "Positive_Case_DeleteMacInPortMap",
+			args: args{
+				macAddr: macAdd,
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{
+				macPortMap: macPort,
+			}
+			va.DeleteMacInPortMap(tt.args.macAddr)
+		})
+	}
+}
+
+func TestVoltApplication_TriggerPendingServiceDeactivateReq(t *testing.T) {
+	type args struct {
+		cntx   context.Context
+		device string
+	}
+	ServicesDeactivate := map[string]bool{}
+	ServicesDeactivate["SDX6320031-1_SDX6320031-1-4096-2310-4096-65"] = true
+	voltServ := &VoltService{
+		VoltServiceOper: VoltServiceOper{
+			Device: "SDX6320031",
+		},
+		VoltServiceCfg: VoltServiceCfg{
+			Name:          "SDX6320031-1_SDX6320031-1-4096-2310-4096-65",
+			SVlan:         4096,
+			CVlan:         2310,
+			UniVlan:       4096,
+			Port:          "16777472",
+			TechProfileID: 65,
+		},
+	}
+
+	voltPortVnets := make([]*VoltPortVnet, 0)
+	voltPortVnet := &VoltPortVnet{
+		Device:           "SDX6320031",
+		Port:             "16777472",
+		DeleteInProgress: false,
+		services:         sync.Map{},
+		SVlan:            4096,
+		CVlan:            2310,
+		UniVlan:          4096,
+		SVlanTpid:        65,
+		servicesCount:    atomic.NewUint64(1),
+	}
+
+	voltPortVnets = append(voltPortVnets, voltPortVnet)
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "Positive_Case_DeleteMacInPortMap",
+			args: args{
+				cntx:   context.Background(),
+				device: "SDX6320031",
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{
+				ServicesToDeactivate: ServicesDeactivate,
+				ServiceByName:        sync.Map{},
+				VnetsByPort:          sync.Map{},
+			}
+			va.ServiceByName.Store("SDX6320031-1_SDX6320031-1-4096-2310-4096-65", voltServ)
+			va.VnetsByPort.Store("16777472", voltPortVnets)
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			dbintf.EXPECT().PutService(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+			dbintf.EXPECT().PutVpv(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
+			va.TriggerPendingServiceDeactivateReq(tt.args.cntx, tt.args.device)
+		})
+	}
+}
+
+func TestVoltApplication_ReadAllFromDb(t *testing.T) {
+	type args struct {
+		cntx context.Context
+	}
+
+	migrationInfo := "migration done"
+	deviceConfig := DeviceConfig{
+		SerialNumber:       "SDX6320031",
+		UplinkPort:         "16777472",
+		HardwareIdentifier: "0.0.0.0",
+		IPAddress:          "127.26.1.74",
+		NasID:              "12345",
+		NniDhcpTrapVid:     123,
+	}
+
+	voltVnet := &VoltVnet{
+		Version: "v3",
+		VnetConfig: VnetConfig{
+			Name:      "2310-4096-4096",
+			VnetType:  "Encapsulation",
+			SVlan:     2310,
+			CVlan:     4096,
+			UniVlan:   4096,
+			SVlanTpid: 33024,
+		},
+
+		VnetOper: VnetOper{
+			PendingDeviceToDelete: "SDX6320031",
+			DeleteInProgress:      true,
+		},
+	}
+
+	cuncurrentMap := &util.ConcurrentMap{
+		Count: atomic.NewUint64(0),
+	}
+
+	vnetToDelete := map[string]bool{}
+	vnetToDelete["2310-4096-4096"] = true
+	macAdd, _ := net.ParseMAC("ff:ff:ff:ff:ff:ff")
+	voltPortVnet := &VoltPortVnet{
+		Device:           "SDX6320031",
+		Port:             "16777472",
+		DeleteInProgress: true,
+		MacAddr:          macAdd,
+	}
+
+	macPortMap := map[string]string{}
+	voltPortVnetsToDelete := map[*VoltPortVnet]bool{}
+	voltPortVnetsToDelete[voltPortVnet] = true
+	macPortMap[macAdd.String()] = "16777472"
+
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "Positive_Case_ReadAllFromDb",
+			args: args{
+				cntx: context.Background(),
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{
+				VnetsBySvlan:          util.NewConcurrentMap(),
+				VnetsToDelete:         vnetToDelete,
+				macPortMap:            macPortMap,
+				VoltPortVnetsToDelete: voltPortVnetsToDelete,
+				VnetsByName:           sync.Map{},
+			}
+
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			dbintf.EXPECT().GetMeters(gomock.Any()).AnyTimes()
+			vnet, _ := json.Marshal(voltVnet)
+			voltVnets := map[string]*kvstore.KVPair{}
+			voltVnets["2310-4096-4096"] = &kvstore.KVPair{
+				Key:   "2310-4096-4096",
+				Value: vnet,
+			}
+
+			va.VnetsBySvlan.Set(of.VlanAny, cuncurrentMap)
+			dbintf.EXPECT().GetVnets(gomock.Any()).AnyTimes().Return(voltVnets, nil).AnyTimes()
+			dbintf.EXPECT().PutVnet(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(nil).AnyTimes()
+			vpvs, _ := json.Marshal(voltPortVnet)
+			voltPort := map[string]*kvstore.KVPair{}
+			voltPort["16777472"] = &kvstore.KVPair{
+				Key:   "16777472",
+				Value: vpvs,
+			}
+			va.VnetsByName.Store("2310-4096-4096", voltVnet)
+			dbintf.EXPECT().GetVpvs(gomock.Any()).AnyTimes().Return(voltPort, nil).AnyTimes()
+			dbintf.EXPECT().GetServices(gomock.Any()).AnyTimes()
+			dbintf.EXPECT().GetMvlans(gomock.Any()).AnyTimes()
+			dbintf.EXPECT().GetIgmpProfiles(gomock.Any()).AnyTimes()
+			dbintf.EXPECT().GetMcastConfigs(gomock.Any()).AnyTimes()
+			dbintf.EXPECT().GetIgmpGroups(gomock.Any()).AnyTimes()
+			dbintf.EXPECT().GetMigrationInfo(gomock.Any()).Return(migrationInfo, nil).AnyTimes()
+			dbintf.EXPECT().GetOltFlowService(gomock.Any()).AnyTimes()
+			b, _ := json.Marshal(deviceConfig)
+			test := map[string]*kvstore.KVPair{}
+			test["SDX6320031"] = &kvstore.KVPair{
+				Key:   "SDX6320031",
+				Value: b,
+			}
+			dbintf.EXPECT().GetDeviceConfig(gomock.Any()).Return(test, nil).AnyTimes()
+			dbintf.EXPECT().PutDeviceConfig(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+			va.ReadAllFromDb(tt.args.cntx)
+		})
+	}
+}
+
+func TestVoltApplication_RemoveGroupDevicesFromPendingPool(t *testing.T) {
+	type args struct {
+		ig *IgmpGroup
+	}
+	pendingGroupForDevice := map[string]time.Time{}
+	pendingGroupForDevice[test_device] = time.Now()
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "VoltApplication_RemoveGroupDevicesFromPendingPool",
+			args: args{
+				ig: &IgmpGroup{
+					Version:               "test_version",
+					PendingGroupForDevice: pendingGroupForDevice,
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{}
+			va.RemoveGroupDevicesFromPendingPool(tt.args.ig)
+		})
+	}
+}
diff --git a/internal/pkg/application/dhcprelay_test.go b/internal/pkg/application/dhcprelay_test.go
new file mode 100644
index 0000000..2354d41
--- /dev/null
+++ b/internal/pkg/application/dhcprelay_test.go
@@ -0,0 +1,637 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ */
+
+package application
+
+import (
+	"context"
+	"encoding/json"
+	"net"
+	"reflect"
+	"sync"
+	"testing"
+	"voltha-go-controller/internal/pkg/of"
+	"voltha-go-controller/internal/test/mocks"
+
+	"github.com/golang/mock/gomock"
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestVoltApplication_GetIgnoredPorts(t *testing.T) {
+	voltDevice := &VoltDevice{
+		Name:         "11c3175b-50f3-4220-9555-93df733ded1d",
+		SerialNum:    "SDX6320031",
+		SouthBoundID: "68580342-6b3e-57cb-9ea4-06125594e330",
+		NniPort:      "16777472",
+		Ports:        sync.Map{},
+		PonPortList:  sync.Map{},
+	}
+	voltPort := &VoltPort{
+		Name:                     "16777472",
+		Device:                   "SDX6320031",
+		ID:                       16777472,
+		State:                    PortStateDown,
+		ChannelPerSubAlarmRaised: false,
+		Type:                     VoltPortTypeNni,
+	}
+	voltPortVnets := make([]*VoltPortVnet, 0)
+	voltPortVnet := &VoltPortVnet{
+		Device:      "SDX6320031",
+		Port:        "16777472",
+		MacLearning: MacLearningNone,
+	}
+	voltPortVnets = append(voltPortVnets, voltPortVnet)
+	IgnoredPorts := make(map[string][]string)
+	IgnoredPorts["SDX6320031"] = append(IgnoredPorts["SDX6320031"], "16777472")
+	tests := []struct {
+		name    string
+		want    map[string][]string
+		wantErr bool
+	}{
+		{
+			name:    "Positive_Case_GetIgnoredPorts",
+			want:    IgnoredPorts,
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{
+				DevicesDisc: sync.Map{},
+			}
+			va.DevicesDisc.Store("SDX6320031", voltDevice)
+			voltDevice.Ports.Store("16777472", voltPort)
+			voltApp := GetApplication()
+			voltApp.VnetsByPort.Store("16777472", voltPortVnets)
+			got, err := va.GetIgnoredPorts()
+			if (err != nil) != tt.wantErr {
+				t.Errorf("VoltApplication.GetIgnoredPorts() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("VoltApplication.GetIgnoredPorts() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestDhcpNetworks_AddDhcpSession(t *testing.T) {
+	pkt := mocks.NewMockPacket(gomock.NewController(t))
+	type args struct {
+		pkt     gopacket.Packet
+		session IDhcpRelaySession
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "DhcpNetworks_AddDhcpSession",
+			args: args{
+				pkt:     pkt,
+				session: &VoltPortVnet{},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			network := make(map[uint32]*DhcpRelayVnet)
+			dn := &DhcpNetworks{
+				Networks: network,
+			}
+			pkt.EXPECT().Layer(layers.LayerTypeEthernet).Return(eth).Times(1)
+			if err := dn.AddDhcpSession(tt.args.pkt, tt.args.session); (err != nil) != tt.wantErr {
+				t.Errorf("DhcpNetworks.AddDhcpSession() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestDhcpNetworks_DelDhcpSession(t *testing.T) {
+	pkt := mocks.NewMockPacket(gomock.NewController(t))
+	type args struct {
+		pkt     gopacket.Packet
+		session IDhcpRelaySession
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "DhcpNetworks_DelDhcpSession",
+			args: args{
+				pkt:     pkt,
+				session: &VoltPortVnet{},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			network := make(map[uint32]*DhcpRelayVnet)
+			dn := &DhcpNetworks{
+				Networks: network,
+			}
+			pkt.EXPECT().Layer(layers.LayerTypeEthernet).Return(eth).Times(1)
+			dn.DelDhcpSession(tt.args.pkt, tt.args.session)
+		})
+	}
+}
+
+func TestDhcpNetworks_AddDhcp6Session(t *testing.T) {
+	type args struct {
+		key     [MaxLenDhcpv6DUID]byte
+		session IDhcpRelaySession
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "DhcpNetworks_AddDhcp6Session",
+			args: args{
+				session: &VoltPortVnet{},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			network := make(map[uint32]*DhcpRelayVnet)
+			dn := &DhcpNetworks{
+				Networks: network,
+			}
+			if err := dn.AddDhcp6Session(tt.args.key, tt.args.session); (err != nil) != tt.wantErr {
+				t.Errorf("DhcpNetworks.AddDhcp6Session() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestDhcpNetworks_DelDhcp6Session(t *testing.T) {
+	type args struct {
+		key     [MaxLenDhcpv6DUID]byte
+		session IDhcpRelaySession
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "DhcpNetworks_DelDhcp6Session",
+			args: args{
+				session: &VoltPortVnet{},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			network := make(map[uint32]*DhcpRelayVnet)
+			network[uint32(4097)] = &DhcpRelayVnet{
+				InnerVlan: uint16(4097),
+			}
+			dn := &DhcpNetworks{
+				Networks: network,
+			}
+			dn.DelDhcp6Session(tt.args.key, tt.args.session)
+		})
+	}
+}
+
+func TestDhcpNetworks_GetDhcpSession(t *testing.T) {
+	type fields struct {
+		Networks map[uint32]*DhcpRelayVnet
+	}
+	type args struct {
+		outerVlan uint16
+		innerVlan uint16
+		addr      net.HardwareAddr
+	}
+	macAdd, _ := net.ParseMAC("ff:ff:ff:ff:ff:ff")
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+		want   IDhcpRelaySession
+	}{
+		{
+			name: "DhcpNetworks_GetDhcpSession",
+			args: args{
+				outerVlan: uint16(0),
+				innerVlan: uint16(4097),
+				addr:      macAdd,
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			network := make(map[uint32]*DhcpRelayVnet)
+			network[uint32(4097)] = &DhcpRelayVnet{
+				InnerVlan: uint16(4097),
+			}
+			dn := &DhcpNetworks{
+				Networks: network,
+			}
+			got, err := dn.GetDhcpSession(tt.args.outerVlan, tt.args.innerVlan, tt.args.addr)
+			assert.NotNil(t, err)
+			assert.Nil(t, got)
+		})
+	}
+}
+
+func TestDhcpNetworks_GetDhcp6Session(t *testing.T) {
+	type fields struct {
+		Networks map[uint32]*DhcpRelayVnet
+	}
+	type args struct {
+		outerVlan uint16
+		innerVlan uint16
+		key       [MaxLenDhcpv6DUID]byte
+	}
+	tests := []struct {
+		name    string
+		fields  fields
+		args    args
+		want    IDhcpRelaySession
+		wantErr bool
+	}{
+		{
+			name: "DhcpNetworks_GetDhcp6Session",
+			args: args{
+				outerVlan: uint16(0),
+				innerVlan: uint16(4097),
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			network := make(map[uint32]*DhcpRelayVnet)
+			network[uint32(4097)] = &DhcpRelayVnet{
+				InnerVlan: uint16(4097),
+			}
+			dn := &DhcpNetworks{
+				Networks: network,
+			}
+			got, err := dn.GetDhcp6Session(tt.args.outerVlan, tt.args.innerVlan, tt.args.key)
+			assert.NotNil(t, err)
+			assert.Nil(t, got)
+		})
+	}
+}
+
+func TestGetVnetForV4Nni(t *testing.T) {
+	type args struct {
+		dhcp  *layers.DHCPv4
+		cvlan of.VlanType
+		svlan of.VlanType
+		pbit  uint8
+	}
+	macAdd, _ := net.ParseMAC("ff:ff:ff:ff:ff:ff")
+	tests := []struct {
+		name    string
+		args    args
+		want    []*VoltPortVnet
+		wantErr bool
+	}{
+		{
+			name: "GetVnetForV4Nni",
+			args: args{
+				cvlan: of.VlanAny,
+				svlan: of.VlanAny,
+				dhcp: &layers.DHCPv4{
+					BaseLayer:    dot1Q.BaseLayer,
+					ClientHWAddr: macAdd,
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := GetVnetForV4Nni(tt.args.dhcp, tt.args.cvlan, tt.args.svlan, tt.args.pbit)
+			assert.NotNil(t, err)
+			assert.Nil(t, got)
+		})
+	}
+}
+
+func TestGetVnetForV6Nni(t *testing.T) {
+	type args struct {
+		dhcp      *layers.DHCPv6
+		cvlan     of.VlanType
+		svlan     of.VlanType
+		pbit      uint8
+		clientMAC net.HardwareAddr
+	}
+	macAdd, _ := net.ParseMAC("ff:ff:ff:ff:ff:ff")
+	tests := []struct {
+		name    string
+		args    args
+		want    []*VoltPortVnet
+		want1   net.HardwareAddr
+		wantErr bool
+	}{
+		{
+			name: "GetVnetForV6Nni",
+			args: args{
+				dhcp: &layers.DHCPv6{
+					BaseLayer: dot1Q.BaseLayer,
+					Options: layers.DHCPv6Options{
+						{
+							Code: layers.DHCPv6OptClientID,
+							Data: []byte{2, 3, 4, 2, 3, 4, 2, 3, 4},
+						},
+					},
+				},
+				cvlan:     of.VlanAny,
+				svlan:     of.VlanAny,
+				clientMAC: macAdd,
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, got1, err := GetVnetForV6Nni(tt.args.dhcp, tt.args.cvlan, tt.args.svlan, tt.args.pbit, tt.args.clientMAC)
+			assert.NotNil(t, err)
+			assert.Nil(t, got)
+			assert.NotNil(t, got1)
+		})
+	}
+}
+
+func TestAddDhcpv4Option82(t *testing.T) {
+	type args struct {
+		svc    *VoltService
+		rID    []byte
+		dhcpv4 *layers.DHCPv4
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "AddDhcpv4Option82",
+			args: args{
+				svc: &VoltService{
+					VoltServiceCfg: VoltServiceCfg{
+						CircuitID:    "test_circuit_id",
+						DataRateAttr: DSLAttrEnabled,
+					},
+				},
+				rID: []byte{1},
+				dhcpv4: &layers.DHCPv4{
+					Options: layers.DHCPOptions{
+						{
+							Type: layers.DHCPOptARPTimeout,
+						},
+					},
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			AddDhcpv4Option82(tt.args.svc, tt.args.rID, tt.args.dhcpv4)
+		})
+	}
+}
+
+func TestVoltApplication_ProcessDsDhcpv4Packet(t *testing.T) {
+	pkt := mocks.NewMockPacket(gomock.NewController(t))
+	type args struct {
+		cntx   context.Context
+		device string
+		port   string
+		pkt    gopacket.Packet
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "VoltApplication_ProcessDsDhcpv4Packet",
+			args: args{
+				cntx:   context.Background(),
+				device: test_device,
+				port:   "test_port",
+				pkt:    pkt,
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{}
+			iPv4 := &layers.IPv4{
+				Version: uint8(1),
+			}
+			uDP := &layers.UDP{
+				Length: uint16(1),
+			}
+			dHCPv4 := &layers.DHCPv4{
+				HardwareLen: uint8(1),
+			}
+			dot1Q_test := &layers.Dot1Q{
+				Priority: uint8(1),
+			}
+			pkt.EXPECT().Layer(layers.LayerTypeEthernet).Return(eth).Times(1)
+			pkt.EXPECT().Layer(layers.LayerTypeIPv4).Return(iPv4).Times(1)
+			pkt.EXPECT().Layer(layers.LayerTypeUDP).Return(uDP).Times(1)
+			pkt.EXPECT().Layer(layers.LayerTypeDHCPv4).Return(dHCPv4).Times(1)
+			pkt.EXPECT().Layer(layers.LayerTypeDot1Q).Return(dot1Q_test).Times(1)
+			pkt.EXPECT().Layers().Return(LayerTypeDot2Q).Times(1)
+			va.ProcessDsDhcpv4Packet(tt.args.cntx, tt.args.device, tt.args.port, tt.args.pkt)
+		})
+	}
+}
+
+func TestDelOption82(t *testing.T) {
+	type args struct {
+		dhcpv4 *layers.DHCPv4
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "DelOption82",
+			args: args{
+				dhcpv4: &layers.DHCPv4{
+					Options: layers.DHCPOptions{
+						{
+							Type: opt82,
+						},
+					},
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			DelOption82(tt.args.dhcpv4)
+		})
+	}
+}
+
+func TestDhcpMsgType(t *testing.T) {
+	type args struct {
+		dhcp *layers.DHCPv4
+	}
+	tests := []struct {
+		name string
+		args args
+		want layers.DHCPMsgType
+	}{
+		{
+			name: "DhcpMsgType",
+			args: args{
+				dhcp: &layers.DHCPv4{
+					Options: layers.DHCPOptions{
+						{
+							Type: layers.DHCPOptMessageType,
+							Data: []byte{1},
+						},
+					},
+				},
+			},
+			want: layers.DHCPMsgTypeDiscover,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := DhcpMsgType(tt.args.dhcp); !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("DhcpMsgType() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestGetIpv4Addr(t *testing.T) {
+	type args struct {
+		dhcp *layers.DHCPv4
+	}
+	tests := []struct {
+		name  string
+		args  args
+		want  net.IP
+		want1 int64
+	}{
+		{
+			name: "GetIpv4Addr",
+			args: args{
+				dhcp: &layers.DHCPv4{
+					Options: layers.DHCPOptions{
+						{
+							Type: layers.DHCPOptLeaseTime,
+							Data: []byte{1, 2, 3, 4, 5},
+						},
+					},
+				},
+			},
+			want1: int64(16909060),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, got1 := GetIpv4Addr(tt.args.dhcp)
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetIpv4Addr() got = %v, want %v", got, tt.want)
+			}
+			if got1 != tt.want1 {
+				t.Errorf("GetIpv4Addr() got1 = %v, want %v", got1, tt.want1)
+			}
+		})
+	}
+}
+
+func TestGetIpv6Addr(t *testing.T) {
+	type args struct {
+		dhcp6 *layers.DHCPv6
+	}
+	b, err := json.Marshal(layers.DHCPv6OptIAAddr)
+	if err != nil {
+		panic(err)
+	}
+	tests := []struct {
+		name  string
+		args  args
+		want  net.IP
+		want1 uint32
+	}{
+		{
+			name: "GetIpv6Addr_error",
+			args: args{
+				dhcp6: &layers.DHCPv6{
+					MsgType: layers.DHCPv6MsgTypeReply,
+					Options: layers.DHCPv6Options{
+						{
+							Code: layers.DHCPv6OptIANA,
+							Data: b,
+						},
+					},
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, got1 := GetIpv6Addr(tt.args.dhcp6)
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("GetIpv6Addr() got = %v, want %v", got, tt.want)
+			}
+			if got1 != tt.want1 {
+				t.Errorf("GetIpv6Addr() got1 = %v, want %v", got1, tt.want1)
+			}
+		})
+	}
+}
+
+func TestVoltApplication_GetMacLearnerInfo(t *testing.T) {
+	type args struct {
+		cntx       context.Context
+		deviceID   string
+		portNumber string
+		vlanID     string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		want    MacLearnerInfo
+		wantErr bool
+	}{
+		{
+			name: "VoltApplication_GetMacLearnerInfo",
+			args: args{
+				cntx:       context.Background(),
+				deviceID:   test_device,
+				portNumber: "test_port_number",
+				vlanID:     "test_vlanID",
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{}
+			got, err := va.GetMacLearnerInfo(tt.args.cntx, tt.args.deviceID, tt.args.portNumber, tt.args.vlanID)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("VoltApplication.GetMacLearnerInfo() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("VoltApplication.GetMacLearnerInfo() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/application/flowevent_test.go b/internal/pkg/application/flowevent_test.go
index 400176a..b6b8738 100644
--- a/internal/pkg/application/flowevent_test.go
+++ b/internal/pkg/application/flowevent_test.go
@@ -132,6 +132,21 @@
 				},
 			},
 		},
+		{
+			name: "ProcessUsIgmpFlowAddEvent_else_condition",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					device:    "test_device",
+					eType:     EventTypeControlFlowAdded,
+					eventData: voltPortVnet,
+				},
+				flowStatus: intf.FlowStatus{
+					Device: "test_device",
+					Status: uint32(1001),
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -161,6 +176,19 @@
 				},
 			},
 		},
+		{
+			name: "ProcessServiceFlowAddEvent_else_condition",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					device:    "test_device",
+					eventData: voltService,
+				},
+				flowStatus: intf.FlowStatus{
+					Status: uint32(1001),
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -188,6 +216,18 @@
 				},
 			},
 		},
+		{
+			name: "ProcessControlFlowAddEvent_else_condition",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					eventData: voltPortVnet,
+				},
+				flowStatus: intf.FlowStatus{
+					Status: uint32(1001),
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -215,6 +255,18 @@
 				},
 			},
 		},
+		{
+			name: "ProcessServiceFlowDelEvent_else_condition",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					eventData: voltService,
+				},
+				flowStatus: intf.FlowStatus{
+					Status: uint32(1001),
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -245,6 +297,18 @@
 				},
 			},
 		},
+		{
+			name: "ProcessControlFlowDelEvent_else_condition",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					eventData: voltPortVnet,
+				},
+				flowStatus: intf.FlowStatus{
+					Status: uint32(1001),
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -278,6 +342,18 @@
 				},
 			},
 		},
+		{
+			name: "ProcessMcastFlowDelEvent_else_condition",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					eventData: mvlanProfile,
+				},
+				flowStatus: intf.FlowStatus{
+					Status: uint32(1001),
+				},
+			},
+		},
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -288,3 +364,56 @@
 		})
 	}
 }
+
+func TestProcessDeviceFlowDelEvent(t *testing.T) {
+	type args struct {
+		cntx       context.Context
+		event      *FlowEvent
+		flowStatus intf.FlowStatus
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "ProcessDeviceFlowDelEvent",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					device:    test_device,
+					eventData: voltVnet,
+				},
+				flowStatus: intf.FlowStatus{
+					Device: test_device,
+				},
+			},
+		},
+		{
+			name: "ProcessDeviceFlowDelEvent_else_condition",
+			args: args{
+				cntx: context.Background(),
+				event: &FlowEvent{
+					device:    test_device,
+					eventData: voltVnet,
+				},
+				flowStatus: intf.FlowStatus{
+					Device: test_device,
+					Status: uint32(1001),
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			switch tt.name {
+			case "ProcessDeviceFlowDelEvent":
+				dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+				db = dbintf
+				dbintf.EXPECT().PutVnet(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes().Return(nil).AnyTimes()
+				ProcessDeviceFlowDelEvent(tt.args.cntx, tt.args.event, tt.args.flowStatus)
+			case "ProcessDeviceFlowDelEvent_else_condition":
+				ProcessDeviceFlowDelEvent(tt.args.cntx, tt.args.event, tt.args.flowStatus)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/application/major_upgrade_test.go b/internal/pkg/application/major_upgrade_test.go
new file mode 100644
index 0000000..47e1f45
--- /dev/null
+++ b/internal/pkg/application/major_upgrade_test.go
@@ -0,0 +1,1038 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ */
+
+package application
+
+import (
+	"context"
+	"encoding/json"
+	"errors"
+	"reflect"
+	"testing"
+	"voltha-go-controller/internal/test/mocks"
+
+	"github.com/golang/mock/gomock"
+	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
+)
+
+func TestDeleteDbPathKeys(t *testing.T) {
+	type args struct {
+		cntx    context.Context
+		keyPath string
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "Positive_Case_DeleteDbPathKeys",
+			args: args{
+				cntx:    context.Background(),
+				keyPath: "test_key",
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			dbintf.EXPECT().DeleteAll(gomock.Any(), gomock.Any()).AnyTimes()
+			if err := DeleteDbPathKeys(tt.args.cntx, tt.args.keyPath); (err != nil) != tt.wantErr {
+				t.Errorf("DeleteDbPathKeys() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestMigrateVnets(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	voltVnet_test := &VoltVnet{
+		Version: "v3",
+		VnetConfig: VnetConfig{
+			Name:      "2310-4096-4096",
+			VnetType:  "Encapsulation",
+			SVlan:     2310,
+			CVlan:     4096,
+			UniVlan:   4096,
+			SVlanTpid: 0,
+			DhcpRelay: true,
+		},
+		VnetOper: VnetOper{
+			PendingDeviceToDelete: "SDX63200313",
+		},
+	}
+
+	byteData, _ := json.Marshal(voltVnet_test)
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_DeleteDbPathKeys",
+			args: args{
+				cntx: context.Background(),
+				data: byteData,
+			},
+			want: string(byteData),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateVnets(tt.args.cntx, tt.args.data); reflect.DeepEqual(got, tt.want) {
+				t.Errorf("MigrateVnets() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateServices(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	vsmap := make(map[string]interface{})
+	vsmap["MecLearning"] = true
+	byteData, _ := json.Marshal(&vsmap)
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateServices",
+			args: args{
+				cntx: context.Background(),
+				data: byteData,
+			},
+			want: string(byteData),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateServices(tt.args.cntx, tt.args.data); reflect.DeepEqual(got, tt.want) {
+				t.Errorf("MigrateServices() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateVpvs(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	vpvmap := make(map[string]interface{})
+	byteData, _ := json.Marshal(&vpvmap)
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateVpvs",
+			args: args{
+				cntx: context.Background(),
+				data: byteData,
+			},
+			want: string(byteData),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateVpvs(tt.args.cntx, tt.args.data); reflect.DeepEqual(got, tt.want) {
+				t.Errorf("MigrateVpvs() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateMvlans(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	devicesList := make(map[string]OperInProgress)
+	devicesList["SDX6320031"] = opt82
+	mvp := &MvlanProfile{
+		DevicesList: devicesList,
+	}
+	byteData, _ := json.Marshal(mvp)
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateMvlans",
+			args: args{
+				cntx: context.Background(),
+				data: byteData,
+			},
+			want: string(byteData),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateMvlans(tt.args.cntx, tt.args.data); reflect.DeepEqual(got, tt.want) {
+				t.Errorf("MigrateMvlans() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateIgmpConfs(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	igmpProfile_data := IgmpProfile{
+		ProfileID: "test_profile_id",
+	}
+	b, err := json.Marshal(igmpProfile_data)
+	if err != nil {
+		panic(err)
+	}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "test_MigrateIgmpConfs",
+			args: args{
+				cntx: context.Background(),
+				data: b,
+			},
+			want: "ModuleToBeDeleted",
+		},
+		{
+			name: "unmarshal error",
+			args: args{
+				cntx: context.Background(),
+				data: []byte{},
+			},
+		},
+		{
+			name: "WriteToDb_error",
+			args: args{
+				cntx: context.Background(),
+				data: b,
+			},
+			want: "ModuleToBeDeleted",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			switch tt.name {
+			case "test_MigrateIgmpConfs":
+				dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+				db = dbintf
+				dbintf.EXPECT().PutIgmpProfile(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
+				if got := MigrateIgmpConfs(tt.args.cntx, tt.args.data); got != tt.want {
+					t.Errorf("MigrateIgmpConfs() = %v, want %v", got, tt.want)
+				}
+			case "unmarshal error":
+				if got := MigrateIgmpConfs(tt.args.cntx, tt.args.data); got != tt.want {
+					t.Errorf("MigrateIgmpConfs() = %v, want %v", got, tt.want)
+				}
+			case "WriteToDb_error":
+				dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+				db = dbintf
+				dbintf.EXPECT().PutIgmpProfile(gomock.Any(), gomock.Any(), gomock.Any()).Return(errors.New("error"))
+				if got := MigrateIgmpConfs(tt.args.cntx, tt.args.data); got != tt.want {
+					t.Errorf("MigrateIgmpConfs() = %v, want %v", got, tt.want)
+				}
+			}
+		})
+	}
+}
+
+func TestMigrateIgmpGroups(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateIgmpGroups",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateIgmpGroups(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateIgmpGroups() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateIgmpDevices(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateIgmpDevices",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateIgmpDevices(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateIgmpDevices() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateIgmpChannels(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateIgmpChannels",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateIgmpChannels(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateIgmpChannels() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateIgmpPorts(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateIgmpPorts",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateIgmpPorts(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateIgmpPorts() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateIgmpProfs(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateIgmpProfs",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateIgmpProfs(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateIgmpProfs() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateMcastConfs(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateMcastConfs",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateMcastConfs(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateMcastConfs() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateLogLevels(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateLogLevels",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateLogLevels(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateLogLevels() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateHealth(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateHealth",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateHealth(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateHealth() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigratePonCounters(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigratePonCounters",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigratePonCounters(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigratePonCounters() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateChannelCounters(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateChannelCounters",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateChannelCounters(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateChannelCounters() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateServiceCounters(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateServiceCounters",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateServiceCounters(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateServiceCounters() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateNbDevices(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateNbDevices",
+			args: args{
+				cntx: context.Background(),
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateNbDevices(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateNbDevices() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateFlowHash(t *testing.T) {
+	type args struct {
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateFlowHash(tt.args.data); got != tt.want {
+				t.Errorf("MigrateFlowHash() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateMeters(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateMeters",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateMeters(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateMeters() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateDevices(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateDevices(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateDevices() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateDevicePorts(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateDevicePorts(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateDevicePorts() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateDeviceFlows(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateDeviceFlows(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateDeviceFlows() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateDeviceGroups(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateDeviceGroups(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateDeviceGroups() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateDeviceMeters(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateDeviceMeters(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateDeviceMeters() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestMigrateDeviceFlowHash(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		data []byte
+	}
+	data := []byte{}
+	tests := []struct {
+		name string
+		args args
+		want string
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				data: data,
+			},
+			want: "",
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := MigrateDeviceFlowHash(tt.args.cntx, tt.args.data); got != tt.want {
+				t.Errorf("MigrateDeviceFlowHash() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestFetchAndMigrateDeviceDBData(t *testing.T) {
+	type args struct {
+		module string
+	}
+	var module string
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				module: module,
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := FetchAndMigrateDeviceDBData(tt.args.module); (err != nil) != tt.wantErr {
+				t.Errorf("FetchAndMigrateDeviceDBData() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestDataMigration_WriteToDb(t *testing.T) {
+	type args struct {
+		cntx context.Context
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "Positive_Case_MigrateFlowHash",
+			args: args{
+				cntx: context.Background(),
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			md := &DataMigration{}
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			dbintf.EXPECT().PutMigrationInfo(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+			if err := md.WriteToDb(tt.args.cntx); (err != nil) != tt.wantErr {
+				t.Errorf("DataMigration.WriteToDb() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestGetMigrationInfo(t *testing.T) {
+	type args struct {
+		cntx   context.Context
+		dmInfo *DataMigration
+	}
+	dmInfo := &DataMigration{
+		Version: "v1",
+		Status:  "done",
+	}
+	dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+	db = dbintf
+	dbintf.EXPECT().GetMigrationInfo(gomock.Any()).Return("migrationInfo", nil).AnyTimes()
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "Positive_Case_GetMigrationInfo",
+			args: args{
+				cntx:   context.Background(),
+				dmInfo: dmInfo,
+			},
+			wantErr: true,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := GetMigrationInfo(tt.args.cntx, tt.args.dmInfo); (err != nil) != tt.wantErr {
+				t.Errorf("GetMigrationInfo() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
+
+func TestCheckIfMigrationRequired(t *testing.T) {
+	type args struct {
+		ctx context.Context
+	}
+
+	dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+	db = dbintf
+	dbintf.EXPECT().GetMigrationInfo(gomock.Any()).Return("Migration_Info", nil).AnyTimes()
+	dbintf.EXPECT().PutMigrationInfo(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+	tests := []struct {
+		name string
+		args args
+		want bool
+	}{
+		{
+			name: "Positive_Case_CheckIfMigrationRequired",
+			args: args{
+				ctx: context.Background(),
+			},
+			want: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := CheckIfMigrationRequired(tt.args.ctx); got != tt.want {
+				t.Errorf("CheckIfMigrationRequired() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
+func TestDataMigration_DelFromDb(t *testing.T) {
+	type args struct {
+		cntx context.Context
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "Positive_Case_DelFromDb",
+			args: args{
+				cntx: context.Background(),
+			},
+		},
+		{
+			name: "Negetive_Case_DelFromDb",
+			args: args{
+				cntx: context.Background(),
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			md := &DataMigration{}
+			switch tt.name {
+			case "Positive_Case_DelFromDb":
+				dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+				db = dbintf
+				dbintf.EXPECT().DelMigrationInfo(gomock.Any()).Return(nil).AnyTimes()
+			case "Negetive_Case_DelFromDb":
+				myError := errors.New("WRONG MESSAGE")
+				dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+				db = dbintf
+				dbintf.EXPECT().DelMigrationInfo(gomock.Any()).Return(myError).AnyTimes()
+			}
+			md.DelFromDb(tt.args.cntx)
+		})
+	}
+}
+
+func TestMigrateDBData(t *testing.T) {
+	type args struct {
+		cntx context.Context
+	}
+	byteArr := []byte{23}
+	dbPathKeysValueMap := map[string]*kvstore.KVPair{}
+	dbPathKeysValueMap["devices/%s/flows/"] = &kvstore.KVPair{
+		Key:   "devices/%s/flows/",
+		Value: byteArr,
+	}
+
+	dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+	db = dbintf
+	dbintf.EXPECT().List(gomock.Any(), gomock.Any()).Return(dbPathKeysValueMap, nil).AnyTimes()
+
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "Positive_Case_DelFromDb",
+			args: args{
+				cntx: context.Background(),
+			},
+			wantErr: true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if err := MigrateDBData(tt.args.cntx); (err != nil) != tt.wantErr {
+				t.Errorf("MigrateDBData() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/application/pppoeia_test.go b/internal/pkg/application/pppoeia_test.go
index 45b76fa..fc07d1f 100644
--- a/internal/pkg/application/pppoeia_test.go
+++ b/internal/pkg/application/pppoeia_test.go
@@ -264,3 +264,35 @@
 		})
 	}
 }
+
+func TestAddIaOption(t *testing.T) {
+	type args struct {
+		svc   *VoltService
+		pppoe *layers.PPPoE
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "AddIaOption",
+			args: args{
+				svc: &VoltService{
+					VoltServiceCfg: VoltServiceCfg{
+						CircuitID:    "test_circuit_id",
+						RemoteID:     []byte{1},
+						DataRateAttr: DSLAttrEnabled,
+					},
+				},
+				pppoe: &layers.PPPoE{
+					Options: make(layers.PPPoEOptions, 1),
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			AddIaOption(tt.args.svc, tt.args.pppoe)
+		})
+	}
+}
diff --git a/internal/pkg/application/service_test.go b/internal/pkg/application/service_test.go
index 21bc49d..7622016 100644
--- a/internal/pkg/application/service_test.go
+++ b/internal/pkg/application/service_test.go
@@ -42,11 +42,13 @@
 	Device: test_device,
 }
 var voltDevice = &VoltDevice{
-	Name:            "test_name",
-	State:           controller.DeviceStateUP,
-	FlowAddEventMap: util.NewConcurrentMap(),
-	FlowDelEventMap: util.NewConcurrentMap(),
-	SerialNum:       "test_serial_number",
+	Name:                         "test_name",
+	State:                        controller.DeviceStateUP,
+	FlowAddEventMap:              util.NewConcurrentMap(),
+	FlowDelEventMap:              util.NewConcurrentMap(),
+	SerialNum:                    "test_serial_number",
+	ConfiguredVlanForDeviceFlows: util.NewConcurrentMap(),
+	NniPort:                      "16777216",
 }
 
 var voltMeter = &VoltMeter{
diff --git a/internal/pkg/application/vnets.go b/internal/pkg/application/vnets.go
index 1374faa..2a9d4b2 100644
--- a/internal/pkg/application/vnets.go
+++ b/internal/pkg/application/vnets.go
@@ -20,6 +20,7 @@
 	"encoding/json"
 	"errors"
 	"net"
+	"reflect"
 	"strconv"
 	"sync"
 	"time"
@@ -2260,7 +2261,7 @@
 	}
 	vpvs := vpvsIntf.([]*VoltPortVnet)
 	for i, lvpv := range vpvs {
-		if lvpv == vpv {
+		if reflect.DeepEqual(lvpv, vpv) {
 			logger.Debugw(ctx, "Deleting VPV from port", log.Fields{"Port": vpv.Port, "SVLAN": vpv.SVlan, "CVLAN": vpv.CVlan,
 				"UNIVLAN": vpv.UniVlan})
 
diff --git a/internal/pkg/application/vnets_test.go b/internal/pkg/application/vnets_test.go
index 8942dbb..5a26bea 100644
--- a/internal/pkg/application/vnets_test.go
+++ b/internal/pkg/application/vnets_test.go
@@ -17,7 +17,10 @@
 
 import (
 	"context"
+	"encoding/json"
+	"net"
 	"reflect"
+	"sync"
 	"testing"
 	cntlr "voltha-go-controller/internal/pkg/controller"
 	"voltha-go-controller/internal/pkg/of"
@@ -25,6 +28,7 @@
 	"voltha-go-controller/internal/test/mocks"
 
 	"github.com/golang/mock/gomock"
+	"github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -645,3 +649,248 @@
 		})
 	}
 }
+
+func TestVoltApplication_RestoreVnetsFromDb(t *testing.T) {
+	type args struct {
+		cntx context.Context
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "VoltApplication_RestoreVnetsFromDb",
+			args: args{
+				cntx: context.Background(),
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			vnetsToDelete := map[string]bool{}
+			vnetsToDelete["test_name"] = true
+			va := &VoltApplication{
+				VnetsBySvlan:  util.NewConcurrentMap(),
+				VnetsToDelete: vnetsToDelete,
+			}
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			vnets := map[string]*kvstore.KVPair{}
+			voltVnet.SVlan = of.VlanAny
+			b, err := json.Marshal(voltVnet)
+			if err != nil {
+				panic(err)
+			}
+			vnets["test_device_id"] = &kvstore.KVPair{
+				Key:   "test_device_id",
+				Value: b,
+			}
+			dbintf.EXPECT().PutVnet(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
+			dbintf.EXPECT().GetVnets(tt.args.cntx).Return(vnets, nil)
+			va.RestoreVnetsFromDb(tt.args.cntx)
+		})
+	}
+}
+
+func TestVoltApplication_DeleteDevFlowForDevice(t *testing.T) {
+	type args struct {
+		cntx   context.Context
+		device *VoltDevice
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "VoltApplication_DeleteDevFlowForDevice",
+			args: args{
+				cntx: context.Background(),
+				device: &VoltDevice{
+					Name:                         test_device,
+					ConfiguredVlanForDeviceFlows: util.NewConcurrentMap(),
+				},
+			},
+		},
+	}
+	var voltVnet_DeleteDevFlowForDevice = &VoltVnet{
+		Version: "test_version",
+		VnetConfig: VnetConfig{
+			Name:  "test_name",
+			SVlan: of.VlanAny,
+			CVlan: of.VlanAny,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{}
+			va.VnetsByName.Store("4096-4096-0", voltVnet_DeleteDevFlowForDevice)
+			//tt.args.device.ConfiguredVlanForDeviceFlows.SyncMap.Store("4096-4069-0", util.NewConcurrentMap())
+			va.DeleteDevFlowForDevice(tt.args.cntx, tt.args.device)
+		})
+	}
+}
+
+func TestVoltApplication_DelVnetFromPort(t *testing.T) {
+	macAdd, _ := net.ParseMAC("ff:ff:ff:ff:ff:ff")
+	vpv_test := []*VoltPortVnet{
+		{
+			Device:   test_device,
+			Port:     "test_port",
+			MacAddr:  macAdd,
+			VnetName: "test_vnet_name",
+		},
+	}
+	type args struct {
+		cntx context.Context
+		port string
+		vpv  *VoltPortVnet
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "VoltApplication_DelVnetFromPort",
+			args: args{
+				cntx: context.Background(),
+				port: "test_port",
+				vpv: &VoltPortVnet{
+					Device:   test_device,
+					Port:     "test_port",
+					MacAddr:  macAdd,
+					VnetName: "test_vnet_name",
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{}
+			va.VnetsByPort.Store("test_port", vpv_test)
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			dbintf.EXPECT().PutVpv(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+			dbintf.EXPECT().DelVpv(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
+			va.VnetsByName.Store("test_vnet_name", &VoltVnet{
+				Version: "test_version",
+			})
+			va.DelVnetFromPort(tt.args.cntx, tt.args.port, tt.args.vpv)
+		})
+	}
+}
+
+func TestVoltApplication_PushDevFlowForVlan(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		vnet *VoltVnet
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "VoltApplication_PushDevFlowForVlan",
+			args: args{
+				cntx: context.Background(),
+				vnet: &VoltVnet{
+					Version: "test_version",
+					VnetConfig: VnetConfig{
+						DevicesList: []string{"test_serialNum"},
+						SVlan:       of.VlanAny,
+					},
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{}
+			voltDevice.SerialNum = "test_serialNum"
+			voltDevice.VlanPortStatus.Store(uint16(of.VlanAny), true)
+			voltDevice.Name = test_device
+			va.DevicesDisc.Store(test_device, voltDevice)
+			ga := GetApplication()
+			ga.DevicesDisc.Store(test_device, voltDevice)
+			_ = cntlr.NewController(context.Background(), mocks.NewMockApp(gomock.NewController(t)))
+			va.PushDevFlowForVlan(tt.args.cntx, tt.args.vnet)
+		})
+	}
+}
+
+func TestVoltApplication_PushDevFlowForDevice(t *testing.T) {
+	type args struct {
+		cntx   context.Context
+		device *VoltDevice
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "device.ConfiguredVlanForDeviceFlows is ok",
+			args: args{
+				cntx: context.Background(),
+				device: &VoltDevice{
+					Name:                         test_device,
+					ConfiguredVlanForDeviceFlows: util.NewConcurrentMap(),
+				},
+			},
+		},
+		{
+			name: "device.VlanPortStatus is false",
+			args: args{
+				cntx: context.Background(),
+				device: &VoltDevice{
+					Name:                         test_device,
+					ConfiguredVlanForDeviceFlows: util.NewConcurrentMap(),
+					NniPort:                      "test_nni_port",
+				},
+			},
+		},
+		{
+			name: "device.VlanPortStatus is true",
+			args: args{
+				cntx: context.Background(),
+				device: &VoltDevice{
+					Name:                         test_device,
+					ConfiguredVlanForDeviceFlows: util.NewConcurrentMap(),
+					NniPort:                      "test_nni_port",
+					VlanPortStatus:               sync.Map{},
+				},
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			va := &VoltApplication{}
+			switch tt.name {
+			case "device.ConfiguredVlanForDeviceFlows is ok":
+				va.VnetsByName.Store("test_vnet_name", &VoltVnet{
+					Version: "test_version",
+				})
+				tt.args.device.ConfiguredVlanForDeviceFlows.Set("0-0-0", util.NewConcurrentMap())
+				va.PushDevFlowForDevice(tt.args.cntx, tt.args.device)
+			case "device.VlanPortStatus is false":
+				va.VnetsByName.Store("test_vnet_name", &VoltVnet{
+					Version: "test_version",
+				})
+				va.PortsDisc.Store("test_nni_port", &VoltPort{
+					Name: "test_name",
+				})
+				va.PushDevFlowForDevice(tt.args.cntx, tt.args.device)
+			case "device.VlanPortStatus is true":
+				va.VnetsByName.Store("test_vnet_name", &VoltVnet{
+					Version: "test_version",
+					VnetConfig: VnetConfig{
+						SVlan: of.VlanAny,
+					},
+				})
+				va.PortsDisc.Store("test_nni_port", &VoltPort{
+					Name: "test_name",
+				})
+				tt.args.device.VlanPortStatus.Store(uint16(of.VlanAny), true)
+				va.PushDevFlowForDevice(tt.args.cntx, tt.args.device)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/controller/addflows_test.go b/internal/pkg/controller/addflows_test.go
index d1e86ec..aee998f 100644
--- a/internal/pkg/controller/addflows_test.go
+++ b/internal/pkg/controller/addflows_test.go
@@ -16,8 +16,13 @@
 package controller
 
 import (
+	"context"
+	"reflect"
 	"testing"
 	"voltha-go-controller/internal/pkg/of"
+	"voltha-go-controller/internal/test/mocks"
+
+	"github.com/golang/mock/gomock"
 )
 
 func Test_isFlowOperSuccess(t *testing.T) {
@@ -47,3 +52,181 @@
 		})
 	}
 }
+
+func TestAddFlowsTask_Start(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		taskID uint8
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "AddFlowsTask_Start",
+			args: args{
+				ctx:    context.Background(),
+				taskID: 0,
+			},
+			wantErr: false,
+		},
+		{
+			name: "DeleteFlowsTask_Start",
+			args: args{
+				ctx:    context.Background(),
+				taskID: 0,
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			switch tt.name {
+			case "AddFlowsTask_Start":
+				subFlows := map[uint64]*of.VoltSubFlow{}
+				vltSubFlow := &of.VoltSubFlow{
+					Priority: 100,
+					Cookie:   103112802816,
+					State:    of.FlowAddSuccess,
+					Match: of.Match{
+						InPort:     1573376,
+						MatchVlan:  4096,
+						L4Protocol: 255,
+					},
+					Action: of.Action{
+						Metadata:    279189651712,
+						GoToTableID: 1,
+						MeterID:     1,
+						SetVlan:     4097,
+						Pcp:         8,
+						Output:      4,
+					},
+				}
+				subFlows[0] = vltSubFlow
+				portsByID := map[uint32]*DevicePort{}
+				portsByID[256] = &DevicePort{
+					Name: "SDX6320031",
+					ID:   256,
+				}
+				device := &Device{
+					flows:     subFlows,
+					PortsByID: portsByID,
+				}
+				flow := &of.VoltFlow{
+					SubFlows: subFlows,
+					PortName: "SDX6320031-1",
+					PortID:   256,
+					Command:  0,
+				}
+				aft := &AddFlowsTask{
+					flow:   flow,
+					device: device,
+				}
+				dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+				db = dbintf
+				dbintf.EXPECT().PutFlow(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+				if err := aft.Start(tt.args.ctx, tt.args.taskID); (err != nil) != tt.wantErr {
+					t.Errorf("AddFlowsTask.Start() error = %v, wantErr %v", err, tt.wantErr)
+				}
+			case "DeleteFlowsTask_Start":
+				subFlows := map[uint64]*of.VoltSubFlow{}
+				vltSubFlow := &of.VoltSubFlow{
+					Priority: 100,
+					Cookie:   103112802816,
+					State:    of.FlowAddSuccess,
+					Match: of.Match{
+						InPort:     1573376,
+						MatchVlan:  4096,
+						L4Protocol: 255,
+					},
+					Action: of.Action{
+						Metadata:    279189651712,
+						GoToTableID: 1,
+						MeterID:     1,
+						SetVlan:     4097,
+						Pcp:         8,
+						Output:      4,
+					},
+				}
+				subFlows[0] = vltSubFlow
+				portsByID := map[uint32]*DevicePort{}
+				portsByID[256] = &DevicePort{
+					Name: "SDX6320031",
+					ID:   256,
+				}
+				device := &Device{
+					flows:     subFlows,
+					PortsByID: portsByID,
+				}
+				flow := &of.VoltFlow{
+					SubFlows: subFlows,
+					PortName: "SDX6320031-1",
+					PortID:   256,
+					Command:  1,
+				}
+				aft := &AddFlowsTask{
+					flow:   flow,
+					device: device,
+				}
+				appMock := mocks.NewMockApp(gomock.NewController(t))
+				NewController(ctx, appMock)
+				appMock.EXPECT().ProcessFlowModResultIndication(gomock.Any(), gomock.Any()).AnyTimes()
+				dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+				db = dbintf
+				dbintf.EXPECT().DelFlow(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+				if err := aft.Start(tt.args.ctx, tt.args.taskID); (err != nil) != tt.wantErr {
+					t.Errorf("AddFlowsTask.Start() error = %v, wantErr %v", err, tt.wantErr)
+				}
+			}
+		})
+	}
+}
+
+func TestNewAddFlowsTask(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		flow   *of.VoltFlow
+		device *Device
+	}
+	flow := &of.VoltFlow{
+		PortName: "SDX6320031-1",
+		PortID:   256,
+		Command:  0,
+	}
+	portsByID := map[uint32]*DevicePort{}
+	portsByID[256] = &DevicePort{
+		Name: "SDX6320031",
+		ID:   256,
+	}
+	device := &Device{
+		PortsByID: portsByID,
+	}
+
+	tests := []struct {
+		name string
+		args args
+		want *AddFlowsTask
+	}{
+		{
+			name: "NewAddFlowsTask",
+			args: args{
+				ctx:    context.Background(),
+				flow:   flow,
+				device: device,
+			},
+			want: &AddFlowsTask{
+				ctx:    context.Background(),
+				flow:   flow,
+				device: device,
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			if got := NewAddFlowsTask(tt.args.ctx, tt.args.flow, tt.args.device); reflect.DeepEqual(got, tt.want) {
+				t.Errorf("NewAddFlowsTask() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/controller/auditdevice_test.go b/internal/pkg/controller/auditdevice_test.go
new file mode 100644
index 0000000..b2a76ea
--- /dev/null
+++ b/internal/pkg/controller/auditdevice_test.go
@@ -0,0 +1,163 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ */
+
+package controller
+
+import (
+	"context"
+	"testing"
+	"voltha-go-controller/internal/pkg/holder"
+	"voltha-go-controller/internal/pkg/of"
+	"voltha-go-controller/internal/test/mocks"
+
+	"github.com/golang/mock/gomock"
+	"github.com/opencord/voltha-protos/v5/go/openflow_13"
+	"github.com/opencord/voltha-protos/v5/go/voltha"
+)
+
+func TestAuditDevice_DelExcessPorts(t *testing.T) {
+	type args struct {
+		cntx context.Context
+		eps  []uint32
+	}
+	subFlows := map[uint64]*of.VoltSubFlow{}
+	vltSubFlow := &of.VoltSubFlow{
+		Priority: 100,
+		Cookie:   103112802816,
+		State:    of.FlowAddSuccess,
+		Match: of.Match{
+			InPort:     1573376,
+			MatchVlan:  4096,
+			L4Protocol: 255,
+		},
+		Action: of.Action{
+			Metadata:    279189651712,
+			GoToTableID: 1,
+			MeterID:     1,
+			SetVlan:     4097,
+			Pcp:         8,
+			Output:      4,
+		},
+	}
+	subFlows[0] = vltSubFlow
+	portsByID := map[uint32]*DevicePort{}
+	portsByID[256] = &DevicePort{
+		Name:  "SDX6320031",
+		ID:    256,
+		State: PortStateUp,
+	}
+	eps := []uint32{256}
+	device := &Device{
+		flows:     subFlows,
+		PortsByID: portsByID,
+		ID:        "SDX6320031",
+	}
+	tests := []struct {
+		name string
+		args args
+	}{
+		{
+			name: "AddFlowsTask_Start",
+			args: args{
+				cntx: context.Background(),
+				eps:  eps,
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ad := &AuditDevice{
+				device: device,
+			}
+			appMock := mocks.NewMockApp(gomock.NewController(t))
+			NewController(ctx, appMock)
+			appMock.EXPECT().PortDownInd(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
+			appMock.EXPECT().PortDelInd(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			dbintf.EXPECT().DelPort(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+			ad.DelExcessPorts(tt.args.cntx, tt.args.eps)
+		})
+	}
+}
+
+func TestAuditDevice_Start(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		taskID uint8
+	}
+	volthaClientMock := mocks.NewMockVolthaServiceClient(gomock.NewController(t))
+	volthaServiceClientHolder := &holder.VolthaServiceClientHolder{
+		VolthaSvcClient: volthaClientMock,
+	}
+	portsByID := map[uint32]*DevicePort{}
+	portsByID[16777216] = &DevicePort{
+		Name:  "SDX6320031",
+		ID:    16777216,
+		State: PortStateUp,
+	}
+	device := &Device{
+		ID:            "SDX6320031",
+		vclientHolder: volthaServiceClientHolder,
+		PortsByID:     portsByID,
+	}
+	items := []*voltha.LogicalPort{}
+	item := &voltha.LogicalPort{
+		Id:           "SDX6320031-1",
+		DeviceId:     "SDX6320031",
+		DevicePortNo: 16777216,
+		OfpPort: &openflow_13.OfpPort{
+			PortNo: 16777216,
+			Name:   "SDX6320031-1",
+		},
+	}
+	items = append(items, item)
+
+	ofpps := &voltha.LogicalPorts{
+		Items: items,
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "AddFlowsTask_Start",
+			args: args{
+				ctx:    context.Background(),
+				taskID: 0,
+			},
+			wantErr: false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ad := &AuditDevice{
+				device: device,
+			}
+			volthaClientMock.EXPECT().ListLogicalDevicePorts(gomock.Any(), gomock.Any(), gomock.Any()).Return(ofpps, nil).AnyTimes()
+			appMock := mocks.NewMockApp(gomock.NewController(t))
+			NewController(ctx, appMock)
+			appMock.EXPECT().SetRebootFlag(gomock.Any()).AnyTimes()
+			appMock.EXPECT().PortDownInd(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes()
+			dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+			db = dbintf
+			dbintf.EXPECT().PutPort(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
+			if err := ad.Start(tt.args.ctx, tt.args.taskID); (err != nil) != tt.wantErr {
+				t.Errorf("AuditDevice.Start() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/controller/pendingprofiles_test.go b/internal/pkg/controller/pendingprofiles_test.go
new file mode 100644
index 0000000..fe0639c
--- /dev/null
+++ b/internal/pkg/controller/pendingprofiles_test.go
@@ -0,0 +1,62 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ */
+
+package controller
+
+import (
+	"context"
+	"testing"
+	"voltha-go-controller/internal/test/mocks"
+
+	"github.com/golang/mock/gomock"
+)
+
+func TestPendingProfilesTask_Start(t *testing.T) {
+	type args struct {
+		ctx    context.Context
+		taskID uint8
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantErr bool
+	}{
+		{
+			name: "PendingProfilesTask_Start",
+			args: args{
+				ctx:    context.Background(),
+				taskID: uint8(1),
+			},
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			ppt := &PendingProfilesTask{
+				device: &Device{
+					ID: "test_device",
+				},
+			}
+			appMock := mocks.NewMockApp(gomock.NewController(t))
+			_ = NewController(context.Background(), appMock)
+			appMock.EXPECT().SetRebootFlag(gomock.Any()).AnyTimes()
+			appMock.EXPECT().TriggerPendingProfileDeleteReq(gomock.Any(), gomock.Any()).AnyTimes()
+			appMock.EXPECT().TriggerPendingMigrateServicesReq(gomock.Any(), gomock.Any()).AnyTimes()
+			appMock.EXPECT().UpdateMvlanProfilesForDevice(gomock.Any(), gomock.Any()).AnyTimes()
+			if err := ppt.Start(tt.args.ctx, tt.args.taskID); (err != nil) != tt.wantErr {
+				t.Errorf("PendingProfilesTask.Start() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}
diff --git a/internal/pkg/holder/holder.go b/internal/pkg/holder/holder.go
index 4cf1838..eae241f 100644
--- a/internal/pkg/holder/holder.go
+++ b/internal/pkg/holder/holder.go
@@ -26,7 +26,7 @@
 // point for a mutable value that represents a GRPC service interface to
 // VOLTHA
 type VolthaServiceClientHolder struct {
-	volthaSvcClient voltha.VolthaServiceClient
+	VolthaSvcClient voltha.VolthaServiceClient
 	mutex           sync.RWMutex
 }
 
@@ -38,19 +38,19 @@
 func (h *VolthaServiceClientHolder) Clear() {
 	h.mutex.Lock()
 	defer h.mutex.Unlock()
-	h.volthaSvcClient = nil
+	h.VolthaSvcClient = nil
 }
 
 // Set assigns the value being held to the specified value
 func (h *VolthaServiceClientHolder) Set(client voltha.VolthaServiceClient) {
 	h.mutex.Lock()
 	defer h.mutex.Unlock()
-	h.volthaSvcClient = client
+	h.VolthaSvcClient = client
 }
 
 // Get returns the currently held value
 func (h *VolthaServiceClientHolder) Get() voltha.VolthaServiceClient {
 	h.mutex.RLock()
 	defer h.mutex.RUnlock()
-	return h.volthaSvcClient
+	return h.VolthaSvcClient
 }
diff --git a/internal/test/mocks/mock_voltha.pb.go b/internal/test/mocks/mock_voltha.pb.go
new file mode 100644
index 0000000..03309bd
--- /dev/null
+++ b/internal/test/mocks/mock_voltha.pb.go
@@ -0,0 +1,3058 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: /home/vinod/go/src/gerrit.opencord.org/voltha-go-controller/vendor/github.com/opencord/voltha-protos/v5/go/voltha/voltha.pb.go
+
+// Package mock_voltha is a generated GoMock package.
+package mocks
+
+import (
+	context "context"
+	reflect "reflect"
+	voltha "github.com/opencord/voltha-protos/v5/go/voltha"
+
+	gomock "github.com/golang/mock/gomock"
+	empty "github.com/golang/protobuf/ptypes/empty"
+	common "github.com/opencord/voltha-protos/v5/go/common"
+	extension "github.com/opencord/voltha-protos/v5/go/extension"
+	omci "github.com/opencord/voltha-protos/v5/go/omci"
+	openflow_13 "github.com/opencord/voltha-protos/v5/go/openflow_13"
+	grpc "google.golang.org/grpc"
+	metadata "google.golang.org/grpc/metadata"
+)
+
+// MockVolthaServiceClient is a mock of VolthaServiceClient interface.
+type MockVolthaServiceClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaServiceClientMockRecorder
+}
+
+// MockVolthaServiceClientMockRecorder is the mock recorder for MockVolthaServiceClient.
+type MockVolthaServiceClientMockRecorder struct {
+	mock *MockVolthaServiceClient
+}
+
+// NewMockVolthaServiceClient creates a new mock instance.
+func NewMockVolthaServiceClient(ctrl *gomock.Controller) *MockVolthaServiceClient {
+	mock := &MockVolthaServiceClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaServiceClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaServiceClient) EXPECT() *MockVolthaServiceClientMockRecorder {
+	return m.recorder
+}
+
+// AbortImageUpgradeToDevice mocks base method.
+func (m *MockVolthaServiceClient) AbortImageUpgradeToDevice(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "AbortImageUpgradeToDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AbortImageUpgradeToDevice indicates an expected call of AbortImageUpgradeToDevice.
+func (mr *MockVolthaServiceClientMockRecorder) AbortImageUpgradeToDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortImageUpgradeToDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).AbortImageUpgradeToDevice), varargs...)
+}
+
+// ActivateImage mocks base method.
+func (m *MockVolthaServiceClient) ActivateImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ActivateImage", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImage indicates an expected call of ActivateImage.
+func (mr *MockVolthaServiceClientMockRecorder) ActivateImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).ActivateImage), varargs...)
+}
+
+// ActivateImageUpdate mocks base method.
+func (m *MockVolthaServiceClient) ActivateImageUpdate(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ActivateImageUpdate", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
+func (mr *MockVolthaServiceClientMockRecorder) ActivateImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockVolthaServiceClient)(nil).ActivateImageUpdate), varargs...)
+}
+
+// CancelImageDownload mocks base method.
+func (m *MockVolthaServiceClient) CancelImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CancelImageDownload", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CancelImageDownload indicates an expected call of CancelImageDownload.
+func (mr *MockVolthaServiceClientMockRecorder) CancelImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockVolthaServiceClient)(nil).CancelImageDownload), varargs...)
+}
+
+// CommitImage mocks base method.
+func (m *MockVolthaServiceClient) CommitImage(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CommitImage", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CommitImage indicates an expected call of CommitImage.
+func (mr *MockVolthaServiceClientMockRecorder) CommitImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).CommitImage), varargs...)
+}
+
+// CreateDevice mocks base method.
+func (m *MockVolthaServiceClient) CreateDevice(ctx context.Context, in *voltha.Device, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CreateDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateDevice indicates an expected call of CreateDevice.
+func (mr *MockVolthaServiceClientMockRecorder) CreateDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).CreateDevice), varargs...)
+}
+
+// CreateEventFilter mocks base method.
+func (m *MockVolthaServiceClient) CreateEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "CreateEventFilter", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateEventFilter indicates an expected call of CreateEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) CreateEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).CreateEventFilter), varargs...)
+}
+
+// DeleteDevice mocks base method.
+func (m *MockVolthaServiceClient) DeleteDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteDevice indicates an expected call of DeleteDevice.
+func (mr *MockVolthaServiceClientMockRecorder) DeleteDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteDevice), varargs...)
+}
+
+// DeleteEventFilter mocks base method.
+func (m *MockVolthaServiceClient) DeleteEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DeleteEventFilter", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteEventFilter indicates an expected call of DeleteEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) DeleteEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).DeleteEventFilter), varargs...)
+}
+
+// DisableDevice mocks base method.
+func (m *MockVolthaServiceClient) DisableDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisableDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableDevice indicates an expected call of DisableDevice.
+func (mr *MockVolthaServiceClientMockRecorder) DisableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableDevice), varargs...)
+}
+
+// DisableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceClient) DisableLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisableLogicalDevicePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableLogicalDevicePort indicates an expected call of DisableLogicalDevicePort.
+func (mr *MockVolthaServiceClientMockRecorder) DisableLogicalDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisableLogicalDevicePort), varargs...)
+}
+
+// DisablePort mocks base method.
+func (m *MockVolthaServiceClient) DisablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DisablePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisablePort indicates an expected call of DisablePort.
+func (mr *MockVolthaServiceClientMockRecorder) DisablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).DisablePort), varargs...)
+}
+
+// DownloadImage mocks base method.
+func (m *MockVolthaServiceClient) DownloadImage(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DownloadImage", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImage indicates an expected call of DownloadImage.
+func (mr *MockVolthaServiceClientMockRecorder) DownloadImage(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockVolthaServiceClient)(nil).DownloadImage), varargs...)
+}
+
+// DownloadImageToDevice mocks base method.
+func (m *MockVolthaServiceClient) DownloadImageToDevice(ctx context.Context, in *voltha.DeviceImageDownloadRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "DownloadImageToDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImageToDevice indicates an expected call of DownloadImageToDevice.
+func (mr *MockVolthaServiceClientMockRecorder) DownloadImageToDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImageToDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).DownloadImageToDevice), varargs...)
+}
+
+// EnableDevice mocks base method.
+func (m *MockVolthaServiceClient) EnableDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "EnableDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableDevice indicates an expected call of EnableDevice.
+func (mr *MockVolthaServiceClientMockRecorder) EnableDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableDevice), varargs...)
+}
+
+// EnableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceClient) EnableLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "EnableLogicalDevicePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableLogicalDevicePort indicates an expected call of EnableLogicalDevicePort.
+func (mr *MockVolthaServiceClientMockRecorder) EnableLogicalDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnableLogicalDevicePort), varargs...)
+}
+
+// EnablePort mocks base method.
+func (m *MockVolthaServiceClient) EnablePort(ctx context.Context, in *voltha.Port, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "EnablePort", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnablePort indicates an expected call of EnablePort.
+func (mr *MockVolthaServiceClientMockRecorder) EnablePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).EnablePort), varargs...)
+}
+
+// ForceDeleteDevice mocks base method.
+func (m *MockVolthaServiceClient) ForceDeleteDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ForceDeleteDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ForceDeleteDevice indicates an expected call of ForceDeleteDevice.
+func (mr *MockVolthaServiceClientMockRecorder) ForceDeleteDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForceDeleteDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).ForceDeleteDevice), varargs...)
+}
+
+// GetAlarmDeviceData mocks base method.
+func (m *MockVolthaServiceClient) GetAlarmDeviceData(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*omci.AlarmDeviceData, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetAlarmDeviceData", varargs...)
+	ret0, _ := ret[0].(*omci.AlarmDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAlarmDeviceData indicates an expected call of GetAlarmDeviceData.
+func (mr *MockVolthaServiceClientMockRecorder) GetAlarmDeviceData(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmDeviceData", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetAlarmDeviceData), varargs...)
+}
+
+// GetCoreInstance mocks base method.
+func (m *MockVolthaServiceClient) GetCoreInstance(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.CoreInstance, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetCoreInstance", varargs...)
+	ret0, _ := ret[0].(*voltha.CoreInstance)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetCoreInstance indicates an expected call of GetCoreInstance.
+func (mr *MockVolthaServiceClientMockRecorder) GetCoreInstance(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreInstance", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetCoreInstance), varargs...)
+}
+
+// GetDevice mocks base method.
+func (m *MockVolthaServiceClient) GetDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevice indicates an expected call of GetDevice.
+func (mr *MockVolthaServiceClientMockRecorder) GetDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetDevice), varargs...)
+}
+
+// GetDeviceType mocks base method.
+func (m *MockVolthaServiceClient) GetDeviceType(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.DeviceType, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetDeviceType", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceType)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDeviceType indicates an expected call of GetDeviceType.
+func (mr *MockVolthaServiceClientMockRecorder) GetDeviceType(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceType", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetDeviceType), varargs...)
+}
+
+// GetEventFilter mocks base method.
+func (m *MockVolthaServiceClient) GetEventFilter(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetEventFilter", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetEventFilter indicates an expected call of GetEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) GetEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetEventFilter), varargs...)
+}
+
+// GetExtValue mocks base method.
+func (m *MockVolthaServiceClient) GetExtValue(ctx context.Context, in *extension.ValueSpecifier, opts ...grpc.CallOption) (*extension.ReturnValues, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetExtValue", varargs...)
+	ret0, _ := ret[0].(*extension.ReturnValues)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetExtValue indicates an expected call of GetExtValue.
+func (mr *MockVolthaServiceClientMockRecorder) GetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetExtValue), varargs...)
+}
+
+// GetImageDownload mocks base method.
+func (m *MockVolthaServiceClient) GetImageDownload(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImageDownload", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownload indicates an expected call of GetImageDownload.
+func (mr *MockVolthaServiceClientMockRecorder) GetImageDownload(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownload", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageDownload), varargs...)
+}
+
+// GetImageDownloadStatus mocks base method.
+func (m *MockVolthaServiceClient) GetImageDownloadStatus(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImageDownloadStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
+func (mr *MockVolthaServiceClientMockRecorder) GetImageDownloadStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageDownloadStatus), varargs...)
+}
+
+// GetImageStatus mocks base method.
+func (m *MockVolthaServiceClient) GetImageStatus(ctx context.Context, in *voltha.DeviceImageRequest, opts ...grpc.CallOption) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImageStatus", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageStatus indicates an expected call of GetImageStatus.
+func (mr *MockVolthaServiceClientMockRecorder) GetImageStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStatus", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImageStatus), varargs...)
+}
+
+// GetImages mocks base method.
+func (m *MockVolthaServiceClient) GetImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Images, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetImages", varargs...)
+	ret0, _ := ret[0].(*voltha.Images)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImages indicates an expected call of GetImages.
+func (mr *MockVolthaServiceClientMockRecorder) GetImages(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImages", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetImages), varargs...)
+}
+
+// GetLogicalDevice mocks base method.
+func (m *MockVolthaServiceClient) GetLogicalDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.LogicalDevice, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetLogicalDevice", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalDevice)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevice indicates an expected call of GetLogicalDevice.
+func (mr *MockVolthaServiceClientMockRecorder) GetLogicalDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetLogicalDevice), varargs...)
+}
+
+// GetLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceClient) GetLogicalDevicePort(ctx context.Context, in *voltha.LogicalPortId, opts ...grpc.CallOption) (*voltha.LogicalPort, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetLogicalDevicePort", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalPort)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevicePort indicates an expected call of GetLogicalDevicePort.
+func (mr *MockVolthaServiceClientMockRecorder) GetLogicalDevicePort(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetLogicalDevicePort), varargs...)
+}
+
+// GetMibDeviceData mocks base method.
+func (m *MockVolthaServiceClient) GetMibDeviceData(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*omci.MibDeviceData, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetMibDeviceData", varargs...)
+	ret0, _ := ret[0].(*omci.MibDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMibDeviceData indicates an expected call of GetMibDeviceData.
+func (mr *MockVolthaServiceClientMockRecorder) GetMibDeviceData(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMibDeviceData", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetMibDeviceData), varargs...)
+}
+
+// GetOnuImages mocks base method.
+func (m *MockVolthaServiceClient) GetOnuImages(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.OnuImages, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetOnuImages", varargs...)
+	ret0, _ := ret[0].(*voltha.OnuImages)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImages indicates an expected call of GetOnuImages.
+func (mr *MockVolthaServiceClientMockRecorder) GetOnuImages(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetOnuImages), varargs...)
+}
+
+// GetVoltha mocks base method.
+func (m *MockVolthaServiceClient) GetVoltha(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.Voltha, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "GetVoltha", varargs...)
+	ret0, _ := ret[0].(*voltha.Voltha)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVoltha indicates an expected call of GetVoltha.
+func (mr *MockVolthaServiceClientMockRecorder) GetVoltha(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVoltha", reflect.TypeOf((*MockVolthaServiceClient)(nil).GetVoltha), varargs...)
+}
+
+// ListAdapters mocks base method.
+func (m *MockVolthaServiceClient) ListAdapters(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.Adapters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListAdapters", varargs...)
+	ret0, _ := ret[0].(*voltha.Adapters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListAdapters indicates an expected call of ListAdapters.
+func (mr *MockVolthaServiceClientMockRecorder) ListAdapters(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAdapters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListAdapters), varargs...)
+}
+
+// ListCoreInstances mocks base method.
+func (m *MockVolthaServiceClient) ListCoreInstances(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.CoreInstances, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListCoreInstances", varargs...)
+	ret0, _ := ret[0].(*voltha.CoreInstances)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListCoreInstances indicates an expected call of ListCoreInstances.
+func (mr *MockVolthaServiceClientMockRecorder) ListCoreInstances(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCoreInstances", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListCoreInstances), varargs...)
+}
+
+// ListDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceFlowGroups(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceFlowGroups", varargs...)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlowGroups indicates an expected call of ListDeviceFlowGroups.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceFlowGroups(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceFlowGroups), varargs...)
+}
+
+// ListDeviceFlows mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceFlows(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceFlows", varargs...)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlows indicates an expected call of ListDeviceFlows.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceFlows(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlows", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceFlows), varargs...)
+}
+
+// ListDeviceIds mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceIds(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*common.IDs, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceIds", varargs...)
+	ret0, _ := ret[0].(*common.IDs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceIds indicates an expected call of ListDeviceIds.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceIds(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceIds", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceIds), varargs...)
+}
+
+// ListDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceClient) ListDevicePmConfigs(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.PmConfigs, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDevicePmConfigs", varargs...)
+	ret0, _ := ret[0].(*voltha.PmConfigs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePmConfigs indicates an expected call of ListDevicePmConfigs.
+func (mr *MockVolthaServiceClientMockRecorder) ListDevicePmConfigs(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevicePmConfigs), varargs...)
+}
+
+// ListDevicePorts mocks base method.
+func (m *MockVolthaServiceClient) ListDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDevicePorts", varargs...)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePorts indicates an expected call of ListDevicePorts.
+func (mr *MockVolthaServiceClientMockRecorder) ListDevicePorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevicePorts), varargs...)
+}
+
+// ListDeviceTypes mocks base method.
+func (m *MockVolthaServiceClient) ListDeviceTypes(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.DeviceTypes, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDeviceTypes", varargs...)
+	ret0, _ := ret[0].(*voltha.DeviceTypes)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceTypes indicates an expected call of ListDeviceTypes.
+func (mr *MockVolthaServiceClientMockRecorder) ListDeviceTypes(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceTypes", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDeviceTypes), varargs...)
+}
+
+// ListDevices mocks base method.
+func (m *MockVolthaServiceClient) ListDevices(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.Devices, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListDevices", varargs...)
+	ret0, _ := ret[0].(*voltha.Devices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevices indicates an expected call of ListDevices.
+func (mr *MockVolthaServiceClientMockRecorder) ListDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListDevices), varargs...)
+}
+
+// ListEventFilters mocks base method.
+func (m *MockVolthaServiceClient) ListEventFilters(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListEventFilters", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListEventFilters indicates an expected call of ListEventFilters.
+func (mr *MockVolthaServiceClientMockRecorder) ListEventFilters(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEventFilters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListEventFilters), varargs...)
+}
+
+// ListImageDownloads mocks base method.
+func (m *MockVolthaServiceClient) ListImageDownloads(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.ImageDownloads, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListImageDownloads", varargs...)
+	ret0, _ := ret[0].(*voltha.ImageDownloads)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListImageDownloads indicates an expected call of ListImageDownloads.
+func (mr *MockVolthaServiceClientMockRecorder) ListImageDownloads(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImageDownloads", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListImageDownloads), varargs...)
+}
+
+// ListLogicalDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDeviceFlowGroups(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlowGroups", varargs...)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlowGroups indicates an expected call of ListLogicalDeviceFlowGroups.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceFlowGroups(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceFlowGroups), varargs...)
+}
+
+// ListLogicalDeviceFlows mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDeviceFlows(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlows", varargs...)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlows indicates an expected call of ListLogicalDeviceFlows.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceFlows(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlows", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceFlows), varargs...)
+}
+
+// ListLogicalDeviceMeters mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDeviceMeters(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*openflow_13.Meters, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDeviceMeters", varargs...)
+	ret0, _ := ret[0].(*openflow_13.Meters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceMeters indicates an expected call of ListLogicalDeviceMeters.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDeviceMeters(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceMeters", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDeviceMeters), varargs...)
+}
+
+// ListLogicalDevicePorts mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDevicePorts(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.LogicalPorts, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDevicePorts", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalPorts)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevicePorts indicates an expected call of ListLogicalDevicePorts.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDevicePorts(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevicePorts", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDevicePorts), varargs...)
+}
+
+// ListLogicalDevices mocks base method.
+func (m *MockVolthaServiceClient) ListLogicalDevices(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (*voltha.LogicalDevices, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ListLogicalDevices", varargs...)
+	ret0, _ := ret[0].(*voltha.LogicalDevices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevices indicates an expected call of ListLogicalDevices.
+func (mr *MockVolthaServiceClientMockRecorder) ListLogicalDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ListLogicalDevices), varargs...)
+}
+
+// RebootDevice mocks base method.
+func (m *MockVolthaServiceClient) RebootDevice(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "RebootDevice", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RebootDevice indicates an expected call of RebootDevice.
+func (mr *MockVolthaServiceClientMockRecorder) RebootDevice(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockVolthaServiceClient)(nil).RebootDevice), varargs...)
+}
+
+// ReceiveChangeEvents mocks base method.
+func (m *MockVolthaServiceClient) ReceiveChangeEvents(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (voltha.VolthaService_ReceiveChangeEventsClient, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReceiveChangeEvents", varargs...)
+	ret0, _ := ret[0].(voltha.VolthaService_ReceiveChangeEventsClient)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReceiveChangeEvents indicates an expected call of ReceiveChangeEvents.
+func (mr *MockVolthaServiceClientMockRecorder) ReceiveChangeEvents(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveChangeEvents", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReceiveChangeEvents), varargs...)
+}
+
+// ReceivePacketsIn mocks base method.
+func (m *MockVolthaServiceClient) ReceivePacketsIn(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (voltha.VolthaService_ReceivePacketsInClient, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReceivePacketsIn", varargs...)
+	ret0, _ := ret[0].(voltha.VolthaService_ReceivePacketsInClient)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReceivePacketsIn indicates an expected call of ReceivePacketsIn.
+func (mr *MockVolthaServiceClientMockRecorder) ReceivePacketsIn(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivePacketsIn", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReceivePacketsIn), varargs...)
+}
+
+// ReconcileDevices mocks base method.
+func (m *MockVolthaServiceClient) ReconcileDevices(ctx context.Context, in *common.IDs, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "ReconcileDevices", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileDevices indicates an expected call of ReconcileDevices.
+func (mr *MockVolthaServiceClientMockRecorder) ReconcileDevices(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevices", reflect.TypeOf((*MockVolthaServiceClient)(nil).ReconcileDevices), varargs...)
+}
+
+// RevertImageUpdate mocks base method.
+func (m *MockVolthaServiceClient) RevertImageUpdate(ctx context.Context, in *voltha.ImageDownload, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "RevertImageUpdate", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RevertImageUpdate indicates an expected call of RevertImageUpdate.
+func (mr *MockVolthaServiceClientMockRecorder) RevertImageUpdate(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockVolthaServiceClient)(nil).RevertImageUpdate), varargs...)
+}
+
+// SelfTest mocks base method.
+func (m *MockVolthaServiceClient) SelfTest(ctx context.Context, in *common.ID, opts ...grpc.CallOption) (*voltha.SelfTestResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SelfTest", varargs...)
+	ret0, _ := ret[0].(*voltha.SelfTestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SelfTest indicates an expected call of SelfTest.
+func (mr *MockVolthaServiceClientMockRecorder) SelfTest(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTest", reflect.TypeOf((*MockVolthaServiceClient)(nil).SelfTest), varargs...)
+}
+
+// SetExtValue mocks base method.
+func (m *MockVolthaServiceClient) SetExtValue(ctx context.Context, in *extension.ValueSet, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SetExtValue", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetExtValue indicates an expected call of SetExtValue.
+func (mr *MockVolthaServiceClientMockRecorder) SetExtValue(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockVolthaServiceClient)(nil).SetExtValue), varargs...)
+}
+
+// SimulateAlarm mocks base method.
+func (m *MockVolthaServiceClient) SimulateAlarm(ctx context.Context, in *voltha.SimulateAlarmRequest, opts ...grpc.CallOption) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "SimulateAlarm", varargs...)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SimulateAlarm indicates an expected call of SimulateAlarm.
+func (mr *MockVolthaServiceClientMockRecorder) SimulateAlarm(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockVolthaServiceClient)(nil).SimulateAlarm), varargs...)
+}
+
+// StartOmciTestAction mocks base method.
+func (m *MockVolthaServiceClient) StartOmciTestAction(ctx context.Context, in *omci.OmciTestRequest, opts ...grpc.CallOption) (*omci.TestResponse, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "StartOmciTestAction", varargs...)
+	ret0, _ := ret[0].(*omci.TestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StartOmciTestAction indicates an expected call of StartOmciTestAction.
+func (mr *MockVolthaServiceClientMockRecorder) StartOmciTestAction(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTestAction", reflect.TypeOf((*MockVolthaServiceClient)(nil).StartOmciTestAction), varargs...)
+}
+
+// StreamPacketsOut mocks base method.
+func (m *MockVolthaServiceClient) StreamPacketsOut(ctx context.Context, opts ...grpc.CallOption) (voltha.VolthaService_StreamPacketsOutClient, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "StreamPacketsOut", varargs...)
+	ret0, _ := ret[0].(voltha.VolthaService_StreamPacketsOutClient)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StreamPacketsOut indicates an expected call of StreamPacketsOut.
+func (mr *MockVolthaServiceClientMockRecorder) StreamPacketsOut(ctx interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamPacketsOut", reflect.TypeOf((*MockVolthaServiceClient)(nil).StreamPacketsOut), varargs...)
+}
+
+// UpdateDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceClient) UpdateDevicePmConfigs(ctx context.Context, in *voltha.PmConfigs, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateDevicePmConfigs", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateDevicePmConfigs indicates an expected call of UpdateDevicePmConfigs.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateDevicePmConfigs(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateDevicePmConfigs), varargs...)
+}
+
+// UpdateEventFilter mocks base method.
+func (m *MockVolthaServiceClient) UpdateEventFilter(ctx context.Context, in *voltha.EventFilter, opts ...grpc.CallOption) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateEventFilter", varargs...)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateEventFilter indicates an expected call of UpdateEventFilter.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateEventFilter(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEventFilter", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateEventFilter), varargs...)
+}
+
+// UpdateLogicalDeviceFlowGroupTable mocks base method.
+func (m *MockVolthaServiceClient) UpdateLogicalDeviceFlowGroupTable(ctx context.Context, in *openflow_13.FlowGroupTableUpdate, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowGroupTable", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowGroupTable indicates an expected call of UpdateLogicalDeviceFlowGroupTable.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceFlowGroupTable(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowGroupTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceFlowGroupTable), varargs...)
+}
+
+// UpdateLogicalDeviceFlowTable mocks base method.
+func (m *MockVolthaServiceClient) UpdateLogicalDeviceFlowTable(ctx context.Context, in *openflow_13.FlowTableUpdate, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowTable", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowTable indicates an expected call of UpdateLogicalDeviceFlowTable.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceFlowTable(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceFlowTable), varargs...)
+}
+
+// UpdateLogicalDeviceMeterTable mocks base method.
+func (m *MockVolthaServiceClient) UpdateLogicalDeviceMeterTable(ctx context.Context, in *openflow_13.MeterModUpdate, opts ...grpc.CallOption) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	varargs := []interface{}{ctx, in}
+	for _, a := range opts {
+		varargs = append(varargs, a)
+	}
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceMeterTable", varargs...)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceMeterTable indicates an expected call of UpdateLogicalDeviceMeterTable.
+func (mr *MockVolthaServiceClientMockRecorder) UpdateLogicalDeviceMeterTable(ctx, in interface{}, opts ...interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	varargs := append([]interface{}{ctx, in}, opts...)
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceMeterTable", reflect.TypeOf((*MockVolthaServiceClient)(nil).UpdateLogicalDeviceMeterTable), varargs...)
+}
+
+// MockVolthaService_StreamPacketsOutClient is a mock of VolthaService_StreamPacketsOutClient interface.
+type MockVolthaService_StreamPacketsOutClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_StreamPacketsOutClientMockRecorder
+}
+
+// MockVolthaService_StreamPacketsOutClientMockRecorder is the mock recorder for MockVolthaService_StreamPacketsOutClient.
+type MockVolthaService_StreamPacketsOutClientMockRecorder struct {
+	mock *MockVolthaService_StreamPacketsOutClient
+}
+
+// NewMockVolthaService_StreamPacketsOutClient creates a new mock instance.
+func NewMockVolthaService_StreamPacketsOutClient(ctrl *gomock.Controller) *MockVolthaService_StreamPacketsOutClient {
+	mock := &MockVolthaService_StreamPacketsOutClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_StreamPacketsOutClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_StreamPacketsOutClient) EXPECT() *MockVolthaService_StreamPacketsOutClientMockRecorder {
+	return m.recorder
+}
+
+// CloseAndRecv mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) CloseAndRecv() (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseAndRecv")
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CloseAndRecv indicates an expected call of CloseAndRecv.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) CloseAndRecv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseAndRecv", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).CloseAndRecv))
+}
+
+// CloseSend mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) CloseSend() error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseSend")
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CloseSend indicates an expected call of CloseSend.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) CloseSend() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).CloseSend))
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Context))
+}
+
+// Header mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Header() (metadata.MD, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Header")
+	ret0, _ := ret[0].(metadata.MD)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Header indicates an expected call of Header.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Header() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Header))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutClient) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).RecvMsg), m)
+}
+
+// Send mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Send(arg0 *openflow_13.PacketOut) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Send", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Send indicates an expected call of Send.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Send(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Send), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutClient) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).SendMsg), m)
+}
+
+// Trailer mocks base method.
+func (m *MockVolthaService_StreamPacketsOutClient) Trailer() metadata.MD {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Trailer")
+	ret0, _ := ret[0].(metadata.MD)
+	return ret0
+}
+
+// Trailer indicates an expected call of Trailer.
+func (mr *MockVolthaService_StreamPacketsOutClientMockRecorder) Trailer() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockVolthaService_StreamPacketsOutClient)(nil).Trailer))
+}
+
+// MockVolthaService_ReceivePacketsInClient is a mock of VolthaService_ReceivePacketsInClient interface.
+type MockVolthaService_ReceivePacketsInClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceivePacketsInClientMockRecorder
+}
+
+// MockVolthaService_ReceivePacketsInClientMockRecorder is the mock recorder for MockVolthaService_ReceivePacketsInClient.
+type MockVolthaService_ReceivePacketsInClientMockRecorder struct {
+	mock *MockVolthaService_ReceivePacketsInClient
+}
+
+// NewMockVolthaService_ReceivePacketsInClient creates a new mock instance.
+func NewMockVolthaService_ReceivePacketsInClient(ctrl *gomock.Controller) *MockVolthaService_ReceivePacketsInClient {
+	mock := &MockVolthaService_ReceivePacketsInClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceivePacketsInClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceivePacketsInClient) EXPECT() *MockVolthaService_ReceivePacketsInClientMockRecorder {
+	return m.recorder
+}
+
+// CloseSend mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) CloseSend() error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseSend")
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CloseSend indicates an expected call of CloseSend.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) CloseSend() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).CloseSend))
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Context))
+}
+
+// Header mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Header() (metadata.MD, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Header")
+	ret0, _ := ret[0].(metadata.MD)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Header indicates an expected call of Header.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Header() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Header))
+}
+
+// Recv mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Recv() (*openflow_13.PacketIn, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Recv")
+	ret0, _ := ret[0].(*openflow_13.PacketIn)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Recv indicates an expected call of Recv.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Recv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Recv))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInClient) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).RecvMsg), m)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInClient) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).SendMsg), m)
+}
+
+// Trailer mocks base method.
+func (m *MockVolthaService_ReceivePacketsInClient) Trailer() metadata.MD {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Trailer")
+	ret0, _ := ret[0].(metadata.MD)
+	return ret0
+}
+
+// Trailer indicates an expected call of Trailer.
+func (mr *MockVolthaService_ReceivePacketsInClientMockRecorder) Trailer() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockVolthaService_ReceivePacketsInClient)(nil).Trailer))
+}
+
+// MockVolthaService_ReceiveChangeEventsClient is a mock of VolthaService_ReceiveChangeEventsClient interface.
+type MockVolthaService_ReceiveChangeEventsClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceiveChangeEventsClientMockRecorder
+}
+
+// MockVolthaService_ReceiveChangeEventsClientMockRecorder is the mock recorder for MockVolthaService_ReceiveChangeEventsClient.
+type MockVolthaService_ReceiveChangeEventsClientMockRecorder struct {
+	mock *MockVolthaService_ReceiveChangeEventsClient
+}
+
+// NewMockVolthaService_ReceiveChangeEventsClient creates a new mock instance.
+func NewMockVolthaService_ReceiveChangeEventsClient(ctrl *gomock.Controller) *MockVolthaService_ReceiveChangeEventsClient {
+	mock := &MockVolthaService_ReceiveChangeEventsClient{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceiveChangeEventsClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceiveChangeEventsClient) EXPECT() *MockVolthaService_ReceiveChangeEventsClientMockRecorder {
+	return m.recorder
+}
+
+// CloseSend mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) CloseSend() error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CloseSend")
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CloseSend indicates an expected call of CloseSend.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) CloseSend() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseSend", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).CloseSend))
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Context))
+}
+
+// Header mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Header() (metadata.MD, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Header")
+	ret0, _ := ret[0].(metadata.MD)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Header indicates an expected call of Header.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Header() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Header", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Header))
+}
+
+// Recv mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Recv() (*openflow_13.ChangeEvent, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Recv")
+	ret0, _ := ret[0].(*openflow_13.ChangeEvent)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Recv indicates an expected call of Recv.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Recv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Recv))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsClient) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).RecvMsg), m)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsClient) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).SendMsg), m)
+}
+
+// Trailer mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsClient) Trailer() metadata.MD {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Trailer")
+	ret0, _ := ret[0].(metadata.MD)
+	return ret0
+}
+
+// Trailer indicates an expected call of Trailer.
+func (mr *MockVolthaService_ReceiveChangeEventsClientMockRecorder) Trailer() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Trailer", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsClient)(nil).Trailer))
+}
+
+// MockVolthaServiceServer is a mock of VolthaServiceServer interface.
+type MockVolthaServiceServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaServiceServerMockRecorder
+}
+
+// MockVolthaServiceServerMockRecorder is the mock recorder for MockVolthaServiceServer.
+type MockVolthaServiceServerMockRecorder struct {
+	mock *MockVolthaServiceServer
+}
+
+// NewMockVolthaServiceServer creates a new mock instance.
+func NewMockVolthaServiceServer(ctrl *gomock.Controller) *MockVolthaServiceServer {
+	mock := &MockVolthaServiceServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaServiceServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaServiceServer) EXPECT() *MockVolthaServiceServerMockRecorder {
+	return m.recorder
+}
+
+// AbortImageUpgradeToDevice mocks base method.
+func (m *MockVolthaServiceServer) AbortImageUpgradeToDevice(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "AbortImageUpgradeToDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// AbortImageUpgradeToDevice indicates an expected call of AbortImageUpgradeToDevice.
+func (mr *MockVolthaServiceServerMockRecorder) AbortImageUpgradeToDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AbortImageUpgradeToDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).AbortImageUpgradeToDevice), arg0, arg1)
+}
+
+// ActivateImage mocks base method.
+func (m *MockVolthaServiceServer) ActivateImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ActivateImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImage indicates an expected call of ActivateImage.
+func (mr *MockVolthaServiceServerMockRecorder) ActivateImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImage", reflect.TypeOf((*MockVolthaServiceServer)(nil).ActivateImage), arg0, arg1)
+}
+
+// ActivateImageUpdate mocks base method.
+func (m *MockVolthaServiceServer) ActivateImageUpdate(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ActivateImageUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ActivateImageUpdate indicates an expected call of ActivateImageUpdate.
+func (mr *MockVolthaServiceServerMockRecorder) ActivateImageUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivateImageUpdate", reflect.TypeOf((*MockVolthaServiceServer)(nil).ActivateImageUpdate), arg0, arg1)
+}
+
+// CancelImageDownload mocks base method.
+func (m *MockVolthaServiceServer) CancelImageDownload(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CancelImageDownload", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CancelImageDownload indicates an expected call of CancelImageDownload.
+func (mr *MockVolthaServiceServerMockRecorder) CancelImageDownload(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CancelImageDownload", reflect.TypeOf((*MockVolthaServiceServer)(nil).CancelImageDownload), arg0, arg1)
+}
+
+// CommitImage mocks base method.
+func (m *MockVolthaServiceServer) CommitImage(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CommitImage", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CommitImage indicates an expected call of CommitImage.
+func (mr *MockVolthaServiceServerMockRecorder) CommitImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CommitImage", reflect.TypeOf((*MockVolthaServiceServer)(nil).CommitImage), arg0, arg1)
+}
+
+// CreateDevice mocks base method.
+func (m *MockVolthaServiceServer) CreateDevice(arg0 context.Context, arg1 *voltha.Device) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CreateDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateDevice indicates an expected call of CreateDevice.
+func (mr *MockVolthaServiceServerMockRecorder) CreateDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).CreateDevice), arg0, arg1)
+}
+
+// CreateEventFilter mocks base method.
+func (m *MockVolthaServiceServer) CreateEventFilter(arg0 context.Context, arg1 *voltha.EventFilter) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CreateEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// CreateEventFilter indicates an expected call of CreateEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) CreateEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).CreateEventFilter), arg0, arg1)
+}
+
+// DeleteDevice mocks base method.
+func (m *MockVolthaServiceServer) DeleteDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteDevice indicates an expected call of DeleteDevice.
+func (mr *MockVolthaServiceServerMockRecorder) DeleteDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).DeleteDevice), arg0, arg1)
+}
+
+// DeleteEventFilter mocks base method.
+func (m *MockVolthaServiceServer) DeleteEventFilter(arg0 context.Context, arg1 *voltha.EventFilter) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DeleteEventFilter indicates an expected call of DeleteEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) DeleteEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).DeleteEventFilter), arg0, arg1)
+}
+
+// DisableDevice mocks base method.
+func (m *MockVolthaServiceServer) DisableDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisableDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableDevice indicates an expected call of DisableDevice.
+func (mr *MockVolthaServiceServerMockRecorder) DisableDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).DisableDevice), arg0, arg1)
+}
+
+// DisableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceServer) DisableLogicalDevicePort(arg0 context.Context, arg1 *voltha.LogicalPortId) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisableLogicalDevicePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisableLogicalDevicePort indicates an expected call of DisableLogicalDevicePort.
+func (mr *MockVolthaServiceServerMockRecorder) DisableLogicalDevicePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).DisableLogicalDevicePort), arg0, arg1)
+}
+
+// DisablePort mocks base method.
+func (m *MockVolthaServiceServer) DisablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DisablePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DisablePort indicates an expected call of DisablePort.
+func (mr *MockVolthaServiceServerMockRecorder) DisablePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DisablePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).DisablePort), arg0, arg1)
+}
+
+// DownloadImage mocks base method.
+func (m *MockVolthaServiceServer) DownloadImage(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DownloadImage", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImage indicates an expected call of DownloadImage.
+func (mr *MockVolthaServiceServerMockRecorder) DownloadImage(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImage", reflect.TypeOf((*MockVolthaServiceServer)(nil).DownloadImage), arg0, arg1)
+}
+
+// DownloadImageToDevice mocks base method.
+func (m *MockVolthaServiceServer) DownloadImageToDevice(arg0 context.Context, arg1 *voltha.DeviceImageDownloadRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DownloadImageToDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// DownloadImageToDevice indicates an expected call of DownloadImageToDevice.
+func (mr *MockVolthaServiceServerMockRecorder) DownloadImageToDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DownloadImageToDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).DownloadImageToDevice), arg0, arg1)
+}
+
+// EnableDevice mocks base method.
+func (m *MockVolthaServiceServer) EnableDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "EnableDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableDevice indicates an expected call of EnableDevice.
+func (mr *MockVolthaServiceServerMockRecorder) EnableDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).EnableDevice), arg0, arg1)
+}
+
+// EnableLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceServer) EnableLogicalDevicePort(arg0 context.Context, arg1 *voltha.LogicalPortId) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "EnableLogicalDevicePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnableLogicalDevicePort indicates an expected call of EnableLogicalDevicePort.
+func (mr *MockVolthaServiceServerMockRecorder) EnableLogicalDevicePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnableLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).EnableLogicalDevicePort), arg0, arg1)
+}
+
+// EnablePort mocks base method.
+func (m *MockVolthaServiceServer) EnablePort(arg0 context.Context, arg1 *voltha.Port) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "EnablePort", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// EnablePort indicates an expected call of EnablePort.
+func (mr *MockVolthaServiceServerMockRecorder) EnablePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EnablePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).EnablePort), arg0, arg1)
+}
+
+// ForceDeleteDevice mocks base method.
+func (m *MockVolthaServiceServer) ForceDeleteDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ForceDeleteDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ForceDeleteDevice indicates an expected call of ForceDeleteDevice.
+func (mr *MockVolthaServiceServerMockRecorder) ForceDeleteDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForceDeleteDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).ForceDeleteDevice), arg0, arg1)
+}
+
+// GetAlarmDeviceData mocks base method.
+func (m *MockVolthaServiceServer) GetAlarmDeviceData(arg0 context.Context, arg1 *common.ID) (*omci.AlarmDeviceData, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAlarmDeviceData", arg0, arg1)
+	ret0, _ := ret[0].(*omci.AlarmDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAlarmDeviceData indicates an expected call of GetAlarmDeviceData.
+func (mr *MockVolthaServiceServerMockRecorder) GetAlarmDeviceData(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAlarmDeviceData", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetAlarmDeviceData), arg0, arg1)
+}
+
+// GetCoreInstance mocks base method.
+func (m *MockVolthaServiceServer) GetCoreInstance(arg0 context.Context, arg1 *common.ID) (*voltha.CoreInstance, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetCoreInstance", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.CoreInstance)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetCoreInstance indicates an expected call of GetCoreInstance.
+func (mr *MockVolthaServiceServerMockRecorder) GetCoreInstance(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCoreInstance", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetCoreInstance), arg0, arg1)
+}
+
+// GetDevice mocks base method.
+func (m *MockVolthaServiceServer) GetDevice(arg0 context.Context, arg1 *common.ID) (*voltha.Device, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Device)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDevice indicates an expected call of GetDevice.
+func (mr *MockVolthaServiceServerMockRecorder) GetDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetDevice), arg0, arg1)
+}
+
+// GetDeviceType mocks base method.
+func (m *MockVolthaServiceServer) GetDeviceType(arg0 context.Context, arg1 *common.ID) (*voltha.DeviceType, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetDeviceType", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceType)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetDeviceType indicates an expected call of GetDeviceType.
+func (mr *MockVolthaServiceServerMockRecorder) GetDeviceType(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDeviceType", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetDeviceType), arg0, arg1)
+}
+
+// GetEventFilter mocks base method.
+func (m *MockVolthaServiceServer) GetEventFilter(arg0 context.Context, arg1 *common.ID) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetEventFilter indicates an expected call of GetEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) GetEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetEventFilter), arg0, arg1)
+}
+
+// GetExtValue mocks base method.
+func (m *MockVolthaServiceServer) GetExtValue(arg0 context.Context, arg1 *extension.ValueSpecifier) (*extension.ReturnValues, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetExtValue", arg0, arg1)
+	ret0, _ := ret[0].(*extension.ReturnValues)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetExtValue indicates an expected call of GetExtValue.
+func (mr *MockVolthaServiceServerMockRecorder) GetExtValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetExtValue", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetExtValue), arg0, arg1)
+}
+
+// GetImageDownload mocks base method.
+func (m *MockVolthaServiceServer) GetImageDownload(arg0 context.Context, arg1 *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImageDownload", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownload indicates an expected call of GetImageDownload.
+func (mr *MockVolthaServiceServerMockRecorder) GetImageDownload(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownload", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImageDownload), arg0, arg1)
+}
+
+// GetImageDownloadStatus mocks base method.
+func (m *MockVolthaServiceServer) GetImageDownloadStatus(arg0 context.Context, arg1 *voltha.ImageDownload) (*voltha.ImageDownload, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImageDownloadStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownload)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageDownloadStatus indicates an expected call of GetImageDownloadStatus.
+func (mr *MockVolthaServiceServerMockRecorder) GetImageDownloadStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageDownloadStatus", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImageDownloadStatus), arg0, arg1)
+}
+
+// GetImageStatus mocks base method.
+func (m *MockVolthaServiceServer) GetImageStatus(arg0 context.Context, arg1 *voltha.DeviceImageRequest) (*voltha.DeviceImageResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImageStatus", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceImageResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImageStatus indicates an expected call of GetImageStatus.
+func (mr *MockVolthaServiceServerMockRecorder) GetImageStatus(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageStatus", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImageStatus), arg0, arg1)
+}
+
+// GetImages mocks base method.
+func (m *MockVolthaServiceServer) GetImages(arg0 context.Context, arg1 *common.ID) (*voltha.Images, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetImages", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Images)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetImages indicates an expected call of GetImages.
+func (mr *MockVolthaServiceServerMockRecorder) GetImages(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImages", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetImages), arg0, arg1)
+}
+
+// GetLogicalDevice mocks base method.
+func (m *MockVolthaServiceServer) GetLogicalDevice(arg0 context.Context, arg1 *common.ID) (*voltha.LogicalDevice, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetLogicalDevice", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalDevice)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevice indicates an expected call of GetLogicalDevice.
+func (mr *MockVolthaServiceServerMockRecorder) GetLogicalDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetLogicalDevice), arg0, arg1)
+}
+
+// GetLogicalDevicePort mocks base method.
+func (m *MockVolthaServiceServer) GetLogicalDevicePort(arg0 context.Context, arg1 *voltha.LogicalPortId) (*voltha.LogicalPort, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetLogicalDevicePort", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalPort)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetLogicalDevicePort indicates an expected call of GetLogicalDevicePort.
+func (mr *MockVolthaServiceServerMockRecorder) GetLogicalDevicePort(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogicalDevicePort", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetLogicalDevicePort), arg0, arg1)
+}
+
+// GetMibDeviceData mocks base method.
+func (m *MockVolthaServiceServer) GetMibDeviceData(arg0 context.Context, arg1 *common.ID) (*omci.MibDeviceData, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetMibDeviceData", arg0, arg1)
+	ret0, _ := ret[0].(*omci.MibDeviceData)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetMibDeviceData indicates an expected call of GetMibDeviceData.
+func (mr *MockVolthaServiceServerMockRecorder) GetMibDeviceData(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMibDeviceData", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetMibDeviceData), arg0, arg1)
+}
+
+// GetOnuImages mocks base method.
+func (m *MockVolthaServiceServer) GetOnuImages(arg0 context.Context, arg1 *common.ID) (*voltha.OnuImages, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetOnuImages", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.OnuImages)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetOnuImages indicates an expected call of GetOnuImages.
+func (mr *MockVolthaServiceServerMockRecorder) GetOnuImages(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOnuImages", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetOnuImages), arg0, arg1)
+}
+
+// GetVoltha mocks base method.
+func (m *MockVolthaServiceServer) GetVoltha(arg0 context.Context, arg1 *empty.Empty) (*voltha.Voltha, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetVoltha", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Voltha)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetVoltha indicates an expected call of GetVoltha.
+func (mr *MockVolthaServiceServerMockRecorder) GetVoltha(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetVoltha", reflect.TypeOf((*MockVolthaServiceServer)(nil).GetVoltha), arg0, arg1)
+}
+
+// ListAdapters mocks base method.
+func (m *MockVolthaServiceServer) ListAdapters(arg0 context.Context, arg1 *empty.Empty) (*voltha.Adapters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListAdapters", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Adapters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListAdapters indicates an expected call of ListAdapters.
+func (mr *MockVolthaServiceServerMockRecorder) ListAdapters(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAdapters", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListAdapters), arg0, arg1)
+}
+
+// ListCoreInstances mocks base method.
+func (m *MockVolthaServiceServer) ListCoreInstances(arg0 context.Context, arg1 *empty.Empty) (*voltha.CoreInstances, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListCoreInstances", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.CoreInstances)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListCoreInstances indicates an expected call of ListCoreInstances.
+func (mr *MockVolthaServiceServerMockRecorder) ListCoreInstances(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListCoreInstances", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListCoreInstances), arg0, arg1)
+}
+
+// ListDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceFlowGroups(arg0 context.Context, arg1 *common.ID) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceFlowGroups", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlowGroups indicates an expected call of ListDeviceFlowGroups.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceFlowGroups(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceFlowGroups), arg0, arg1)
+}
+
+// ListDeviceFlows mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceFlows(arg0 context.Context, arg1 *common.ID) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceFlows", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceFlows indicates an expected call of ListDeviceFlows.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceFlows(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceFlows", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceFlows), arg0, arg1)
+}
+
+// ListDeviceIds mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceIds(arg0 context.Context, arg1 *empty.Empty) (*common.IDs, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceIds", arg0, arg1)
+	ret0, _ := ret[0].(*common.IDs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceIds indicates an expected call of ListDeviceIds.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceIds(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceIds", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceIds), arg0, arg1)
+}
+
+// ListDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceServer) ListDevicePmConfigs(arg0 context.Context, arg1 *common.ID) (*voltha.PmConfigs, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDevicePmConfigs", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.PmConfigs)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePmConfigs indicates an expected call of ListDevicePmConfigs.
+func (mr *MockVolthaServiceServerMockRecorder) ListDevicePmConfigs(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDevicePmConfigs), arg0, arg1)
+}
+
+// ListDevicePorts mocks base method.
+func (m *MockVolthaServiceServer) ListDevicePorts(arg0 context.Context, arg1 *common.ID) (*voltha.Ports, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDevicePorts", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Ports)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevicePorts indicates an expected call of ListDevicePorts.
+func (mr *MockVolthaServiceServerMockRecorder) ListDevicePorts(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevicePorts", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDevicePorts), arg0, arg1)
+}
+
+// ListDeviceTypes mocks base method.
+func (m *MockVolthaServiceServer) ListDeviceTypes(arg0 context.Context, arg1 *empty.Empty) (*voltha.DeviceTypes, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDeviceTypes", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.DeviceTypes)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDeviceTypes indicates an expected call of ListDeviceTypes.
+func (mr *MockVolthaServiceServerMockRecorder) ListDeviceTypes(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDeviceTypes", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDeviceTypes), arg0, arg1)
+}
+
+// ListDevices mocks base method.
+func (m *MockVolthaServiceServer) ListDevices(arg0 context.Context, arg1 *empty.Empty) (*voltha.Devices, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListDevices", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.Devices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListDevices indicates an expected call of ListDevices.
+func (mr *MockVolthaServiceServerMockRecorder) ListDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListDevices", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListDevices), arg0, arg1)
+}
+
+// ListEventFilters mocks base method.
+func (m *MockVolthaServiceServer) ListEventFilters(arg0 context.Context, arg1 *empty.Empty) (*voltha.EventFilters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListEventFilters", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListEventFilters indicates an expected call of ListEventFilters.
+func (mr *MockVolthaServiceServerMockRecorder) ListEventFilters(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEventFilters", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListEventFilters), arg0, arg1)
+}
+
+// ListImageDownloads mocks base method.
+func (m *MockVolthaServiceServer) ListImageDownloads(arg0 context.Context, arg1 *common.ID) (*voltha.ImageDownloads, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListImageDownloads", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.ImageDownloads)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListImageDownloads indicates an expected call of ListImageDownloads.
+func (mr *MockVolthaServiceServerMockRecorder) ListImageDownloads(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListImageDownloads", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListImageDownloads), arg0, arg1)
+}
+
+// ListLogicalDeviceFlowGroups mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDeviceFlowGroups(arg0 context.Context, arg1 *common.ID) (*openflow_13.FlowGroups, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlowGroups", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.FlowGroups)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlowGroups indicates an expected call of ListLogicalDeviceFlowGroups.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDeviceFlowGroups(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlowGroups", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDeviceFlowGroups), arg0, arg1)
+}
+
+// ListLogicalDeviceFlows mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDeviceFlows(arg0 context.Context, arg1 *common.ID) (*openflow_13.Flows, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDeviceFlows", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.Flows)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceFlows indicates an expected call of ListLogicalDeviceFlows.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDeviceFlows(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceFlows", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDeviceFlows), arg0, arg1)
+}
+
+// ListLogicalDeviceMeters mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDeviceMeters(arg0 context.Context, arg1 *common.ID) (*openflow_13.Meters, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDeviceMeters", arg0, arg1)
+	ret0, _ := ret[0].(*openflow_13.Meters)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDeviceMeters indicates an expected call of ListLogicalDeviceMeters.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDeviceMeters(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDeviceMeters", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDeviceMeters), arg0, arg1)
+}
+
+// ListLogicalDevicePorts mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDevicePorts(arg0 context.Context, arg1 *common.ID) (*voltha.LogicalPorts, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDevicePorts", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalPorts)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevicePorts indicates an expected call of ListLogicalDevicePorts.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDevicePorts(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevicePorts", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDevicePorts), arg0, arg1)
+}
+
+// ListLogicalDevices mocks base method.
+func (m *MockVolthaServiceServer) ListLogicalDevices(arg0 context.Context, arg1 *empty.Empty) (*voltha.LogicalDevices, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ListLogicalDevices", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.LogicalDevices)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ListLogicalDevices indicates an expected call of ListLogicalDevices.
+func (mr *MockVolthaServiceServerMockRecorder) ListLogicalDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListLogicalDevices", reflect.TypeOf((*MockVolthaServiceServer)(nil).ListLogicalDevices), arg0, arg1)
+}
+
+// RebootDevice mocks base method.
+func (m *MockVolthaServiceServer) RebootDevice(arg0 context.Context, arg1 *common.ID) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RebootDevice", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RebootDevice indicates an expected call of RebootDevice.
+func (mr *MockVolthaServiceServerMockRecorder) RebootDevice(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RebootDevice", reflect.TypeOf((*MockVolthaServiceServer)(nil).RebootDevice), arg0, arg1)
+}
+
+// ReceiveChangeEvents mocks base method.
+func (m *MockVolthaServiceServer) ReceiveChangeEvents(arg0 *empty.Empty, arg1 voltha.VolthaService_ReceiveChangeEventsServer) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReceiveChangeEvents", arg0, arg1)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// ReceiveChangeEvents indicates an expected call of ReceiveChangeEvents.
+func (mr *MockVolthaServiceServerMockRecorder) ReceiveChangeEvents(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceiveChangeEvents", reflect.TypeOf((*MockVolthaServiceServer)(nil).ReceiveChangeEvents), arg0, arg1)
+}
+
+// ReceivePacketsIn mocks base method.
+func (m *MockVolthaServiceServer) ReceivePacketsIn(arg0 *empty.Empty, arg1 voltha.VolthaService_ReceivePacketsInServer) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReceivePacketsIn", arg0, arg1)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// ReceivePacketsIn indicates an expected call of ReceivePacketsIn.
+func (mr *MockVolthaServiceServerMockRecorder) ReceivePacketsIn(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReceivePacketsIn", reflect.TypeOf((*MockVolthaServiceServer)(nil).ReceivePacketsIn), arg0, arg1)
+}
+
+// ReconcileDevices mocks base method.
+func (m *MockVolthaServiceServer) ReconcileDevices(arg0 context.Context, arg1 *common.IDs) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "ReconcileDevices", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// ReconcileDevices indicates an expected call of ReconcileDevices.
+func (mr *MockVolthaServiceServerMockRecorder) ReconcileDevices(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReconcileDevices", reflect.TypeOf((*MockVolthaServiceServer)(nil).ReconcileDevices), arg0, arg1)
+}
+
+// RevertImageUpdate mocks base method.
+func (m *MockVolthaServiceServer) RevertImageUpdate(arg0 context.Context, arg1 *voltha.ImageDownload) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "RevertImageUpdate", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// RevertImageUpdate indicates an expected call of RevertImageUpdate.
+func (mr *MockVolthaServiceServerMockRecorder) RevertImageUpdate(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RevertImageUpdate", reflect.TypeOf((*MockVolthaServiceServer)(nil).RevertImageUpdate), arg0, arg1)
+}
+
+// SelfTest mocks base method.
+func (m *MockVolthaServiceServer) SelfTest(arg0 context.Context, arg1 *common.ID) (*voltha.SelfTestResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SelfTest", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.SelfTestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SelfTest indicates an expected call of SelfTest.
+func (mr *MockVolthaServiceServerMockRecorder) SelfTest(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelfTest", reflect.TypeOf((*MockVolthaServiceServer)(nil).SelfTest), arg0, arg1)
+}
+
+// SetExtValue mocks base method.
+func (m *MockVolthaServiceServer) SetExtValue(arg0 context.Context, arg1 *extension.ValueSet) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetExtValue", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SetExtValue indicates an expected call of SetExtValue.
+func (mr *MockVolthaServiceServerMockRecorder) SetExtValue(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetExtValue", reflect.TypeOf((*MockVolthaServiceServer)(nil).SetExtValue), arg0, arg1)
+}
+
+// SimulateAlarm mocks base method.
+func (m *MockVolthaServiceServer) SimulateAlarm(arg0 context.Context, arg1 *voltha.SimulateAlarmRequest) (*common.OperationResp, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SimulateAlarm", arg0, arg1)
+	ret0, _ := ret[0].(*common.OperationResp)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// SimulateAlarm indicates an expected call of SimulateAlarm.
+func (mr *MockVolthaServiceServerMockRecorder) SimulateAlarm(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SimulateAlarm", reflect.TypeOf((*MockVolthaServiceServer)(nil).SimulateAlarm), arg0, arg1)
+}
+
+// StartOmciTestAction mocks base method.
+func (m *MockVolthaServiceServer) StartOmciTestAction(arg0 context.Context, arg1 *omci.OmciTestRequest) (*omci.TestResponse, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StartOmciTestAction", arg0, arg1)
+	ret0, _ := ret[0].(*omci.TestResponse)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// StartOmciTestAction indicates an expected call of StartOmciTestAction.
+func (mr *MockVolthaServiceServerMockRecorder) StartOmciTestAction(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StartOmciTestAction", reflect.TypeOf((*MockVolthaServiceServer)(nil).StartOmciTestAction), arg0, arg1)
+}
+
+// StreamPacketsOut mocks base method.
+func (m *MockVolthaServiceServer) StreamPacketsOut(arg0 voltha.VolthaService_StreamPacketsOutServer) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "StreamPacketsOut", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// StreamPacketsOut indicates an expected call of StreamPacketsOut.
+func (mr *MockVolthaServiceServerMockRecorder) StreamPacketsOut(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StreamPacketsOut", reflect.TypeOf((*MockVolthaServiceServer)(nil).StreamPacketsOut), arg0)
+}
+
+// UpdateDevicePmConfigs mocks base method.
+func (m *MockVolthaServiceServer) UpdateDevicePmConfigs(arg0 context.Context, arg1 *voltha.PmConfigs) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateDevicePmConfigs", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateDevicePmConfigs indicates an expected call of UpdateDevicePmConfigs.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateDevicePmConfigs(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDevicePmConfigs", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateDevicePmConfigs), arg0, arg1)
+}
+
+// UpdateEventFilter mocks base method.
+func (m *MockVolthaServiceServer) UpdateEventFilter(arg0 context.Context, arg1 *voltha.EventFilter) (*voltha.EventFilter, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateEventFilter", arg0, arg1)
+	ret0, _ := ret[0].(*voltha.EventFilter)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateEventFilter indicates an expected call of UpdateEventFilter.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateEventFilter(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEventFilter", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateEventFilter), arg0, arg1)
+}
+
+// UpdateLogicalDeviceFlowGroupTable mocks base method.
+func (m *MockVolthaServiceServer) UpdateLogicalDeviceFlowGroupTable(arg0 context.Context, arg1 *openflow_13.FlowGroupTableUpdate) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowGroupTable", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowGroupTable indicates an expected call of UpdateLogicalDeviceFlowGroupTable.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateLogicalDeviceFlowGroupTable(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowGroupTable", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateLogicalDeviceFlowGroupTable), arg0, arg1)
+}
+
+// UpdateLogicalDeviceFlowTable mocks base method.
+func (m *MockVolthaServiceServer) UpdateLogicalDeviceFlowTable(arg0 context.Context, arg1 *openflow_13.FlowTableUpdate) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceFlowTable", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceFlowTable indicates an expected call of UpdateLogicalDeviceFlowTable.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateLogicalDeviceFlowTable(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceFlowTable", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateLogicalDeviceFlowTable), arg0, arg1)
+}
+
+// UpdateLogicalDeviceMeterTable mocks base method.
+func (m *MockVolthaServiceServer) UpdateLogicalDeviceMeterTable(arg0 context.Context, arg1 *openflow_13.MeterModUpdate) (*empty.Empty, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "UpdateLogicalDeviceMeterTable", arg0, arg1)
+	ret0, _ := ret[0].(*empty.Empty)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// UpdateLogicalDeviceMeterTable indicates an expected call of UpdateLogicalDeviceMeterTable.
+func (mr *MockVolthaServiceServerMockRecorder) UpdateLogicalDeviceMeterTable(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateLogicalDeviceMeterTable", reflect.TypeOf((*MockVolthaServiceServer)(nil).UpdateLogicalDeviceMeterTable), arg0, arg1)
+}
+
+// MockVolthaService_StreamPacketsOutServer is a mock of VolthaService_StreamPacketsOutServer interface.
+type MockVolthaService_StreamPacketsOutServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_StreamPacketsOutServerMockRecorder
+}
+
+// MockVolthaService_StreamPacketsOutServerMockRecorder is the mock recorder for MockVolthaService_StreamPacketsOutServer.
+type MockVolthaService_StreamPacketsOutServerMockRecorder struct {
+	mock *MockVolthaService_StreamPacketsOutServer
+}
+
+// NewMockVolthaService_StreamPacketsOutServer creates a new mock instance.
+func NewMockVolthaService_StreamPacketsOutServer(ctrl *gomock.Controller) *MockVolthaService_StreamPacketsOutServer {
+	mock := &MockVolthaService_StreamPacketsOutServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_StreamPacketsOutServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_StreamPacketsOutServer) EXPECT() *MockVolthaService_StreamPacketsOutServerMockRecorder {
+	return m.recorder
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).Context))
+}
+
+// Recv mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) Recv() (*openflow_13.PacketOut, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Recv")
+	ret0, _ := ret[0].(*openflow_13.PacketOut)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// Recv indicates an expected call of Recv.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) Recv() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Recv", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).Recv))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutServer) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).RecvMsg), m)
+}
+
+// SendAndClose mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SendAndClose(arg0 *empty.Empty) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendAndClose", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendAndClose indicates an expected call of SendAndClose.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SendAndClose(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendAndClose", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SendAndClose), arg0)
+}
+
+// SendHeader mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SendHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendHeader indicates an expected call of SendHeader.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SendHeader), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_StreamPacketsOutServer) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SendMsg), m)
+}
+
+// SetHeader mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SetHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SetHeader indicates an expected call of SetHeader.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SetHeader), arg0)
+}
+
+// SetTrailer mocks base method.
+func (m *MockVolthaService_StreamPacketsOutServer) SetTrailer(arg0 metadata.MD) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "SetTrailer", arg0)
+}
+
+// SetTrailer indicates an expected call of SetTrailer.
+func (mr *MockVolthaService_StreamPacketsOutServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockVolthaService_StreamPacketsOutServer)(nil).SetTrailer), arg0)
+}
+
+// MockVolthaService_ReceivePacketsInServer is a mock of VolthaService_ReceivePacketsInServer interface.
+type MockVolthaService_ReceivePacketsInServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceivePacketsInServerMockRecorder
+}
+
+// MockVolthaService_ReceivePacketsInServerMockRecorder is the mock recorder for MockVolthaService_ReceivePacketsInServer.
+type MockVolthaService_ReceivePacketsInServerMockRecorder struct {
+	mock *MockVolthaService_ReceivePacketsInServer
+}
+
+// NewMockVolthaService_ReceivePacketsInServer creates a new mock instance.
+func NewMockVolthaService_ReceivePacketsInServer(ctrl *gomock.Controller) *MockVolthaService_ReceivePacketsInServer {
+	mock := &MockVolthaService_ReceivePacketsInServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceivePacketsInServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceivePacketsInServer) EXPECT() *MockVolthaService_ReceivePacketsInServerMockRecorder {
+	return m.recorder
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).Context))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInServer) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).RecvMsg), m)
+}
+
+// Send mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) Send(arg0 *openflow_13.PacketIn) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Send", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Send indicates an expected call of Send.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) Send(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).Send), arg0)
+}
+
+// SendHeader mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) SendHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendHeader indicates an expected call of SendHeader.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SendHeader), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceivePacketsInServer) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SendMsg), m)
+}
+
+// SetHeader mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) SetHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SetHeader indicates an expected call of SetHeader.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SetHeader), arg0)
+}
+
+// SetTrailer mocks base method.
+func (m *MockVolthaService_ReceivePacketsInServer) SetTrailer(arg0 metadata.MD) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "SetTrailer", arg0)
+}
+
+// SetTrailer indicates an expected call of SetTrailer.
+func (mr *MockVolthaService_ReceivePacketsInServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockVolthaService_ReceivePacketsInServer)(nil).SetTrailer), arg0)
+}
+
+// MockVolthaService_ReceiveChangeEventsServer is a mock of VolthaService_ReceiveChangeEventsServer interface.
+type MockVolthaService_ReceiveChangeEventsServer struct {
+	ctrl     *gomock.Controller
+	recorder *MockVolthaService_ReceiveChangeEventsServerMockRecorder
+}
+
+// MockVolthaService_ReceiveChangeEventsServerMockRecorder is the mock recorder for MockVolthaService_ReceiveChangeEventsServer.
+type MockVolthaService_ReceiveChangeEventsServerMockRecorder struct {
+	mock *MockVolthaService_ReceiveChangeEventsServer
+}
+
+// NewMockVolthaService_ReceiveChangeEventsServer creates a new mock instance.
+func NewMockVolthaService_ReceiveChangeEventsServer(ctrl *gomock.Controller) *MockVolthaService_ReceiveChangeEventsServer {
+	mock := &MockVolthaService_ReceiveChangeEventsServer{ctrl: ctrl}
+	mock.recorder = &MockVolthaService_ReceiveChangeEventsServerMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockVolthaService_ReceiveChangeEventsServer) EXPECT() *MockVolthaService_ReceiveChangeEventsServerMockRecorder {
+	return m.recorder
+}
+
+// Context mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) Context() context.Context {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Context")
+	ret0, _ := ret[0].(context.Context)
+	return ret0
+}
+
+// Context indicates an expected call of Context.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) Context() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Context", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).Context))
+}
+
+// RecvMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsServer) RecvMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "RecvMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// RecvMsg indicates an expected call of RecvMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) RecvMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecvMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).RecvMsg), m)
+}
+
+// Send mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) Send(arg0 *openflow_13.ChangeEvent) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Send", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// Send indicates an expected call of Send.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) Send(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).Send), arg0)
+}
+
+// SendHeader mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) SendHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SendHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendHeader indicates an expected call of SendHeader.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SendHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeader", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SendHeader), arg0)
+}
+
+// SendMsg mocks base method.
+func (m_2 *MockVolthaService_ReceiveChangeEventsServer) SendMsg(m interface{}) error {
+	m_2.ctrl.T.Helper()
+	ret := m_2.ctrl.Call(m_2, "SendMsg", m)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SendMsg indicates an expected call of SendMsg.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SendMsg(m interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendMsg", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SendMsg), m)
+}
+
+// SetHeader mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) SetHeader(arg0 metadata.MD) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "SetHeader", arg0)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// SetHeader indicates an expected call of SetHeader.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SetHeader(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHeader", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SetHeader), arg0)
+}
+
+// SetTrailer mocks base method.
+func (m *MockVolthaService_ReceiveChangeEventsServer) SetTrailer(arg0 metadata.MD) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "SetTrailer", arg0)
+}
+
+// SetTrailer indicates an expected call of SetTrailer.
+func (mr *MockVolthaService_ReceiveChangeEventsServerMockRecorder) SetTrailer(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetTrailer", reflect.TypeOf((*MockVolthaService_ReceiveChangeEventsServer)(nil).SetTrailer), arg0)
+}
