Skip to content

Commit

Permalink
add uts for multi interface infos single add call, verify endpoint id…
Browse files Browse the repository at this point in the history
…, cns to cni data conversion and vice versa, get endpoint info from container id (noop)

verifies partial success will delete all endpoints, even successfully created ones in the same cni add call
  • Loading branch information
QxBytes committed May 30, 2024
1 parent 209650c commit 2f15ae4
Show file tree
Hide file tree
Showing 4 changed files with 393 additions and 5 deletions.
13 changes: 13 additions & 0 deletions cni/network/invoker_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type MockIpamInvoker struct {
delegatedVMNIC bool
delegatedVMNICFail bool
ipMap map[string]bool
customReturn map[string]network.InterfaceInfo
}

func NewMockIpamInvoker(ipv6, v4Fail, v6Fail, delegatedVMNIC, delegatedVMNICFail bool) *MockIpamInvoker {
Expand All @@ -44,6 +45,13 @@ func NewMockIpamInvoker(ipv6, v4Fail, v6Fail, delegatedVMNIC, delegatedVMNICFail
ipMap: make(map[string]bool),
}
}
func NewCustomMockIpamInvoker(customReturn map[string]network.InterfaceInfo) *MockIpamInvoker {
return &MockIpamInvoker{
customReturn: customReturn,

ipMap: make(map[string]bool),
}
}

func (invoker *MockIpamInvoker) Add(opt IPAMAddConfig) (ipamAddResult IPAMAddResult, err error) {
if invoker.v4Fail {
Expand Down Expand Up @@ -104,6 +112,11 @@ func (invoker *MockIpamInvoker) Add(opt IPAMAddConfig) (ipamAddResult IPAMAddRes
}
}

if invoker.customReturn != nil {
ipamAddResult.interfaceInfo = invoker.customReturn
return ipamAddResult, nil
}

return ipamAddResult, nil
}

Expand Down
139 changes: 139 additions & 0 deletions cni/network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1304,3 +1304,142 @@ func TestPluginSwiftV2Add(t *testing.T) {
})
}
}

func TestPluginSwiftV2MultipleAdd(t *testing.T) {
// checks cases where we create multiple endpoints in one call (also checks endpoint id)
// assumes we never get two infras created in one add call
plugin, _ := cni.NewPlugin("name", "0.3.0")

localNwCfg := cni.NetworkConfig{
CNIVersion: "0.3.0",
Name: "swiftv2",
ExecutionMode: string(util.V4Overlay),
EnableExactMatchForPodName: true,
Master: "eth0",
}

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,
}

tests := []struct {
name string
plugin *NetPlugin
args *cniSkel.CmdArgs
wantErr bool
wantErrMsg string
wantNumEps int
validEpIDs map[string]struct{}
}{
{
name: "SwiftV2 Add Infra and Delegated",
plugin: &NetPlugin{
Plugin: plugin,
nm: acnnetwork.NewMockNetworkmanager(acnnetwork.NewMockEndpointClient(nil)),
ipamInvoker: NewCustomMockIpamInvoker(map[string]acnnetwork.InterfaceInfo{
"eth0-1": {
NICType: cns.DelegatedVMNIC,
},
"eth0": {
NICType: cns.InfraNIC,
},
}),
report: &telemetry.CNIReport{},
tb: &telemetry.TelemetryBuffer{},
netClient: &InterfaceGetterMock{
interfaces: []net.Interface{
{Name: "eth0"},
},
},
},
args: args,
wantErr: false,
wantNumEps: 2,
},
{
name: "SwiftV2 Add Two Delegated",
plugin: &NetPlugin{
Plugin: plugin,
nm: acnnetwork.NewMockNetworkmanager(acnnetwork.NewMockEndpointClient(nil)),
ipamInvoker: NewCustomMockIpamInvoker(map[string]acnnetwork.InterfaceInfo{
"eth0": {
NICType: cns.DelegatedVMNIC,
},
"eth0-1": {
NICType: cns.DelegatedVMNIC,
},
}),
report: &telemetry.CNIReport{},
tb: &telemetry.TelemetryBuffer{},
netClient: &InterfaceGetterMock{
interfaces: []net.Interface{
{Name: "eth0"},
},
},
},
args: args,
wantErr: false,
wantNumEps: 2,
},
{
// creates 2 endpoints, the first succeeds, the second doesn't
// ensures that delete is called to clean up the first endpoint that succeeded
name: "SwiftV2 Partial Add fail",
plugin: &NetPlugin{
Plugin: plugin,
nm: acnnetwork.NewMockNetworkmanager(acnnetwork.NewMockEndpointClient(func(ep *acnnetwork.EndpointInfo) error {
if ep.NICType == cns.DelegatedVMNIC {
return acnnetwork.NewErrorMockEndpointClient("AddEndpoints Delegated VM NIC failed") //nolint:wrapcheck // ignore wrapping for test
}

return nil
})),
ipamInvoker: NewCustomMockIpamInvoker(map[string]acnnetwork.InterfaceInfo{
"eth0": {
NICType: cns.InfraNIC,
},
"eth0-1": {
NICType: cns.DelegatedVMNIC,
},
}),
report: &telemetry.CNIReport{},
tb: &telemetry.TelemetryBuffer{},
netClient: &InterfaceGetterMock{
interfaces: []net.Interface{
{Name: "eth0"},
},
},
},
args: args,
wantNumEps: 0,
wantErr: true,
wantErrMsg: "failed to create endpoint: MockEndpointClient Error : AddEndpoints Delegated VM NIC failed",
},
}

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.Equal(t, tt.wantErrMsg, err.Error(), "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) == tt.wantNumEps }))
for _, ep := range endpoints {
if ep.NICType == cns.InfraNIC {
require.Equal(t, "test-con-"+tt.args.IfName, ep.EndpointID, "infra nic must use ifname for its endpoint id")
} else {
require.Regexp(t, `test-con-\d+$`, ep.EndpointID, "other nics must use an index for their endpoint ids")
}
}
})
}
}
21 changes: 16 additions & 5 deletions network/manager_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type MockNetworkManager struct {
TestNetworkInfoMap map[string]*EndpointInfo
TestEndpointInfoMap map[string]*EndpointInfo
TestEndpointClient *MockEndpointClient
SaveStateMap map[string]*endpoint
}

// NewMockNetworkmanager returns a new mock
Expand All @@ -17,6 +18,7 @@ func NewMockNetworkmanager(mockEndpointclient *MockEndpointClient) *MockNetworkM
TestNetworkInfoMap: make(map[string]*EndpointInfo),
TestEndpointInfoMap: make(map[string]*EndpointInfo),
TestEndpointClient: mockEndpointclient,
SaveStateMap: make(map[string]*endpoint),
}
}

Expand Down Expand Up @@ -154,8 +156,11 @@ func (nm *MockNetworkManager) GetNumEndpointsByContainerID(_ string) int {
return numEndpoints
}

func (nm *MockNetworkManager) SaveState(_ []*endpoint) error {
// TODO: Mock behavior for saving the state separate from TestEndpointInfo/NetworkInfo map maybe
func (nm *MockNetworkManager) SaveState(eps []*endpoint) error {
for _, ep := range eps {
nm.SaveStateMap[ep.Id] = ep
}

return nil
}

Expand All @@ -174,15 +179,21 @@ func (nm *MockNetworkManager) EndpointCreate(client apipaClient, epInfos []*Endp
if err != nil {
return err
}
eps = append(eps, &endpoint{}) // mock append
eps = append(eps, &endpoint{
Id: epInfo.EndpointID,
ContainerID: epInfo.ContainerID,
NICType: epInfo.NICType,
}) // mock append
}

// mock save endpoints
return nm.SaveState(eps)
}

func (nm *MockNetworkManager) DeleteState(_ []*EndpointInfo) error {
// TODO: Mock behavior for deleting the state separate from TestEndpointInfo/NetworkInfo map maybe
func (nm *MockNetworkManager) DeleteState(epInfos []*EndpointInfo) error {
for _, epInfo := range epInfos {
delete(nm.SaveStateMap, epInfo.EndpointID)
}
return nil
}

Expand Down
Loading

0 comments on commit 2f15ae4

Please sign in to comment.