Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement delete real server for fakeIPVS and add UTs #53130

Merged
merged 1 commit into from
Oct 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 10 additions & 2 deletions pkg/util/ipvs/ipvs.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ type RealServer struct {
Weight int
}

func (dest *RealServer) String() string {
return net.JoinHostPort(dest.Address.String(), strconv.Itoa(int(dest.Port)))
func (rs *RealServer) String() string {
return net.JoinHostPort(rs.Address.String(), strconv.Itoa(int(rs.Port)))
}

// Equal check the equality of real server.
// We don't use struct == since it doesn't work because of slice.
func (rs *RealServer) Equal(other *RealServer) bool {
return rs.Address.Equal(other.Address) &&
rs.Port == other.Port &&
rs.Weight == other.Weight
}
101 changes: 101 additions & 0 deletions pkg/util/ipvs/ipvs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,107 @@ func TestVirtualServerEqual(t *testing.T) {
}
}

func TestRealServerEqual(t *testing.T) {
Tests := []struct {
rsA *RealServer
rsB *RealServer
equal bool
reason string
}{
{
rsA: &RealServer{
Address: net.ParseIP("10.20.30.40"),
Port: 80,
Weight: 1,
},
rsB: &RealServer{
Address: net.ParseIP("10.20.30.41"),
Port: 80,
Weight: 1,
},
equal: false,
reason: "IPv4 address not equal",
},
{
rsA: &RealServer{
Address: net.ParseIP("2012::beef"),
Port: 80,
Weight: 1,
},
rsB: &RealServer{
Address: net.ParseIP("2017::beef"),
Port: 80,
Weight: 1,
},
equal: false,
reason: "IPv6 address not equal",
},
{
rsA: &RealServer{
Address: net.ParseIP("2012::beef"),
Port: 80,
Weight: 1,
},
rsB: &RealServer{
Address: net.ParseIP("2012::beef"),
Port: 8080,
Weight: 1,
},
equal: false,
reason: "Port not equal",
},
{
rsA: &RealServer{
Address: net.ParseIP("10.20.30.40"),
Port: 8080,
Weight: 1,
},
rsB: &RealServer{
Address: net.ParseIP("10.20.30.40"),
Port: 8080,
Weight: 10,
},
equal: false,
reason: "Weight not equal",
},
{
rsA: &RealServer{
Address: net.ParseIP("1.2.3.4"),
Port: 3080,
Weight: 10,
},
rsB: &RealServer{
Address: net.ParseIP("1.2.3.4"),
Port: 3080,
Weight: 10,
},
equal: true,
reason: "All fields equal",
},
{
rsA: &RealServer{
Address: net.ParseIP("2012::beef"),
Port: 3080,
Weight: 10,
},
rsB: &RealServer{
Address: net.ParseIP("2012::beef"),
Port: 3080,
Weight: 10,
},
equal: true,
reason: "All fields equal",
},
}

for i := range Tests {
equal := Tests[i].rsA.Equal(Tests[i].rsB)
if equal != Tests[i].equal {
t.Errorf("case: %d got %v, expected %v, reason: %s", i, equal, Tests[i].equal, Tests[i].reason)
}
}
}

func TestFrontendServiceString(t *testing.T) {
Tests := []struct {
svc *VirtualServer
Expand Down
8 changes: 8 additions & 0 deletions pkg/util/ipvs/testing/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
"go_test",
)

go_library(
Expand All @@ -23,3 +24,10 @@ filegroup(
srcs = [":package-srcs"],
tags = ["automanaged"],
)

go_test(
name = "go_default_test",
srcs = ["fake_test.go"],
library = ":go_default_library",
deps = ["//pkg/util/ipvs:go_default_library"],
)
45 changes: 31 additions & 14 deletions pkg/util/ipvs/testing/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (s *serviceKey) String() string {
return fmt.Sprintf("%s:%d/%s", s.IP, s.Port, s.Protocol)
}

//NewFake creates a fake ipvs strucuter
//NewFake creates a fake ipvs implementation - a cache store.
func NewFake() *FakeIPVS {
return &FakeIPVS{
Services: make(map[serviceKey]*utilipvs.VirtualServer),
Expand All @@ -55,20 +55,20 @@ func toServiceKey(serv *utilipvs.VirtualServer) serviceKey {
}
}

//EnsureVirtualServerAddressBind is a fake implementation
//EnsureVirtualServerAddressBind is an empty implementation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to modify the comment here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Glad to receive your feedback, @dixudx

I wrote the original comment, and I find it can be improved now. I just fix it conveniently - I don't want to raise another PR...

func (*FakeIPVS) EnsureVirtualServerAddressBind(serv *utilipvs.VirtualServer, dev string) (exist bool, err error) {
return true, nil
}

//UnbindVirtualServerAddress is a fake implementation
//UnbindVirtualServerAddress is an empty implementation
func (*FakeIPVS) UnbindVirtualServerAddress(serv *utilipvs.VirtualServer, dev string) error {
return nil
}

//AddVirtualServer is a fake implementation
//AddVirtualServer is a fake implementation, it simply adds the VirtualServer into the cache store.
func (f *FakeIPVS) AddVirtualServer(serv *utilipvs.VirtualServer) error {
if serv == nil {
return fmt.Errorf("Failed to add service: service can't be nil")
return fmt.Errorf("Failed to add virtual server, error: virtual server can't be nil")
}
key := toServiceKey(serv)
f.Services[key] = serv
Expand All @@ -77,15 +77,15 @@ func (f *FakeIPVS) AddVirtualServer(serv *utilipvs.VirtualServer) error {
return nil
}

//UpdateVirtualServer is a fake implementation
//UpdateVirtualServer is an empty implementation
func (f *FakeIPVS) UpdateVirtualServer(serv *utilipvs.VirtualServer) error {
if serv == nil {
return fmt.Errorf("Failed to update service, service can't be nil")
}
return nil
}

//DeleteVirtualServer is a fake implementation
//DeleteVirtualServer is a fake implementation, it simply deletes the VirtualServer from the cache store.
func (f *FakeIPVS) DeleteVirtualServer(serv *utilipvs.VirtualServer) error {
if serv == nil {
return fmt.Errorf("Failed to delete service: service can't be nil")
Expand All @@ -97,7 +97,7 @@ func (f *FakeIPVS) DeleteVirtualServer(serv *utilipvs.VirtualServer) error {
return nil
}

//GetVirtualServer is a fake implementation
//GetVirtualServer is a fake implementation, it tries to find a specific VirtualServer from the cache store.
func (f *FakeIPVS) GetVirtualServer(serv *utilipvs.VirtualServer) (*utilipvs.VirtualServer, error) {
if serv == nil {
return nil, fmt.Errorf("Failed to get service: service can't be nil")
Expand All @@ -110,7 +110,7 @@ func (f *FakeIPVS) GetVirtualServer(serv *utilipvs.VirtualServer) (*utilipvs.Vir
return nil, fmt.Errorf("Not found serv: %v", key.String())
}

//GetVirtualServers is a fake implementation
//GetVirtualServers is a fake implementation, it simply returns all VirtualServers in the cache store.
func (f *FakeIPVS) GetVirtualServers() ([]*utilipvs.VirtualServer, error) {
res := make([]*utilipvs.VirtualServer, 0)
for _, svc := range f.Services {
Expand All @@ -119,15 +119,15 @@ func (f *FakeIPVS) GetVirtualServers() ([]*utilipvs.VirtualServer, error) {
return res, nil
}

//Flush is a fake implementation
//Flush is a fake implementation, it simply clears the cache store.
func (f *FakeIPVS) Flush() error {
// directly drop old data
f.Services = nil
f.Destinations = nil
return nil
}

//AddRealServer is a fake implementation
//AddRealServer is a fake implementation, it simply creates a RealServer for a VirtualServer in the cache store.
func (f *FakeIPVS) AddRealServer(serv *utilipvs.VirtualServer, dest *utilipvs.RealServer) error {
if serv == nil || dest == nil {
return fmt.Errorf("Failed to add destination for service, neither service nor destination shouldn't be nil")
Expand All @@ -145,7 +145,7 @@ func (f *FakeIPVS) AddRealServer(serv *utilipvs.VirtualServer, dest *utilipvs.Re
return nil
}

//GetRealServers is a fake implementation
//GetRealServers is a fake implementation, it simply returns all RealServers in the cache store.
func (f *FakeIPVS) GetRealServers(serv *utilipvs.VirtualServer) ([]*utilipvs.RealServer, error) {
if serv == nil {
return nil, fmt.Errorf("Failed to get destination for nil service")
Expand All @@ -157,11 +157,28 @@ func (f *FakeIPVS) GetRealServers(serv *utilipvs.VirtualServer) ([]*utilipvs.Rea
return f.Destinations[key], nil
}

//DeleteRealServer is a fake implementation
func (*FakeIPVS) DeleteRealServer(serv *utilipvs.VirtualServer, dest *utilipvs.RealServer) error {
//DeleteRealServer is a fake implementation, it deletes the real server in the cache store.
func (f *FakeIPVS) DeleteRealServer(serv *utilipvs.VirtualServer, dest *utilipvs.RealServer) error {
if serv == nil || dest == nil {
return fmt.Errorf("Failed to delete destination, neither service nor destination can't be nil")
}
key := toServiceKey(serv)
if _, ok := f.Services[key]; !ok {
return fmt.Errorf("Failed to delete destination for service %v, service not found", key.String())
}
dests := f.Destinations[key]
var i int
for i = range dests {
if dests[i].Equal(dest) {
break
}
}
// Not Found
if i >= len(f.Destinations[key]) {
return fmt.Errorf("Failed to delete real server for service %v, real server not found", key.String())
}
// Delete one element
f.Destinations[key] = append(f.Destinations[key][:i], f.Destinations[key][i+1:]...)
return nil
}

Expand Down