Skip to content

Commit

Permalink
Fix unit test TestReconcile (#5798)
Browse files Browse the repository at this point in the history
cniServer.reconcile() now installs flows asynchorously.

Signed-off-by: Quan Tian <qtian@vmware.com>
  • Loading branch information
tnqn committed Jan 10, 2024
1 parent d014453 commit 301153b
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 208 deletions.
2 changes: 1 addition & 1 deletion pkg/agent/cniserver/interface_configuration_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func (ns *fakeNS) clear() {
}

func createNS(t *testing.T, waitForComplete bool) *fakeNS {
nsPath := generateUUID(t)
nsPath := generateUUID()
fakeNs := &fakeNS{path: nsPath, fd: uintptr(unsafe.Pointer(&nsPath)), waitCompleted: waitForComplete, stopCh: make(chan struct{})}
validNSs.Store(nsPath, fakeNs)
return fakeNs
Expand Down
20 changes: 10 additions & 10 deletions pkg/agent/cniserver/pod_configuration_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func TestConnectInterceptedInterface(t *testing.T) {
testPodName := "test-pod"
podNamespace := testPodNamespace
hostInterfaceName := util.GenerateContainerInterfaceName(testPodName, testPodNamespace, testPodInfraContainerID)
containerID := generateUUID(t)
containerID := generateUUID()
containerNetNS := "container-ns"
containerDev := "eth0"

Expand Down Expand Up @@ -210,7 +210,7 @@ func TestConnectInterceptedInterface(t *testing.T) {
if tc.migratedRoute {
mockRoute.EXPECT().MigrateRoutesToGw(hostInterfaceName).Return(tc.migrateRouteErr)
}
ovsPortID := generateUUID(t)
ovsPortID := generateUUID()
if tc.connectedOVS {
mockOVSBridgeClient.EXPECT().CreatePort(hostInterfaceName, gomock.Any(), gomock.Any()).Return(ovsPortID, tc.createOVSPortErr).Times(1)
if tc.createOVSPortErr == nil {
Expand Down Expand Up @@ -239,7 +239,7 @@ func TestConnectInterceptedInterface(t *testing.T) {

func TestCreateOVSPort(t *testing.T) {
controller := gomock.NewController(t)
containerID := generateUUID(t)
containerID := generateUUID()
podName := "p0"
podNameSpace := testPodNamespace

Expand Down Expand Up @@ -271,10 +271,10 @@ func TestCreateOVSPort(t *testing.T) {
containerConfig := buildContainerConfig(tc.portName, containerID, podName, podNameSpace, &current.Interface{Mac: "01:02:03:04:05:06"}, ipamResult.IPs, tc.vlanID)
attachInfo := BuildOVSPortExternalIDs(containerConfig)
if tc.createOVSPort {
mockOVSBridgeClient.EXPECT().CreatePort(tc.portName, tc.portName, attachInfo).Times(1).Return(generateUUID(t), nil)
mockOVSBridgeClient.EXPECT().CreatePort(tc.portName, tc.portName, attachInfo).Times(1).Return(generateUUID(), nil)
}
if tc.createOVSAccessPort {
mockOVSBridgeClient.EXPECT().CreateAccessPort(tc.portName, tc.portName, attachInfo, tc.vlanID).Times(1).Return(generateUUID(t), nil)
mockOVSBridgeClient.EXPECT().CreateAccessPort(tc.portName, tc.portName, attachInfo, tc.vlanID).Times(1).Return(generateUUID(), nil)
}
_, err := podConfigurator.createOVSPort(tc.portName, attachInfo, tc.vlanID)
assert.NoError(t, err)
Expand All @@ -283,8 +283,8 @@ func TestCreateOVSPort(t *testing.T) {
}

func TestParseOVSPortInterfaceConfig(t *testing.T) {
containerID := generateUUID(t)
portUUID := generateUUID(t)
containerID := generateUUID()
portUUID := generateUUID()
ofPort := int32(1)
containerIPs := "1.1.1.2,aabb:1122::101:102"
parsedIPs := []net.IP{net.ParseIP("1.1.1.2"), net.ParseIP("aabb:1122::101:102")}
Expand Down Expand Up @@ -398,14 +398,14 @@ func TestParseOVSPortInterfaceConfig(t *testing.T) {
func TestCheckHostInterface(t *testing.T) {
controller := gomock.NewController(t)
hostIfaceName := "port1"
containerID := generateUUID(t)
containerID := generateUUID()
containerIntf := &current.Interface{Name: ifname, Sandbox: netns, Mac: "01:02:03:04:05:06"}
interfaces := []*current.Interface{containerIntf, {Name: hostIfaceName}}
containeIPs := ipamResult.IPs
ifaceMAC, _ := net.ParseMAC("01:02:03:04:05:06")
containerInterface := interfacestore.NewContainerInterface(hostIfaceName, containerID, "pod1", testPodNamespace, ifaceMAC, []net.IP{containerIP}, 1)
containerInterface.OVSPortConfig = &interfacestore.OVSPortConfig{
PortUUID: generateUUID(t),
PortUUID: generateUUID(),
OFPort: int32(10),
}

Expand Down Expand Up @@ -454,7 +454,7 @@ func TestCheckHostInterface(t *testing.T) {

func TestConfigureSriovSecondaryInterface(t *testing.T) {
controller := gomock.NewController(t)
containerID := generateUUID(t)
containerID := generateUUID()
containerNS := "containerNS"

for _, tc := range []struct {
Expand Down
105 changes: 19 additions & 86 deletions pkg/agent/cniserver/server_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,14 @@ import (
"fmt"
"net"
"testing"
"time"

cnitypes "github.com/containernetworking/cni/pkg/types"
current "github.com/containernetworking/cni/pkg/types/100"
"github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
fakeclientset "k8s.io/client-go/kubernetes/fake"

"antrea.io/antrea/pkg/agent/cniserver/ipam"
Expand Down Expand Up @@ -348,7 +346,7 @@ func TestCmdAdd(t *testing.T) {
if tc.addLocalIPAMRoute {
mockRoute.EXPECT().AddLocalAntreaFlexibleIPAMPodRule(gomock.Any()).Return(tc.addLocalIPAMRouteError).Times(1)
}
ovsPortID := generateUUID(t)
ovsPortID := generateUUID()
if tc.connectOVS {
mockOVSBridgeClient.EXPECT().CreatePort(hostInterfaceName, gomock.Any(), gomock.Any()).Return(ovsPortID, nil).Times(1)
mockOVSBridgeClient.EXPECT().GetOFPort(hostInterfaceName, false).Return(int32(100), nil).Times(1)
Expand Down Expand Up @@ -394,7 +392,7 @@ func TestCmdAdd(t *testing.T) {
func TestCmdDel(t *testing.T) {
controller := gomock.NewController(t)
ipamMock := ipamtest.NewMockIPAMDriver(controller)
ovsPortID := generateUUID(t)
ovsPortID := generateUUID()
ovsPort := int32(100)
ctx := context.TODO()

Expand Down Expand Up @@ -543,7 +541,7 @@ func TestCmdDel(t *testing.T) {
func TestCmdCheck(t *testing.T) {
controller := gomock.NewController(t)
ipamMock := ipamtest.NewMockIPAMDriver(controller)
ovsPortID := generateUUID(t)
ovsPortID := generateUUID()
ovsPort := int32(100)
ctx := context.TODO()

Expand Down Expand Up @@ -635,98 +633,33 @@ func TestReconcile(t *testing.T) {
mockOFClient = openflowtest.NewMockClient(controller)
ifaceStore = interfacestore.NewInterfaceStore()
mockRoute = routetest.NewMockInterface(controller)
nodeName := "node1"
cniServer := newCNIServer(t)
cniServer.routeClient = mockRoute
gwMAC, _ := net.ParseMAC("00:00:11:11:11:11")
cniServer.podConfigurator, _ = newPodConfigurator(mockOVSBridgeClient, mockOFClient, mockRoute, ifaceStore, gwMAC, "system", false, channel.NewSubscribableChannel("PodUpdate", 100), nil, false)
cniServer.podConfigurator.ifConfigurator = newTestInterfaceConfigurator()
cniServer.nodeConfig = &config.NodeConfig{
Name: nodeName,
}
pods := []runtime.Object{
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "p1",
Namespace: testPodNamespace,
},
Spec: v1.PodSpec{
NodeName: nodeName,
},
},
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "p2",
Namespace: testPodNamespace,
},
Spec: v1.PodSpec{
NodeName: nodeName,
HostNetwork: true,
},
},
&v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "p4",
Namespace: testPodNamespace,
},
Spec: v1.PodSpec{
NodeName: nodeName,
},
},
}
containerIfaces := map[string]*interfacestore.InterfaceConfig{
"iface1": {
InterfaceName: "iface1",
Type: interfacestore.ContainerInterface,
OVSPortConfig: &interfacestore.OVSPortConfig{
PortUUID: generateUUID(t),
OFPort: int32(3),
},
ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{
PodName: "p1",
PodNamespace: testPodNamespace,
ContainerID: generateUUID(t),
},
},
"iface3": {
InterfaceName: "iface3",
Type: interfacestore.ContainerInterface,
OVSPortConfig: &interfacestore.OVSPortConfig{
PortUUID: generateUUID(t),
OFPort: int32(4),
},
ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{
PodName: "p3",
PodNamespace: testPodNamespace,
ContainerID: generateUUID(t),
},
},
"iface4": {
InterfaceName: "iface4",
Type: interfacestore.ContainerInterface,
OVSPortConfig: &interfacestore.OVSPortConfig{
PortUUID: generateUUID(t),
OFPort: int32(-1),
},
ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{
PodName: "p4",
PodNamespace: testPodNamespace,
ContainerID: generateUUID(t),
},
},
}
kubeClient := fakeclientset.NewSimpleClientset(pods...)
kubeClient := fakeclientset.NewSimpleClientset(pod1, pod2, pod3)
cniServer.kubeClient = kubeClient
for _, containerIface := range containerIfaces {
for _, containerIface := range []*interfacestore.InterfaceConfig{normalInterface, staleInterface, unconnectedInterface} {
ifaceStore.AddInterface(containerIface)
}
mockOFClient.EXPECT().InstallPodFlows("iface1", gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Times(1)
iface := containerIfaces["iface3"]
mockOFClient.EXPECT().UninstallPodFlows("iface3").Return(nil).Times(1)
mockOVSBridgeClient.EXPECT().DeletePort(iface.PortUUID).Return(nil).Times(1)
podFlowsInstalled := make(chan struct{})
mockOFClient.EXPECT().InstallPodFlows(normalInterface.InterfaceName, normalInterface.IPs, normalInterface.MAC, uint32(normalInterface.OFPort), uint16(0), nil).
Do(func(_ string, _ []net.IP, _ net.HardwareAddr, _ uint32, _ uint16, _ *uint32) {
close(podFlowsInstalled)
}).Times(1)
mockOFClient.EXPECT().UninstallPodFlows(staleInterface.InterfaceName).Return(nil).Times(1)
mockOVSBridgeClient.EXPECT().DeletePort(staleInterface.PortUUID).Return(nil).Times(1)
mockRoute.EXPECT().DeleteLocalAntreaFlexibleIPAMPodRule(gomock.Any()).Return(nil).Times(1)
err := cniServer.reconcile()
assert.NoError(t, err)
_, exists := ifaceStore.GetInterfaceByName("iface3")
_, exists := ifaceStore.GetInterfaceByName(staleInterface.InterfaceName)
assert.False(t, exists)
select {
case <-podFlowsInstalled:
case <-time.After(500 * time.Millisecond):
t.Errorf("InstallPodFlows for %s should be called but was not", normalInterface.InterfaceName)
}
}
86 changes: 80 additions & 6 deletions pkg/agent/cniserver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"antrea.io/antrea/pkg/agent/cniserver/ipam"
ipamtest "antrea.io/antrea/pkg/agent/cniserver/ipam/testing"
Expand All @@ -43,6 +45,7 @@ import (
"antrea.io/antrea/pkg/cni"
"antrea.io/antrea/pkg/ovs/ovsconfig"
ovsconfigtest "antrea.io/antrea/pkg/ovs/ovsconfig/testing"
utilip "antrea.io/antrea/pkg/util/ip"
"antrea.io/antrea/pkg/util/wait"
)

Expand Down Expand Up @@ -76,6 +79,80 @@ var (
ifaceStore interfacestore.InterfaceStore

emptyResponse = &cnipb.CniCmdResponse{CniResult: []byte("")}

nodeName = "node1"
gwMAC = utilip.MustParseMAC("00:00:11:11:11:11")
pod1 = &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "p1",
Namespace: testPodNamespace,
},
Spec: v1.PodSpec{
NodeName: nodeName,
},
}
pod2 = &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "p2",
Namespace: testPodNamespace,
},
Spec: v1.PodSpec{
NodeName: nodeName,
HostNetwork: true,
},
}
pod3 = &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "p3",
Namespace: testPodNamespace,
},
Spec: v1.PodSpec{
NodeName: nodeName,
},
}
normalInterface = &interfacestore.InterfaceConfig{
InterfaceName: "iface1",
Type: interfacestore.ContainerInterface,
IPs: []net.IP{net.ParseIP("1.1.1.1")},
MAC: utilip.MustParseMAC("00:11:22:33:44:01"),
OVSPortConfig: &interfacestore.OVSPortConfig{
PortUUID: generateUUID(),
OFPort: int32(3),
},
ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{
PodName: pod1.Name,
PodNamespace: testPodNamespace,
ContainerID: generateUUID(),
},
}
staleInterface = &interfacestore.InterfaceConfig{
InterfaceName: "iface3",
Type: interfacestore.ContainerInterface,
OVSPortConfig: &interfacestore.OVSPortConfig{
PortUUID: generateUUID(),
OFPort: int32(4),
},
ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{
PodName: "non-existing-pod",
PodNamespace: testPodNamespace,
ContainerID: generateUUID(),
},
}
unconnectedInterface = &interfacestore.InterfaceConfig{
InterfaceName: "iface4",
Type: interfacestore.ContainerInterface,
IPs: []net.IP{net.ParseIP("1.1.1.2")},
MAC: utilip.MustParseMAC("00:11:22:33:44:02"),
OVSPortConfig: &interfacestore.OVSPortConfig{
PortUUID: generateUUID(),
OFPort: int32(-1),
},
ContainerInterfaceConfig: &interfacestore.ContainerInterfaceConfig{
PodName: pod3.Name,
PodNamespace: testPodNamespace,
ContainerID: generateUUID(),
},
}
)

func TestLoadNetConfig(t *testing.T) {
Expand Down Expand Up @@ -695,7 +772,7 @@ func generateNetworkConfiguration(name, cniVersion, cniType, ipamType string) *t
}

func newRequest(args string, netCfg *types.NetworkConfig, path string, t *testing.T) (*cnipb.CniCmdRequest, string) {
containerID := generateUUID(t)
containerID := generateUUID()
networkConfig, err := json.Marshal(netCfg)
if err != nil {
t.Error("Failed to generate Network configuration")
Expand All @@ -714,11 +791,8 @@ func newRequest(args string, netCfg *types.NetworkConfig, path string, t *testin
return cmdRequest, containerID
}

func generateUUID(t *testing.T) string {
newID, err := uuid.NewUUID()
if err != nil {
t.Fatal("Failed to generate UUID")
}
func generateUUID() string {
newID, _ := uuid.NewUUID()
return newID.String()
}

Expand Down
Loading

0 comments on commit 301153b

Please sign in to comment.