diff --git a/go/dpservice-go/client/client.go b/go/dpservice-go/client/client.go index 4da81af38..dbe81534d 100644 --- a/go/dpservice-go/client/client.go +++ b/go/dpservice-go/client/client.go @@ -24,7 +24,7 @@ type Client interface { CreateLoadBalancerPrefix(ctx context.Context, prefix *api.LoadBalancerPrefix, ignoredErrors ...[]uint32) (*api.LoadBalancerPrefix, error) DeleteLoadBalancerPrefix(ctx context.Context, interfaceID string, prefix *netip.Prefix, ignoredErrors ...[]uint32) (*api.LoadBalancerPrefix, error) - ListLoadBalancerTargets(ctx context.Context, interfaceID string, ignoredErrors ...[]uint32) (*api.LoadBalancerTargetList, error) + ListLoadBalancerTargets(ctx context.Context, loadbalancerID string, ignoredErrors ...[]uint32) (*api.LoadBalancerTargetList, error) CreateLoadBalancerTarget(ctx context.Context, lbtarget *api.LoadBalancerTarget, ignoredErrors ...[]uint32) (*api.LoadBalancerTarget, error) DeleteLoadBalancerTarget(ctx context.Context, id string, targetIP *netip.Addr, ignoredErrors ...[]uint32) (*api.LoadBalancerTarget, error) @@ -126,6 +126,9 @@ func (c *client) ListLoadBalancers(ctx context.Context, ignoredErrors ...[]uint3 } func (c *client) CreateLoadBalancer(ctx context.Context, lb *api.LoadBalancer, ignoredErrors ...[]uint32) (*api.LoadBalancer, error) { + if lb == nil { + return &api.LoadBalancer{}, fmt.Errorf("error: input loadbalancer cannot be nil") + } var lbPorts = make([]*dpdkproto.LbPort, 0, len(lb.Spec.Lbports)) for _, p := range lb.Spec.Lbports { lbPort := &dpdkproto.LbPort{Port: p.Port, Protocol: dpdkproto.Protocol(p.Protocol)} @@ -210,6 +213,9 @@ func (c *client) ListLoadBalancerPrefixes(ctx context.Context, interfaceID strin } func (c *client) CreateLoadBalancerPrefix(ctx context.Context, lbprefix *api.LoadBalancerPrefix, ignoredErrors ...[]uint32) (*api.LoadBalancerPrefix, error) { + if lbprefix == nil { + return &api.LoadBalancerPrefix{}, fmt.Errorf("error: input loadbalancer prefix cannot be nil") + } lbPrefixAddr := lbprefix.Spec.Prefix.Addr() res, err := c.DPDKironcoreClient.CreateLoadBalancerPrefix(ctx, &dpdkproto.CreateLoadBalancerPrefixRequest{ InterfaceId: []byte(lbprefix.InterfaceID), @@ -241,6 +247,9 @@ func (c *client) CreateLoadBalancerPrefix(ctx context.Context, lbprefix *api.Loa } func (c *client) DeleteLoadBalancerPrefix(ctx context.Context, interfaceID string, prefix *netip.Prefix, ignoredErrors ...[]uint32) (*api.LoadBalancerPrefix, error) { + if prefix == nil { + return &api.LoadBalancerPrefix{}, fmt.Errorf("error: input prefix cannot be nil") + } lbPrefixAddr := prefix.Addr() res, err := c.DPDKironcoreClient.DeleteLoadBalancerPrefix(ctx, &dpdkproto.DeleteLoadBalancerPrefixRequest{ InterfaceId: []byte(interfaceID), @@ -299,6 +308,9 @@ func (c *client) ListLoadBalancerTargets(ctx context.Context, loadBalancerID str } func (c *client) CreateLoadBalancerTarget(ctx context.Context, lbtarget *api.LoadBalancerTarget, ignoredErrors ...[]uint32) (*api.LoadBalancerTarget, error) { + if lbtarget == nil { + return &api.LoadBalancerTarget{}, fmt.Errorf("error: input loadbalancer target cannot be nil") + } res, err := c.DPDKironcoreClient.CreateLoadBalancerTarget(ctx, &dpdkproto.CreateLoadBalancerTargetRequest{ LoadbalancerId: []byte(lbtarget.LoadBalancerTargetMeta.LoadbalancerID), TargetIp: api.NetIPAddrToProtoIpAddress(lbtarget.Spec.TargetIP), @@ -382,6 +394,9 @@ func (c *client) ListInterfaces(ctx context.Context, ignoredErrors ...[]uint32) } func (c *client) CreateInterface(ctx context.Context, iface *api.Interface, ignoredErrors ...[]uint32) (*api.Interface, error) { + if iface == nil { + return &api.Interface{}, fmt.Errorf("error: input interface cannot be nil") + } req := dpdkproto.CreateInterfaceRequest{ InterfaceType: dpdkproto.InterfaceType_VIRTUAL, InterfaceId: []byte(iface.ID), @@ -458,6 +473,9 @@ func (c *client) GetVirtualIP(ctx context.Context, interfaceID string, ignoredEr } func (c *client) CreateVirtualIP(ctx context.Context, virtualIP *api.VirtualIP, ignoredErrors ...[]uint32) (*api.VirtualIP, error) { + if virtualIP == nil { + return &api.VirtualIP{}, fmt.Errorf("error: input virtual ip cannot be nil") + } res, err := c.DPDKironcoreClient.CreateVip(ctx, &dpdkproto.CreateVipRequest{ InterfaceId: []byte(virtualIP.InterfaceID), VipIp: api.NetIPAddrToProtoIpAddress(virtualIP.Spec.IP), @@ -534,6 +552,9 @@ func (c *client) ListPrefixes(ctx context.Context, interfaceID string, ignoredEr } func (c *client) CreatePrefix(ctx context.Context, prefix *api.Prefix, ignoredErrors ...[]uint32) (*api.Prefix, error) { + if prefix == nil { + return &api.Prefix{}, fmt.Errorf("error: input prefix cannot be nil") + } prefixAddr := prefix.Spec.Prefix.Addr() res, err := c.DPDKironcoreClient.CreatePrefix(ctx, &dpdkproto.CreatePrefixRequest{ InterfaceId: []byte(prefix.InterfaceID), @@ -564,6 +585,9 @@ func (c *client) CreatePrefix(ctx context.Context, prefix *api.Prefix, ignoredEr } func (c *client) DeletePrefix(ctx context.Context, interfaceID string, prefix *netip.Prefix, ignoredErrors ...[]uint32) (*api.Prefix, error) { + if prefix == nil { + return &api.Prefix{}, fmt.Errorf("error: input prefix cannot be nil") + } prefixAddr := prefix.Addr() res, err := c.DPDKironcoreClient.DeletePrefix(ctx, &dpdkproto.DeletePrefixRequest{ InterfaceId: []byte(interfaceID), @@ -588,6 +612,10 @@ func (c *client) DeletePrefix(ctx context.Context, interfaceID string, prefix *n } func (c *client) CreateRoute(ctx context.Context, route *api.Route, ignoredErrors ...[]uint32) (*api.Route, error) { + if route == nil { + return &api.Route{}, fmt.Errorf("error: input route cannot be nil") + } + if route.Spec.Prefix == nil { return &api.Route{}, fmt.Errorf("prefix needs to be specified") } @@ -627,6 +655,9 @@ func (c *client) CreateRoute(ctx context.Context, route *api.Route, ignoredError } func (c *client) DeleteRoute(ctx context.Context, vni uint32, prefix *netip.Prefix, ignoredErrors ...[]uint32) (*api.Route, error) { + if prefix == nil { + return &api.Route{}, fmt.Errorf("error: input prefix cannot be nil") + } routePrefixAddr := prefix.Addr() res, err := c.DPDKironcoreClient.DeleteRoute(ctx, &dpdkproto.DeleteRouteRequest{ Vni: vni, @@ -702,6 +733,9 @@ func (c *client) GetNat(ctx context.Context, interfaceID string, ignoredErrors . } func (c *client) CreateNat(ctx context.Context, nat *api.Nat, ignoredErrors ...[]uint32) (*api.Nat, error) { + if nat == nil { + return &api.Nat{}, fmt.Errorf("error: input nat cannot be nil") + } res, err := c.DPDKironcoreClient.CreateNat(ctx, &dpdkproto.CreateNatRequest{ InterfaceId: []byte(nat.NatMeta.InterfaceID), NatIp: api.NetIPAddrToProtoIpAddress(nat.Spec.NatIP), @@ -753,6 +787,9 @@ func (c *client) ListLocalNats(ctx context.Context, natIP *netip.Addr, ignoredEr } func (c *client) CreateNeighborNat(ctx context.Context, nNat *api.NeighborNat, ignoredErrors ...[]uint32) (*api.NeighborNat, error) { + if nNat == nil { + return &api.NeighborNat{}, fmt.Errorf("error: input neighbor nat cannot be nil") + } if nNat.Spec.UnderlayRoute == nil { return &api.NeighborNat{}, fmt.Errorf("underlayRoute needs to be specified") } @@ -844,7 +881,7 @@ func (c *client) ListNats(ctx context.Context, natIP *netip.Addr, natType string return &api.NatList{}, fmt.Errorf("error parsing underlay route: %w", err) } nat.Spec.UnderlayRoute = &underlayRoute - nat.Spec.NatIP = nil // "natted" IP, i.e. local NIC IP is not applicable for neighnats + nat.Spec.NatIP = nil // "natted" IP, i.e. local NIC IP is not applicable for neighnats nat.Kind = api.NeighborNatKind } else if natEntry.GetNatIp() != nil { nattedIP, err = netip.ParseAddr(string(natEntry.GetNatIp().GetAddress())) @@ -875,6 +912,9 @@ func (c *client) ListNats(ctx context.Context, natIP *netip.Addr, natType string } func (c *client) DeleteNeighborNat(ctx context.Context, neigbhorNat *api.NeighborNat, ignoredErrors ...[]uint32) (*api.NeighborNat, error) { + if neigbhorNat == nil { + return &api.NeighborNat{}, fmt.Errorf("error: input neighbor nat cannot be nil") + } res, err := c.DPDKironcoreClient.DeleteNeighborNat(ctx, &dpdkproto.DeleteNeighborNatRequest{ NatIp: api.NetIPAddrToProtoIpAddress(neigbhorNat.NatIP), Vni: neigbhorNat.Spec.Vni, @@ -930,6 +970,10 @@ func (c *client) ListFirewallRules(ctx context.Context, interfaceID string, igno } func (c *client) CreateFirewallRule(ctx context.Context, fwRule *api.FirewallRule, ignoredErrors ...[]uint32) (*api.FirewallRule, error) { + if fwRule == nil { + return &api.FirewallRule{}, fmt.Errorf("error: input firewall rule cannot be nil") + } + var action, direction uint8 switch strings.ToLower(fwRule.Spec.FirewallAction) { @@ -1109,6 +1153,9 @@ func (c *client) ResetVni(ctx context.Context, vni uint32, vniType uint8, ignore } func (c *client) GetVersion(ctx context.Context, version *api.Version, ignoredErrors ...[]uint32) (*api.Version, error) { + if version == nil { + return &api.Version{}, fmt.Errorf("error: input version cannot be nil") + } version.ClientProtocol = strings.TrimSpace(dpdkproto.GeneratedFrom) res, err := c.DPDKironcoreClient.GetVersion(ctx, &dpdkproto.GetVersionRequest{ ClientProtocol: version.ClientProtocol, @@ -1128,6 +1175,10 @@ func (c *client) GetVersion(ctx context.Context, version *api.Version, ignoredEr } func (c *client) CaptureStart(ctx context.Context, capture *api.CaptureStart, ignoredErrors ...[]uint32) (*api.CaptureStart, error) { + if capture == nil { + return &api.CaptureStart{}, fmt.Errorf("error: input capture cannot be nil") + } + var interfaces = make([]*dpdkproto.CapturedInterface, 0, len(capture.Spec.Interfaces)) for _, iface := range capture.Spec.Interfaces { diff --git a/go/dpservice-go/client/client_test.go b/go/dpservice-go/client/client_test.go index f74044f57..96c5981e1 100644 --- a/go/dpservice-go/client/client_test.go +++ b/go/dpservice-go/client/client_test.go @@ -19,7 +19,8 @@ const positiveTestVNI = uint32(500) const negativeTestIfaceID = "vm4" const negativeTestVNI = uint32(400) -var _ = Describe("interface", Label("interface"), func() { +// Positive tests (should be successful) +var _ = Describe("interface tests", Label("interface"), func() { ctx := context.TODO() Context("When using interface functions", Ordered, func() { @@ -111,7 +112,7 @@ var _ = Describe("interface", Label("interface"), func() { }) }) -var _ = Describe("interface related", func() { +var _ = Describe("interface related tests", func() { ctx := context.TODO() // Creates the network interface object @@ -555,7 +556,7 @@ var _ = Describe("interface related", func() { }) }) -var _ = Describe("loadbalancer related", func() { +var _ = Describe("loadbalancer related tests", func() { ctx := context.TODO() Context("When using loadbalancer functions", Label("loadbalancer"), Ordered, func() { @@ -608,12 +609,8 @@ var _ = Describe("loadbalancer related", func() { }) It("should list successfully", func() { - res, err := dpdkClient.ListLoadBalancers(ctx) + _, err := dpdkClient.ListLoadBalancers(ctx) Expect(err).ToNot(HaveOccurred()) - - Expect(len(res.Items)).To(Equal(1)) - Expect(res.Items[0].Spec.LbVipIP.String()).To(Equal("10.20.30.40")) - Expect(res.Items[0].Spec.Lbports[0].Port).To(Equal(uint32(443))) }) It("should delete successfully", func() { @@ -712,7 +709,7 @@ var _ = Describe("loadbalancer related", func() { }) }) -var _ = Describe("init", Label("init"), func() { +var _ = Describe("other functions tests", Label("other"), func() { ctx := context.TODO() Context("When using init functions", Ordered, func() { @@ -757,6 +754,7 @@ var _ = Describe("init", Label("init"), func() { }) }) +// Negative tests (error is expected) var _ = Describe("negative interface tests", Label("negative"), func() { ctx := context.TODO() var iface api.Interface @@ -777,6 +775,14 @@ var _ = Describe("negative interface tests", Label("negative"), func() { } }) + Context("When creating and Interface is nil", func() { + It("should not create", func() { + _, err := dpdkClient.CreateInterface(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input interface cannot be nil")) + }) + }) + Context("When creating and IPv4 is nil", func() { It("should not create", func() { iface.Spec.IPv4 = nil @@ -812,6 +818,22 @@ var _ = Describe("negative interface tests", Label("negative"), func() { Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) }) }) + + Context("When getting and ID is empty", func() { + It("should not get", func() { + _, err := dpdkClient.GetInterface(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + }) + }) + + Context("When deleting and id is empty", func() { + It("should not delete", func() { + _, err := dpdkClient.DeleteInterface(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + }) + }) }) var _ = Describe("negative interface related tests", Label("negative"), func() { @@ -848,6 +870,11 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { var err error It("should not create", func() { + By("inputting nil prefix") + res, err = dpdkClient.CreatePrefix(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input prefix cannot be nil")) + By("not defining IP prefix") prefix := api.Prefix{ PrefixMeta: api.PrefixMeta{ @@ -860,7 +887,7 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid prefix.ip")) - By("not defining InterfaceID") + By("not defining interfaceID") prefix.InterfaceID = "" prefix.Spec.Prefix = netip.MustParsePrefix("10.20.30.0/24") res, err = dpdkClient.CreatePrefix(ctx, &prefix) @@ -874,6 +901,25 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { Expect(res.InterfaceID).To(Equal("xxx")) Expect(res.Status.Code).To(Equal(uint32(errors.NO_VM))) }) + + It("should not list", func() { + By("not defining interfaceID") + _, err = dpdkClient.ListPrefixes(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + }) + + It("should not delete", func() { + By("not defining interfaceID") + res, err = dpdkClient.DeletePrefix(ctx, "", &netip.Prefix{}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + + By("inputting nil prefix") + res, err = dpdkClient.DeletePrefix(ctx, negativeTestIfaceID, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input prefix cannot be nil")) + }) }) Context("When using loadbalancerprefix functions", Label("lbprefix"), Ordered, func() { @@ -881,6 +927,11 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { var err error It("should not create", func() { + By("inputting nil loadbalancer prefix") + res, err = dpdkClient.CreateLoadBalancerPrefix(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input loadbalancer prefix cannot be nil")) + By("not defining IP prefix") lbprefix := api.LoadBalancerPrefix{ LoadBalancerPrefixMeta: api.LoadBalancerPrefixMeta{ @@ -907,6 +958,25 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { Expect(res.InterfaceID).To(Equal("xxx")) Expect(res.Status.Code).To(Equal(uint32(errors.NO_VM))) }) + + It("should not list", func() { + By("not defining interface ID") + _, err = dpdkClient.ListLoadBalancerPrefixes(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + }) + + It("should not delete", func() { + By("not defining interface ID") + _, err = dpdkClient.DeleteLoadBalancerPrefix(ctx, "", &netip.Prefix{}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + + By("inputting nil prefix") + res, err = dpdkClient.DeleteLoadBalancerPrefix(ctx, negativeTestIfaceID, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input prefix cannot be nil")) + }) }) Context("When using virtualIP functions", Label("vip"), Ordered, func() { @@ -914,6 +984,11 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { var err error It("should not create", func() { + By("inputting nil virtual IP") + res, err = dpdkClient.CreateVirtualIP(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input virtual ip cannot be nil")) + By("not defining IP") vip := api.VirtualIP{ VirtualIPMeta: api.VirtualIPMeta{ @@ -947,6 +1022,11 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { var err error It("should not create", func() { + By("inputting nil nat") + res, err = dpdkClient.CreateNat(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input nat cannot be nil")) + By("not defining port range") ip := netip.MustParseAddr("10.20.30.40") nat := api.Nat{ @@ -1000,6 +1080,13 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { Expect(res.InterfaceID).To(Equal("xxx")) Expect(res.Status.Code).To(Equal(uint32(errors.NO_VM))) }) + + It("should not list", func() { + By("not defining nat IP") + _, err = dpdkClient.ListLocalNats(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid nat_ip")) + }) }) Context("When using neighbor nat functions", Label("neighbornat"), Ordered, func() { @@ -1007,8 +1094,12 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { var err error It("should not create", func() { - By("not defining nat IP") + By("inputting nil neighbornat") + _, err = dpdkClient.CreateNeighborNat(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input neighbor nat cannot be nil")) + By("not defining nat IP") underlayRoute := netip.MustParseAddr("ff80::1") neighborNat = api.NeighborNat{ NeighborNatMeta: api.NeighborNatMeta{}, @@ -1046,6 +1137,13 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("underlayRoute needs to be specified")) }) + + It("should not delete", func() { + By("inputting nil neighbornat") + _, err = dpdkClient.DeleteNeighborNat(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input neighbor nat cannot be nil")) + }) }) Context("When using route functions", Label("route"), Ordered, func() { @@ -1054,6 +1152,11 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { var err error It("should not create", func() { + By("inputting nil route") + res, err = dpdkClient.CreateRoute(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input route cannot be nil")) + By("not defining VNI") prefix := netip.MustParsePrefix("10.100.3.0/24") nextHopIp := netip.MustParseAddr("fc00:2::64:0:1") @@ -1091,6 +1194,18 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("nextHop needs to be specified")) }) + + It("should not delete", func() { + By("using empty prefix") + res, err = dpdkClient.DeleteRoute(ctx, negativeTestVNI, &netip.Prefix{}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid route.prefix.length")) + + By("inputting nil prefix") + res, err = dpdkClient.DeleteRoute(ctx, negativeTestVNI, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input prefix cannot be nil")) + }) }) Context("When using firewall rule functions", Label("fwrule"), Ordered, func() { @@ -1098,6 +1213,11 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { var err error It("should not create", func() { + By("inputting nil firewall rule") + _, err = dpdkClient.CreateFirewallRule(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input firewall rule cannot be nil")) + By("not defining InterfaceID") src := netip.MustParsePrefix("1.1.1.1/32") dst := netip.MustParsePrefix("5.5.5.0/24") @@ -1220,6 +1340,37 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { Expect(err).To(HaveOccurred()) Expect(err.Error()).To(Equal("firewall action can be only: drop/deny/0|accept/allow/1")) }) + + It("should not list", func() { + By("not defining interface ID") + _, err = dpdkClient.ListFirewallRules(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + }) + + It("should not get", func() { + By("not defining interface ID") + _, err = dpdkClient.GetFirewallRule(ctx, "", "1") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + + By("not defining rule ID") + _, err = dpdkClient.GetFirewallRule(ctx, negativeTestIfaceID, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid rule_id")) + }) + + It("should not delete", func() { + By("not defining interface ID") + _, err = dpdkClient.DeleteFirewallRule(ctx, "", "1") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid interface_id")) + + By("not defining rule ID") + _, err = dpdkClient.DeleteFirewallRule(ctx, negativeTestIfaceID, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid rule_id")) + }) }) Context("When using capture functions", Label("capture"), Ordered, func() { @@ -1253,6 +1404,11 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { }) It("should return error", func() { + By("inputting nil capture") + _, err = dpdkClient.CaptureStart(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input capture cannot be nil")) + By("not defining sink node") _, err := dpdkClient.CaptureStart(ctx, &captureStart) @@ -1300,3 +1456,199 @@ var _ = Describe("negative interface related tests", Label("negative"), func() { }) }) }) + +var _ = Describe("negative loadbalancer related tests", Label("negative"), func() { + ctx := context.TODO() + + Context("When using loadbalancer functions", Label("loadbalancer"), Ordered, func() { + var lb *api.LoadBalancer + var res *api.LoadBalancer + var err error + + It("should not create", func() { + By("using nil loadbalancer") + _, err = dpdkClient.CreateLoadBalancer(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input loadbalancer cannot be nil")) + + var lbVipIp = netip.MustParseAddr("10.20.30.40") + lb = &api.LoadBalancer{ + LoadBalancerMeta: api.LoadBalancerMeta{ + ID: "lb1", + }, + Spec: api.LoadBalancerSpec{ + VNI: negativeTestVNI, + LbVipIP: &lbVipIp, + Lbports: []api.LBPort{ + { + Protocol: 6, + Port: 443, + }, + }, + }, + } + + By("not defining loadbalancer virtual ip") + lb.Spec.LbVipIP = nil + res, err = dpdkClient.CreateLoadBalancer(ctx, lb) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalanced_ip")) + + By("not defining ID") + lb.Spec.LbVipIP = &lbVipIp + lb.ID = "" + res, err = dpdkClient.CreateLoadBalancer(ctx, lb) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalancer_id")) + + By("defining lbport with incorrect protocol") + lb.ID = "lb1" + lb.Spec.Lbports = []api.LBPort{{Protocol: 999, Port: 443}} + res, err = dpdkClient.CreateLoadBalancer(ctx, lb) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalanced_ports.protocol")) + + By("defining lbport with incorrect port") + lb.Spec.Lbports = []api.LBPort{{Protocol: 6, Port: 90000}} + res, err = dpdkClient.CreateLoadBalancer(ctx, lb) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalanced_ports.port")) + + By("defining incorrect vni") + lb.Spec.Lbports = []api.LBPort{{Protocol: 6, Port: 443}} + lb.Spec.VNI = 999999999 + res, err = dpdkClient.CreateLoadBalancer(ctx, lb) + Expect(err).To(HaveOccurred()) + Expect(res.GetStatus().Code).To(Equal(uint32(errors.VNI_INIT4))) + }) + + It("should not get", func() { + By("not defining loadbalancer ID") + res, err = dpdkClient.GetLoadBalancer(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalancer_id")) + }) + + It("should not delete", func() { + By("not defining loadbalancer ID") + res, err = dpdkClient.DeleteLoadBalancer(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalancer_id")) + }) + }) + + Context("When using loadbalancer target functions", Label("lbtarget"), Ordered, func() { + var lbtarget api.LoadBalancerTarget + var lb api.LoadBalancer + var err error + + It("should not create", func() { + By("using nil loadbalancer target") + _, err = dpdkClient.CreateLoadBalancerTarget(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input loadbalancer target cannot be nil")) + + var lbVipIp = netip.MustParseAddr("10.20.30.40") + lb = api.LoadBalancer{ + LoadBalancerMeta: api.LoadBalancerMeta{ + ID: "lb2", + }, + Spec: api.LoadBalancerSpec{ + VNI: negativeTestVNI, + LbVipIP: &lbVipIp, + Lbports: []api.LBPort{ + { + Protocol: 6, + Port: 443, + }, + }, + }, + } + + _, err = dpdkClient.CreateLoadBalancer(ctx, &lb) + Expect(err).ToNot(HaveOccurred()) + + targetIp := netip.MustParseAddr("ff80::5") + lbtarget = api.LoadBalancerTarget{ + LoadBalancerTargetMeta: api.LoadBalancerTargetMeta{}, + Spec: api.LoadBalancerTargetSpec{ + TargetIP: &targetIp, + }, + } + + By("not defining loadbalancer ID") + _, err = dpdkClient.CreateLoadBalancerTarget(ctx, &lbtarget) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalancer_id")) + + By("not defining non-existent ID") + lbtarget.LoadbalancerID = "xxx" + _, err = dpdkClient.CreateLoadBalancerTarget(ctx, &lbtarget) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("[error code 422] NO_LB")) + + By("not defining target IP") + lbtarget.LoadbalancerID = "lb2" + lbtarget.Spec.TargetIP = nil + _, err = dpdkClient.CreateLoadBalancerTarget(ctx, &lbtarget) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid target_ip")) + + By("defining target IP as IPv4") + targetIp = netip.MustParseAddr("1.2.3.4") + lbtarget.Spec.TargetIP = &targetIp + _, err = dpdkClient.CreateLoadBalancerTarget(ctx, &lbtarget) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("[error code 204] BAD_IPVER")) + }) + + It("should not list", func() { + By("not defining loadbalancer ID") + _, err = dpdkClient.ListLoadBalancerTargets(ctx, "") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalancer_id")) + }) + + It("should not delete", func() { + By("not defining loadbalancer ID") + targetIp := netip.MustParseAddr("ff80::5") + _, err = dpdkClient.DeleteLoadBalancerTarget(ctx, "", &targetIp) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid loadbalancer_id")) + + By("inputting nil target IP") + _, err = dpdkClient.DeleteLoadBalancerTarget(ctx, "lb2", nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid target_ip")) + }) + }) + +}) + +var _ = Describe("negative other functions tests", Label("negative"), func() { + ctx := context.TODO() + + Context("When using other functions", Ordered, func() { + + It("should not get vni", func() { + By("using wrong vni type") + _, err := dpdkClient.GetVni(ctx, negativeTestVNI, 3) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid type")) + }) + + It("should not reset vni", func() { + By("using wrong vni type") + _, err := dpdkClient.ResetVni(ctx, negativeTestVNI, 3) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = InvalidArgument desc = Invalid type")) + }) + + It("should not get version", func() { + By("inputting nil version") + _, err := dpdkClient.GetVersion(ctx, nil) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("error: input version cannot be nil")) + }) + }) +}) diff --git a/go/dpservice-go/client/suite_test.go b/go/dpservice-go/client/suite_test.go index a8f4ddd91..02e171ca5 100644 --- a/go/dpservice-go/client/suite_test.go +++ b/go/dpservice-go/client/suite_test.go @@ -40,15 +40,24 @@ var _ = BeforeSuite(func() { //+kubebuilder:scaffold:scheme - // setup net-dpservice client + // setup dpservice-cli client ctxGrpc, ctxCancel = context.WithTimeout(context.Background(), 100*time.Millisecond) - conn, err := grpc.DialContext(ctxGrpc, dpserviceAddr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()) + conn, err := grpc.NewClient(dpserviceAddr, grpc.WithTransportCredentials(insecure.NewCredentials())) Expect(err).NotTo(HaveOccurred()) dpdkProtoClient = dpdkproto.NewDPDKironcoreClient(conn) dpdkClient = NewClient(dpdkProtoClient) + // running gRPC command before initialization should return error + _, err = dpdkClient.ListInterfaces(context.TODO()) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = Aborted desc = not initialized")) + + _, err = dpdkClient.GetInterface(context.TODO(), "vm1") + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("rpc error: code = Aborted desc = not initialized")) + _, err = dpdkClient.Initialize(context.TODO()) Expect(err).NotTo(HaveOccurred()) }) diff --git a/go/dpservice-go/docs/README.md b/go/dpservice-go/docs/README.md index 816e71dab..0c4330b4b 100644 --- a/go/dpservice-go/docs/README.md +++ b/go/dpservice-go/docs/README.md @@ -1,11 +1,13 @@ -# Generate bindings +# Generate gRPC bindings -To regenerate the Golang bindings run +To manually regenerate the gRPC Go bindings run: ```shell make clean generate ``` +This will generate gRPC Go files from [protofile](/proto/dpdk.proto) into proto [folder](/go/dpservice-go/proto/) + ## Usage examples Here is an example of how to integrate dpservice-go bindings in your developed applications. @@ -30,3 +32,24 @@ func main() { ... } ``` + +## Testing + +Tests are created with use of Ginkgo and Gomega frameworks. +Test cases are running in parallel and can be filtered by label. +They are split to positive and negative: positive tests are expected to be successfull, negative tests are expected to return error. + +To run the test of dpservice-go gRPC library, you need to have dpservice-bin running on the same host on port 1337 and dpservice needs to be uninitialized. +If dpservice is already initialized, tests will fail in BeforeSuite stage. When rerunning tests, dpservice needs to be restarted before each run. + +To run all tests: + +```shell +make test +``` + +To filter tests (one or more labels can be filtered): + +```shell +make test labels=,,... +```