Change:
Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: IPVS real server can't be right deleted in FakeIPVS for ipvs testing. What you expected to happen: When delete ipvs real server, we can't give the weight information, so we can't use deep equal in .
/sig network /area ipvs
/kind bug

Discussion:
import ( "fmt" <ins> "net" "strconv" </ins> utilipvs "k8s.io/kubernetes/pkg/util/ipvs" )

return fmt.Sprintf("%s:%d/%s", s.IP, s.Port, s.Protocol) } <ins> type realServerKey struct { Address net.IP Port    uint16 } func (r *realServerKey) String() string { return net.JoinHostPort(r.Address.String(), strconv.Itoa(int(r.Port))) } </ins> //NewFake creates a fake ipvs implementation - a cache store. func NewFake() *FakeIPVS { return &FakeIPVS{

} } <ins> func toRealServerKey(rs *utilipvs.RealServer) *realServerKey { return &realServerKey{ Address: rs.Address, Port:    rs.Port, } } </ins> //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 delete destination for service %v, service not found", key.String()) } dests := f.Destinations[key] <del> var i int for i = range dests { if dests[i].Equal(dest) { </del> <ins> exist := false for i := range dests { if toRealServerKey(dests[i]).String() == toRealServerKey(dest).String() { // Delete one element f.Destinations[key] = append(f.Destinations[key][:i], f.Destinations[key][i+1:]...) exist = true </ins> break } } // Not Found <del> if i >= len(f.Destinations[key]) { </del> <ins> if !exist { </ins> return fmt.Errorf("Failed to delete real server for service %v, real server not found", key.String()) } <del> // Delete one element f.Destinations[key] = append(f.Destinations[key][:i], f.Destinations[key][i+1:]...) </del> return nil }

Port:     uint16(80), Protocol: string("TCP"), } <ins> rss := []*utilipvs.RealServer{ {net.ParseIP("172.16.2.1"), 8080, 1}, {net.ParseIP("172.16.2.2"), 8080, 2}, {net.ParseIP("172.16.2.3"), 8080, 3}, } </ins> err := fake.AddVirtualServer(vs) if err != nil { t.Errorf("Fail to add virutal server, error: %v", err) } <del> // 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)) </del> <ins> // Add real server to the virtual server for i := range rss { if err = fake.AddRealServer(vs, rss[i]); err != nil { t.Errorf("Fail to add real server, error: %v", err) } </ins> } // Delete a real server of the virtual server <del> 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) </del> <ins> // Make sure any position of the list can be real deleted rssLen := len(rss) for i := range rss { // 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) != rssLen { t.Errorf("Expect %d virutal servers, got: %d", len(rss), len(list)) } rsToDel := list[i] if err = fake.DeleteRealServer(vs, rsToDel); err != nil { t.Errorf("Fail to delete real server of the virtual server, error: %v", err) } else { dests, err := fake.GetRealServers(vs) if err != nil { t.Errorf("Fail to get real servers of the virtual server, error: %v", err) } for _, dest := range dests { if toRealServerKey(dest).String() == toRealServerKey(rsToDel).String() { t.Errorf("Expect real server %q be deleted.", rsToDel.String()) } } if err = fake.AddRealServer(vs, rsToDel); err != nil { t.Errorf("Fail to add real server, error: %v", err) } } } // Test delete real server that not exist rs := &utilipvs.RealServer{ Address: net.ParseIP("172.16.2.4"), Port:    uint16(8080), Weight:  1, </ins> } <del> if len(list) != 1 { t.Errorf("Expect 1 real server, got: %d", len(list)) </del> <ins> if err = fake.DeleteRealServer(vs, rs); err == nil { t.Errorf("Delete real server that not exist, Expect error, got nil") </ins> } // Delete the virtual server err = fake.DeleteVirtualServer(vs)