vgc UTs part 4
Change-Id: I0e78854fefb8f0ad270a84bc88982f859a0d5995
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)
+ }
+ })
+ }
+}