Skip to content

Commit

Permalink
Add UTs to configure secondary interfaces add Result for windows swif…
Browse files Browse the repository at this point in the history
…tv2 (#2923)

* add UTs for adding interface NICs to cni Result

* add UTs to add interface nics to cniResult

* add an unhappy path ut

* fix linter issues

* fix linter issues

* add a new UT

* fix comments

* remove configurhcnEndpoint UT

* fix linter issue

* fix comments

* fix UT

---------

Signed-off-by: Paul Yu <129891899+paulyufan2@users.noreply.github.com>
  • Loading branch information
paulyufan2 authored Aug 22, 2024
1 parent cf8fb62 commit 4c66f48
Show file tree
Hide file tree
Showing 4 changed files with 394 additions and 14 deletions.
340 changes: 340 additions & 0 deletions cni/network/invoker_cns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2151,3 +2151,343 @@ func TestShallowCopyIpamAddConfigOptions(t *testing.T) {
nullRes := nullOpts.shallowCopyIpamAddConfigOptions()
require.Equal(t, map[string]interface{}{}, nullRes)
}

// Test addBackendNICToResult() and configureSecondaryAddResult() to update secondary interfaces to cni Result
func TestAddNICsToCNIResult(t *testing.T) {
require := require.New(t) //nolint further usage of require without passing t

macAddress := "bc:9a:78:56:34:12"
newMacAddress := "bc:9a:78:56:34:45"
newParsedMacAddress, _ := net.ParseMAC(newMacAddress)
newNCGatewayIPAddress := "40.0.0.1"

pnpID := "PCI\\VEN_15B3&DEV_101C&SUBSYS_000715B3&REV_00\\5&8c5acce&0&0"
newPnpID := "PCI\\VEN_15B3&DEV_101C&SUBSYS_000715B3&REV_00\\5&8c5acce&0&1"

newPodIPConfig := &cns.IPSubnet{
IPAddress: "30.1.1.10",
PrefixLength: 24,
}

newIP, newIPNet, _ := newPodIPConfig.GetIPNet()

type fields struct {
podName string
podNamespace string
cnsClient cnsclient
}

type args struct {
nwCfg *cni.NetworkConfig
args *cniSkel.CmdArgs
hostSubnetPrefix *net.IPNet
options map[string]interface{}
info IPResultInfo
podIPConfig *cns.IPSubnet
}

tests := []struct {
name string
fields fields
args args
wantSecondaryInterfacesInfo map[string]network.InterfaceInfo
}{
{
name: "add new backendNIC to cni Result",
fields: fields{
podName: testPodInfo.PodName,
podNamespace: testPodInfo.PodNamespace,
cnsClient: &MockCNSClient{
require: require,
requestIPs: requestIPsHandler{
ipconfigArgument: cns.IPConfigsRequest{
PodInterfaceID: "testcont-testifname1",
InfraContainerID: "testcontainerid1",
OrchestratorContext: marshallPodInfo(testPodInfo),
},
result: &cns.IPConfigsResponse{
PodIPInfo: []cns.PodIpInfo{
{
PodIPConfig: cns.IPSubnet{
IPAddress: "10.0.1.10",
PrefixLength: 24,
},
NetworkContainerPrimaryIPConfig: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: "10.0.1.0",
PrefixLength: 24,
},
DNSServers: nil,
GatewayIPAddress: "10.0.0.1",
},
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: "10.0.0.1",
PrimaryIP: "10.0.0.1",
Subnet: "10.0.0.0/24",
},
NICType: cns.InfraNIC,
},
{
MacAddress: macAddress,
NICType: cns.BackendNIC,
PnPID: pnpID,
},
},
Response: cns.Response{
ReturnCode: 0,
Message: "",
},
},
err: nil,
},
},
},
args: args{
nwCfg: &cni.NetworkConfig{},
args: &cniSkel.CmdArgs{
ContainerID: "testcontainerid1",
Netns: "testnetns1",
IfName: "testifname1",
},
hostSubnetPrefix: getCIDRNotationForAddress("10.0.0.1/24"),
options: map[string]interface{}{},
// update new pnpID, macAddress
info: IPResultInfo{
pnpID: newPnpID,
macAddress: newMacAddress,
nicType: cns.BackendNIC,
},
},
wantSecondaryInterfacesInfo: map[string]network.InterfaceInfo{
macAddress: {
MacAddress: newParsedMacAddress,
PnPID: newPnpID,
NICType: cns.BackendNIC,
},
},
},
{
name: "add new delegatedVMNIC to cni Result",
fields: fields{
podName: testPodInfo.PodName,
podNamespace: testPodInfo.PodNamespace,
cnsClient: &MockCNSClient{
require: require,
requestIPs: requestIPsHandler{
ipconfigArgument: cns.IPConfigsRequest{
PodInterfaceID: "testcont-testifname1",
InfraContainerID: "testcontainerid1",
OrchestratorContext: marshallPodInfo(testPodInfo),
},
result: &cns.IPConfigsResponse{
PodIPInfo: []cns.PodIpInfo{
{
PodIPConfig: cns.IPSubnet{
IPAddress: "10.0.1.10",
PrefixLength: 24,
},
NetworkContainerPrimaryIPConfig: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: "10.0.1.0",
PrefixLength: 24,
},
DNSServers: nil,
GatewayIPAddress: "10.0.0.1",
},
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: "10.0.0.1",
PrimaryIP: "10.0.0.1",
Subnet: "10.0.0.0/24",
},
NICType: cns.InfraNIC,
SkipDefaultRoutes: true,
},
{
PodIPConfig: cns.IPSubnet{
IPAddress: "20.1.1.10",
PrefixLength: 24,
},
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: "20.0.0.1",
PrimaryIP: "20.0.0.2",
Subnet: "20.0.0.1/24",
},
NICType: cns.NodeNetworkInterfaceFrontendNIC,
MacAddress: macAddress,
},
},
Response: cns.Response{
ReturnCode: 0,
Message: "",
},
},
err: nil,
},
},
},
args: args{
nwCfg: &cni.NetworkConfig{},
args: &cniSkel.CmdArgs{
ContainerID: "testcontainerid1",
Netns: "testnetns1",
IfName: "testifname1",
},
hostSubnetPrefix: getCIDRNotationForAddress("10.0.0.1/24"),
options: map[string]interface{}{},
// update podIPConfig
podIPConfig: newPodIPConfig,
// update new mac address and ncGatewayIPAddress
info: IPResultInfo{
macAddress: newMacAddress,
nicType: cns.NodeNetworkInterfaceFrontendNIC,
ncGatewayIPAddress: newNCGatewayIPAddress,
},
},
wantSecondaryInterfacesInfo: map[string]network.InterfaceInfo{
macAddress: {
MacAddress: newParsedMacAddress,
NICType: cns.NodeNetworkInterfaceFrontendNIC,
IPConfigs: []*network.IPConfig{
{
Address: net.IPNet{
IP: newIP,
Mask: newIPNet.Mask,
},
Gateway: net.ParseIP(newNCGatewayIPAddress),
},
},
Routes: []network.RouteInfo{},
},
},
},
{
name: "add new accelnetNIC to cni Result",
fields: fields{
podName: testPodInfo.PodName,
podNamespace: testPodInfo.PodNamespace,
cnsClient: &MockCNSClient{
require: require,
requestIPs: requestIPsHandler{
ipconfigArgument: cns.IPConfigsRequest{
PodInterfaceID: "testcont-testifname1",
InfraContainerID: "testcontainerid1",
OrchestratorContext: marshallPodInfo(testPodInfo),
},
result: &cns.IPConfigsResponse{
PodIPInfo: []cns.PodIpInfo{
{
PodIPConfig: cns.IPSubnet{
IPAddress: "10.0.1.10",
PrefixLength: 24,
},
NetworkContainerPrimaryIPConfig: cns.IPConfiguration{
IPSubnet: cns.IPSubnet{
IPAddress: "10.0.1.0",
PrefixLength: 24,
},
DNSServers: nil,
GatewayIPAddress: "10.0.0.1",
},
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: "10.0.0.1",
PrimaryIP: "10.0.0.1",
Subnet: "10.0.0.0/24",
},
NICType: cns.InfraNIC,
SkipDefaultRoutes: true,
},
{
PodIPConfig: cns.IPSubnet{
IPAddress: "20.1.1.10",
PrefixLength: 24,
},
HostPrimaryIPInfo: cns.HostIPInfo{
Gateway: "20.0.0.1",
PrimaryIP: "20.0.0.2",
Subnet: "20.0.0.1/24",
},
NICType: cns.NodeNetworkInterfaceAccelnetFrontendNIC,
MacAddress: macAddress,
},
},
Response: cns.Response{
ReturnCode: 0,
Message: "",
},
},
err: nil,
},
},
},
args: args{
nwCfg: &cni.NetworkConfig{},
args: &cniSkel.CmdArgs{
ContainerID: "testcontainerid1",
Netns: "testnetns1",
IfName: "testifname1",
},
hostSubnetPrefix: getCIDRNotationForAddress("10.0.0.1/24"),
options: map[string]interface{}{},
// update podIPConfig
podIPConfig: newPodIPConfig,
// update new mac address and ncGatewayIPAddress
info: IPResultInfo{
macAddress: newMacAddress,
nicType: cns.NodeNetworkInterfaceFrontendNIC,
ncGatewayIPAddress: newNCGatewayIPAddress,
},
},
wantSecondaryInterfacesInfo: map[string]network.InterfaceInfo{
macAddress: {
MacAddress: newParsedMacAddress,
NICType: cns.NodeNetworkInterfaceFrontendNIC,
IPConfigs: []*network.IPConfig{
{
Address: net.IPNet{
IP: newIP,
Mask: newIPNet.Mask,
},
Gateway: net.ParseIP(newNCGatewayIPAddress),
},
},
Routes: []network.RouteInfo{},
},
},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
invoker := &CNSIPAMInvoker{
podName: tt.fields.podName,
podNamespace: tt.fields.podNamespace,
cnsClient: tt.fields.cnsClient,
}
ipamAddResult, err := invoker.Add(IPAMAddConfig{nwCfg: tt.args.nwCfg, args: tt.args.args, options: tt.args.options})
if err != nil {
t.Fatalf("Failed to create ipamAddResult due to error: %v", err)
}

for _, ifInfo := range ipamAddResult.interfaceInfo {
if ifInfo.NICType == cns.BackendNIC {
// add new backendNIC info to cni Result
err := addBackendNICToResult(&tt.args.info, &ipamAddResult, macAddress)
if err != nil {
t.Fatalf("Failed to add backend NIC to cni Result due to error %v", err)
}
fmt.Printf("want:%+v\nrest:%+v\n", tt.wantSecondaryInterfacesInfo, ipamAddResult.interfaceInfo[macAddress])
require.EqualValues(tt.wantSecondaryInterfacesInfo[macAddress], ipamAddResult.interfaceInfo[macAddress], "incorrect response for IB")
}
if ifInfo.NICType == cns.NodeNetworkInterfaceFrontendNIC || ifInfo.NICType == cns.NodeNetworkInterfaceAccelnetFrontendNIC {
// add new secondaryInterfaceNIC to cni Result
err := configureSecondaryAddResult(&tt.args.info, &ipamAddResult, tt.args.podIPConfig, macAddress)
if err != nil {
t.Fatalf("Failed to add secondary interface NIC %s to cni Result due to error %v", ifInfo.NICType, err)
}
fmt.Printf("want:%+v\nrest:%+v\n", tt.wantSecondaryInterfacesInfo, ipamAddResult.interfaceInfo[macAddress])
require.EqualValues(tt.wantSecondaryInterfacesInfo[macAddress], ipamAddResult.interfaceInfo[macAddress], "incorrect response for delegatedVMNIC/accelnetNIC")
}
}
})
}
}
8 changes: 5 additions & 3 deletions cni/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,11 @@ func (plugin *NetPlugin) findMasterInterface(opt *createEpInfoOpt) string {
return plugin.findMasterInterfaceBySubnet(opt.ipamAddConfig.nwCfg, &opt.ifInfo.HostSubnetPrefix)
case cns.NodeNetworkInterfaceFrontendNIC, cns.NodeNetworkInterfaceAccelnetFrontendNIC:
return plugin.findInterfaceByMAC(opt.ifInfo.MacAddress.String())
case cns.BackendNIC: // TODO: how to find interface with IB NIC by mac address
opt.ifInfo.Name = ibInterfacePrefix + strconv.Itoa(opt.endpointIndex)
return opt.ifInfo.Name
case cns.BackendNIC:
// if windows swiftv2 has right network drivers, there will be an NDIS interface while the VFs are mounted
// when the VF is dismounted, this interface will go away
// return an unique interface name to containerd
return ibInterfacePrefix + strconv.Itoa(opt.endpointIndex)
default:
return ""
}
Expand Down
Loading

0 comments on commit 4c66f48

Please sign in to comment.