mirror of https://github.com/k3s-io/k3s
implement delete real server for fakeIPVS and add UTs
parent
4f2d7b93da
commit
f21cf88797
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,6 +3,7 @@ package(default_visibility = ["//visibility:public"])
|
|||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_library(
|
||||
|
@ -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"],
|
||||
)
|
||||
|
|
|
@ -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),
|
||||
|
@ -55,20 +55,20 @@ func toServiceKey(serv *utilipvs.VirtualServer) serviceKey {
|
|||
}
|
||||
}
|
||||
|
||||
//EnsureVirtualServerAddressBind is a fake implementation
|
||||
//EnsureVirtualServerAddressBind is an empty implementation
|
||||
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
|
||||
|
@ -77,7 +77,7 @@ 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")
|
||||
|
@ -85,7 +85,7 @@ func (f *FakeIPVS) UpdateVirtualServer(serv *utilipvs.VirtualServer) error {
|
|||
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")
|
||||
|
@ -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")
|
||||
|
@ -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 {
|
||||
|
@ -119,7 +119,7 @@ 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
|
||||
|
@ -127,7 +127,7 @@ func (f *FakeIPVS) Flush() error {
|
|||
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")
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package testing
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
utilipvs "k8s.io/kubernetes/pkg/util/ipvs"
|
||||
)
|
||||
|
||||
func TestVirtualServer(t *testing.T) {
|
||||
// Initialize
|
||||
fake := NewFake()
|
||||
// Add a virtual server
|
||||
vs1 := &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("1.2.3.4"),
|
||||
Port: uint16(80),
|
||||
Protocol: string("TCP"),
|
||||
}
|
||||
err := fake.AddVirtualServer(vs1)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to add virutal server, error: %v", err)
|
||||
}
|
||||
// Get a specific virtual server
|
||||
got1, err := fake.GetVirtualServer(vs1)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to get virutal server, error: %v", err)
|
||||
}
|
||||
if !vs1.Equal(got1) {
|
||||
t.Errorf("Expect virtual server: %v, got: %v", vs1, got1)
|
||||
}
|
||||
// Add another virtual server
|
||||
vs2 := &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("10::40"),
|
||||
Port: uint16(8080),
|
||||
Protocol: string("UDP"),
|
||||
}
|
||||
err = fake.AddVirtualServer(vs2)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error when add virutal server, error: %v", err)
|
||||
}
|
||||
// List all virtual servers
|
||||
list, err := fake.GetVirtualServers()
|
||||
if err != nil {
|
||||
t.Errorf("Fail to list virutal servers, error: %v", err)
|
||||
}
|
||||
if len(list) != 2 {
|
||||
t.Errorf("Expect 2 virutal servers, got: %d", len(list))
|
||||
}
|
||||
// Delete a virtual server
|
||||
err = fake.DeleteVirtualServer(vs1)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to delete virutal server: %v, error: %v", vs1, err)
|
||||
}
|
||||
// Check the deleted virtual server no longer exists
|
||||
got, _ := fake.GetVirtualServer(vs1)
|
||||
if got != nil {
|
||||
t.Errorf("Expect nil, got: %v", got)
|
||||
}
|
||||
// Flush all virtual servers
|
||||
err = fake.Flush()
|
||||
if err != nil {
|
||||
t.Errorf("Fail to flush virutal servers, error: %v", err)
|
||||
}
|
||||
// List all virtual servers
|
||||
list, err = fake.GetVirtualServers()
|
||||
if err != nil {
|
||||
t.Errorf("Fail to list virutal servers, error: %v", err)
|
||||
}
|
||||
if len(list) != 0 {
|
||||
t.Errorf("Expect 0 virutal servers, got: %d", len(list))
|
||||
}
|
||||
}
|
||||
|
||||
func TestRealServer(t *testing.T) {
|
||||
// Initialize
|
||||
fake := NewFake()
|
||||
// Add a virtual server
|
||||
vs := &utilipvs.VirtualServer{
|
||||
Address: net.ParseIP("10.20.30.40"),
|
||||
Port: uint16(80),
|
||||
Protocol: string("TCP"),
|
||||
}
|
||||
err := fake.AddVirtualServer(vs)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to add virutal server, error: %v", err)
|
||||
}
|
||||
// Add a real server to the virtual server
|
||||
rs1 := &utilipvs.RealServer{
|
||||
Address: net.ParseIP("172.16.2.1"),
|
||||
Port: uint16(8080),
|
||||
Weight: 1,
|
||||
}
|
||||
err = fake.AddRealServer(vs, rs1)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to add real server, error: %v", err)
|
||||
}
|
||||
// Add another real server to the virtual server
|
||||
rs2 := &utilipvs.RealServer{
|
||||
Address: net.ParseIP("172.16.3.2"),
|
||||
Port: uint16(8080),
|
||||
Weight: 2,
|
||||
}
|
||||
err = fake.AddRealServer(vs, rs2)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to add real server, error: %v", err)
|
||||
}
|
||||
// List all real servers of the virtual server
|
||||
list, err := fake.GetRealServers(vs)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to get real servers of the virtual server, error: %v", err)
|
||||
}
|
||||
if len(list) != 2 {
|
||||
t.Errorf("Expect 2 virutal servers, got: %d", len(list))
|
||||
}
|
||||
// Delete a real server of the virtual server
|
||||
err = fake.DeleteRealServer(vs, rs2)
|
||||
list, err = fake.GetRealServers(vs)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to get real servers of the virtual server, error: %v", err)
|
||||
}
|
||||
if len(list) != 1 {
|
||||
t.Errorf("Expect 1 real server, got: %d", len(list))
|
||||
}
|
||||
// Delete the virtual server
|
||||
err = fake.DeleteVirtualServer(vs)
|
||||
if err != nil {
|
||||
t.Errorf("Fail to delete virtual server, error: %v", err)
|
||||
}
|
||||
_, err = fake.GetRealServers(vs)
|
||||
if err == nil {
|
||||
t.Errorf("Expect error, got nil")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue