Skip to content

Commit

Permalink
Add unit tests for pkg/ovs/openflow
Browse files Browse the repository at this point in the history
Signed-off-by: Hongliang Liu <lhongliang@vmware.com>
  • Loading branch information
hongliangl committed Jul 10, 2023
1 parent fbfa97d commit e1c95fb
Show file tree
Hide file tree
Showing 8 changed files with 4,684 additions and 24 deletions.
2,133 changes: 2,133 additions & 0 deletions pkg/ovs/openflow/ofctrl_action_test.go

Large diffs are not rendered by default.

1,935 changes: 1,914 additions & 21 deletions pkg/ovs/openflow/ofctrl_builder_test.go

Large diffs are not rendered by default.

163 changes: 163 additions & 0 deletions pkg/ovs/openflow/ofctrl_group_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
// Copyright 2023 Antrea Authors
//
// 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 openflow

import (
"net"
"testing"

"antrea.io/libOpenflow/openflow15"
"antrea.io/libOpenflow/util"
"antrea.io/ofnet/ofctrl"
"github.com/stretchr/testify/assert"
)

func getGroupMod(t *testing.T, g Group) *openflow15.GroupMod {
msgs, err := g.GetBundleMessages(AddMessage)
assert.NoError(t, err)
assert.Equal(t, 1, len(msgs))
return msgs[0].GetMessage().(*openflow15.GroupMod)
}

func TestBucketBuilder(t *testing.T) {
t.Run("Weight", func(t *testing.T) {
weight := uint16(100)
g := &ofGroup{ofctrl: &ofctrl.Group{}}
group := g.Bucket().Weight(weight).Done()
groupMod := getGroupMod(t, group)
assert.Equal(t, 1, len(groupMod.Buckets))
assert.Equal(t, 1, len(groupMod.Buckets[0].Properties))
assert.Equal(t, weight, groupMod.Buckets[0].Properties[0].(*openflow15.GroupBucketPropWeight).Weight)
assert.Contains(t, GroupModToString(groupMod), "weight:100")
})
t.Run("LoadToRegField", func(t *testing.T) {
testCases := []struct {
regField *RegField
value uint32
expected *openflow15.ActionSetField
expectedActionStr string
}{
{
regField: NewRegField(1, 0, 31),
value: uint32(0xffff_ffff),
expected: &openflow15.ActionSetField{
Field: openflow15.MatchField{
Class: openflow15.OXM_CLASS_NXM_1,
Field: openflow15.NXM_NX_REG1,
Value: &openflow15.Uint32Message{Data: uint32(0xffff_ffff)},
Mask: &openflow15.Uint32Message{Data: uint32(0xffff_ffff)},
},
},
expectedActionStr: "set_field:0xffffffff->reg1",
},
{
regField: NewRegField(1, 4, 15),
value: uint32(0xf),
expected: &openflow15.ActionSetField{
Field: openflow15.MatchField{
Class: openflow15.OXM_CLASS_NXM_1,
Field: openflow15.NXM_NX_REG1,
Value: &openflow15.Uint32Message{Data: uint32(0xf0)},
Mask: &openflow15.Uint32Message{Data: uint32(0xfff0)},
},
},
expectedActionStr: "set_field:0xf0/0xfff0->reg1",
},
}
for _, tc := range testCases {
g := &ofGroup{ofctrl: &ofctrl.Group{}}
group := g.Bucket().LoadToRegField(tc.regField, tc.value).Done()
groupMod := getGroupMod(t, group)
assert.Equal(t, 1, len(groupMod.Buckets))
checkActionSetFields(t, []*openflow15.ActionSetField{tc.expected}, groupMod.Buckets[0].Actions)
assert.Contains(t, GroupModToString(groupMod), tc.expectedActionStr)
}
})
t.Run("LoadXXReg", func(t *testing.T) {
regID := 0
data := []byte{0x11, 0x22, 0x33, 0x44}
expected := &openflow15.ActionSetField{
Field: openflow15.MatchField{
Class: openflow15.OXM_CLASS_NXM_1,
Field: openflow15.NXM_NX_XXREG0,
Value: util.NewBuffer(data),
},
}
expectedActionStr := "set_field:0x11223344->xxreg0"

g := &ofGroup{ofctrl: &ofctrl.Group{}}
group := g.Bucket().LoadXXReg(regID, data).Done()
groupMod := getGroupMod(t, group)
assert.Equal(t, 1, len(groupMod.Buckets))
checkActionSetFields(t, []*openflow15.ActionSetField{expected}, groupMod.Buckets[0].Actions)
assert.Contains(t, GroupModToString(groupMod), expectedActionStr)
})
t.Run("SetTunnelDst", func(t *testing.T) {
testCases := []struct {
dstIP net.IP
expected *openflow15.ActionSetField
expectedActionStr string
}{
{
dstIP: net.ParseIP("1.1.1.1"),
expected: &openflow15.ActionSetField{
Field: openflow15.MatchField{
Class: openflow15.OXM_CLASS_NXM_1,
Field: openflow15.NXM_NX_TUN_IPV4_DST,
Value: &openflow15.TunnelIpv4DstField{
TunnelIpv4Dst: net.ParseIP("1.1.1.1"),
},
},
},
expectedActionStr: "set_field:1.1.1.1->tun_dst",
},
{
dstIP: net.ParseIP("fec0::1111"),
expected: &openflow15.ActionSetField{
Field: openflow15.MatchField{
Class: openflow15.OXM_CLASS_NXM_1,
Field: openflow15.NXM_NX_TUN_IPV6_DST,
Value: &openflow15.Ipv6DstField{
Ipv6Dst: net.ParseIP("fec0::1111"),
},
},
},
expectedActionStr: "set_field:fec0::1111->tun_ipv6_dst",
},
}
for _, tc := range testCases {
g := &ofGroup{ofctrl: &ofctrl.Group{}}
group := g.Bucket().SetTunnelDst(tc.dstIP).Done()
groupMod := getGroupMod(t, group)
assert.Equal(t, 1, len(groupMod.Buckets))
checkActionSetFields(t, []*openflow15.ActionSetField{tc.expected}, groupMod.Buckets[0].Actions)
assert.Contains(t, GroupModToString(groupMod), tc.expectedActionStr)
}
})
t.Run("ResubmitToTable", func(t *testing.T) {
tableID := uint8(100)
g := &ofGroup{ofctrl: &ofctrl.Group{}}
group := g.Bucket().ResubmitToTable(tableID).Done()
groupMod := getGroupMod(t, group)
assert.Equal(t, 1, len(groupMod.Buckets))
assert.Equal(t, 1, len(groupMod.Buckets[0].Actions))
assert.IsType(t, &openflow15.NXActionResubmitTable{}, groupMod.Buckets[0].Actions[0])

action := groupMod.Buckets[0].Actions[0].(*openflow15.NXActionResubmitTable)
assert.Equal(t, uint16(openflow15.OFPP_IN_PORT), action.InPort)
assert.Equal(t, tableID, action.TableID)
assert.Contains(t, GroupModToString(groupMod), "resubmit:100")
})
}
113 changes: 113 additions & 0 deletions pkg/ovs/openflow/ofctrl_meter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2023 Antrea Authors
//
// 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 openflow

import (
"testing"

"antrea.io/libOpenflow/openflow15"
"antrea.io/libOpenflow/util"
"antrea.io/ofnet/ofctrl"
"github.com/stretchr/testify/assert"
)

func getMeterMod(t *testing.T, m Meter) *openflow15.MeterMod {
msgs, err := m.GetBundleMessages(AddMessage)
assert.NoError(t, err)
assert.Equal(t, 1, len(msgs))
return msgs[0].GetMessage().(*openflow15.MeterMod)
}

func TestMeterBandBuilder(t *testing.T) {
m := &ofMeter{ofctrl: &ofctrl.Meter{}}

t.Run("MeterType", func(t *testing.T) {
testCases := []struct {
meterType ofctrl.MeterType
expectedBandType util.Message
}{
{ofctrl.MeterDrop, &openflow15.MeterBandDrop{}},
{ofctrl.MeterDSCPRemark, &openflow15.MeterBandDSCP{}},
{ofctrl.MeterExperimenter, &openflow15.MeterBandExperimenter{}},
}
for _, tc := range testCases {
m.ResetMeterBands()
meter := m.MeterBand().MeterType(tc.meterType).Done()
meterMod := getMeterMod(t, meter)
assert.Equal(t, 1, len(meterMod.MeterBands))
assert.IsType(t, tc.expectedBandType, meterMod.MeterBands[0])
}
})
t.Run("Rate", func(t *testing.T) {
testCases := []struct {
rate uint32
}{
{100},
{200},
}
for _, tc := range testCases {
m.ResetMeterBands()
meter := m.MeterBand().MeterType(ofctrl.MeterDSCPRemark).Rate(tc.rate).Done()
meterMod := getMeterMod(t, meter)
assert.Equal(t, 1, len(meterMod.MeterBands))
assert.Equal(t, tc.rate, meterMod.MeterBands[0].(*openflow15.MeterBandDSCP).MeterBandHeader.Rate)
}
})
t.Run("Burst", func(t *testing.T) {
testCases := []struct {
burst uint32
}{
{100},
{200},
}
for _, tc := range testCases {
m.ResetMeterBands()
meter := m.MeterBand().MeterType(ofctrl.MeterDSCPRemark).Burst(tc.burst).Done()
meterMod := getMeterMod(t, meter)
assert.Equal(t, 1, len(meterMod.MeterBands))
assert.Equal(t, tc.burst, meterMod.MeterBands[0].(*openflow15.MeterBandDSCP).MeterBandHeader.BurstSize)
}
})
t.Run("PrecLevel", func(t *testing.T) {
testCases := []struct {
precLevel uint8
}{
{100},
{200},
}
for _, tc := range testCases {
m.ResetMeterBands()
meter := m.MeterBand().MeterType(ofctrl.MeterDSCPRemark).PrecLevel(tc.precLevel).Done()
meterMod := getMeterMod(t, meter)
assert.Equal(t, 1, len(meterMod.MeterBands))
assert.Equal(t, tc.precLevel, meterMod.MeterBands[0].(*openflow15.MeterBandDSCP).PrecLevel)
}
})
t.Run("Experimenter", func(t *testing.T) {
testCases := []struct {
experimenter uint32
}{
{100},
{200},
}
for _, tc := range testCases {
m.ResetMeterBands()
meter := m.MeterBand().MeterType(ofctrl.MeterExperimenter).Experimenter(tc.experimenter).Done()
meterMod := getMeterMod(t, meter)
assert.Equal(t, 1, len(meterMod.MeterBands))
assert.Equal(t, tc.experimenter, meterMod.MeterBands[0].(*openflow15.MeterBandExperimenter).Experimenter)
}
})
}
2 changes: 1 addition & 1 deletion pkg/ovs/openflow/ofctrl_packetout.go
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ func (b *ofPacketOutBuilder) SetEthPacket(packet *protocol.Ethernet) PacketOutBu
return b
}

// AddSetIPToSAction sets the IP_TOS field in the packet-out message. The action clears the two ECN bits as 0,
// AddSetIPTOSAction sets the IP_TOS field in the packet-out message. The action clears the two ECN bits as 0,
// and only 2-7 bits of the DSCP field in IP header is set.
func (b *ofPacketOutBuilder) AddSetIPTOSAction(data uint8) PacketOutBuilder {
field, _ := openflow15.FindFieldHeaderByName(NxmFieldIPToS, true)
Expand Down
Loading

0 comments on commit e1c95fb

Please sign in to comment.