blob: 8942dbb615bd0fa2d83a018fa99cdcc2c50460a5 [file] [log] [blame]
/*
* 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"
"reflect"
"testing"
cntlr "voltha-go-controller/internal/pkg/controller"
"voltha-go-controller/internal/pkg/of"
"voltha-go-controller/internal/pkg/util"
"voltha-go-controller/internal/test/mocks"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)
func TestVoltPortVnet_JSONMarshal(t *testing.T) {
tests := []struct {
name string
want []byte
wantErr bool
}{
{
name: "VoltPortVnet_JSONMarshal",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vpv := &VoltPortVnet{}
_, err := vpv.JSONMarshal()
if (err != nil) != tt.wantErr {
t.Errorf("VoltPortVnet.JSONMarshal() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
func TestVoltPortVnet_IsServiceActivated(t *testing.T) {
type args struct {
cntx context.Context
}
tests := []struct {
name string
args args
want bool
}{
{
name: "VoltPortVnet_IsServiceActivated",
args: args{
cntx: context.Background(),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vpv := &VoltPortVnet{}
voltServ := &VoltService{
VoltServiceOper: VoltServiceOper{
Device: test_device,
ForceDelete: true,
},
}
vpv.services.Store(test_device, voltServ)
if got := vpv.IsServiceActivated(tt.args.cntx); got != tt.want {
t.Errorf("VoltPortVnet.IsServiceActivated() = %v, want %v", got, tt.want)
}
})
}
}
func TestVoltVnet_JSONMarshal(t *testing.T) {
tests := []struct {
name string
want []byte
wantErr bool
}{
{
name: "VoltVnet_JSONMarshal",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vv := &VoltVnet{}
_, err := vv.JSONMarshal()
if (err != nil) != tt.wantErr {
t.Errorf("VoltVnet.JSONMarshal() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}
func TestVoltVnet_TriggerAssociatedFlowDelete(t *testing.T) {
type args struct {
cntx context.Context
device string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "VoltVnet_TriggerAssociatedFlowDelete",
args: args{
cntx: context.Background(),
device: test_device,
},
want: true,
},
{
name: "cookieList_empty",
args: args{
cntx: context.Background(),
device: test_device,
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vv := &VoltVnet{}
switch tt.name {
case "VoltVnet_TriggerAssociatedFlowDelete":
cookie := map[string]bool{}
cookie["1234"] = true
pendingDeleteFlow := map[string]map[string]bool{}
pendingDeleteFlow[test_device] = cookie
vv.PendingDeleteFlow = pendingDeleteFlow
dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
db = dbintf
dbintf.EXPECT().PutVnet(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
if got := vv.TriggerAssociatedFlowDelete(tt.args.cntx, tt.args.device); got != tt.want {
t.Errorf("VoltVnet.TriggerAssociatedFlowDelete() = %v, want %v", got, tt.want)
}
case "cookieList_empty":
if got := vv.TriggerAssociatedFlowDelete(tt.args.cntx, tt.args.device); got != tt.want {
t.Errorf("VoltVnet.TriggerAssociatedFlowDelete() = %v, want %v", got, tt.want)
}
}
})
}
}
func TestVoltApplication_GetMatchingMcastService(t *testing.T) {
type args struct {
port string
device string
cvlan of.VlanType
}
tests := []struct {
name string
args args
want *VoltService
}{
{
name: "VoltApplication_GetMatchingMcastService",
args: args{
port: "test_port",
device: test_device,
cvlan: of.VlanAny,
},
},
{
name: "dIntf_error",
args: args{
port: "test_port",
device: test_device,
cvlan: of.VlanAny,
},
},
{
name: "port == d.NniPort",
args: args{
port: "test_port",
device: test_device,
cvlan: of.VlanAny,
},
},
{
name: "vnets_error",
args: args{
port: "",
device: test_device,
cvlan: of.VlanAny,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
va := &VoltApplication{}
switch tt.name {
case "VoltApplication_GetMatchingMcastService":
va.DevicesDisc.Store(test_device, voltDevice)
va.VnetsByPort.Store("test_port", voltPortVnet1)
if got := va.GetMatchingMcastService(tt.args.port, tt.args.device, tt.args.cvlan); !reflect.DeepEqual(got, tt.want) {
t.Errorf("VoltApplication.GetMatchingMcastService() = %v, want %v", got, tt.want)
}
case "dIntf_error":
if got := va.GetMatchingMcastService(tt.args.port, tt.args.device, tt.args.cvlan); !reflect.DeepEqual(got, tt.want) {
t.Errorf("VoltApplication.GetMatchingMcastService() = %v, want %v", got, tt.want)
}
case "port == d.NniPort":
va.DevicesDisc.Store(test_device, voltDevice)
voltDevice.NniPort = "test_port"
if got := va.GetMatchingMcastService(tt.args.port, tt.args.device, tt.args.cvlan); !reflect.DeepEqual(got, tt.want) {
t.Errorf("VoltApplication.GetMatchingMcastService() = %v, want %v", got, tt.want)
}
case "vnets_error":
va.DevicesDisc.Store(test_device, voltDevice)
va.VnetsByPort.Store("test_port1", voltPortVnet1)
if got := va.GetMatchingMcastService(tt.args.port, tt.args.device, tt.args.cvlan); !reflect.DeepEqual(got, tt.want) {
t.Errorf("VoltApplication.GetMatchingMcastService() = %v, want %v", got, tt.want)
}
}
})
}
}
func TestVoltPortVnet_IgmpFlowInstallFailure(t *testing.T) {
type args struct {
cookie string
errorCode uint32
errReason string
}
tests := []struct {
name string
args args
}{
{
name: "VoltPortVnet_IgmpFlowInstallFailure",
args: args{
cookie: "test_cookie",
errorCode: uint32(1),
errReason: "errReason",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vpv := &VoltPortVnet{}
switch tt.name {
case "VoltPortVnet_IgmpFlowInstallFailure":
voltService.IgmpEnabled = true
vpv.services.Store("test_cookie", voltService)
vpv.IgmpFlowInstallFailure(tt.args.cookie, tt.args.errorCode, tt.args.errReason)
}
})
}
}
func TestVoltVnet_FlowRemoveFailure(t *testing.T) {
type args struct {
cntx context.Context
cookie string
device string
errorCode uint32
errReason string
}
tests := []struct {
name string
args args
}{
{
name: "VoltVnet_FlowRemoveFailure",
args: args{
cntx: context.Background(),
cookie: "1234",
device: test_device,
},
},
{
name: "mismatch_cookie",
args: args{
cntx: context.Background(),
cookie: "1234",
device: test_device,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vv := &VoltVnet{}
switch tt.name {
case "VoltVnet_FlowRemoveFailure":
cookie := map[string]bool{}
cookie["1234"] = true
pendingDeleteFlow := map[string]map[string]bool{}
pendingDeleteFlow[test_device] = cookie
vv.PendingDeleteFlow = pendingDeleteFlow
vv.DeleteInProgress = true
vv.Name = "test_name"
dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
db = dbintf
dbintf.EXPECT().DelVnet(tt.args.cntx, "test_name").Return(nil).Times(1)
vv.FlowRemoveFailure(tt.args.cntx, tt.args.cookie, tt.args.device, tt.args.errorCode, tt.args.errReason)
case "mismatch_cookie":
cookie := map[string]bool{}
cookie["12345"] = true
pendingDeleteFlow := map[string]map[string]bool{}
pendingDeleteFlow[test_device] = cookie
vv.PendingDeleteFlow = pendingDeleteFlow
vv.DeleteInProgress = true
vv.Name = "test_name"
dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
db = dbintf
dbintf.EXPECT().DelVnet(tt.args.cntx, "test_name").Return(nil).Times(1)
vv.FlowRemoveFailure(tt.args.cntx, tt.args.cookie, tt.args.device, tt.args.errorCode, tt.args.errReason)
}
})
}
}
func TestVoltVnet_FlowRemoveSuccess(t *testing.T) {
type args struct {
cntx context.Context
cookie string
device string
}
tests := []struct {
name string
args args
}{
{
name: "VoltVnet_FlowRemoveSuccess",
args: args{
cntx: context.Background(),
cookie: "1234",
device: test_device,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vv := &VoltVnet{}
cookie := map[string]bool{}
cookie["1234"] = true
pendingDeleteFlow := map[string]map[string]bool{}
pendingDeleteFlow[test_device] = cookie
vv.PendingDeleteFlow = pendingDeleteFlow
ga := GetApplication()
voltDevice.ConfiguredVlanForDeviceFlows = util.NewConcurrentMap()
ga.DevicesDisc.Store(test_device, voltDevice)
dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
db = dbintf
dbintf.EXPECT().PutVnet(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
vv.FlowRemoveSuccess(tt.args.cntx, tt.args.cookie, tt.args.device)
})
}
}
func TestVoltPortVnet_FlowRemoveFailure(t *testing.T) {
type args struct {
cntx context.Context
cookie string
device string
errorCode uint32
errReason string
}
tests := []struct {
name string
args args
}{
{
name: "VoltPortVnet_FlowRemoveFailure",
args: args{
cntx: context.Background(),
cookie: "1234",
device: test_device,
},
},
{
name: "DeleteInProgress_false",
args: args{
cntx: context.Background(),
cookie: "1234",
device: test_device,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vpv := &VoltPortVnet{}
switch tt.name {
case "VoltPortVnet_FlowRemoveFailure":
vpv.services.Store("1234", voltService)
vpv.DeleteInProgress = true
dbintf := mocks.NewMockDBIntf(gomock.NewController(t))
db = dbintf
dbintf.EXPECT().DelVpv(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1)
vpv.FlowRemoveFailure(tt.args.cntx, tt.args.cookie, tt.args.device, tt.args.errorCode, tt.args.errReason)
case "DeleteInProgress_false":
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).Times(1)
vpv.FlowRemoveFailure(tt.args.cntx, tt.args.cookie, tt.args.device, tt.args.errorCode, tt.args.errReason)
}
})
}
}
func TestVoltPortVnet_PushFlows(t *testing.T) {
type args struct {
cntx context.Context
device *VoltDevice
flow *of.VoltFlow
}
vsf := make(map[uint64]*of.VoltSubFlow)
vsf[uint64(1)] = &of.VoltSubFlow{
Cookie: uint64(1234),
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "VoltPortVnet_PushFlows",
args: args{
cntx: context.Background(),
device: voltDevice,
flow: &of.VoltFlow{
PortName: "test_port",
SubFlows: vsf,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vpv := &VoltPortVnet{}
_ = cntlr.NewController(context.Background(), mocks.NewMockApp(gomock.NewController(t)))
err := vpv.PushFlows(tt.args.cntx, tt.args.device, tt.args.flow)
assert.NotNil(t, err)
})
}
}
func TestVoltPortVnet_isVlanMatching(t *testing.T) {
type args struct {
cvlan of.VlanType
svlan of.VlanType
}
tests := []struct {
name string
args args
want bool
}{
{
name: "VoltPortVnet_isVlanMatching",
args: args{
cvlan: of.VlanAny,
svlan: of.VlanAny,
},
want: true,
},
{
name: "vpv.VlanControl_nil",
args: args{
cvlan: of.VlanAny,
svlan: of.VlanAny,
},
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vpv := &VoltPortVnet{}
switch tt.name {
case "VoltPortVnet_isVlanMatching":
vpv.VlanControl = ONUCVlanOLTSVlan
vpv.SVlan = of.VlanAny
vpv.CVlan = of.VlanAny
if got := vpv.isVlanMatching(tt.args.cvlan, tt.args.svlan); got != tt.want {
t.Errorf("VoltPortVnet.isVlanMatching() = %v, want %v", got, tt.want)
}
}
})
}
}
func TestProcessIcmpv6McGroup(t *testing.T) {
type args struct {
device string
delete bool
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "TestProcessIcmpv6McGroup",
args: args{
device: test_device,
delete: false,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ProcessIcmpv6McGroup(tt.args.device, tt.args.delete)
assert.NotNil(t, err)
})
}
}
func TestVoltVnet_setPbitRemarking(t *testing.T) {
tests := []struct {
name string
want uint32
}{
{
name: "VoltVnet_setPbitRemarking",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
vv := &VoltVnet{}
a := make(map[of.PbitType]of.PbitType)
a[of.PbitMatchAll] = of.PbitMatchAll
vv.CtrlPktPbitRemark = a
if got := vv.setPbitRemarking(); got != tt.want {
t.Errorf("VoltVnet.setPbitRemarking() = %v, want %v", got, tt.want)
}
})
}
}
func TestBuildDSArpFlow(t *testing.T) {
type args struct {
inport uint32
vnet *VoltVnet
}
tests := []struct {
name string
args args
want *of.VoltFlow
}{
{
name: "BuildDSArpFlow",
args: args{
inport: uint32(1),
vnet: &VoltVnet{
Version: "test_version",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
switch tt.name {
case "BuildDSArpFlow":
got := BuildDSArpFlow(tt.args.inport, tt.args.vnet)
assert.NotNil(t, got)
}
})
}
}
func TestBuildICMPv6Flow(t *testing.T) {
type args struct {
inport uint32
vnet *VoltVnet
}
tests := []struct {
name string
args args
want *of.VoltFlow
}{
{
name: "BuildICMPv6Flow",
args: args{
inport: uint32(1),
vnet: &VoltVnet{
Version: "test_version",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := BuildICMPv6Flow(tt.args.inport, tt.args.vnet)
assert.NotNil(t, got)
})
}
}
func TestVoltApplication_DeleteDevFlowForVlanFromDevice(t *testing.T) {
type args struct {
cntx context.Context
vnet *VoltVnet
deviceSerialNum string
}
tests := []struct {
name string
args args
}{
{
name: "device.SerialNum != deviceSerialNum",
args: args{
cntx: context.Background(),
vnet: &VoltVnet{
Version: "test_version",
},
},
},
{
name: "VoltApplication_DeleteDevFlowForVlanFromDevice",
args: args{
cntx: context.Background(),
vnet: &VoltVnet{
Version: "test_version",
},
deviceSerialNum: "test_serial_number",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
va := &VoltApplication{}
switch tt.name {
case "device.SerialNum != deviceSerialNum":
va.DevicesDisc.Store(test_device, voltDevice)
va.DeleteDevFlowForVlanFromDevice(tt.args.cntx, tt.args.vnet, tt.args.deviceSerialNum)
case "VoltApplication_DeleteDevFlowForVlanFromDevice":
va.DevicesDisc.Store(test_device, voltDevice)
va.DeleteDevFlowForVlanFromDevice(tt.args.cntx, tt.args.vnet, tt.args.deviceSerialNum)
}
})
}
}