diff --git a/pkg/evpn/bridge_test.go b/pkg/evpn/bridge_test.go index 42145b75..24a87af4 100644 --- a/pkg/evpn/bridge_test.go +++ b/pkg/evpn/bridge_test.go @@ -13,7 +13,6 @@ import ( "log" "net" "reflect" - "strings" "testing" "github.com/vishvananda/netlink" @@ -60,6 +59,7 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode codes.Code errMsg string exist bool + on func(mockNetlink *mocks.Netlink, errMsg string) }{ "illegal resource_id": { id: "CapitalLettersNotAllowed", @@ -68,6 +68,7 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.Unknown, errMsg: fmt.Sprintf("user-settable ID must only contain lowercase, numbers and hyphens (%v)", "got: 'C' in position 0"), exist: false, + on: nil, }, "no required bridge field": { id: testLogicalBridgeID, @@ -76,6 +77,7 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: logical_bridge", exist: false, + on: nil, }, "no required vlan_id field": { id: testLogicalBridgeID, @@ -86,6 +88,7 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: logical_bridge.spec.vlan_id", exist: false, + on: nil, }, "illegal VlanId": { id: testLogicalBridgeID, @@ -99,6 +102,7 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.InvalidArgument, errMsg: fmt.Sprintf("VlanId value (%v) have to be between 1 and 4095", 4096), exist: false, + on: nil, }, "empty vni": { id: testLogicalBridgeID, @@ -118,6 +122,7 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.OK, errMsg: "", exist: false, + on: nil, }, "already exists": { id: testLogicalBridgeID, @@ -134,6 +139,9 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.NotFound, errMsg: "unable to find key br-tenant", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(nil, errors.New(errMsg)).Once() + }, }, "failed LinkAdd call": { id: testLogicalBridgeID, @@ -142,6 +150,16 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkAdd", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + // myip := net.ParseIP("10.0.0.2") + myip := make(net.IP, 4) + binary.BigEndian.PutUint32(myip, 167772162) + vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) + vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() + mockNetlink.EXPECT().LinkAdd(vxlan).Return(errors.New(errMsg)).Once() + }, }, "failed LinkSetMaster call": { id: testLogicalBridgeID, @@ -150,6 +168,16 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkSetMaster", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + myip := make(net.IP, 4) + binary.BigEndian.PutUint32(myip, 167772162) + vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) + vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() + mockNetlink.EXPECT().LinkAdd(vxlan).Return(nil).Once() + mockNetlink.EXPECT().LinkSetMaster(vxlan, bridge).Return(errors.New(errMsg)).Once() + }, }, "failed LinkSetUp call": { id: testLogicalBridgeID, @@ -158,6 +186,17 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkSetUp", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + myip := make(net.IP, 4) + binary.BigEndian.PutUint32(myip, 167772162) + vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) + vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() + mockNetlink.EXPECT().LinkAdd(vxlan).Return(nil).Once() + mockNetlink.EXPECT().LinkSetMaster(vxlan, bridge).Return(nil).Once() + mockNetlink.EXPECT().LinkSetUp(vxlan).Return(errors.New(errMsg)).Once() + }, }, "failed BridgeVlanAdd call": { id: testLogicalBridgeID, @@ -166,6 +205,18 @@ func Test_CreateLogicalBridge(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call BridgeVlanAdd", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + myip := make(net.IP, 4) + binary.BigEndian.PutUint32(myip, 167772162) + vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) + vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() + mockNetlink.EXPECT().LinkAdd(vxlan).Return(nil).Once() + mockNetlink.EXPECT().LinkSetMaster(vxlan, bridge).Return(nil).Once() + mockNetlink.EXPECT().LinkSetUp(vxlan).Return(nil).Once() + mockNetlink.EXPECT().BridgeVlanAdd(vxlan, uint16(testLogicalBridge.Spec.VlanId), true, true, false, false).Return(errors.New(errMsg)).Once() + }, }, } @@ -199,49 +250,8 @@ func Test_CreateLogicalBridge(t *testing.T) { tt.out = protoClone(tt.out) tt.out.Name = testLogicalBridgeName } - - // TODO: refactor this mocking - if strings.Contains(name, "failed LinkByName") { - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(nil, errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed LinkAdd") { - // myip := net.ParseIP("10.0.0.2") - myip := make(net.IP, 4) - binary.BigEndian.PutUint32(myip, 167772162) - vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) - vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - mockNetlink.EXPECT().LinkAdd(vxlan).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed LinkSetMaster") { - myip := make(net.IP, 4) - binary.BigEndian.PutUint32(myip, 167772162) - vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) - vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - mockNetlink.EXPECT().LinkAdd(vxlan).Return(nil).Once() - mockNetlink.EXPECT().LinkSetMaster(vxlan, bridge).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed LinkSetUp") { - myip := make(net.IP, 4) - binary.BigEndian.PutUint32(myip, 167772162) - vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) - vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - mockNetlink.EXPECT().LinkAdd(vxlan).Return(nil).Once() - mockNetlink.EXPECT().LinkSetMaster(vxlan, bridge).Return(nil).Once() - mockNetlink.EXPECT().LinkSetUp(vxlan).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed BridgeVlanAdd") { - myip := make(net.IP, 4) - binary.BigEndian.PutUint32(myip, 167772162) - vxlanName := fmt.Sprintf("vni%d", *testLogicalBridge.Spec.Vni) - vxlan := &netlink.Vxlan{LinkAttrs: netlink.LinkAttrs{Name: vxlanName}, VxlanId: int(*testLogicalBridge.Spec.Vni), Port: 4789, Learning: false, SrcAddr: myip} - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - mockNetlink.EXPECT().LinkAdd(vxlan).Return(nil).Once() - mockNetlink.EXPECT().LinkSetMaster(vxlan, bridge).Return(nil).Once() - mockNetlink.EXPECT().LinkSetUp(vxlan).Return(nil).Once() - mockNetlink.EXPECT().BridgeVlanAdd(vxlan, uint16(testLogicalBridge.Spec.VlanId), true, true, false, false).Return(errors.New(tt.errMsg)).Once() + if tt.on != nil { + tt.on(mockNetlink, tt.errMsg) } request := &pb.CreateLogicalBridgeRequest{LogicalBridge: tt.in, LogicalBridgeId: tt.id} diff --git a/pkg/evpn/port_test.go b/pkg/evpn/port_test.go index 22490994..686895ab 100644 --- a/pkg/evpn/port_test.go +++ b/pkg/evpn/port_test.go @@ -11,7 +11,6 @@ import ( "fmt" "log" "reflect" - "strings" "testing" "google.golang.org/grpc" @@ -47,6 +46,7 @@ func Test_CreateBridgePort(t *testing.T) { errCode codes.Code errMsg string exist bool + on func(mockNetlink *mocks.Netlink, errMsg string) }{ "illegal resource_id": { id: "CapitalLettersNotAllowed", @@ -55,6 +55,7 @@ func Test_CreateBridgePort(t *testing.T) { errCode: codes.Unknown, errMsg: fmt.Sprintf("user-settable ID must only contain lowercase, numbers and hyphens (%v)", "got: 'C' in position 0"), exist: false, + on: nil, }, "already exists": { id: testBridgePortID, @@ -63,6 +64,7 @@ func Test_CreateBridgePort(t *testing.T) { errCode: codes.OK, errMsg: "", exist: true, + on: nil, }, "no required port field": { id: testBridgePortID, @@ -71,6 +73,7 @@ func Test_CreateBridgePort(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: bridge_port", exist: false, + on: nil, }, "no required mac_address field": { id: testBridgePortID, @@ -81,6 +84,7 @@ func Test_CreateBridgePort(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: bridge_port.spec.mac_address", exist: false, + on: nil, }, "no required ptype field": { id: testBridgePortID, @@ -93,6 +97,7 @@ func Test_CreateBridgePort(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: bridge_port.spec.ptype", exist: false, + on: nil, }, "access port and list bridge": { id: testBridgePortID, @@ -107,6 +112,7 @@ func Test_CreateBridgePort(t *testing.T) { errCode: codes.InvalidArgument, errMsg: fmt.Sprintf("ACCESS type must have single LogicalBridge and not (%d)", len(testBridgePort.Spec.LogicalBridges)), exist: false, + on: nil, }, "failed LinkByName call": { id: testBridgePortID, @@ -115,6 +121,9 @@ func Test_CreateBridgePort(t *testing.T) { errCode: codes.NotFound, errMsg: "unable to find key br-tenant", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(nil, errors.New(errMsg)).Once() + }, }, } @@ -148,10 +157,8 @@ func Test_CreateBridgePort(t *testing.T) { tt.out = protoClone(tt.out) tt.out.Name = testBridgePortName } - - // TODO: refactor this mocking - if strings.Contains(name, "LinkByName") { - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(nil, errors.New(tt.errMsg)).Once() + if tt.on != nil { + tt.on(mockNetlink, tt.errMsg) } request := &pb.CreateBridgePortRequest{BridgePort: tt.in, BridgePortId: tt.id} diff --git a/pkg/evpn/svi_test.go b/pkg/evpn/svi_test.go index 1c14750c..6fa07e83 100644 --- a/pkg/evpn/svi_test.go +++ b/pkg/evpn/svi_test.go @@ -12,7 +12,6 @@ import ( "log" "net" "reflect" - "strings" "testing" "github.com/vishvananda/netlink" @@ -52,6 +51,7 @@ func Test_CreateSvi(t *testing.T) { errCode codes.Code errMsg string exist bool + on func(mockNetlink *mocks.Netlink, errMsg string) }{ "illegal resource_id": { id: "CapitalLettersNotAllowed", @@ -60,6 +60,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: fmt.Sprintf("user-settable ID must only contain lowercase, numbers and hyphens (%v)", "got: 'C' in position 0"), exist: false, + on: nil, }, "already exists": { id: testSviID, @@ -68,6 +69,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.OK, errMsg: "", exist: true, + on: nil, }, "no required svi field": { id: testSviID, @@ -76,6 +78,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: svi", exist: false, + on: nil, }, "no required vrf field": { id: testSviID, @@ -86,6 +89,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: svi.spec.vrf", exist: false, + on: nil, }, "no required bridge field": { id: testSviID, @@ -98,6 +102,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: svi.spec.logical_bridge", exist: false, + on: nil, }, "no required mac field": { id: testSviID, @@ -111,6 +116,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: svi.spec.mac_address", exist: false, + on: nil, }, "no required gw ip field": { id: testSviID, @@ -125,6 +131,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: svi.spec.gw_ip_prefix", exist: false, + on: nil, }, "malformed LogicalBridge name": { id: testSviID, @@ -140,6 +147,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: fmt.Sprintf("segment '%s': not a valid DNS name", "-ABC-DEF"), exist: false, + on: nil, }, "malformed Vrf name": { id: testSviID, @@ -155,6 +163,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: fmt.Sprintf("segment '%s': not a valid DNS name", "-ABC-DEF"), exist: false, + on: nil, }, "missing LogicalBridge name": { id: testSviID, @@ -170,6 +179,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.NotFound, errMsg: fmt.Sprintf("unable to find key %v", "unknown-bridge-id"), exist: false, + on: nil, }, "missing Vrf name": { id: testSviID, @@ -185,6 +195,7 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.NotFound, errMsg: fmt.Sprintf("unable to find key %v", "unknown-vrf-id"), exist: false, + on: nil, }, "failed LinkByName call": { id: testSviID, @@ -193,6 +204,9 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.NotFound, errMsg: "unable to find key br-tenant", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(nil, errors.New(errMsg)).Once() + }, }, "failed BridgeVlanAdd call": { id: testSviID, @@ -201,6 +215,12 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call BridgeVlanAdd", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + vid := uint16(testLogicalBridge.Spec.VlanId) + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() + mockNetlink.EXPECT().BridgeVlanAdd(bridge, vid, false, false, true, false).Return(errors.New(errMsg)).Once() + }, }, "failed LinkAdd call": { id: testSviID, @@ -209,6 +229,15 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkAdd", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + vid := uint16(testLogicalBridge.Spec.VlanId) + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() + mockNetlink.EXPECT().BridgeVlanAdd(bridge, vid, false, false, true, false).Return(nil).Once() + vlanName := fmt.Sprintf("vlan%d", vid) + vlandev := &netlink.Vlan{LinkAttrs: netlink.LinkAttrs{Name: vlanName, ParentIndex: bridge.Attrs().Index}, VlanId: int(vid)} + mockNetlink.EXPECT().LinkAdd(vlandev).Return(errors.New(errMsg)).Once() + }, }, "failed LinkSetHardwareAddr call": { id: testSviID, @@ -217,6 +246,17 @@ func Test_CreateSvi(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkSetHardwareAddr", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + vid := uint16(testLogicalBridge.Spec.VlanId) + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} + mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() + mockNetlink.EXPECT().BridgeVlanAdd(bridge, vid, false, false, true, false).Return(nil).Once() + vlanName := fmt.Sprintf("vlan%d", vid) + vlandev := &netlink.Vlan{LinkAttrs: netlink.LinkAttrs{Name: vlanName, ParentIndex: bridge.Attrs().Index}, VlanId: int(vid)} + mockNetlink.EXPECT().LinkAdd(vlandev).Return(nil).Once() + mac := net.HardwareAddr(testSvi.Spec.MacAddress[:]) + mockNetlink.EXPECT().LinkSetHardwareAddr(vlandev, mac).Return(errors.New(errMsg)).Once() + }, }, } @@ -250,42 +290,12 @@ func Test_CreateSvi(t *testing.T) { tt.out = protoClone(tt.out) tt.out.Name = testSviName } + if tt.on != nil { + tt.on(mockNetlink, tt.errMsg) + } opi.Vrfs[testVrfName] = protoClone(&testVrf) opi.Bridges[testLogicalBridgeName] = protoClone(&testLogicalBridge) - // TODO: refactor this mocking - if strings.Contains(name, "failed LinkByName") { - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(nil, errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed BridgeVlanAdd") { - vid := uint16(testLogicalBridge.Spec.VlanId) - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - mockNetlink.EXPECT().BridgeVlanAdd(bridge, vid, false, false, true, false).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed LinkAdd") { - vid := uint16(testLogicalBridge.Spec.VlanId) - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - mockNetlink.EXPECT().BridgeVlanAdd(bridge, vid, false, false, true, false).Return(nil).Once() - vlanName := fmt.Sprintf("vlan%d", vid) - vlandev := &netlink.Vlan{LinkAttrs: netlink.LinkAttrs{Name: vlanName, ParentIndex: bridge.Attrs().Index}, VlanId: int(vid)} - mockNetlink.EXPECT().LinkAdd(vlandev).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed LinkSetHardwareAddr") { - vid := uint16(testLogicalBridge.Spec.VlanId) - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - mockNetlink.EXPECT().BridgeVlanAdd(bridge, vid, false, false, true, false).Return(nil).Once() - vlanName := fmt.Sprintf("vlan%d", vid) - vlandev := &netlink.Vlan{LinkAttrs: netlink.LinkAttrs{Name: vlanName, ParentIndex: bridge.Attrs().Index}, VlanId: int(vid)} - mockNetlink.EXPECT().LinkAdd(vlandev).Return(nil).Once() - mac := net.HardwareAddr(testSvi.Spec.MacAddress[:]) - mockNetlink.EXPECT().LinkSetHardwareAddr(vlandev, mac).Return(errors.New(tt.errMsg)).Once() - } - - if tt.out != nil && !tt.exist { - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: tenantbridgeName}} - mockNetlink.EXPECT().LinkByName(tenantbridgeName).Return(bridge, nil).Once() - } - request := &pb.CreateSviRequest{Svi: tt.in, SviId: tt.id} response, err := client.CreateSvi(ctx, request) if !proto.Equal(tt.out, response) { diff --git a/pkg/evpn/vrf_test.go b/pkg/evpn/vrf_test.go index fd20047c..6502d0b9 100644 --- a/pkg/evpn/vrf_test.go +++ b/pkg/evpn/vrf_test.go @@ -11,7 +11,6 @@ import ( "fmt" "log" "reflect" - "strings" "testing" "github.com/vishvananda/netlink" @@ -57,6 +56,7 @@ func Test_CreateVrf(t *testing.T) { errCode codes.Code errMsg string exist bool + on func(mockNetlink *mocks.Netlink, errMsg string) }{ "illegal resource_id": { id: "CapitalLettersNotAllowed", @@ -65,6 +65,7 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.Unknown, errMsg: fmt.Sprintf("user-settable ID must only contain lowercase, numbers and hyphens (%v)", "got: 'C' in position 0"), exist: false, + on: nil, }, "no required vrf field": { id: testVrfID, @@ -73,6 +74,7 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: vrf", exist: false, + on: nil, }, "no required loopback_ip_prefix field": { id: testVrfID, @@ -83,6 +85,7 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.Unknown, errMsg: "missing required field: vrf.spec.loopback_ip_prefix", exist: false, + on: nil, }, "already exists": { id: testVrfID, @@ -91,6 +94,7 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.OK, errMsg: "", exist: true, + on: nil, }, "valid request empty VNI amd empty Loopback": { id: testVrfID, @@ -116,6 +120,11 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.OK, errMsg: "", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1000} + mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() + mockNetlink.EXPECT().LinkSetUp(vrf).Return(nil).Once() + }, }, "failed LinkAdd call": { id: testVrfID, @@ -124,6 +133,10 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkAdd", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} + mockNetlink.EXPECT().LinkAdd(vrf).Return(errors.New(errMsg)).Once() + }, }, "failed LinkSetUp call": { id: testVrfID, @@ -132,6 +145,11 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkSetUp", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} + mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() + mockNetlink.EXPECT().LinkSetUp(vrf).Return(errors.New(errMsg)).Once() + }, }, "failed bridge LinkAdd call": { id: testVrfID, @@ -140,6 +158,14 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkAdd", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + bridgeName := fmt.Sprintf("br%d", *testVrf.Spec.Vni) + vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}} + mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() + mockNetlink.EXPECT().LinkSetUp(vrf).Return(nil).Once() + mockNetlink.EXPECT().LinkAdd(bridge).Return(errors.New(errMsg)).Once() + }, }, "failed bridge LinkSetMaster call": { id: testVrfID, @@ -148,6 +174,15 @@ func Test_CreateVrf(t *testing.T) { errCode: codes.Unknown, errMsg: "Failed to call LinkSetMaster", exist: false, + on: func(mockNetlink *mocks.Netlink, errMsg string) { + bridgeName := fmt.Sprintf("br%d", *testVrf.Spec.Vni) + vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} + bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}} + mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() + mockNetlink.EXPECT().LinkSetUp(vrf).Return(nil).Once() + mockNetlink.EXPECT().LinkAdd(bridge).Return(nil).Once() + mockNetlink.EXPECT().LinkSetMaster(bridge, vrf).Return(errors.New(errMsg)).Once() + }, }, } @@ -181,36 +216,8 @@ func Test_CreateVrf(t *testing.T) { tt.out = protoClone(tt.out) tt.out.Name = testVrfName } - - // TODO: refactor this mocking - if strings.Contains(name, "failed LinkAdd") { - vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} - mockNetlink.EXPECT().LinkAdd(vrf).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed LinkSetUp") { - vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} - mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() - mockNetlink.EXPECT().LinkSetUp(vrf).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed bridge LinkAdd") { - bridgeName := fmt.Sprintf("br%d", *testVrf.Spec.Vni) - vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}} - mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() - mockNetlink.EXPECT().LinkSetUp(vrf).Return(nil).Once() - mockNetlink.EXPECT().LinkAdd(bridge).Return(errors.New(tt.errMsg)).Once() - } else if strings.Contains(name, "failed bridge LinkSetMaster") { - bridgeName := fmt.Sprintf("br%d", *testVrf.Spec.Vni) - vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1001} - bridge := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: bridgeName}} - mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() - mockNetlink.EXPECT().LinkSetUp(vrf).Return(nil).Once() - mockNetlink.EXPECT().LinkAdd(bridge).Return(nil).Once() - mockNetlink.EXPECT().LinkSetMaster(bridge, vrf).Return(errors.New(tt.errMsg)).Once() - } - - if tt.out != nil && !tt.exist { - vrf := &netlink.Vrf{LinkAttrs: netlink.LinkAttrs{Name: testVrfID}, Table: 1000} - mockNetlink.EXPECT().LinkAdd(vrf).Return(nil).Once() - mockNetlink.EXPECT().LinkSetUp(vrf).Return(nil).Once() + if tt.on != nil { + tt.on(mockNetlink, tt.errMsg) } request := &pb.CreateVrfRequest{Vrf: tt.in, VrfId: tt.id}