[kube-proxy] Unit test for unmatched IP version

This commit is contained in:
Zihong Zheng 2018-02-19 17:50:34 -08:00
parent 95cde4fb98
commit 06064498de
2 changed files with 407 additions and 161 deletions

View File

@ -133,183 +133,259 @@ func makeTestEndpoints(namespace, name string, eptFunc func(*api.Endpoints)) *ap
func TestEndpointsToEndpointsMap(t *testing.T) { func TestEndpointsToEndpointsMap(t *testing.T) {
epTracker := NewEndpointChangeTracker("test-hostname", nil, nil, nil) epTracker := NewEndpointChangeTracker("test-hostname", nil, nil, nil)
trueVal := true
falseVal := false
testCases := []struct { testCases := []struct {
desc string
newEndpoints *api.Endpoints newEndpoints *api.Endpoints
expected map[ServicePortName][]*EndpointInfoCommon expected map[ServicePortName][]*EndpointInfoCommon
}{{ isIPv6Mode *bool
// Case[0]: nothing }{
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {}), {
expected: map[ServicePortName][]*EndpointInfoCommon{}, desc: "nothing",
}, { newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {}),
// Case[1]: no changes, unnamed port expected: map[ServicePortName][]*EndpointInfoCommon{},
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) { },
ept.Subsets = []api.EndpointSubset{ {
{ desc: "no changes, unnamed port",
Addresses: []api.EndpointAddress{{ newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
IP: "1.1.1.1", ept.Subsets = []api.EndpointSubset{
}}, {
Ports: []api.EndpointPort{{ Addresses: []api.EndpointAddress{{
Name: "", IP: "1.1.1.1",
Port: 11, }},
}}, Ports: []api.EndpointPort{{
Name: "",
Port: 11,
}},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", ""): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", ""): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}, },
}, { {
// Case[2]: no changes, named port desc: "no changes, named port",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) { newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
ept.Subsets = []api.EndpointSubset{ ept.Subsets = []api.EndpointSubset{
{ {
Addresses: []api.EndpointAddress{{ Addresses: []api.EndpointAddress{{
IP: "1.1.1.1", IP: "1.1.1.1",
}}, }},
Ports: []api.EndpointPort{{ Ports: []api.EndpointPort{{
Name: "port", Name: "port",
Port: 11, Port: 11,
}}, }},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "port"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "port"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}, },
}, { {
// Case[3]: new port desc: "new port",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) { newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
ept.Subsets = []api.EndpointSubset{ ept.Subsets = []api.EndpointSubset{
{ {
Addresses: []api.EndpointAddress{{ Addresses: []api.EndpointAddress{{
IP: "1.1.1.1", IP: "1.1.1.1",
}}, }},
Ports: []api.EndpointPort{{ Ports: []api.EndpointPort{{
Port: 11, Port: 11,
}}, }},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", ""): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", ""): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}, },
}, { {
// Case[4]: remove port desc: "remove port",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {}), newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {}),
expected: map[ServicePortName][]*EndpointInfoCommon{}, expected: map[ServicePortName][]*EndpointInfoCommon{},
}, { },
// Case[5]: new IP and port {
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) { desc: "new IP and port",
ept.Subsets = []api.EndpointSubset{ newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
{ ept.Subsets = []api.EndpointSubset{
Addresses: []api.EndpointAddress{{ {
IP: "1.1.1.1", Addresses: []api.EndpointAddress{{
}, { IP: "1.1.1.1",
IP: "2.2.2.2", }, {
}}, IP: "2.2.2.2",
Ports: []api.EndpointPort{{ }},
Name: "p1", Ports: []api.EndpointPort{{
Port: 11, Name: "p1",
}, { Port: 11,
Name: "p2", }, {
Port: 22, Name: "p2",
}}, Port: 22,
}},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
{Endpoint: "2.2.2.2:11", IsLocal: false},
},
makeServicePortName("ns1", "ep1", "p2"): {
{Endpoint: "1.1.1.1:22", IsLocal: false},
{Endpoint: "2.2.2.2:22", IsLocal: false},
}, },
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
{Endpoint: "2.2.2.2:11", IsLocal: false},
},
makeServicePortName("ns1", "ep1", "p2"): {
{Endpoint: "1.1.1.1:22", IsLocal: false},
{Endpoint: "2.2.2.2:22", IsLocal: false},
}, },
}, },
}, { {
// Case[6]: remove IP and port desc: "remove IP and port",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) { newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
ept.Subsets = []api.EndpointSubset{ ept.Subsets = []api.EndpointSubset{
{ {
Addresses: []api.EndpointAddress{{ Addresses: []api.EndpointAddress{{
IP: "1.1.1.1", IP: "1.1.1.1",
}}, }},
Ports: []api.EndpointPort{{ Ports: []api.EndpointPort{{
Name: "p1", Name: "p1",
Port: 11, Port: 11,
}}, }},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}, },
}, { {
// Case[7]: rename port desc: "rename port",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) { newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
ept.Subsets = []api.EndpointSubset{ ept.Subsets = []api.EndpointSubset{
{ {
Addresses: []api.EndpointAddress{{ Addresses: []api.EndpointAddress{{
IP: "1.1.1.1", IP: "1.1.1.1",
}}, }},
Ports: []api.EndpointPort{{ Ports: []api.EndpointPort{{
Name: "p2", Name: "p2",
Port: 11, Port: 11,
}}, }},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p2"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p2"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
}, },
}, },
}, { {
// Case[8]: renumber port desc: "renumber port",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) { newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
ept.Subsets = []api.EndpointSubset{ ept.Subsets = []api.EndpointSubset{
{ {
Addresses: []api.EndpointAddress{{ Addresses: []api.EndpointAddress{{
IP: "1.1.1.1", IP: "1.1.1.1",
}}, }},
Ports: []api.EndpointPort{{ Ports: []api.EndpointPort{{
Name: "p1", Name: "p1",
Port: 22, Port: 22,
}}, }},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "1.1.1.1:22", IsLocal: false},
}, },
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "1.1.1.1:22", IsLocal: false},
}, },
}, },
}} {
desc: "should omit IPv6 address in IPv4 mode",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
ept.Subsets = []api.EndpointSubset{
{
Addresses: []api.EndpointAddress{{
IP: "1.1.1.1",
}, {
IP: "2001:db8:85a3:0:0:8a2e:370:7334",
}},
Ports: []api.EndpointPort{{
Name: "p1",
Port: 11,
}, {
Name: "p2",
Port: 22,
}},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "1.1.1.1:11", IsLocal: false},
},
makeServicePortName("ns1", "ep1", "p2"): {
{Endpoint: "1.1.1.1:22", IsLocal: false},
},
},
isIPv6Mode: &falseVal,
},
{
desc: "should omit IPv4 address in IPv6 mode",
newEndpoints: makeTestEndpoints("ns1", "ep1", func(ept *api.Endpoints) {
ept.Subsets = []api.EndpointSubset{
{
Addresses: []api.EndpointAddress{{
IP: "1.1.1.1",
}, {
IP: "2001:db8:85a3:0:0:8a2e:370:7334",
}},
Ports: []api.EndpointPort{{
Name: "p1",
Port: 11,
}, {
Name: "p2",
Port: 22,
}},
},
}
}),
expected: map[ServicePortName][]*EndpointInfoCommon{
makeServicePortName("ns1", "ep1", "p1"): {
{Endpoint: "[2001:db8:85a3:0:0:8a2e:370:7334]:11", IsLocal: false},
},
makeServicePortName("ns1", "ep1", "p2"): {
{Endpoint: "[2001:db8:85a3:0:0:8a2e:370:7334]:22", IsLocal: false},
},
},
isIPv6Mode: &trueVal,
},
}
for tci, tc := range testCases { for _, tc := range testCases {
epTracker.isIPv6Mode = tc.isIPv6Mode
// outputs // outputs
newEndpoints := epTracker.endpointsToEndpointsMap(tc.newEndpoints) newEndpoints := epTracker.endpointsToEndpointsMap(tc.newEndpoints)
if len(newEndpoints) != len(tc.expected) { if len(newEndpoints) != len(tc.expected) {
t.Errorf("[%d] expected %d new, got %d: %v", tci, len(tc.expected), len(newEndpoints), spew.Sdump(newEndpoints)) t.Errorf("[%s] expected %d new, got %d: %v", tc.desc, len(tc.expected), len(newEndpoints), spew.Sdump(newEndpoints))
} }
for x := range tc.expected { for x := range tc.expected {
if len(newEndpoints[x]) != len(tc.expected[x]) { if len(newEndpoints[x]) != len(tc.expected[x]) {
t.Errorf("[%d] expected %d endpoints for %v, got %d", tci, len(tc.expected[x]), x, len(newEndpoints[x])) t.Errorf("[%s] expected %d endpoints for %v, got %d", tc.desc, len(tc.expected[x]), x, len(newEndpoints[x]))
} else { } else {
for i := range newEndpoints[x] { for i := range newEndpoints[x] {
ep := newEndpoints[x][i].(*EndpointInfoCommon) ep := newEndpoints[x][i].(*EndpointInfoCommon)
if *ep != *(tc.expected[x][i]) { if *ep != *(tc.expected[x][i]) {
t.Errorf("[%d] expected new[%v][%d] to be %v, got %v", tci, x, i, tc.expected[x][i], *ep) t.Errorf("[%s] expected new[%v][%d] to be %v, got %v", tc.desc, x, i, tc.expected[x][i], *ep)
} }
} }
} }

View File

@ -25,12 +25,13 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/sets"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
) )
const testHostname = "test-hostname" const testHostname = "test-hostname"
func makeTestServiceInfo(clusterIP string, port int, protocol string, healthcheckNodePort int) *ServiceInfoCommon { func makeTestServiceInfo(clusterIP string, port int, protocol string, healthcheckNodePort int, svcInfoFuncs ...func(*ServiceInfoCommon)) *ServiceInfoCommon {
info := &ServiceInfoCommon{ info := &ServiceInfoCommon{
ClusterIP: net.ParseIP(clusterIP), ClusterIP: net.ParseIP(clusterIP),
Port: port, Port: port,
@ -39,6 +40,9 @@ func makeTestServiceInfo(clusterIP string, port int, protocol string, healthchec
if healthcheckNodePort != 0 { if healthcheckNodePort != 0 {
info.HealthCheckNodePort = healthcheckNodePort info.HealthCheckNodePort = healthcheckNodePort
} }
for _, svcInfoFunc := range svcInfoFuncs {
svcInfoFunc(info)
}
return info return info
} }
@ -81,17 +85,28 @@ func makeServicePortName(ns, name, port string) ServicePortName {
func TestServiceToServiceMap(t *testing.T) { func TestServiceToServiceMap(t *testing.T) {
svcTracker := NewServiceChangeTracker(nil, nil, nil) svcTracker := NewServiceChangeTracker(nil, nil, nil)
trueVal := true
falseVal := false
testClusterIPv4 := "10.0.0.1"
testExternalIPv4 := "8.8.8.8"
testSourceRangeIPv4 := "0.0.0.0/1"
testClusterIPv6 := "2001:db8:85a3:0:0:8a2e:370:7334"
testExternalIPv6 := "2001:db8:85a3:0:0:8a2e:370:7335"
testSourceRangeIPv6 := "2001:db8::/32"
testCases := []struct { testCases := []struct {
service *api.Service desc string
expected map[ServicePortName]*ServiceInfoCommon service *api.Service
expected map[ServicePortName]*ServiceInfoCommon
isIPv6Mode *bool
}{ }{
{ {
// Case[0]: nothing desc: "nothing",
service: nil, service: nil,
expected: map[ServicePortName]*ServiceInfoCommon{}, expected: map[ServicePortName]*ServiceInfoCommon{},
}, },
{ {
// Case[1]: headless service desc: "headless service",
service: makeTestService("ns2", "headless", func(svc *api.Service) { service: makeTestService("ns2", "headless", func(svc *api.Service) {
svc.Spec.Type = api.ServiceTypeClusterIP svc.Spec.Type = api.ServiceTypeClusterIP
svc.Spec.ClusterIP = api.ClusterIPNone svc.Spec.ClusterIP = api.ClusterIPNone
@ -100,7 +115,7 @@ func TestServiceToServiceMap(t *testing.T) {
expected: map[ServicePortName]*ServiceInfoCommon{}, expected: map[ServicePortName]*ServiceInfoCommon{},
}, },
{ {
// Case[2]: headless service without port desc: "headless service without port",
service: makeTestService("ns2", "headless-without-port", func(svc *api.Service) { service: makeTestService("ns2", "headless-without-port", func(svc *api.Service) {
svc.Spec.Type = api.ServiceTypeClusterIP svc.Spec.Type = api.ServiceTypeClusterIP
svc.Spec.ClusterIP = api.ClusterIPNone svc.Spec.ClusterIP = api.ClusterIPNone
@ -108,7 +123,7 @@ func TestServiceToServiceMap(t *testing.T) {
expected: map[ServicePortName]*ServiceInfoCommon{}, expected: map[ServicePortName]*ServiceInfoCommon{},
}, },
{ {
// Case[3]: cluster ip service desc: "cluster ip service",
service: makeTestService("ns2", "cluster-ip", func(svc *api.Service) { service: makeTestService("ns2", "cluster-ip", func(svc *api.Service) {
svc.Spec.Type = api.ServiceTypeClusterIP svc.Spec.Type = api.ServiceTypeClusterIP
svc.Spec.ClusterIP = "172.16.55.4" svc.Spec.ClusterIP = "172.16.55.4"
@ -121,7 +136,7 @@ func TestServiceToServiceMap(t *testing.T) {
}, },
}, },
{ {
// Case[4]: nodeport service desc: "nodeport service",
service: makeTestService("ns2", "node-port", func(svc *api.Service) { service: makeTestService("ns2", "node-port", func(svc *api.Service) {
svc.Spec.Type = api.ServiceTypeNodePort svc.Spec.Type = api.ServiceTypeNodePort
svc.Spec.ClusterIP = "172.16.55.10" svc.Spec.ClusterIP = "172.16.55.10"
@ -134,7 +149,7 @@ func TestServiceToServiceMap(t *testing.T) {
}, },
}, },
{ {
// Case[5]: load balancer service desc: "load balancer service",
service: makeTestService("ns1", "load-balancer", func(svc *api.Service) { service: makeTestService("ns1", "load-balancer", func(svc *api.Service) {
svc.Spec.Type = api.ServiceTypeLoadBalancer svc.Spec.Type = api.ServiceTypeLoadBalancer
svc.Spec.ClusterIP = "172.16.55.11" svc.Spec.ClusterIP = "172.16.55.11"
@ -153,7 +168,7 @@ func TestServiceToServiceMap(t *testing.T) {
}, },
}, },
{ {
// Case[6]: load balancer service with only local traffic policy desc: "load balancer service with only local traffic policy",
service: makeTestService("ns1", "only-local-load-balancer", func(svc *api.Service) { service: makeTestService("ns1", "only-local-load-balancer", func(svc *api.Service) {
svc.Spec.Type = api.ServiceTypeLoadBalancer svc.Spec.Type = api.ServiceTypeLoadBalancer
svc.Spec.ClusterIP = "172.16.55.12" svc.Spec.ClusterIP = "172.16.55.12"
@ -174,7 +189,7 @@ func TestServiceToServiceMap(t *testing.T) {
}, },
}, },
{ {
// Case[7]: external name service desc: "external name service",
service: makeTestService("ns2", "external-name", func(svc *api.Service) { service: makeTestService("ns2", "external-name", func(svc *api.Service) {
svc.Spec.Type = api.ServiceTypeExternalName svc.Spec.Type = api.ServiceTypeExternalName
svc.Spec.ClusterIP = "172.16.55.4" // Should be ignored svc.Spec.ClusterIP = "172.16.55.4" // Should be ignored
@ -183,22 +198,177 @@ func TestServiceToServiceMap(t *testing.T) {
}), }),
expected: map[ServicePortName]*ServiceInfoCommon{}, expected: map[ServicePortName]*ServiceInfoCommon{},
}, },
{
desc: "service with ipv6 clusterIP under ipv4 mode, service should be filtered",
service: &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "invalidIPv6InIPV4Mode",
Namespace: "test",
},
Spec: api.ServiceSpec{
ClusterIP: testClusterIPv6,
Ports: []api.ServicePort{
{
Name: "testPort",
Port: int32(12345),
Protocol: api.ProtocolTCP,
},
},
},
},
isIPv6Mode: &falseVal,
},
{
desc: "service with ipv4 clusterIP under ipv6 mode, service should be filtered",
service: &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "invalidIPv4InIPV6Mode",
Namespace: "test",
},
Spec: api.ServiceSpec{
ClusterIP: testClusterIPv4,
Ports: []api.ServicePort{
{
Name: "testPort",
Port: int32(12345),
Protocol: api.ProtocolTCP,
},
},
},
},
isIPv6Mode: &trueVal,
},
{
desc: "service with ipv4 configurations under ipv4 mode",
service: &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "validIPv4",
Namespace: "test",
},
Spec: api.ServiceSpec{
ClusterIP: testClusterIPv4,
ExternalIPs: []string{testExternalIPv4},
LoadBalancerSourceRanges: []string{testSourceRangeIPv4},
Ports: []api.ServicePort{
{
Name: "testPort",
Port: int32(12345),
Protocol: api.ProtocolTCP,
},
},
},
},
expected: map[ServicePortName]*ServiceInfoCommon{
makeServicePortName("test", "validIPv4", "testPort"): makeTestServiceInfo(testClusterIPv4, 12345, "TCP", 0, func(info *ServiceInfoCommon) {
info.ExternalIPs = []string{testExternalIPv4}
info.LoadBalancerSourceRanges = []string{testSourceRangeIPv4}
}),
},
isIPv6Mode: &falseVal,
},
{
desc: "service with ipv6 configurations under ipv6 mode",
service: &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "validIPv6",
Namespace: "test",
},
Spec: api.ServiceSpec{
ClusterIP: testClusterIPv6,
ExternalIPs: []string{testExternalIPv6},
LoadBalancerSourceRanges: []string{testSourceRangeIPv6},
Ports: []api.ServicePort{
{
Name: "testPort",
Port: int32(12345),
Protocol: api.ProtocolTCP,
},
},
},
},
expected: map[ServicePortName]*ServiceInfoCommon{
makeServicePortName("test", "validIPv6", "testPort"): makeTestServiceInfo(testClusterIPv6, 12345, "TCP", 0, func(info *ServiceInfoCommon) {
info.ExternalIPs = []string{testExternalIPv6}
info.LoadBalancerSourceRanges = []string{testSourceRangeIPv6}
}),
},
isIPv6Mode: &trueVal,
},
{
desc: "service with both ipv4 and ipv6 configurations under ipv4 mode, ipv6 fields should be filtered",
service: &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "filterIPv6InIPV4Mode",
Namespace: "test",
},
Spec: api.ServiceSpec{
ClusterIP: testClusterIPv4,
ExternalIPs: []string{testExternalIPv4, testExternalIPv6},
LoadBalancerSourceRanges: []string{testSourceRangeIPv4, testSourceRangeIPv6},
Ports: []api.ServicePort{
{
Name: "testPort",
Port: int32(12345),
Protocol: api.ProtocolTCP,
},
},
},
},
expected: map[ServicePortName]*ServiceInfoCommon{
makeServicePortName("test", "filterIPv6InIPV4Mode", "testPort"): makeTestServiceInfo(testClusterIPv4, 12345, "TCP", 0, func(info *ServiceInfoCommon) {
info.ExternalIPs = []string{testExternalIPv4}
info.LoadBalancerSourceRanges = []string{testSourceRangeIPv4}
}),
},
isIPv6Mode: &falseVal,
},
{
desc: "service with both ipv4 and ipv6 configurations under ipv6 mode, ipv4 fields should be filtered",
service: &api.Service{
ObjectMeta: metav1.ObjectMeta{
Name: "filterIPv4InIPV6Mode",
Namespace: "test",
},
Spec: api.ServiceSpec{
ClusterIP: testClusterIPv6,
ExternalIPs: []string{testExternalIPv4, testExternalIPv6},
LoadBalancerSourceRanges: []string{testSourceRangeIPv4, testSourceRangeIPv6},
Ports: []api.ServicePort{
{
Name: "testPort",
Port: int32(12345),
Protocol: api.ProtocolTCP,
},
},
},
},
expected: map[ServicePortName]*ServiceInfoCommon{
makeServicePortName("test", "filterIPv4InIPV6Mode", "testPort"): makeTestServiceInfo(testClusterIPv6, 12345, "TCP", 0, func(info *ServiceInfoCommon) {
info.ExternalIPs = []string{testExternalIPv6}
info.LoadBalancerSourceRanges = []string{testSourceRangeIPv6}
}),
},
isIPv6Mode: &trueVal,
},
} }
for tci, tc := range testCases { for _, tc := range testCases {
svcTracker.isIPv6Mode = tc.isIPv6Mode
// outputs // outputs
newServices := svcTracker.serviceToServiceMap(tc.service) newServices := svcTracker.serviceToServiceMap(tc.service)
if len(newServices) != len(tc.expected) { if len(newServices) != len(tc.expected) {
t.Errorf("[%d] expected %d new, got %d: %v", tci, len(tc.expected), len(newServices), spew.Sdump(newServices)) t.Errorf("[%s] expected %d new, got %d: %v", tc.desc, len(tc.expected), len(newServices), spew.Sdump(newServices))
} }
for x := range tc.expected { for svcKey, expectedInfo := range tc.expected {
svcInfo := newServices[x].(*ServiceInfoCommon) svcInfo := newServices[svcKey].(*ServiceInfoCommon)
if !svcInfo.ClusterIP.Equal(tc.expected[x].ClusterIP) || if !svcInfo.ClusterIP.Equal(expectedInfo.ClusterIP) ||
svcInfo.Port != tc.expected[x].Port || svcInfo.Port != expectedInfo.Port ||
svcInfo.Protocol != tc.expected[x].Protocol || svcInfo.Protocol != expectedInfo.Protocol ||
svcInfo.HealthCheckNodePort != tc.expected[x].HealthCheckNodePort { svcInfo.HealthCheckNodePort != expectedInfo.HealthCheckNodePort ||
t.Errorf("[%d] expected new[%v]to be %v, got %v", tci, x, tc.expected[x], *svcInfo) !sets.NewString(svcInfo.ExternalIPs...).Equal(sets.NewString(expectedInfo.ExternalIPs...)) ||
!sets.NewString(svcInfo.LoadBalancerSourceRanges...).Equal(sets.NewString(expectedInfo.LoadBalancerSourceRanges...)) {
t.Errorf("[%s] expected new[%v]to be %v, got %v", tc.desc, svcKey, expectedInfo, *svcInfo)
} }
} }
} }