Merge pull request #80779 from andrewsykim/ipvs-test-tables

proxy/ipvs: refactor IPVS unit tests TestClusterIP and TestNodePort to use test tables
This commit is contained in:
Kubernetes Prow Robot
2019-08-13 07:55:42 -07:00
committed by GitHub

View File

@@ -414,365 +414,474 @@ func TestGetNodeIPs(t *testing.T) {
} }
} }
func TestNodePortUDP(t *testing.T) { func TestNodePort(t *testing.T) {
nodeIP := net.ParseIP("100.101.102.103") tests := []struct {
ipt := iptablestest.NewFake() name string
ipvs := ipvstest.NewFake() services []*v1.Service
ipset := ipsettest.NewFake(testIPSetVersion) endpoints []*v1.Endpoints
fp := NewFakeProxier(ipt, ipvs, ipset, []net.IP{nodeIP}, nil) nodeIPs []net.IP
nodePortAddresses []string
svcIP := "10.20.30.41" expectedIPVS *ipvstest.FakeIPVS
svcPort := 80 expectedIPSets netlinktest.ExpectedIPSet
svcNodePort := 3001 expectedIptablesChains netlinktest.ExpectedIptablesChain
svcPortName := proxy.ServicePortName{ }{
NamespacedName: makeNSN("ns1", "svc1"), {
Port: "p80", name: "1 service with node port, has 2 endpoints",
} services: []*v1.Service{
makeTestService("ns1", "svc1", func(svc *v1.Service) {
makeServiceMap(fp,
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
svc.Spec.Type = "NodePort" svc.Spec.Type = "NodePort"
svc.Spec.ClusterIP = svcIP svc.Spec.ClusterIP = "10.20.30.41"
svc.Spec.Ports = []v1.ServicePort{{ svc.Spec.Ports = []v1.ServicePort{{
Name: svcPortName.Port, Name: "p80",
Port: int32(svcPort), Port: int32(80),
Protocol: v1.ProtocolUDP, Protocol: v1.ProtocolTCP,
NodePort: int32(svcNodePort), NodePort: int32(3001),
}} }}
}), }),
) },
epIP := "10.180.0.1" endpoints: []*v1.Endpoints{
makeEndpointsMap(fp, makeTestEndpoints("ns1", "svc1", func(ept *v1.Endpoints) {
makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *v1.Endpoints) {
ept.Subsets = []v1.EndpointSubset{{ ept.Subsets = []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{ Addresses: []v1.EndpointAddress{{
IP: epIP, IP: "10.180.0.1",
}, {
IP: "1002:ab8::2:10",
}}, }},
Ports: []v1.EndpointPort{{ Ports: []v1.EndpointPort{{
Name: svcPortName.Port, Name: "p80",
Port: int32(svcPort), Port: int32(80),
}}, }},
}} }}
}), }),
) },
nodeIPs: []net.IP{
fp.nodePortAddresses = []string{"0.0.0.0/0"} net.ParseIP("100.101.102.103"),
fp.syncProxyRules() net.ParseIP("2001:db8::1:1"),
},
// Check ipvs service and destinations nodePortAddresses: []string{},
epVS := &netlinktest.ExpectedVirtualServer{ expectedIPVS: &ipvstest.FakeIPVS{
VSNum: 2, IP: nodeIP.String(), Port: uint16(svcNodePort), Protocol: string(v1.ProtocolTCP), Services: map[ipvstest.ServiceKey]*utilipvs.VirtualServer{
RS: []netlinktest.ExpectedRealServer{{ {
IP: epIP, Port: uint16(svcPort), IP: "10.20.30.41",
}}} Port: 80,
checkIPVS(t, fp, epVS) Protocol: "TCP",
}: {
// check ipSet rules Address: net.ParseIP("10.20.30.41"),
epIPSet := netlinktest.ExpectedIPSet{ Protocol: "TCP",
Port: uint16(80),
Scheduler: "rr",
},
{
IP: "100.101.102.103",
Port: 3001,
Protocol: "TCP",
}: {
Address: net.ParseIP("100.101.102.103"),
Protocol: "TCP",
Port: uint16(3001),
Scheduler: "rr",
},
{
IP: "2001:db8::1:1",
Port: 3001,
Protocol: "TCP",
}: {
Address: net.ParseIP("2001:db8::1:1"),
Protocol: "TCP",
Port: uint16(3001),
Scheduler: "rr",
},
},
Destinations: map[ipvstest.ServiceKey][]*utilipvs.RealServer{
{
IP: "10.20.30.41",
Port: 80,
Protocol: "TCP",
}: {
{
Address: net.ParseIP("10.180.0.1"),
Port: uint16(80),
Weight: 1,
},
{
Address: net.ParseIP("1002:ab8::2:10"),
Port: uint16(80),
Weight: 1,
},
},
{
IP: "100.101.102.103",
Port: 3001,
Protocol: "TCP",
}: {
{
Address: net.ParseIP("10.180.0.1"),
Port: uint16(80),
Weight: 1,
},
{
Address: net.ParseIP("1002:ab8::2:10"),
Port: uint16(80),
Weight: 1,
},
},
{
IP: "2001:db8::1:1",
Port: 3001,
Protocol: "TCP",
}: {
{
Address: net.ParseIP("10.180.0.1"),
Port: uint16(80),
Weight: 1,
},
{
Address: net.ParseIP("1002:ab8::2:10"),
Port: uint16(80),
Weight: 1,
},
},
},
},
},
{
name: "1 UDP service with node port, has endpoints",
services: []*v1.Service{
makeTestService("ns1", "svc1", func(svc *v1.Service) {
svc.Spec.Type = "NodePort"
svc.Spec.ClusterIP = "10.20.30.41"
svc.Spec.Ports = []v1.ServicePort{{
Name: "p80",
Port: int32(80),
Protocol: v1.ProtocolUDP,
NodePort: int32(3001),
}}
}),
},
endpoints: []*v1.Endpoints{
makeTestEndpoints("ns1", "svc1", func(ept *v1.Endpoints) {
ept.Subsets = []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{
IP: "10.180.0.1",
}},
Ports: []v1.EndpointPort{{
Name: "p80",
Port: int32(80),
}},
}}
}),
},
nodeIPs: []net.IP{
net.ParseIP("100.101.102.103"),
},
nodePortAddresses: []string{"0.0.0.0/0"},
expectedIPVS: &ipvstest.FakeIPVS{
Services: map[ipvstest.ServiceKey]*utilipvs.VirtualServer{
{
IP: "10.20.30.41",
Port: 80,
Protocol: "UDP",
}: {
Address: net.ParseIP("10.20.30.41"),
Protocol: "UDP",
Port: uint16(80),
Scheduler: "rr",
},
{
IP: "100.101.102.103",
Port: 3001,
Protocol: "UDP",
}: {
Address: net.ParseIP("100.101.102.103"),
Protocol: "UDP",
Port: uint16(3001),
Scheduler: "rr",
},
},
Destinations: map[ipvstest.ServiceKey][]*utilipvs.RealServer{
{
IP: "10.20.30.41",
Port: 80,
Protocol: "UDP",
}: {
{
Address: net.ParseIP("10.180.0.1"),
Port: uint16(80),
Weight: 1,
},
},
{
IP: "100.101.102.103",
Port: 3001,
Protocol: "UDP",
}: {
{
Address: net.ParseIP("10.180.0.1"),
Port: uint16(80),
Weight: 1,
},
},
},
},
expectedIPSets: netlinktest.ExpectedIPSet{
kubeNodePortSetUDP: {{ kubeNodePortSetUDP: {{
Port: svcNodePort, Port: 3001,
Protocol: strings.ToLower(string(v1.ProtocolUDP)), Protocol: strings.ToLower(string(v1.ProtocolUDP)),
SetType: utilipset.BitmapPort, SetType: utilipset.BitmapPort,
}}, }},
} },
checkIPSet(t, fp, epIPSet) expectedIptablesChains: netlinktest.ExpectedIptablesChain{
// Check iptables chain and rules
epIpt := netlinktest.ExpectedIptablesChain{
string(KubeNodePortChain): {{ string(KubeNodePortChain): {{
JumpChain: string(KubeMarkMasqChain), MatchSet: kubeNodePortSetUDP, JumpChain: string(KubeMarkMasqChain), MatchSet: kubeNodePortSetUDP,
}}, }},
string(kubeServicesChain): {{ string(kubeServicesChain): {{
JumpChain: string(KubeNodePortChain), MatchSet: "", JumpChain: string(KubeNodePortChain), MatchSet: "",
}}, }},
} },
checkIptables(t, ipt, epIpt) },
} {
name: "service has node port but no endpoints",
func TestNodePort(t *testing.T) { services: []*v1.Service{
ipt := iptablestest.NewFake() makeTestService("ns1", "svc1", func(svc *v1.Service) {
ipvs := ipvstest.NewFake()
ipset := ipsettest.NewFake(testIPSetVersion)
nodeIPv4 := net.ParseIP("100.101.102.103")
nodeIPv6 := net.ParseIP("2001:db8::1:1")
nodeIPs := sets.NewString(nodeIPv4.String(), nodeIPv6.String())
fp := NewFakeProxier(ipt, ipvs, ipset, []net.IP{nodeIPv4, nodeIPv6}, nil)
svcIP := "10.20.30.41"
svcPort := 80
svcNodePort := 3001
svcPortName := proxy.ServicePortName{
NamespacedName: makeNSN("ns1", "svc1"),
Port: "p80",
}
makeServiceMap(fp,
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) {
svc.Spec.Type = "NodePort" svc.Spec.Type = "NodePort"
svc.Spec.ClusterIP = svcIP svc.Spec.ClusterIP = "10.20.30.41"
svc.Spec.Ports = []v1.ServicePort{{ svc.Spec.Ports = []v1.ServicePort{{
Name: svcPortName.Port, Name: "p80",
Port: int32(svcPort), Port: int32(80),
Protocol: v1.ProtocolTCP, Protocol: v1.ProtocolTCP,
NodePort: int32(svcNodePort), NodePort: int32(3001),
}} }}
}), }),
) },
epIPv4 := "10.180.0.1" endpoints: []*v1.Endpoints{},
epIPv6 := "1002:ab8::2:10" nodeIPs: []net.IP{
epIPs := sets.NewString(epIPv4, epIPv6) net.ParseIP("100.101.102.103"),
makeEndpointsMap(fp, },
makeTestEndpoints(svcPortName.Namespace, svcPortName.Name, func(ept *v1.Endpoints) { nodePortAddresses: []string{},
ept.Subsets = []v1.EndpointSubset{{ expectedIPVS: &ipvstest.FakeIPVS{
Addresses: []v1.EndpointAddress{{ Services: map[ipvstest.ServiceKey]*utilipvs.VirtualServer{
IP: epIPv4, {
}, { IP: "10.20.30.41",
IP: epIPv6, Port: 80,
}}, Protocol: "TCP",
Ports: []v1.EndpointPort{{ }: {
Name: svcPortName.Port, Address: net.ParseIP("10.20.30.41"),
Port: int32(svcPort), Protocol: "TCP",
}}, Port: uint16(80),
}} Scheduler: "rr",
}), },
) {
IP: "100.101.102.103",
fp.nodePortAddresses = []string{"0.0.0.0/0"} Port: 3001,
Protocol: "TCP",
fp.syncProxyRules() }: {
Address: net.ParseIP("100.101.102.103"),
// Check ipvs service and destinations Protocol: "TCP",
services, err := ipvs.GetVirtualServers() Port: uint16(3001),
if err != nil { Scheduler: "rr",
t.Errorf("Failed to get ipvs services, err: %v", err) },
} },
if len(services) != 3 { Destinations: map[ipvstest.ServiceKey][]*utilipvs.RealServer{
t.Errorf("Expect 3 ipvs services, got %d", len(services)) {
} IP: "10.20.30.41",
found := false Port: 80,
for _, svc := range services { Protocol: "TCP",
if nodeIPs.Has(svc.Address.String()) && svc.Port == uint16(svcNodePort) && svc.Protocol == string(v1.ProtocolTCP) { }: {}, // no real servers corresponding to no endpoints
found = true {
destinations, err := ipvs.GetRealServers(svc) IP: "100.101.102.103",
if err != nil { Port: 3001,
t.Errorf("Failed to get ipvs destinations, err: %v", err) Protocol: "TCP",
} }: {}, // no real servers corresponding to no endpoints
for _, dest := range destinations { },
if !epIPs.Has(dest.Address.String()) || dest.Port != uint16(svcPort) { },
t.Errorf("service Endpoint mismatch ipvs service destination") },
}
}
break
}
}
if !found {
t.Errorf("Expect node port type service, got none")
}
} }
func TestNodePortNoEndpoint(t *testing.T) { for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ipt := iptablestest.NewFake() ipt := iptablestest.NewFake()
ipvs := ipvstest.NewFake() ipvs := ipvstest.NewFake()
ipset := ipsettest.NewFake(testIPSetVersion) ipset := ipsettest.NewFake(testIPSetVersion)
nodeIP := net.ParseIP("100.101.102.103") fp := NewFakeProxier(ipt, ipvs, ipset, test.nodeIPs, nil)
fp := NewFakeProxier(ipt, ipvs, ipset, []net.IP{nodeIP}, nil) fp.nodePortAddresses = test.nodePortAddresses
svcIP := "10.20.30.41"
svcPort := 80
svcNodePort := 3001
svcPortName := proxy.ServicePortName{
NamespacedName: makeNSN("ns1", "svc1"),
Port: "p80",
}
makeServiceMap(fp, makeServiceMap(fp, test.services...)
makeTestService(svcPortName.Namespace, svcPortName.Name, func(svc *v1.Service) { makeEndpointsMap(fp, test.endpoints...)
svc.Spec.Type = "NodePort"
svc.Spec.ClusterIP = svcIP
svc.Spec.Ports = []v1.ServicePort{{
Name: svcPortName.Port,
Port: int32(svcPort),
Protocol: v1.ProtocolTCP,
NodePort: int32(svcNodePort),
}}
}),
)
makeEndpointsMap(fp)
fp.nodePortAddresses = []string{"0.0.0.0/0"}
fp.syncProxyRules() fp.syncProxyRules()
// Check ipvs service and destinations if !reflect.DeepEqual(ipvs, test.expectedIPVS) {
services, err := ipvs.GetVirtualServers() t.Logf("actual ipvs state: %v", ipvs)
if err != nil { t.Logf("expected ipvs state: %v", test.expectedIPVS)
t.Errorf("Failed to get ipvs services, err: %v", err) t.Errorf("unexpected IPVS state")
}
if len(services) != 2 {
t.Errorf("Expect 2 ipvs services, got %d", len(services))
}
found := false
for _, svc := range services {
if svc.Address.Equal(nodeIP) && svc.Port == uint16(svcNodePort) && svc.Protocol == string(v1.ProtocolTCP) {
found = true
destinations, _ := ipvs.GetRealServers(svc)
if len(destinations) != 0 {
t.Errorf("Unexpected %d destinations, expect 0 destinations", len(destinations))
}
break
}
}
if !found {
t.Errorf("Expect node port type service, got none")
}
} }
func TestClusterIPNoEndpoint(t *testing.T) { if test.expectedIPSets != nil {
ipt := iptablestest.NewFake() checkIPSet(t, fp, test.expectedIPSets)
ipvs := ipvstest.NewFake()
ipset := ipsettest.NewFake(testIPSetVersion)
fp := NewFakeProxier(ipt, ipvs, ipset, nil, nil)
svcIP := "10.20.30.41"
svcPort := 80
svcPortName := proxy.ServicePortName{
NamespacedName: makeNSN("ns1", "svc1"),
Port: "p80",
} }
makeServiceMap(fp, if test.expectedIptablesChains != nil {
makeTestService(svcPortName.Namespace, svcPortName.Namespace, func(svc *v1.Service) { checkIptables(t, ipt, test.expectedIptablesChains)
svc.Spec.ClusterIP = svcIP
svc.Spec.Ports = []v1.ServicePort{{
Name: svcPortName.Port,
Port: int32(svcPort),
Protocol: v1.ProtocolTCP,
}}
}),
)
makeEndpointsMap(fp)
fp.syncProxyRules()
// check ipvs service and destinations
services, err := ipvs.GetVirtualServers()
if err != nil {
t.Errorf("Failed to get ipvs services, err: %v", err)
}
if len(services) != 1 {
t.Errorf("Expect 1 ipvs services, got %d", len(services))
} else {
if services[0].Address.String() != svcIP || services[0].Port != uint16(svcPort) || services[0].Protocol != string(v1.ProtocolTCP) {
t.Errorf("Unexpected mismatch service")
} else {
destinations, _ := ipvs.GetRealServers(services[0])
if len(destinations) != 0 {
t.Errorf("Unexpected %d destinations, expect 0 destinations", len(destinations))
}
} }
})
} }
} }
func TestClusterIP(t *testing.T) { func TestClusterIP(t *testing.T) {
tests := []struct {
name string
services []*v1.Service
endpoints []*v1.Endpoints
expectedIPVS *ipvstest.FakeIPVS
}{
{
name: "2 services with Cluster IP, each with endpoints",
services: []*v1.Service{
makeTestService("ns1", "svc1", func(svc *v1.Service) {
svc.Spec.ClusterIP = "10.20.30.41"
svc.Spec.Ports = []v1.ServicePort{{
Name: "p80",
Port: int32(80),
Protocol: v1.ProtocolTCP,
}}
}),
makeTestService("ns2", "svc2", func(svc *v1.Service) {
svc.Spec.ClusterIP = "1002:ab8::2:1"
svc.Spec.Ports = []v1.ServicePort{{
Name: "p8080",
Port: int32(8080),
Protocol: v1.ProtocolTCP,
}}
}),
},
endpoints: []*v1.Endpoints{
makeTestEndpoints("ns1", "svc1", func(ept *v1.Endpoints) {
ept.Subsets = []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{
IP: "10.180.0.1",
}},
Ports: []v1.EndpointPort{{
Name: "p80",
Port: int32(80),
}},
}}
}),
makeTestEndpoints("ns2", "svc2", func(ept *v1.Endpoints) {
ept.Subsets = []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{
IP: "1009:ab8::5:6",
}},
Ports: []v1.EndpointPort{{
Name: "p8080",
Port: int32(8080),
}},
}}
}),
},
expectedIPVS: &ipvstest.FakeIPVS{
Services: map[ipvstest.ServiceKey]*utilipvs.VirtualServer{
{
IP: "10.20.30.41",
Port: 80,
Protocol: "TCP",
}: {
Address: net.ParseIP("10.20.30.41"),
Protocol: "TCP",
Port: uint16(80),
Scheduler: "rr",
},
{
IP: "1002:ab8::2:1",
Port: 8080,
Protocol: "TCP",
}: {
Address: net.ParseIP("1002:ab8::2:1"),
Protocol: "TCP",
Port: uint16(8080),
Scheduler: "rr",
},
},
Destinations: map[ipvstest.ServiceKey][]*utilipvs.RealServer{
{
IP: "10.20.30.41",
Port: 80,
Protocol: "TCP",
}: {
{
Address: net.ParseIP("10.180.0.1"),
Port: uint16(80),
Weight: 1,
},
},
{
IP: "1002:ab8::2:1",
Port: 8080,
Protocol: "TCP",
}: {
{
Address: net.ParseIP("1009:ab8::5:6"),
Port: uint16(8080),
Weight: 1,
},
},
},
},
},
{
name: "cluster IP service with no endpoints",
services: []*v1.Service{
makeTestService("ns1", "svc1", func(svc *v1.Service) {
svc.Spec.ClusterIP = "10.20.30.41"
svc.Spec.Ports = []v1.ServicePort{{
Name: "p80",
Port: int32(80),
Protocol: v1.ProtocolTCP,
}}
}),
},
endpoints: []*v1.Endpoints{},
expectedIPVS: &ipvstest.FakeIPVS{
Services: map[ipvstest.ServiceKey]*utilipvs.VirtualServer{
{
IP: "10.20.30.41",
Port: 80,
Protocol: "TCP",
}: {
Address: net.ParseIP("10.20.30.41"),
Protocol: "TCP",
Port: uint16(80),
Scheduler: "rr",
},
},
Destinations: map[ipvstest.ServiceKey][]*utilipvs.RealServer{
{
IP: "10.20.30.41",
Port: 80,
Protocol: "TCP",
}: {},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ipt := iptablestest.NewFake() ipt := iptablestest.NewFake()
ipvs := ipvstest.NewFake() ipvs := ipvstest.NewFake()
ipset := ipsettest.NewFake(testIPSetVersion) ipset := ipsettest.NewFake(testIPSetVersion)
fp := NewFakeProxier(ipt, ipvs, ipset, nil, nil) fp := NewFakeProxier(ipt, ipvs, ipset, nil, nil)
svcIPv4 := "10.20.30.41" makeServiceMap(fp, test.services...)
svcPortV4 := 80 makeEndpointsMap(fp, test.endpoints...)
svcPortNameV4 := proxy.ServicePortName{
NamespacedName: makeNSN("ns1", "svc1"),
Port: "p80",
}
svcIPv6 := "1002:ab8::2:1"
svcPortV6 := 8080
svcPortNameV6 := proxy.ServicePortName{
NamespacedName: makeNSN("ns2", "svc2"),
Port: "p8080",
}
makeServiceMap(fp,
makeTestService(svcPortNameV4.Namespace, svcPortNameV4.Name, func(svc *v1.Service) {
svc.Spec.ClusterIP = svcIPv4
svc.Spec.Ports = []v1.ServicePort{{
Name: svcPortNameV4.Port,
Port: int32(svcPortV4),
Protocol: v1.ProtocolTCP,
}}
}),
makeTestService(svcPortNameV6.Namespace, svcPortNameV6.Name, func(svc *v1.Service) {
svc.Spec.ClusterIP = svcIPv6
svc.Spec.Ports = []v1.ServicePort{{
Name: svcPortNameV6.Port,
Port: int32(svcPortV6),
Protocol: v1.ProtocolTCP,
}}
}),
)
epIPv4 := "10.180.0.1"
epIPv6 := "1009:ab8::5:6"
makeEndpointsMap(fp,
makeTestEndpoints(svcPortNameV4.Namespace, svcPortNameV4.Name, func(ept *v1.Endpoints) {
ept.Subsets = []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{
IP: epIPv4,
}},
Ports: []v1.EndpointPort{{
Name: svcPortNameV4.Port,
Port: int32(svcPortV4),
}},
}}
}),
makeTestEndpoints(svcPortNameV6.Namespace, svcPortNameV6.Name, func(ept *v1.Endpoints) {
ept.Subsets = []v1.EndpointSubset{{
Addresses: []v1.EndpointAddress{{
IP: epIPv6,
}},
Ports: []v1.EndpointPort{{
Name: svcPortNameV6.Port,
Port: int32(svcPortV6),
}},
}}
}),
)
fp.syncProxyRules() fp.syncProxyRules()
// check ipvs service and destinations if !reflect.DeepEqual(ipvs, test.expectedIPVS) {
services, err := ipvs.GetVirtualServers() t.Logf("actual ipvs state: %v", ipvs)
if err != nil { t.Logf("expected ipvs state: %v", test.expectedIPVS)
t.Errorf("Failed to get ipvs services, err: %v", err) t.Errorf("unexpected IPVS state")
}
if len(services) != 2 {
t.Errorf("Expect 2 ipvs services, got %d", len(services))
}
for i := range services {
// Check services
if services[i].Address.String() == svcIPv4 {
if services[i].Port != uint16(svcPortV4) || services[i].Protocol != string(v1.ProtocolTCP) {
t.Errorf("Unexpected mismatch service")
}
// Check destinations
destinations, _ := ipvs.GetRealServers(services[i])
if len(destinations) != 1 {
t.Errorf("Expected 1 destinations, got %d destinations", len(destinations))
continue
}
if destinations[0].Address.String() != epIPv4 || destinations[0].Port != uint16(svcPortV4) {
t.Errorf("Unexpected mismatch destinations")
}
}
if services[i].Address.String() == svcIPv6 {
if services[i].Port != uint16(svcPortV6) || services[i].Protocol != string(v1.ProtocolTCP) {
t.Errorf("Unexpected mismatch service")
}
// Check destinations
destinations, _ := ipvs.GetRealServers(services[i])
if len(destinations) != 1 {
t.Errorf("Expected 1 destinations, got %d destinations", len(destinations))
continue
}
if destinations[0].Address.String() != epIPv6 || destinations[0].Port != uint16(svcPortV6) {
t.Errorf("Unexpected mismatch destinations")
}
} }
})
} }
} }