FTTH-55780 [UT coverage for VGC upto 47%]
Change-Id: I6503d90643d214ac2fa7e21d5a39a44913019ad7
diff --git a/internal/pkg/application/igmpprofiles_test.go b/internal/pkg/application/igmpprofiles_test.go
new file mode 100644
index 0000000..e3b7328
--- /dev/null
+++ b/internal/pkg/application/igmpprofiles_test.go
@@ -0,0 +1,755 @@
+/*
+* 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"
+ "net"
+ "reflect"
+ "sync"
+ "testing"
+ "voltha-go-controller/internal/pkg/controller"
+ "voltha-go-controller/internal/pkg/of"
+ common "voltha-go-controller/internal/pkg/types"
+ "voltha-go-controller/internal/pkg/util"
+ "voltha-go-controller/internal/test/mocks"
+
+ "github.com/golang/mock/gomock"
+ "github.com/stretchr/testify/assert"
+)
+
+func Test_newIgmpProfile(t *testing.T) {
+ type args struct {
+ igmpProfileConfig *common.IGMPConfig
+ }
+ b := true
+ tests := []struct {
+ name string
+ args args
+ want *IgmpProfile
+ }{
+ {
+ name: "DelExclSource",
+ args: args{
+ igmpProfileConfig: &common.IGMPConfig{
+ FastLeave: &b,
+ PeriodicQuery: &b,
+ WithRAUpLink: &b,
+ WithRADownLink: &b,
+ },
+ },
+ want: &IgmpProfile{},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got := newIgmpProfile(tt.args.igmpProfileConfig)
+ assert.NotNil(t, got)
+ })
+ }
+}
+
+func TestNewMvlanProfile(t *testing.T) {
+ type args struct {
+ name string
+ mvlan of.VlanType
+ ponVlan of.VlanType
+ isChannelBasedGroup bool
+ OLTSerialNums []string
+ actChannelPerPon uint32
+ }
+ tests := []struct {
+ name string
+ args args
+ want *MvlanProfile
+ }{
+ {
+ name: "DelExclSource",
+ args: args{
+ name: "test_mvlan",
+ },
+ want: &MvlanProfile{},
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got := NewMvlanProfile(tt.args.name, tt.args.mvlan, tt.args.ponVlan, tt.args.isChannelBasedGroup, tt.args.OLTSerialNums, tt.args.actChannelPerPon)
+ assert.NotNil(t, got)
+ })
+ }
+}
+
+func TestMvlanProfile_AddMvlanProxy(t *testing.T) {
+ proxy := map[string]*MCGroupProxy{}
+ proxy["test_key"] = &MCGroupProxy{
+ Mode: common.Exclude,
+ }
+ grp := make(map[string]*MvlanGroup)
+ grp["test_key"] = &MvlanGroup{
+ Name: "test_key",
+ IsStatic: true,
+ }
+ type args struct {
+ name string
+ proxyInfo common.MulticastGroupProxy
+ }
+ tests := []struct {
+ name string
+ args args
+ }{
+ {
+ name: "AddMvlanProxy",
+ args: args{
+ name: "test_key",
+ proxyInfo: common.MulticastGroupProxy{
+ IsStatic: common.IsStaticYes,
+ },
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ Proxy: proxy,
+ Groups: grp,
+ }
+ mvp.AddMvlanProxy(tt.args.name, tt.args.proxyInfo)
+ })
+ }
+}
+
+func TestMvlanProfile_AddMvlanGroup(t *testing.T) {
+ type args struct {
+ name string
+ ips []string
+ }
+ grp := make(map[string]*MvlanGroup)
+ grp["test_key"] = &MvlanGroup{
+ Name: "test_key",
+ IsStatic: true,
+ }
+ tests := []struct {
+ name string
+ args args
+ }{
+ {
+ name: "AddMvlanProxy",
+ args: args{
+ name: "test_key",
+ ips: []string{
+ "0.0.0.0",
+ },
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ Groups: grp,
+ }
+ mvp.AddMvlanGroup(tt.args.name, tt.args.ips)
+ })
+ }
+}
+
+func TestMvlanProfile_GetUsMatchVlan(t *testing.T) {
+ tests := []struct {
+ name string
+ want of.VlanType
+ }{
+ {
+ name: "GetUsMatchVlan",
+ want: of.VlanAny,
+ },
+ {
+ name: "GetUsMatchVlan_IsPonVlanPresent",
+ want: of.VlanAny,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ PonVlan: of.VlanAny,
+ Mvlan: of.VlanAny,
+ }
+ switch tt.name {
+ case "GetUsMatchVlan":
+ mvp.IsPonVlanPresent = true
+ if got := mvp.GetUsMatchVlan(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("MvlanProfile.GetUsMatchVlan() = %v, want %v", got, tt.want)
+ }
+ case "GetUsMatchVlan_IsPonVlanPresent":
+ if got := mvp.GetUsMatchVlan(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("MvlanProfile.GetUsMatchVlan() = %v, want %v", got, tt.want)
+ }
+ }
+ })
+ }
+}
+
+func TestMvlanProfile_isChannelStatic(t *testing.T) {
+ type args struct {
+ channel net.IP
+ }
+ grp := make(map[string]*MvlanGroup)
+ grp["test_key"] = &MvlanGroup{
+ Name: "test_key",
+ IsStatic: true,
+ McIPs: []string{
+ "224.0.0.1",
+ },
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ }{
+ {
+ name: "isChannelStatic",
+ args: args{
+ channel: AllSystemsMulticastGroupIP,
+ },
+ want: true,
+ },
+ {
+ name: "isChannelStatic_false",
+ want: false,
+ },
+ {
+ name: "containsStaticChannels",
+ want: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ Groups: grp,
+ }
+ switch tt.name {
+ case "isChannelStatic", "isChannelStatic_false":
+ if got := mvp.isChannelStatic(tt.args.channel); got != tt.want {
+ t.Errorf("MvlanProfile.isChannelStatic() = %v, want %v", got, tt.want)
+ }
+
+ case "containsStaticChannels":
+ if got := mvp.containsStaticChannels(); got != tt.want {
+ t.Errorf("MvlanProfile.isChannelStatic() = %v, want %v", got, tt.want)
+ }
+ }
+ })
+ }
+}
+
+func TestMvlanProfile_getAllStaticChannels(t *testing.T) {
+ grp := make(map[string]*MvlanGroup)
+ grp["test_key"] = &MvlanGroup{
+ Name: "test_key",
+ IsStatic: true,
+ McIPs: []string{
+ "224.0.0.1",
+ },
+ }
+ tests := []struct {
+ name string
+ want []net.IP
+ want1 bool
+ }{
+ {
+ name: "getAllStaticChannels",
+ want: []net.IP{
+ AllSystemsMulticastGroupIP,
+ },
+ want1: true,
+ },
+ {
+ name: "getAllOldGroupStaticChannels",
+ want: []net.IP{
+ AllSystemsMulticastGroupIP,
+ },
+ want1: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ Groups: grp,
+ oldGroups: grp,
+ }
+ switch tt.name {
+ case "getAllStaticChannels":
+ got, got1 := mvp.getAllStaticChannels()
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("MvlanProfile.getAllStaticChannels() got = %v, want %v", got, tt.want)
+ }
+ if got1 != tt.want1 {
+ t.Errorf("MvlanProfile.getAllStaticChannels() got1 = %v, want %v", got1, tt.want1)
+ }
+ case "getAllOldGroupStaticChannels":
+ got, got1 := mvp.getAllOldGroupStaticChannels()
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("MvlanProfile.getAllStaticChannels() got = %v, want %v", got, tt.want)
+ }
+ if got1 != tt.want1 {
+ t.Errorf("MvlanProfile.getAllStaticChannels() got1 = %v, want %v", got1, tt.want1)
+ }
+ }
+ })
+ }
+}
+
+func TestMvlanProfile_DelFlows(t *testing.T) {
+ type args struct {
+ cntx context.Context
+ device *VoltDevice
+ flow *of.VoltFlow
+ }
+ appMock := mocks.NewMockApp(gomock.NewController(t))
+ controller.NewController(ctx, appMock)
+ pendingDeleteFlow := map[string]map[string]bool{}
+ delFlow := map[string]bool{}
+ delFlow["SDX6320031"] = true
+ pendingDeleteFlow["SDX6320031"] = delFlow
+ voltDev := &VoltDevice{
+ Name: "SDX6320031",
+ SerialNum: "SDX6320031",
+ FlowDelEventMap: util.NewConcurrentMap(),
+ }
+ subFlows := map[uint64]*of.VoltSubFlow{}
+ vltSubFlow := &of.VoltSubFlow{
+ Cookie: 103112802816,
+ State: of.FlowAddSuccess,
+ }
+ subFlows[0] = vltSubFlow
+ flow := &of.VoltFlow{
+ PortName: "SDX6320031-1",
+ SubFlows: subFlows,
+ }
+ tests := []struct {
+ name string
+ args args
+ wantErr bool
+ }{
+ {
+ name: "getAllStaticChannels",
+ args: args{
+ cntx: context.Background(),
+ device: voltDev,
+ flow: flow,
+ },
+ wantErr: true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ PendingDeleteFlow: pendingDeleteFlow,
+ }
+ dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+ db = dbintf
+ dbintf.EXPECT().PutMvlan(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
+ if err := mvp.DelFlows(tt.args.cntx, tt.args.device, tt.args.flow); (err != nil) != tt.wantErr {
+ t.Errorf("MvlanProfile.DelFlows() error = %v, wantErr %v", err, tt.wantErr)
+ }
+ })
+ }
+}
+
+func TestMvlanProfile_generateGroupKey(t *testing.T) {
+ type args struct {
+ name string
+ ipAddr string
+ }
+ tests := []struct {
+ name string
+ args args
+ want string
+ }{
+ {
+ name: "generateGroupKey",
+ args: args{
+ name: "test-key",
+ ipAddr: "0.0.0.0",
+ },
+ want: "0_test-key",
+ },
+ {
+ name: "generateGroupKey_IsChannelBasedGroup",
+ args: args{
+ name: "test-key",
+ ipAddr: "0.0.0.0",
+ },
+ want: "0_0.0.0.0",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{}
+ switch tt.name {
+ case "generateGroupKey":
+ if got := mvp.generateGroupKey(tt.args.name, tt.args.ipAddr); got != tt.want {
+ t.Errorf("MvlanProfile.generateGroupKey() = %v, want %v", got, tt.want)
+ }
+ case "generateGroupKey_IsChannelBasedGroup":
+ mvp.IsChannelBasedGroup = true
+ if got := mvp.generateGroupKey(tt.args.name, tt.args.ipAddr); got != tt.want {
+ t.Errorf("MvlanProfile.generateGroupKey() = %v, want %v", got, tt.want)
+ }
+ }
+ })
+ }
+}
+
+func TestMvlanProfile_GetStaticGroupName(t *testing.T) {
+ type args struct {
+ gip net.IP
+ }
+ grp := make(map[string]*MvlanGroup)
+ grp["test_key"] = &MvlanGroup{
+ Name: "test_key",
+ IsStatic: true,
+ McIPs: []string{
+ "224.0.0.1",
+ },
+ }
+ tests := []struct {
+ name string
+ args args
+ want string
+ }{
+ {
+ name: "GetStaticGroupName",
+ args: args{
+ gip: AllSystemsMulticastGroupIP,
+ },
+ want: "test_key",
+ },
+ {
+ name: "GetStaticGroupName",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ Groups: grp,
+ }
+ if got := mvp.GetStaticGroupName(tt.args.gip); got != tt.want {
+ t.Errorf("MvlanProfile.GetStaticGroupName() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestMvlanProfile_pushIgmpMcastFlows(t *testing.T) {
+ type args struct {
+ cntx context.Context
+ OLTSerialNum string
+ }
+ grp := make(map[string]*MvlanGroup)
+ grp["test_key"] = &MvlanGroup{
+ Name: "test_key",
+ IsStatic: true,
+ McIPs: []string{
+ "224.0.0.1",
+ },
+ }
+ devicesList := make(map[string]OperInProgress)
+ devicesList["SDX6320031"] = opt82
+ va := GetApplication()
+ d := &VoltDevice{
+ Name: "SDX6320031",
+ SerialNum: "SDX6320031",
+ Ports: sync.Map{},
+ NniPort: "16777472",
+ }
+ voltPort := &VoltPort{
+ Name: "16777472",
+ Device: "SDX6320031",
+ ID: 16777472,
+ State: PortStateUp,
+ ChannelPerSubAlarmRaised: false,
+ Type: VoltPortTypeNni,
+ }
+ d.Ports.Store("16777472", voltPort)
+ va.DevicesDisc.Store("SDX6320031", d)
+ mvp := &MvlanProfile{
+ Name: "mvlan_test",
+ }
+ va.MvlanProfilesByTag.Store(of.VlanAny, mvp)
+ tests := []struct {
+ name string
+ args args
+ }{
+ {
+ name: "GetStaticGroupName",
+ args: args{
+ cntx: context.Background(),
+ OLTSerialNum: "SDX6320031",
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ DevicesList: devicesList,
+ Groups: grp,
+ Mvlan: of.VlanAny,
+ }
+ mvp.pushIgmpMcastFlows(tt.args.cntx, tt.args.OLTSerialNum)
+ })
+ }
+}
+
+func TestMvlanProfile_updateStaticGroups(t *testing.T) {
+ type args struct {
+ cntx context.Context
+ deviceID string
+ added []net.IP
+ removed []net.IP
+ }
+ devicesList := make(map[string]OperInProgress)
+ devicesList["SDX6320031"] = opt82
+ va := GetApplication()
+ d := &VoltDevice{
+ Name: "SDX6320031",
+ SerialNum: "SDX6320031",
+ Ports: sync.Map{},
+ NniPort: "16777472",
+ FlowDelEventMap: util.NewConcurrentMap(),
+ }
+ va.DevicesDisc.Store("SDX6320031", d)
+ tests := []struct {
+ name string
+ args args
+ }{
+ {
+ name: "updateStaticGroups",
+ args: args{
+ cntx: context.Background(),
+ deviceID: "SDX6320031",
+ added: []net.IP{AllSystemsMulticastGroupIP},
+ removed: []net.IP{AllSystemsMulticastGroupIP},
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ Name: "mvlan_test",
+ DevicesList: devicesList,
+ Mvlan: of.VlanAny,
+ }
+ va.MvlanProfilesByTag.Store(of.VlanAny, mvp)
+ va.MvlanProfilesByName.Store("mvlan_test", mvp)
+ mvp.updateStaticGroups(tt.args.cntx, tt.args.deviceID, tt.args.added, tt.args.removed)
+ })
+ }
+}
+func TestMvlanProfile_updateDynamicGroups(t *testing.T) {
+ type args struct {
+ cntx context.Context
+ deviceID string
+ added []net.IP
+ removed []net.IP
+ }
+ grp := make(map[string]*MvlanGroup)
+ grp["test_key"] = &MvlanGroup{
+ Name: "test_key",
+ IsStatic: true,
+ McIPs: []string{
+ "224.0.0.1",
+ },
+ }
+ devicesList := make(map[string]OperInProgress)
+ devicesList["SDX6320031"] = opt82
+ va := GetApplication()
+ d := &VoltDevice{
+ Name: "SDX6320031",
+ SerialNum: "SDX6320031",
+ Ports: sync.Map{},
+ NniPort: "16777472",
+ FlowDelEventMap: util.NewConcurrentMap(),
+ }
+ va.DevicesDisc.Store("SDX6320031", d)
+ devices := map[string]*IgmpGroupDevice{}
+ igmpDevice := &IgmpGroupDevice{
+ Device: "SDX6320031",
+ SerialNo: "SDX6320031",
+ GroupName: "4096_test_key",
+ Mvlan: of.VlanAny,
+ GroupChannels: sync.Map{},
+ GroupAddr: AllSystemsMulticastGroupIP,
+ }
+ devices["SDX6320031"] = igmpDevice
+ group := &IgmpGroup{
+ GroupName: "4096_test_key",
+ GroupID: uint32(256),
+ Mvlan: of.VlanAny,
+ Devices: devices,
+ }
+ va.IgmpGroups.Store("4096_test_key", group)
+ newReceivers := map[string]*IgmpGroupPort{}
+ igp := &IgmpGroupPort{
+ Port: "16777470",
+ }
+ newReceivers["16777472"] = igp
+ b := IgmpVersion2
+ igmpChanel := &IgmpGroupChannel{
+ GroupAddr: AllSystemsMulticastGroupIP,
+ GroupName: "test_key",
+ NewReceivers: newReceivers,
+ Version: IgmpVersion2,
+ ServVersion: &b,
+ }
+ igmpDevice.GroupChannels.Store(AllSystemsMulticastGroupIP.String(), igmpChanel)
+ proxy := map[string]*MCGroupProxy{}
+ mgGroupProxy := &MCGroupProxy{
+ Mode: common.Include,
+ SourceList: []net.IP{
+ AllSystemsMulticastGroupIP,
+ },
+ }
+ proxy[igmpChanel.GroupName] = mgGroupProxy
+ tests := []struct {
+ name string
+ args args
+ }{
+ {
+ name: "updateDynamicGroups",
+ args: args{
+ cntx: context.Background(),
+ deviceID: "SDX6320031",
+ added: []net.IP{AllSystemsMulticastGroupIP},
+ removed: []net.IP{AllSystemsMulticastGroupIP},
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ Name: "test_key",
+ DevicesList: devicesList,
+ Mvlan: of.VlanAny,
+ Groups: grp,
+ Proxy: proxy,
+ }
+ va.MvlanProfilesByTag.Store(of.VlanAny, mvp)
+ va.MvlanProfilesByName.Store("test_key", mvp)
+ dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
+ db = dbintf
+ dbintf.EXPECT().PutIgmpRcvr(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
+ dbintf.EXPECT().PutIgmpChannel(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
+ mvp.updateDynamicGroups(tt.args.cntx, tt.args.deviceID, tt.args.added, tt.args.removed)
+ })
+ }
+}
+
+func TestMvlanProfile_checkStaticGrpSSMProxyDiff(t *testing.T) {
+ type args struct {
+ oldProxy *MCGroupProxy
+ newProxy *MCGroupProxy
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ }{
+ {
+ name: "updateDynamicGroups",
+ args: args{
+ oldProxy: &MCGroupProxy{
+ Mode: common.Exclude,
+ SourceList: []net.IP{
+ AllSystemsMulticastGroupIP,
+ },
+ },
+ newProxy: &MCGroupProxy{
+ Mode: common.Exclude,
+ SourceList: []net.IP{
+ AllSystemsMulticastGroupIP,
+ },
+ },
+ },
+ },
+ {
+ name: "updateDynamicGroups_true",
+ args: args{
+ newProxy: &MCGroupProxy{},
+ },
+ want: true,
+ },
+ {
+ name: "updateDynamicGroups_nil",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{}
+ if got := mvp.checkStaticGrpSSMProxyDiff(tt.args.oldProxy, tt.args.newProxy); got != tt.want {
+ t.Errorf("MvlanProfile.checkStaticGrpSSMProxyDiff() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestMvlanProfile_UpdateActiveChannelSubscriberAlarm(t *testing.T) {
+ devicesList := make(map[string]OperInProgress)
+ devicesList["SDX6320031"] = opt82
+ voltDev := &VoltDevice{
+ Name: "SDX6320031",
+ SerialNum: "SDX6320031",
+ FlowDelEventMap: util.NewConcurrentMap(),
+ Ports: sync.Map{},
+ }
+ va := GetApplication()
+ va.DevicesDisc.Store("SDX6320031", voltDev)
+ voltPort := &VoltPort{
+ Name: "16777472",
+ Device: "SDX6320031",
+ ID: 16777472,
+ State: PortStateUp,
+ ChannelPerSubAlarmRaised: true,
+ Type: VoltPortTypeAccess,
+ ActiveChannels: uint32(2),
+ }
+ voltDev.Ports.Store("16777472", voltPort)
+ tests := []struct {
+ name string
+ }{
+ {
+ name: "UpdateActiveChannelSubscriberAlarm",
+ },
+ {
+ name: "UpdateActiveChannelSubscriberAlarm_else",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ mvp := &MvlanProfile{
+ DevicesList: devicesList,
+ MaxActiveChannels: uint32(5),
+ }
+ switch tt.name {
+ case "UpdateActiveChannelSubscriberAlarm":
+ mvp.UpdateActiveChannelSubscriberAlarm()
+ case "UpdateActiveChannelSubscriberAlarm_else":
+ voltPort.ActiveChannels = uint32(6)
+ voltPort.ChannelPerSubAlarmRaised = false
+ mvp.UpdateActiveChannelSubscriberAlarm()
+ }
+ })
+ }
+}