Skip to content

Commit

Permalink
modify multitenancy cni tests to reflect 1.5.x behavior
Browse files Browse the repository at this point in the history
- updates mock network manager to use the network id passed in
- updates mock network manager to get all endpoint infos based on a network id
- updates mock network manager find network id from net ns to reflect dualnic get network id behavior
(gets multiple networks because on deletion, you have one less endpoint that matches the netns/netnspath, and so use the network id of the other endpoint for deletion)
- updates windows tests to use eth1 to avoid mock endpoint client from throwing a duplicate endpoint id error
- separates windows and linux multitenancy tests because their behavior is different
- updates windows unit tests to allow passing in an expected num of endpoints for EACH network id after EACH command is run during delete test
  • Loading branch information
QxBytes committed Aug 27, 2024
1 parent 1be5084 commit d55388b
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 157 deletions.
138 changes: 138 additions & 0 deletions cni/network/network_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
package network

import (
"fmt"
"testing"

"github.com/Azure/azure-container-networking/cni"
"github.com/Azure/azure-container-networking/cns"
"github.com/Azure/azure-container-networking/network"
"github.com/Azure/azure-container-networking/telemetry"
cniSkel "github.com/containernetworking/cni/pkg/skel"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -160,3 +164,137 @@ func TestAddSnatForDns(t *testing.T) {
})
}
}

// Test Linux Multitenancy Add
func TestPluginMultitenancyLinuxAdd(t *testing.T) {
plugin, _ := cni.NewPlugin("test", "0.3.0")

localNwCfg := cni.NetworkConfig{
CNIVersion: "0.3.0",
Name: "mulnet",
MultiTenancy: true,
EnableExactMatchForPodName: true,
Master: "eth0",
}

tests := []struct {
name string
plugin *NetPlugin
args *cniSkel.CmdArgs
wantErr bool
wantErrMsg string
}{
{
name: "Add Happy path",
plugin: &NetPlugin{
Plugin: plugin,
nm: network.NewMockNetworkmanager(network.NewMockEndpointClient(nil)),
tb: &telemetry.TelemetryBuffer{},
report: &telemetry.CNIReport{},
multitenancyClient: NewMockMultitenancy(false, []*cns.GetNetworkContainerResponse{GetTestCNSResponse1()}),
},

args: &cniSkel.CmdArgs{
StdinData: localNwCfg.Serialize(),
ContainerID: "test-container",
Netns: "bc526fae-4ba0-4e80-bc90-ad721e5850bf",
Args: fmt.Sprintf("K8S_POD_NAME=%v;K8S_POD_NAMESPACE=%v", "test-pod", "test-pod-ns"),
IfName: eth0IfName,
},
wantErr: false,
},
{
name: "Add Fail",
plugin: &NetPlugin{
Plugin: plugin,
nm: network.NewMockNetworkmanager(network.NewMockEndpointClient(nil)),
tb: &telemetry.TelemetryBuffer{},
report: &telemetry.CNIReport{},
multitenancyClient: NewMockMultitenancy(true, []*cns.GetNetworkContainerResponse{GetTestCNSResponse1()}),
},
args: &cniSkel.CmdArgs{
StdinData: localNwCfg.Serialize(),
ContainerID: "test-container",
Netns: "test-container",
Args: fmt.Sprintf("K8S_POD_NAME=%v;K8S_POD_NAMESPACE=%v", "test-pod", "test-pod-ns"),
IfName: eth0IfName,
},
wantErr: true,
wantErrMsg: errMockMulAdd.Error(),
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
err := tt.plugin.Add(tt.args)
if tt.wantErr {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.wantErrMsg, "Expected %v but got %+v", tt.wantErrMsg, err.Error())
} else {
require.NoError(t, err)
endpoints, _ := tt.plugin.nm.GetAllEndpoints(localNwCfg.Name)

require.Len(t, endpoints, 1)
}
})
}
}

func TestPluginMultitenancyLinuxDelete(t *testing.T) {
plugin := GetTestResources()
plugin.multitenancyClient = NewMockMultitenancy(false, []*cns.GetNetworkContainerResponse{GetTestCNSResponse1()})
localNwCfg := cni.NetworkConfig{
CNIVersion: "0.3.0",
Name: "mulnet",
MultiTenancy: true,
EnableExactMatchForPodName: true,
Master: "eth0",
}

tests := []struct {
name string
methods []string
args *cniSkel.CmdArgs
wantErr bool
wantErrMsg string
wantNumEps []int
}{
{
name: "Multitenancy delete success",
methods: []string{CNI_ADD, CNI_DEL},
args: &cniSkel.CmdArgs{
StdinData: localNwCfg.Serialize(),
ContainerID: "test-container",
Netns: "test-container",
Args: fmt.Sprintf("K8S_POD_NAME=%v;K8S_POD_NAMESPACE=%v", "test-pod", "test-pod-ns"),
IfName: eth0IfName,
},
wantErr: false,
wantNumEps: []int{1, 0},
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
var err error
for idx, method := range tt.methods {
if method == CNI_ADD {
err = plugin.Add(tt.args)
} else if method == CNI_DEL {
err = plugin.Delete(tt.args)
}
endpoints, _ := plugin.nm.GetAllEndpoints(localNwCfg.Name)
require.Len(t, endpoints, tt.wantNumEps[idx])
}
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
endpoints, _ := plugin.nm.GetAllEndpoints(localNwCfg.Name)
require.Empty(t, endpoints)
}
})
}
}
130 changes: 0 additions & 130 deletions cni/network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -687,136 +687,6 @@ func GetTestCNSResponse2() *cns.GetNetworkContainerResponse {
}
}

// Test Multitenancy Add
func TestPluginMultitenancyAdd(t *testing.T) {
plugin, _ := cni.NewPlugin("test", "0.3.0")

localNwCfg := cni.NetworkConfig{
CNIVersion: "0.3.0",
Name: "mulnet",
MultiTenancy: true,
EnableExactMatchForPodName: true,
Master: "eth0",
}

tests := []struct {
name string
plugin *NetPlugin
args *cniSkel.CmdArgs
wantErr bool
wantErrMsg string
}{
{
name: "Add Happy path",
plugin: &NetPlugin{
Plugin: plugin,
nm: acnnetwork.NewMockNetworkmanager(acnnetwork.NewMockEndpointClient(nil)),
tb: &telemetry.TelemetryBuffer{},
report: &telemetry.CNIReport{},
multitenancyClient: NewMockMultitenancy(false, []*cns.GetNetworkContainerResponse{GetTestCNSResponse1()}),
},

args: &cniSkel.CmdArgs{
StdinData: localNwCfg.Serialize(),
ContainerID: "test-container",
Netns: "bc526fae-4ba0-4e80-bc90-ad721e5850bf",
Args: fmt.Sprintf("K8S_POD_NAME=%v;K8S_POD_NAMESPACE=%v", "test-pod", "test-pod-ns"),
IfName: eth0IfName,
},
wantErr: false,
},
{
name: "Add Fail",
plugin: &NetPlugin{
Plugin: plugin,
nm: acnnetwork.NewMockNetworkmanager(acnnetwork.NewMockEndpointClient(nil)),
tb: &telemetry.TelemetryBuffer{},
report: &telemetry.CNIReport{},
multitenancyClient: NewMockMultitenancy(true, []*cns.GetNetworkContainerResponse{GetTestCNSResponse1()}),
},
args: &cniSkel.CmdArgs{
StdinData: localNwCfg.Serialize(),
ContainerID: "test-container",
Netns: "test-container",
Args: fmt.Sprintf("K8S_POD_NAME=%v;K8S_POD_NAMESPACE=%v", "test-pod", "test-pod-ns"),
IfName: eth0IfName,
},
wantErr: true,
wantErrMsg: errMockMulAdd.Error(),
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
err := tt.plugin.Add(tt.args)
if tt.wantErr {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.wantErrMsg, "Expected %v but got %+v", tt.wantErrMsg, err.Error())
} else {
require.NoError(t, err)
endpoints, _ := tt.plugin.nm.GetAllEndpoints(localNwCfg.Name)

require.Condition(t, assert.Comparison(func() bool { return len(endpoints) == 1 }))
}
})
}
}

func TestPluginMultitenancyDelete(t *testing.T) {
plugin := GetTestResources()
plugin.multitenancyClient = NewMockMultitenancy(false, []*cns.GetNetworkContainerResponse{GetTestCNSResponse1()})
localNwCfg := cni.NetworkConfig{
CNIVersion: "0.3.0",
Name: "mulnet",
MultiTenancy: true,
EnableExactMatchForPodName: true,
Master: "eth0",
}

tests := []struct {
name string
methods []string
args *cniSkel.CmdArgs
wantErr bool
wantErrMsg string
}{
{
name: "Multitenancy delete success",
methods: []string{CNI_ADD, CNI_DEL},
args: &cniSkel.CmdArgs{
StdinData: localNwCfg.Serialize(),
ContainerID: "test-container",
Netns: "test-container",
Args: fmt.Sprintf("K8S_POD_NAME=%v;K8S_POD_NAMESPACE=%v", "test-pod", "test-pod-ns"),
IfName: eth0IfName,
},
wantErr: false,
},
}

for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
var err error
for _, method := range tt.methods {
if method == CNI_ADD {
err = plugin.Add(tt.args)
} else if method == CNI_DEL {
err = plugin.Delete(tt.args)
}
}
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
endpoints, _ := plugin.nm.GetAllEndpoints(localNwCfg.Name)
require.Condition(t, assert.Comparison(func() bool { return len(endpoints) == 0 }))
}
})
}
}

/*
Baremetal scenarios
*/
Expand Down
Loading

0 comments on commit d55388b

Please sign in to comment.