From 89b633d3532e745f78bcf6c7c01b5e9a77899558 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 17 Nov 2020 15:49:17 -0800 Subject: [PATCH 01/20] Fix doc comment --- pkg/registry/core/service/storage/storage.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/registry/core/service/storage/storage.go b/pkg/registry/core/service/storage/storage.go index 0e706bea01d..2ec4bd64389 100644 --- a/pkg/registry/core/service/storage/storage.go +++ b/pkg/registry/core/service/storage/storage.go @@ -45,7 +45,7 @@ type GenericREST struct { secondaryFamily *api.IPFamily } -// NewREST returns a RESTStorage object that will work against services. +// NewGenericREST returns a RESTStorage object that will work against services. func NewGenericREST(optsGetter generic.RESTOptionsGetter, serviceCIDR net.IPNet, hasSecondary bool) (*GenericREST, *StatusREST, error) { strategy, _ := registry.StrategyForServiceCIDRs(serviceCIDR, hasSecondary) From 5970c4671ccfe1cd6fe91254113c877767df006f Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 17 Nov 2020 20:41:55 -0800 Subject: [PATCH 02/20] Add an IPFamily() method to ipallocator --- .../core/service/ipallocator/allocator.go | 18 +++++++++++++++--- .../core/service/ipallocator/allocator_test.go | 7 +++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pkg/registry/core/service/ipallocator/allocator.go b/pkg/registry/core/service/ipallocator/allocator.go index 634569f767a..e42b3401ca4 100644 --- a/pkg/registry/core/service/ipallocator/allocator.go +++ b/pkg/registry/core/service/ipallocator/allocator.go @@ -35,6 +35,7 @@ type Interface interface { Release(net.IP) error ForEach(func(net.IP)) CIDR() net.IPNet + IPFamily() api.IPFamily // For testing Has(ip net.IP) bool @@ -76,6 +77,8 @@ type Range struct { base *big.Int // max is the maximum size of the usable addresses in the range max int + // family is the IP family of this range + family api.IPFamily alloc allocator.Interface } @@ -85,13 +88,16 @@ func NewAllocatorCIDRRange(cidr *net.IPNet, allocatorFactory allocator.Allocator max := utilnet.RangeSize(cidr) base := utilnet.BigForIP(cidr.IP) rangeSpec := cidr.String() + var family api.IPFamily if utilnet.IsIPv6CIDR(cidr) { + family = api.IPv6Protocol // Limit the max size, since the allocator keeps a bitmap of that size. if max > 65536 { max = 65536 } } else { + family = api.IPv4Protocol // Don't use the IPv4 network's broadcast address. max-- } @@ -101,9 +107,10 @@ func NewAllocatorCIDRRange(cidr *net.IPNet, allocatorFactory allocator.Allocator max-- r := Range{ - net: cidr, - base: base, - max: maximum(0, int(max)), + net: cidr, + base: base, + max: maximum(0, int(max)), + family: family, } var err error r.alloc, err = allocatorFactory(r.max, rangeSpec) @@ -219,6 +226,11 @@ func (r *Range) Has(ip net.IP) bool { return r.alloc.Has(offset) } +// IPFamily returns the IP family of this range. +func (r *Range) IPFamily() api.IPFamily { + return r.family +} + // Snapshot saves the current state of the pool. func (r *Range) Snapshot(dst *api.RangeAllocation) error { snapshottable, ok := r.alloc.(allocator.Snapshottable) diff --git a/pkg/registry/core/service/ipallocator/allocator_test.go b/pkg/registry/core/service/ipallocator/allocator_test.go index 63ab5725695..db43f65ef5f 100644 --- a/pkg/registry/core/service/ipallocator/allocator_test.go +++ b/pkg/registry/core/service/ipallocator/allocator_test.go @@ -28,6 +28,7 @@ func TestAllocate(t *testing.T) { testCases := []struct { name string cidr string + family api.IPFamily free int released string outOfRange []string @@ -36,6 +37,7 @@ func TestAllocate(t *testing.T) { { name: "IPv4", cidr: "192.168.1.0/24", + family: api.IPv4Protocol, free: 254, released: "192.168.1.5", outOfRange: []string{ @@ -49,6 +51,7 @@ func TestAllocate(t *testing.T) { { name: "IPv6", cidr: "2001:db8:1::/48", + family: api.IPv6Protocol, free: 65535, released: "2001:db8:1::5", outOfRange: []string{ @@ -79,6 +82,10 @@ func TestAllocate(t *testing.T) { t.Errorf("allocator returned a different cidr") } + if r.IPFamily() != tc.family { + t.Errorf("allocator returned wrong IP family") + } + if f := r.Used(); f != 0 { t.Errorf("Test %s unexpected used %d", tc.name, f) } From 0bb280044ec4db3a53bf32f9bfbd72b7c4fb1c9c Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Thu, 26 Nov 2020 16:15:09 -0800 Subject: [PATCH 03/20] Fix typo in IP allocator error --- pkg/registry/core/service/storage/rest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/registry/core/service/storage/rest.go b/pkg/registry/core/service/storage/rest.go index a2c1a119bfd..5d6102d6295 100644 --- a/pkg/registry/core/service/storage/rest.go +++ b/pkg/registry/core/service/storage/rest.go @@ -612,7 +612,7 @@ func (rs *REST) allocClusterIPs(service *api.Service, toAlloc map[api.IPFamily]s } else { parsedIP := net.ParseIP(ip) if err := allocator.Allocate(parsedIP); err != nil { - el := field.ErrorList{field.Invalid(field.NewPath("spec", "clusterIPs"), service.Spec.ClusterIPs, fmt.Sprintf("failed to allocated ip:%v with error:%v", ip, err))} + el := field.ErrorList{field.Invalid(field.NewPath("spec", "clusterIPs"), service.Spec.ClusterIPs, fmt.Sprintf("failed to allocate IP %v: %v", ip, err))} return allocated, errors.NewInvalid(api.Kind("Service"), service.Name, el) } allocated[family] = ip From 292b1444ebfb5e91b8ed5c06e56044a8f4d41017 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sun, 27 Jun 2021 15:56:11 -0700 Subject: [PATCH 04/20] Remove bad test for AllocateLoadBalancerNodePorts If the gate is open, we should never find nil. --- .../core/service/storage/rest_test.go | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index cff1830607a..d320ac2a3fe 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -1168,26 +1168,6 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { allocateNodePortGate bool expectError bool }{ - { - name: "allocate nil, gate on", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "alloc-nil"}, - Spec: api.ServiceSpec{ - AllocateLoadBalancerNodePorts: nil, - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectNodePorts: true, - allocateNodePortGate: true, - expectError: true, - }, { name: "allocate false, gate on", svc: &api.Service{ From d3a0332b6cdccbfaf214bed3fb82af59cc939f4c Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sun, 27 Jun 2021 12:15:44 -0700 Subject: [PATCH 05/20] Service REST test: remove unused fields These fields are never set, so we can remove them with no change in behavior. --- .../core/service/storage/rest_test.go | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index d320ac2a3fe..59626e366f2 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -63,16 +63,12 @@ var ( // in a completely different way. We should unify it. type serviceStorage struct { - GottenID string - UpdatedID string - CreatedID string - DeletedID string - Created bool - DeletedImmediately bool - Service *api.Service - OldService *api.Service - ServiceList *api.ServiceList - Err error + GottenID string + UpdatedID string + CreatedID string + DeletedID string + Service *api.Service + ServiceList *api.ServiceList } func (s *serviceStorage) NamespaceScoped() bool { @@ -81,11 +77,11 @@ func (s *serviceStorage) NamespaceScoped() bool { func (s *serviceStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { s.GottenID = name - return s.Service, s.Err + return s.Service, nil } func (s *serviceStorage) GetService(ctx context.Context, name string, options *metav1.GetOptions) (*api.Service, error) { - return s.Service, s.Err + return s.Service, nil } func (s *serviceStorage) NewList() runtime.Object { @@ -110,7 +106,7 @@ func (s *serviceStorage) List(ctx context.Context, options *metainternalversion. res.Items = append([]api.Service{}, s.ServiceList.Items...) } - return res, s.Err + return res, nil } func (s *serviceStorage) New() runtime.Object { @@ -119,7 +115,7 @@ func (s *serviceStorage) New() runtime.Object { func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { if dryrun.IsDryRun(options.DryRun) { - return obj, s.Err + return obj, nil } svc := obj.(*api.Service) s.CreatedID = obj.(metav1.Object).GetName() @@ -130,11 +126,11 @@ func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createV } s.ServiceList.Items = append(s.ServiceList.Items, *svc) - return svc, s.Err + return svc, nil } func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { - obj, err := objInfo.UpdatedObject(ctx, s.OldService) + obj, err := objInfo.UpdatedObject(ctx, nil) if err != nil { return nil, false, err } @@ -142,14 +138,14 @@ func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.U s.UpdatedID = name s.Service = obj.(*api.Service) } - return obj, s.Created, s.Err + return obj, false, nil } func (s *serviceStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { if !dryrun.IsDryRun(options.DryRun) { s.DeletedID = name } - return s.Service, s.DeletedImmediately, s.Err + return s.Service, false, nil } func (s *serviceStorage) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { From d64bb1b29ed8a8027c83fb047db9f5993506e384 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sun, 27 Jun 2021 14:34:06 -0700 Subject: [PATCH 06/20] Service REST test: always check errors This will be needed in upcoming changes. --- .../core/service/storage/rest_test.go | 64 +++++++++++++++---- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 59626e366f2..66c548b1a5d 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -1069,7 +1069,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - registry.Create(ctx, &api.Service{ + _, err := registry.Create(ctx, &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, @@ -1079,6 +1079,9 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { }}, }, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } failureCases := map[string]api.Service{ "empty ID": { ObjectMeta: metav1.ObjectMeta{Name: ""}, @@ -1312,7 +1315,10 @@ func TestServiceRegistryDelete(t *testing.T) { }}, }, } - registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) if e, a := "foo", registry.DeletedID; e != a { t.Errorf("Expected %v, but got %v", e, a) @@ -1451,7 +1457,10 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { }}, }, } - registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) if e, a := "foo", registry.DeletedID; e != a { t.Errorf("Expected %v, but got %v", e, a) @@ -1539,12 +1548,15 @@ func TestServiceRegistryGet(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - registry.Create(ctx, &api.Service{ + _, err := registry.Create(ctx, &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo"}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, }, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } storage.Get(ctx, "foo", &metav1.GetOptions{}) if e, a := "foo", registry.GottenID; e != a { t.Errorf("Expected %v, but got %v", e, a) @@ -1626,7 +1638,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { storage, registry, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) defer server.Terminate(t) for _, name := range []string{"foo", "bad"} { - registry.Create(ctx, &api.Service{ + _, err := registry.Create(ctx, &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: name}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, @@ -1640,6 +1652,9 @@ func TestServiceRegistryResourceLocation(t *testing.T) { }, }, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } } redirector := rest.Redirector(storage) @@ -1791,18 +1806,24 @@ func TestServiceRegistryList(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - registry.Create(ctx, &api.Service{ + _, err := registry.Create(ctx, &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, }, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - registry.Create(ctx, &api.Service{ + if err != nil { + t.Fatalf("error creating service: %v", err) + } + _, err = registry.Create(ctx, &api.Service{ ObjectMeta: metav1.ObjectMeta{Name: "foo2", Namespace: metav1.NamespaceDefault}, Spec: api.ServiceSpec{ Selector: map[string]string{"bar2": "baz2"}, }, }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } registry.ServiceList.ResourceVersion = "1" s, _ := storage.List(ctx, nil) sl := s.(*api.ServiceList) @@ -1838,7 +1859,10 @@ func TestServiceRegistryIPAllocation(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - createdSvc1, _ := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + createdSvc1, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } createdService1 := createdSvc1.(*api.Service) if createdService1.Name != "foo" { t.Errorf("Expected foo, but got %v", createdService1.Name) @@ -1860,7 +1884,10 @@ func TestServiceRegistryIPAllocation(t *testing.T) { }}, }} ctx = genericapirequest.NewDefaultContext() - createdSvc2, _ := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + createdSvc2, err := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } createdService2 := createdSvc2.(*api.Service) if createdService2.Name != "bar" { t.Errorf("Expected bar, but got %v", createdService2.Name) @@ -1922,7 +1949,10 @@ func TestServiceRegistryIPReallocation(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - createdSvc1, _ := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + createdSvc1, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } createdService1 := createdSvc1.(*api.Service) if createdService1.Name != "foo" { t.Errorf("Expected foo, but got %v", createdService1.Name) @@ -1931,7 +1961,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { t.Errorf("Unexpected ClusterIP: %s", createdService1.Spec.ClusterIPs[0]) } - _, _, err := storage.Delete(ctx, createdService1.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) + _, _, err = storage.Delete(ctx, createdService1.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) if err != nil { t.Errorf("Unexpected error deleting service: %v", err) } @@ -1950,7 +1980,10 @@ func TestServiceRegistryIPReallocation(t *testing.T) { }, } ctx = genericapirequest.NewDefaultContext() - createdSvc2, _ := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + createdSvc2, err := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } createdService2 := createdSvc2.(*api.Service) if createdService2.Name != "bar" { t.Errorf("Expected bar, but got %v", createdService2.Name) @@ -1978,7 +2011,10 @@ func TestServiceRegistryIPUpdate(t *testing.T) { }, } ctx := genericapirequest.NewDefaultContext() - createdSvc, _ := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("error creating service: %v", err) + } createdService := createdSvc.(*api.Service) if createdService.Spec.Ports[0].Port != 6502 { t.Errorf("Expected port 6502, but got %v", createdService.Spec.Ports[0].Port) @@ -2013,7 +2049,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { update.Spec.ClusterIP = testIP update.Spec.ClusterIPs[0] = testIP - _, _, err := storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) + _, _, err = storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if err == nil || !errors.IsInvalid(err) { t.Errorf("Unexpected error type: %v", err) } From 5f65ba7d766fb8354b4fcee5437ee5b41022836d Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sun, 27 Jun 2021 15:54:58 -0700 Subject: [PATCH 07/20] Service REST test: Use helper funcs to streamline This makes subsequent changes easier to see. --- .../core/service/storage/rest_test.go | 4125 ++++++----------- 1 file changed, 1331 insertions(+), 2794 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 66c548b1a5d..4f956034458 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -120,13 +120,14 @@ func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createV svc := obj.(*api.Service) s.CreatedID = obj.(metav1.Object).GetName() s.Service = svc.DeepCopy() + s.Service.ResourceVersion = "1" if s.ServiceList == nil { s.ServiceList = &api.ServiceList{} } s.ServiceList.Items = append(s.ServiceList.Items, *svc) - return svc, nil + return s.Service.DeepCopy(), nil } func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { @@ -268,6 +269,92 @@ func makeIPNet6(t *testing.T) *net.IPNet { return net } +// For clarity. +type serviceTweak func(*api.Service) + +// This is used to clarify test sites. +func makeService(name string, tweaks ...serviceTweak) *api.Service { + // NOTE: Any field that would be populated by defaulting needs to be + // present and valid here. + svc := &api.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Spec: api.ServiceSpec{ + Selector: map[string]string{"bar": "baz"}, + SessionAffinity: api.ServiceAffinityNone, + Ports: []api.ServicePort{{ + Port: 93, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(76), + }}, + }, + } + // Default to ClusterIP + tweakTypeClusterIP(svc) + + for _, tweak := range tweaks { + tweak(svc) + } + + return svc +} + +func tweakTypeClusterIP(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeClusterIP +} + +func tweakTypeNodePort(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeNodePort +} + +func tweakTypeLoadBalancer(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeLoadBalancer +} + +func tweakTypeExternalName(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeExternalName + svc.Spec.ExternalName = "example.com" + svc.Spec.ExternalTrafficPolicy = "" + svc.Spec.ClusterIP = "" + svc.Spec.ClusterIPs = nil +} + +func tweakPorts(ports ...api.ServicePort) serviceTweak { + return func(svc *api.Service) { + svc.Spec.Ports = ports + } +} + +func makeServicePort(name string, port int, tgtPort intstr.IntOrString) api.ServicePort { + return api.ServicePort{ + Name: name, + Port: int32(port), + TargetPort: tgtPort, + Protocol: api.ProtocolTCP, + } +} + +func tweakClusterIPs(ips ...string) serviceTweak { + return func(svc *api.Service) { + svc.Spec.ClusterIP = ips[0] + svc.Spec.ClusterIPs = ips + } +} + +func tweakIPFamilies(families ...api.IPFamily) serviceTweak { + return func(svc *api.Service) { + svc.Spec.IPFamilies = families + } +} + +func tweakIPFamilyPolicy(policy api.IPFamilyPolicyType) serviceTweak { + return func(svc *api.Service) { + svc.Spec.IPFamilyPolicy = &policy + } +} + func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, rest *REST, registry ServiceStorage) { obj, err := registry.Get(ctx, svcName, &metav1.GetOptions{}) if err != nil { @@ -293,85 +380,27 @@ func TestServiceRegistryCreate(t *testing.T) { name string families []api.IPFamily enableDualStack bool - }{ - { - name: "Service IPFamily default cluster dualstack:off", - enableDualStack: false, - families: []api.IPFamily{api.IPv4Protocol}, - - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "Service IPFamily:v4 dualstack off", - enableDualStack: false, - families: []api.IPFamily{api.IPv4Protocol}, - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "Service IPFamily:v4 dualstack on", - enableDualStack: true, - families: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "Service IPFamily:v6 dualstack on", - enableDualStack: true, - families: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - } + }{{ + name: "Service IPFamily default cluster dualstack:off", + enableDualStack: false, + families: []api.IPFamily{api.IPv4Protocol}, + svc: makeService("foo"), + }, { + name: "Service IPFamily:v4 dualstack off", + enableDualStack: false, + families: []api.IPFamily{api.IPv4Protocol}, + svc: makeService("foo", tweakIPFamilies(api.IPv4Protocol)), + }, { + name: "Service IPFamily:v4 dualstack on", + enableDualStack: true, + families: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, + svc: makeService("foo", tweakIPFamilies(api.IPv4Protocol)), + }, { + name: "Service IPFamily:v6 dualstack on", + enableDualStack: true, + families: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, + svc: makeService("foo", tweakIPFamilies(api.IPv6Protocol)), + }} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { storage, registry, server := NewTestREST(t, nil, tc.families) @@ -417,94 +446,35 @@ func TestServiceRegistryCreate(t *testing.T) { } func TestServiceRegistryCreateDryRun(t *testing.T) { - requireDualStack := api.IPFamilyPolicyRequireDualStack testCases := []struct { name string svc *api.Service enableDualStack bool - }{ - { - name: "v4 service featuregate off", - enableDualStack: false, - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "v6 service featuregate on but singlestack", - enableDualStack: true, - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - ClusterIP: "2000:0:0:0:0:0:0:1", - ClusterIPs: []string{"2000:0:0:0:0:0:0:1"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "dualstack v4,v6 service", - enableDualStack: true, - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4", "2000:0:0:0:0:0:0:1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "dualstack v6,v4 service", - enableDualStack: true, - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIP: "2000:0:0:0:0:0:0:1", - ClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - } + }{{ + name: "v4 service featuregate off", + enableDualStack: false, + svc: makeService("foo", tweakClusterIPs("1.2.3.4")), + }, { + name: "v6 service featuregate on but singlestack", + enableDualStack: true, + svc: makeService("foo", + tweakIPFamilies(api.IPv6Protocol), + tweakClusterIPs("2000::1")), + }, { + name: "dualstack v4,v6 service", + enableDualStack: true, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakClusterIPs("1.2.3.4", "2000::1")), + }, { + name: "dualstack v6,v4 service", + enableDualStack: true, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + tweakClusterIPs("2000::1", "1.2.3.4")), + }} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -546,27 +516,18 @@ func TestDryRunNodePort(t *testing.T) { defer server.Terminate(t) // Test dry run create request with a node port - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{{ - NodePort: 30010, - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc := makeService("foo", tweakTypeNodePort) ctx := genericapirequest.NewDefaultContext() - _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) + obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Unexpected error: %v", err) } - if storage.serviceNodePorts.Has(30010) { + createdSvc := obj.(*api.Service) + if createdSvc.Spec.Ports[0].NodePort == 0 { + t.Errorf("expected NodePort value assigned") + } + if storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort allocated") } srv, err := registry.GetService(ctx, svc.Name, &metav1.GetOptions{}) @@ -578,42 +539,37 @@ func TestDryRunNodePort(t *testing.T) { } // Test dry run create request with multi node port - svc = &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolTCP, - }, - { - Name: "port-udp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolUDP, - }, - }, - }, - } + svc = makeService("foo", + tweakTypeNodePort, + func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + NodePort: 30053, + TargetPort: intstr.FromInt(6503), + Protocol: api.ProtocolTCP, + }, { + Name: "port-udp", + Port: 53, + NodePort: 30053, + TargetPort: intstr.FromInt(6503), + Protocol: api.ProtocolUDP, + }} + }) expectNodePorts := collectServiceNodePorts(svc) - createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) + obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Unexpected error: %v", err) } - createdService := createdSvc.(*api.Service) - serviceNodePorts := collectServiceNodePorts(createdService) - if !reflect.DeepEqual(serviceNodePorts, expectNodePorts) { - t.Errorf("Expected %v, but got %v", expectNodePorts, serviceNodePorts) + createdSvc = obj.(*api.Service) + actualNodePorts := collectServiceNodePorts(createdSvc) + if !reflect.DeepEqual(actualNodePorts, expectNodePorts) { + t.Errorf("Expected %v, but got %v", expectNodePorts, actualNodePorts) } - if storage.serviceNodePorts.Has(30053) { - t.Errorf("unexpected side effect: NodePort allocated") + for i := range svc.Spec.Ports { + if storage.serviceNodePorts.Has(int(svc.Spec.Ports[i].NodePort)) { + t.Errorf("unexpected side effect: NodePort allocated") + } } srv, err = registry.GetService(ctx, svc.Name, &metav1.GetOptions{}) if err != nil { @@ -625,43 +581,41 @@ func TestDryRunNodePort(t *testing.T) { // Test dry run create request with multiple unspecified node ports, // so PortAllocationOperation.AllocateNext() will be called multiple times. - svc = &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-a", - Port: 53, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6503), - }, - { - Name: "port-b", - Port: 54, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6504), - }, - }, - }, - } - createdSvc, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) + svc = makeService("foo", + tweakTypeNodePort, + func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-a", + Port: 53, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6503), + }, { + Name: "port-b", + Port: 54, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6504), + }} + }) + obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Unexpected error: %v", err) } - createdService = createdSvc.(*api.Service) - serviceNodePorts = collectServiceNodePorts(createdService) - if len(serviceNodePorts) != 2 { - t.Errorf("Expected service to have 2 ports, but got %v", serviceNodePorts) - } else if serviceNodePorts[0] == serviceNodePorts[1] { - t.Errorf("Expected unique port numbers, but got %v", serviceNodePorts) + createdSvc = obj.(*api.Service) + actualNodePorts = collectServiceNodePorts(createdSvc) + if len(actualNodePorts) != len(svc.Spec.Ports) { + t.Fatalf("Expected service to have %d ports, but got %v", len(svc.Spec.Ports), actualNodePorts) + } + seen := map[int]bool{} + for _, np := range actualNodePorts { + if seen[np] { + t.Errorf("Expected unique port numbers, but got %v", actualNodePorts) + } else { + seen[np] = true + } } } func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) @@ -669,91 +623,66 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { svc *api.Service name string expectNodePorts []int - }{ - { - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo1"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolTCP, - }, - { - Name: "port-udp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolUDP, - }, - }, - }, - }, - name: "foo1", - expectNodePorts: []int{30053, 30053}, - }, - { - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo2"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 54, - TargetPort: intstr.FromInt(6504), - Protocol: api.ProtocolTCP, - }, - { - Name: "port-udp", - Port: 54, - NodePort: 30054, - TargetPort: intstr.FromInt(6504), - Protocol: api.ProtocolUDP, - }, - }, - }, - }, - name: "foo2", - expectNodePorts: []int{30054, 30054}, - }, - { - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo3"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 55, - NodePort: 30055, - TargetPort: intstr.FromInt(6505), - Protocol: api.ProtocolTCP, - }, - { - Name: "port-udp", - Port: 55, - NodePort: 30056, - TargetPort: intstr.FromInt(6506), - Protocol: api.ProtocolUDP, - }, - }, - }, - }, - name: "foo3", - expectNodePorts: []int{30055, 30056}, - }, - } + }{{ + svc: makeService("foo1", + tweakTypeNodePort, + func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + NodePort: 30053, + TargetPort: intstr.FromInt(6503), + Protocol: api.ProtocolTCP, + }, { + Name: "port-udp", + Port: 53, + NodePort: 30053, + TargetPort: intstr.FromInt(6503), + Protocol: api.ProtocolUDP, + }} + }), + name: "foo1", + expectNodePorts: []int{30053, 30053}, + }, { + svc: makeService("foo2", + tweakTypeNodePort, + func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 54, + TargetPort: intstr.FromInt(6504), + Protocol: api.ProtocolTCP, + }, { + Name: "port-udp", + Port: 54, + NodePort: 30054, + TargetPort: intstr.FromInt(6504), + Protocol: api.ProtocolUDP, + }} + }), + name: "foo2", + expectNodePorts: []int{30054, 30054}, + }, { + svc: makeService("foo3", + tweakTypeNodePort, + func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 55, + NodePort: 30055, + TargetPort: intstr.FromInt(6505), + Protocol: api.ProtocolTCP, + }, { + Name: "port-udp", + Port: 55, + NodePort: 30056, + TargetPort: intstr.FromInt(6506), + Protocol: api.ProtocolUDP, + }} + }), + name: "foo3", + expectNodePorts: []int{30055, 30056}, + }} ctx := genericapirequest.NewDefaultContext() for _, test := range testCases { @@ -794,47 +723,23 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { func TestServiceStorageValidatesCreate(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - failureCases := map[string]api.Service{ - "empty ID": { - ObjectMeta: metav1.ObjectMeta{Name: ""}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - "empty port": { - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Protocol: api.ProtocolTCP, - }}, - }, - }, - "missing targetPort": { - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - }}, - }, - }, + failureCases := map[string]*api.Service{ + "empty ID": makeService(""), + "empty port": makeService("foo", func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Protocol: api.ProtocolTCP, + }} + }), + "missing targetPort": makeService("foo", func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Port: 6502, + Protocol: api.ProtocolTCP, + }} + }), } ctx := genericapirequest.NewDefaultContext() for _, failureCase := range failureCases { - c, err := storage.Create(ctx, &failureCase, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + c, err := storage.Create(ctx, failureCase, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if c != nil { t.Errorf("Expected nil object") } @@ -849,19 +754,7 @@ func TestServiceRegistryUpdate(t *testing.T) { storage, registry, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) - _, err := registry.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - SessionAffinity: api.ServiceAffinityNone, - Selector: map[string]string{"bar": "baz1"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -895,46 +788,21 @@ func TestServiceRegistryUpdate(t *testing.T) { } func TestServiceRegistryUpdateDryRun(t *testing.T) { - ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - obj, err := registry.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeExternalName, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err := registry.Create(ctx, makeService("foo", tweakTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } svc := obj.(*api.Service) // Test dry run update request external name to node port - updatedSvc, created, err := storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(&api.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: svc.Name, - ResourceVersion: svc.ResourceVersion}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{{ - NodePort: 30020, - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) + new1 := svc.DeepCopy() + tweakTypeNodePort(new1) + updatedSvc, created, err := storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new1), + rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -944,7 +812,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { if created { t.Errorf("expected not created") } - if storage.serviceNodePorts.Has(30020) { + if storage.serviceNodePorts.Has(int(svc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort allocated") } if e, a := "", registry.UpdatedID; e != a { @@ -952,115 +820,56 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { } // Test dry run update request external name to cluster ip - _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(&api.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: svc.Name, - ResourceVersion: svc.ResourceVersion}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) + new2 := svc.DeepCopy() + tweakTypeClusterIP(new2) + _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new2), + rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Expected no error: %v", err) } - if storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP("1.2.3.4")) { + if storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(svc.Spec.ClusterIP)) { t.Errorf("unexpected side effect: ip allocated") } // Test dry run update request remove node port - obj, err = storage.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo2", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - ClusterIP: "1.2.3.5", - ClusterIPs: []string{"1.2.3.5"}, - Ports: []api.ServicePort{{ - NodePort: 30020, - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, makeService("foo2", tweakTypeNodePort), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } svc = obj.(*api.Service) + if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(svc.Spec.ClusterIP)) { + t.Errorf("expected IP to be allocated") + } + if !storage.serviceNodePorts.Has(int(svc.Spec.Ports[0].NodePort)) { + t.Errorf("expected NodePort to be allocated") + } - _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(&api.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: svc.Name, - ResourceVersion: svc.ResourceVersion}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeExternalName, - ExternalName: "foo-svc", - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) + new3 := svc.DeepCopy() + tweakTypeExternalName(new3) + _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new3), + rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Expected no error: %v", err) } - if !storage.serviceNodePorts.Has(30020) { + if !storage.serviceNodePorts.Has(int(svc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort unallocated") } // Test dry run update request remove cluster ip - obj, err = storage.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo3", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, makeService("foo3"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("Expected no error: %v", err) + t.Fatalf("expected no error: %v", err) } svc = obj.(*api.Service) - _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(&api.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: svc.Name, - ResourceVersion: svc.ResourceVersion}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeExternalName, - ExternalName: "foo-svc", - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) + + new4 := svc.DeepCopy() + tweakTypeExternalName(new4) + _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new4), + rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { - t.Fatalf("Expected no error: %v", err) + t.Fatalf("expected no error: %v", err) } - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP("1.2.3.4")) { + if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(svc.Spec.ClusterIP)) { t.Errorf("unexpected side effect: ip unallocated") } } @@ -1069,49 +878,18 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - }}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("error creating service: %v", err) + t.Fatalf("unexpected error: %v", err) } - failureCases := map[string]api.Service{ - "empty ID": { - ObjectMeta: metav1.ObjectMeta{Name: ""}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - "invalid selector": { - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"ThisSelectorFailsValidation": "ok"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, + failureCases := map[string]*api.Service{ + "empty ID": makeService(""), + "invalid selector": makeService("", func(svc *api.Service) { + svc.Spec.Selector = map[string]string{"ThisSelectorFailsValidation": "ok"} + }), } for _, failureCase := range failureCases { - c, created, err := storage.Update(ctx, failureCase.Name, rest.DefaultUpdatedObjectInfo(&failureCase), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) + c, created, err := storage.Update(ctx, failureCase.Name, rest.DefaultUpdatedObjectInfo(failureCase), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) if c != nil || created { t.Errorf("Expected nil object or created false") } @@ -1125,19 +903,7 @@ func TestServiceRegistryExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc := makeService("foo", tweakTypeLoadBalancer) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create service: %#v", err) @@ -1159,110 +925,46 @@ func TestServiceRegistryExternalService(t *testing.T) { storage.serviceNodePorts.Release(nodePort) } } + func TestAllocateLoadBalancerNodePorts(t *testing.T) { + setAlloc := func(val bool) serviceTweak { + return func(s *api.Service) { + s.Spec.AllocateLoadBalancerNodePorts = utilpointer.BoolPtr(val) + } + } + testcases := []struct { name string svc *api.Service expectNodePorts bool allocateNodePortGate bool expectError bool - }{ - { - name: "allocate false, gate on", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "alloc-false"}, - Spec: api.ServiceSpec{ - AllocateLoadBalancerNodePorts: utilpointer.BoolPtr(false), - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectNodePorts: false, - allocateNodePortGate: true, - }, - { - name: "allocate true, gate on", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "alloc-true"}, - Spec: api.ServiceSpec{ - AllocateLoadBalancerNodePorts: utilpointer.BoolPtr(true), - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectNodePorts: true, - allocateNodePortGate: true, - }, - { - name: "allocate nil, gate off", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "alloc-false"}, - Spec: api.ServiceSpec{ - AllocateLoadBalancerNodePorts: nil, - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectNodePorts: true, - allocateNodePortGate: false, - }, - { - name: "allocate false, gate off", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "alloc-false"}, - Spec: api.ServiceSpec{ - AllocateLoadBalancerNodePorts: utilpointer.BoolPtr(false), - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectNodePorts: true, - allocateNodePortGate: false, - }, - { - name: "allocate true, gate off", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "alloc-true"}, - Spec: api.ServiceSpec{ - AllocateLoadBalancerNodePorts: utilpointer.BoolPtr(true), - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectNodePorts: true, - allocateNodePortGate: false, - }, - } + }{{ + name: "allocate false, gate on", + svc: makeService("alloc-false", tweakTypeLoadBalancer, setAlloc(false)), + expectNodePorts: false, + allocateNodePortGate: true, + }, { + name: "allocate true, gate on", + svc: makeService("alloc-true", tweakTypeLoadBalancer, setAlloc(true)), + expectNodePorts: true, + allocateNodePortGate: true, + }, { + name: "allocate nil, gate off", + svc: makeService("alloc-nil", tweakTypeLoadBalancer), + expectNodePorts: true, + allocateNodePortGate: false, + }, { + name: "allocate false, gate off", + svc: makeService("alloc-false", tweakTypeLoadBalancer, setAlloc(false)), + expectNodePorts: true, + allocateNodePortGate: false, + }, { + name: "allocate true, gate off", + svc: makeService("alloc-true", tweakTypeLoadBalancer, setAlloc(true)), + expectNodePorts: true, + allocateNodePortGate: false, + }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { ctx := genericapirequest.NewDefaultContext() @@ -1303,21 +1005,10 @@ func TestServiceRegistryDelete(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - }}, - }, - } + svc := makeService("foo") _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("error creating service: %v", err) + t.Fatalf("unexpected error: %v", err) } storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) if e, a := "foo", registry.DeletedID; e != a { @@ -1331,25 +1022,18 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { defer server.Terminate(t) // Test dry run delete request with cluster ip - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } - _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + svc := makeService("foo") + obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } + createdSvc := obj.(*api.Service) + if createdSvc.Spec.ClusterIP == "" { + t.Fatalf("expected ClusterIP to be set") + } + if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(createdSvc.Spec.ClusterIP)) { + t.Errorf("expected ClusterIP to be allocated") + } _, _, err = storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Expected no error: %v", err) @@ -1357,29 +1041,23 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { if e, a := "", registry.DeletedID; e != a { t.Errorf("Expected %v, but got %v", e, a) } - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP("1.2.3.4")) { + if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(createdSvc.Spec.ClusterIP)) { t.Errorf("unexpected side effect: ip unallocated") } // Test dry run delete request with node port - svc = &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo2"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{{ - NodePort: 30030, - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } - _, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + svc = makeService("foo2", tweakTypeNodePort) + obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } + createdSvc = obj.(*api.Service) + if createdSvc.Spec.Ports[0].NodePort == 0 { + t.Fatalf("expected NodePort to be set") + } + if !storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { + t.Errorf("expected NodePort to be allocated") + } isValidClusterIPFields(t, storage, svc, svc) @@ -1390,7 +1068,7 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { if e, a := "", registry.DeletedID; e != a { t.Errorf("Expected %v, but got %v", e, a) } - if !storage.serviceNodePorts.Has(30030) { + if !storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort unallocated") } } @@ -1402,25 +1080,11 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)() dualstack_storage, dualstack_registry, dualstack_server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer dualstack_server.Terminate(t) - requireDualStack := api.IPFamilyPolicyRequireDualStack // Test dry run delete request with cluster ip - dualstack_svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIP: "2000:0:0:0:0:0:0:1", - ClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + dualstack_svc := makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")) _, err := dualstack_storage.Create(ctx, dualstack_svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1445,21 +1109,10 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - }}, - }, - } + svc := makeService("foo", tweakTypeExternalName) _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("error creating service: %v", err) + t.Fatalf("unexpected error: %v", err) } storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) if e, a := "foo", registry.DeletedID; e != a { @@ -1473,25 +1126,14 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { defer server.Terminate(t) // Create non-external load balancer. - svc1 := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } - if _, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { + svc1 := makeService("foo") + obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { t.Fatalf("Unexpected error: %v", err) } // Modify load balancer to be external. - svc2 := svc1.DeepCopy() + svc2 := obj.(*api.Service).DeepCopy() svc2.Spec.Type = api.ServiceTypeLoadBalancer if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) @@ -1512,32 +1154,28 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { defer server.Terminate(t) // Create external load balancer. - svc1 := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Name: "p", - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }, { - Name: "q", - Port: 8086, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(8086), - }}, - }, - } - if _, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}); err != nil { + svc1 := makeService("foo", func(s *api.Service) { + s.Spec.Type = api.ServiceTypeLoadBalancer + s.Spec.Ports = []api.ServicePort{{ + Name: "p", + Port: 6502, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6502), + }, { + Name: "q", + Port: 8086, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(8086), + }} + }) + obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { t.Fatalf("Unexpected error: %v", err) } defer releaseServiceNodePorts(t, ctx, svc1.Name, storage, registry) // Modify ports - svc2 := svc1.DeepCopy() + svc2 := obj.(*api.Service).DeepCopy() svc2.Spec.Ports[1].Port = 8088 if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) @@ -1548,12 +1186,7 @@ func TestServiceRegistryGet(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } @@ -1638,20 +1271,16 @@ func TestServiceRegistryResourceLocation(t *testing.T) { storage, registry, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) defer server.Terminate(t) for _, name := range []string{"foo", "bad"} { - _, err := registry.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: name}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Ports: []api.ServicePort{ - // Service port 9393 should route to endpoint port "p", which is port 93 - {Name: "p", Port: 9393, TargetPort: intstr.FromString("p")}, + _, err := registry.Create(ctx, makeService(name, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{ + // Service port 9393 should route to endpoint port "p", which is port 93 + {Name: "p", Port: 9393, TargetPort: intstr.FromString("p")}, - // Service port 93 should route to unnamed endpoint port, which is port 80 - // This is to test that the service port definition is used when determining resource location - {Name: "", Port: 93, TargetPort: intstr.FromInt(80)}, - }, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + // Service port 93 should route to unnamed endpoint port, which is port 80 + // This is to test that the service port definition is used when determining resource location + {Name: "", Port: 93, TargetPort: intstr.FromInt(80)}, + } + }), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } @@ -1806,23 +1435,13 @@ func TestServiceRegistryList(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("error creating service: %v", err) + t.Fatalf("unexpected error: %v", err) } - _, err = registry.Create(ctx, &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo2", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar2": "baz2"}, - }, - }, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err = registry.Create(ctx, makeService("foo2"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("error creating service: %v", err) + t.Fatalf("unexpected error: %v", err) } registry.ServiceList.ResourceVersion = "1" s, _ := storage.List(ctx, nil) @@ -1845,59 +1464,36 @@ func TestServiceRegistryIPAllocation(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc1 := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc1 := makeService("foo") ctx := genericapirequest.NewDefaultContext() - createdSvc1, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } - createdService1 := createdSvc1.(*api.Service) - if createdService1.Name != "foo" { - t.Errorf("Expected foo, but got %v", createdService1.Name) + createdSvc1 := obj.(*api.Service) + if createdSvc1.Name != "foo" { + t.Errorf("Expected foo, but got %v", createdSvc1.Name) } - if !makeIPNet(t).Contains(net.ParseIP(createdService1.Spec.ClusterIPs[0])) { - t.Errorf("Unexpected ClusterIP: %s", createdService1.Spec.ClusterIPs[0]) + if !makeIPNet(t).Contains(net.ParseIP(createdSvc1.Spec.ClusterIPs[0])) { + t.Errorf("Unexpected ClusterIP: %s", createdSvc1.Spec.ClusterIPs[0]) } - svc2 := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "bar"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }} + svc2 := makeService("bar") ctx = genericapirequest.NewDefaultContext() - createdSvc2, err := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } - createdService2 := createdSvc2.(*api.Service) - if createdService2.Name != "bar" { - t.Errorf("Expected bar, but got %v", createdService2.Name) + createdSvc2 := obj.(*api.Service) + if createdSvc2.Name != "bar" { + t.Errorf("Expected bar, but got %v", createdSvc2.Name) } - if !makeIPNet(t).Contains(net.ParseIP(createdService2.Spec.ClusterIPs[0])) { - t.Errorf("Unexpected ClusterIP: %s", createdService2.Spec.ClusterIPs[0]) + if !makeIPNet(t).Contains(net.ParseIP(createdSvc2.Spec.ClusterIPs[0])) { + t.Errorf("Unexpected ClusterIP: %s", createdSvc2.Spec.ClusterIPs[0]) } testIPs := []string{"1.2.3.93", "1.2.3.94", "1.2.3.95", "1.2.3.96"} - testIP := "" + testIP := "not-an-ip" for _, ip := range testIPs { if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].(*ipallocator.Range).Has(net.ParseIP(ip)) { testIP = ip @@ -1905,29 +1501,15 @@ func TestServiceRegistryIPAllocation(t *testing.T) { } } - svc3 := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "quux"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - ClusterIP: testIP, - ClusterIPs: []string{testIP}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc3 := makeService("qux", tweakClusterIPs(testIP)) ctx = genericapirequest.NewDefaultContext() - createdSvc3, err := storage.Create(ctx, svc3, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, svc3, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatal(err) } - createdService3 := createdSvc3.(*api.Service) - if createdService3.Spec.ClusterIPs[0] != testIP { // specific IP - t.Errorf("Unexpected ClusterIP: %s", createdService3.Spec.ClusterIPs[0]) + createdSvc3 := obj.(*api.Service) + if createdSvc3.Spec.ClusterIPs[0] != testIP { // specific IP + t.Errorf("Unexpected ClusterIP: %s", createdSvc3.Spec.ClusterIPs[0]) } } @@ -1935,61 +1517,37 @@ func TestServiceRegistryIPReallocation(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc1 := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc1 := makeService("foo") ctx := genericapirequest.NewDefaultContext() - createdSvc1, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } - createdService1 := createdSvc1.(*api.Service) - if createdService1.Name != "foo" { - t.Errorf("Expected foo, but got %v", createdService1.Name) + createdSvc1 := obj.(*api.Service) + if createdSvc1.Name != "foo" { + t.Errorf("Expected foo, but got %v", createdSvc1.Name) } - if !makeIPNet(t).Contains(net.ParseIP(createdService1.Spec.ClusterIPs[0])) { - t.Errorf("Unexpected ClusterIP: %s", createdService1.Spec.ClusterIPs[0]) + if !makeIPNet(t).Contains(net.ParseIP(createdSvc1.Spec.ClusterIPs[0])) { + t.Errorf("Unexpected ClusterIP: %s", createdSvc1.Spec.ClusterIPs[0]) } - _, _, err = storage.Delete(ctx, createdService1.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) + _, _, err = storage.Delete(ctx, createdSvc1.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) if err != nil { t.Errorf("Unexpected error deleting service: %v", err) } - svc2 := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "bar"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc2 := makeService("bar", tweakClusterIPs(svc1.Spec.ClusterIP)) ctx = genericapirequest.NewDefaultContext() - createdSvc2, err := storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } - createdService2 := createdSvc2.(*api.Service) - if createdService2.Name != "bar" { - t.Errorf("Expected bar, but got %v", createdService2.Name) + createdSvc2 := obj.(*api.Service) + if createdSvc2.Name != "bar" { + t.Errorf("Expected bar, but got %v", createdSvc2.Name) } - if !makeIPNet(t).Contains(net.ParseIP(createdService2.Spec.ClusterIPs[0])) { - t.Errorf("Unexpected ClusterIP: %s", createdService2.Spec.ClusterIPs[0]) + if !makeIPNet(t).Contains(net.ParseIP(createdSvc2.Spec.ClusterIPs[0])) { + t.Errorf("Unexpected ClusterIP: %s", createdSvc2.Spec.ClusterIPs[0]) } } @@ -1997,27 +1555,15 @@ func TestServiceRegistryIPUpdate(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc := makeService("foo") ctx := genericapirequest.NewDefaultContext() createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("error creating service: %v", err) + t.Fatalf("unexpected error: %v", err) } createdService := createdSvc.(*api.Service) - if createdService.Spec.Ports[0].Port != 6502 { - t.Errorf("Expected port 6502, but got %v", createdService.Spec.Ports[0].Port) + if createdService.Spec.Ports[0].Port != svc.Spec.Ports[0].Port { + t.Errorf("Expected port %d, but got %v", svc.Spec.Ports[0].Port, createdService.Spec.Ports[0].Port) } if !makeIPNet(t).Contains(net.ParseIP(createdService.Spec.ClusterIPs[0])) { t.Errorf("Unexpected ClusterIP: %s", createdService.Spec.ClusterIPs[0]) @@ -2059,19 +1605,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - } + svc := makeService("foo", tweakTypeLoadBalancer) ctx := genericapirequest.NewDefaultContext() createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if createdSvc == nil || err != nil { @@ -2080,8 +1614,8 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) createdService := createdSvc.(*api.Service) - if createdService.Spec.Ports[0].Port != 6502 { - t.Errorf("Expected port 6502, but got %v", createdService.Spec.Ports[0].Port) + if createdService.Spec.Ports[0].Port != svc.Spec.Ports[0].Port { + t.Errorf("Expected port %d, but got %v", svc.Spec.Ports[0].Port, createdService.Spec.Ports[0].Port) } if !makeIPNet(t).Contains(net.ParseIP(createdService.Spec.ClusterIPs[0])) { t.Errorf("Unexpected ClusterIP: %s", createdService.Spec.ClusterIPs[0]) @@ -2098,9 +1632,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { func TestUpdateServiceWithConflictingNamespace(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - service := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "test", Namespace: "not-default"}, - } + service := makeService("test", func(s *api.Service) { s.Namespace = "not-default" }) ctx := genericapirequest.NewDefaultContext() obj, created, err := storage.Update(ctx, service.Name, rest.DefaultUpdatedObjectInfo(service), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) @@ -2120,31 +1652,20 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal, - }, - } - createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if createdSvc == nil || err != nil { + svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal + }) + obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if obj == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) - createdService := createdSvc.(*api.Service) - if !service.NeedsHealthCheck(createdService) { + createdSvc := obj.(*api.Service) + if !service.NeedsHealthCheck(createdSvc) { t.Errorf("Expecting health check needed, returned health check not needed instead") } - port := createdService.Spec.HealthCheckNodePort + port := createdSvc.Spec.HealthCheckNodePort if port == 0 { t.Errorf("Failed to allocate health check node port and set the HealthCheckNodePort") } else { @@ -2159,35 +1680,24 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - // hard-code NodePort to make sure it doesn't conflict with the healthport. - // TODO: remove this once http://issue.k8s.io/93922 fixes auto-allocation conflicting with user-specified health check ports - NodePort: 30500, - }}, - ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal, - HealthCheckNodePort: 30501, - }, - } - createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if createdSvc == nil || err != nil { + svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + // hard-code NodePort to make sure it doesn't conflict with the healthport. + // TODO: remove this once http://issue.k8s.io/93922 fixes auto-allocation conflicting with user-specified health check ports + s.Spec.Ports[0].NodePort = 30500 + s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal + s.Spec.HealthCheckNodePort = 30501 + }) + obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if obj == nil || err != nil { t.Fatalf("Unexpected failure creating service :%v", err) } defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) - createdService := createdSvc.(*api.Service) - if !service.NeedsHealthCheck(createdService) { + createdSvc := obj.(*api.Service) + if !service.NeedsHealthCheck(createdSvc) { t.Errorf("Expecting health check needed, returned health check not needed instead") } - port := createdService.Spec.HealthCheckNodePort + port := createdSvc.Spec.HealthCheckNodePort if port == 0 { t.Errorf("Failed to allocate health check node port and set the HealthCheckNodePort") } @@ -2205,23 +1715,12 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) ctx := genericapirequest.NewDefaultContext() storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeLocal, - HealthCheckNodePort: int32(-1), - }, - } - createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if createdSvc == nil || err != nil { + svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal + s.Spec.HealthCheckNodePort = int32(-1) + }) + obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if obj == nil || err != nil { return } t.Errorf("Unexpected creation of service with invalid HealthCheckNodePort specified") @@ -2232,32 +1731,21 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "external-lb-esipp"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeLoadBalancer, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - ExternalTrafficPolicy: api.ServiceExternalTrafficPolicyTypeCluster, - }, - } - createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if createdSvc == nil || err != nil { + svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster + }) + obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if obj == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) - createdService := createdSvc.(*api.Service) - if service.NeedsHealthCheck(createdService) { + createdSvc := obj.(*api.Service) + if service.NeedsHealthCheck(createdSvc) { t.Errorf("Expecting health check not needed, returned health check needed instead") } // Make sure the service does not have the health check node port allocated - port := createdService.Spec.HealthCheckNodePort + port := createdSvc.Spec.HealthCheckNodePort if port != 0 { // Release the health check node port at the end of the test case. storage.serviceNodePorts.Release(int(port)) @@ -2266,10 +1754,6 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { } func TestInitClusterIP(t *testing.T) { - singleStack := api.IPFamilyPolicySingleStack - requireDualStack := api.IPFamilyPolicyRequireDualStack - preferDualStack := api.IPFamilyPolicyPreferDualStack - testCases := []struct { name string svc *api.Service @@ -2279,347 +1763,141 @@ func TestInitClusterIP(t *testing.T) { expectError bool expectedCountIPs int expectedClusterIPs []string - }{ - { - name: "Allocate single stack ClusterIP (v4)", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - enableDualStackAllocator: false, - expectError: false, - preAllocateClusterIPs: nil, - expectedCountIPs: 1, - }, - { - name: "Allocate single ClusterIP (v6)", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - preAllocateClusterIPs: nil, - expectedCountIPs: 1, - }, - { - name: "Allocate specified ClusterIP (v4)", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - preAllocateClusterIPs: nil, - expectedCountIPs: 1, - expectedClusterIPs: []string{"1.2.3.4"}, - }, - { - name: "Allocate specified ClusterIP-v6", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - ClusterIP: "2000:0:0:0:0:0:0:1", - ClusterIPs: []string{"2000:0:0:0:0:0:0:1"}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - expectedCountIPs: 1, - expectedClusterIPs: []string{"2000:0:0:0:0:0:0:1"}, - }, - { - name: "Allocate dual stack - on a non dual stack ", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &preferDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: false, - expectedCountIPs: 1, - }, - { - name: "Allocate dual stack - upgrade - v4, v6", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &preferDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - expectedCountIPs: 2, - }, - { - name: "Allocate dual stack - upgrade - v4, v6 - specific first IP", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &preferDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - expectedCountIPs: 2, - expectedClusterIPs: []string{"1.2.3.4"}, - }, - { - name: "Allocate dual stack - upgrade - v6, v4", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &preferDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - expectedCountIPs: 2, - }, - { - name: "Allocate dual stack - v4, v6 - specific ips", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &requireDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4", "2000:0:0:0:0:0:0:1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - expectedCountIPs: 2, - expectedClusterIPs: []string{"1.2.3.4", "2000:0:0:0:0:0:0:1"}, - }, - { - name: "Allocate dual stack - upgrade - v6, v4 - specific ips", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &requireDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "2000:0:0:0:0:0:0:1", - ClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: true, - expectedCountIPs: 2, - expectedClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, - }, - { - name: "Shouldn't allocate ClusterIP", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "None", - ClusterIPs: []string{api.ClusterIPNone}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: false, - enableDualStackAllocator: false, - expectedCountIPs: 0, - }, - { - name: "single stack, ip is pre allocated (ipv4)", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &singleStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "1.2.3.4", - ClusterIPs: []string{"1.2.3.4"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: true, - enableDualStackAllocator: false, - expectedCountIPs: 0, - preAllocateClusterIPs: map[api.IPFamily]string{api.IPv4Protocol: "1.2.3.4"}, - }, - - { - name: "single stack, ip is pre allocated (ipv6)", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &singleStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000:0:0:0:0:0:0:1"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: true, - enableDualStackAllocator: true, // ipv6 allocator is always the second one during test - expectedCountIPs: 0, - preAllocateClusterIPs: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, - }, - { - name: "Allocate dual stack - upgrade - v6, v4 - specific ips (first ip can't be allocated)", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &requireDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: true, - enableDualStackAllocator: true, - expectedCountIPs: 0, - preAllocateClusterIPs: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, - }, - { - name: "Allocate dual stack - upgrade - v6, v4 - specific ips (second ip can't be allocated)", - svc: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - IPFamilyPolicy: &requireDualStack, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - ClusterIP: "2000:0:0:0:0:0:0:1", - ClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectError: true, - enableDualStackAllocator: true, - expectedCountIPs: 0, - preAllocateClusterIPs: map[api.IPFamily]string{api.IPv4Protocol: "1.2.3.4"}, - }, - } + }{{ + name: "Allocate single stack ClusterIP (v4)", + svc: makeService("foo"), + enableDualStackAllocator: false, + expectError: false, + preAllocateClusterIPs: nil, + expectedCountIPs: 1, + }, { + name: "Allocate single ClusterIP (v6)", + svc: makeService("foo", + tweakIPFamilies(api.IPv6Protocol)), + expectError: false, + enableDualStackAllocator: true, + preAllocateClusterIPs: nil, + expectedCountIPs: 1, + }, { + name: "Allocate specified ClusterIP (v4)", + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol), + tweakClusterIPs("1.2.3.4")), + expectError: false, + enableDualStackAllocator: true, + preAllocateClusterIPs: nil, + expectedCountIPs: 1, + expectedClusterIPs: []string{"1.2.3.4"}, + }, { + name: "Allocate specified ClusterIP-v6", + svc: makeService("foo", + tweakIPFamilies(api.IPv6Protocol), + tweakClusterIPs("2000:0:0:0:0:0:0:1")), + expectError: false, + enableDualStackAllocator: true, + expectedCountIPs: 1, + expectedClusterIPs: []string{"2000:0:0:0:0:0:0:1"}, + }, { + name: "Allocate dual stack - on a non dual stack ", + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol)), + expectError: false, + enableDualStackAllocator: false, + expectedCountIPs: 1, + }, { + name: "Allocate dual stack - upgrade - v4, v6", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakIPFamilies(api.IPv4Protocol)), + expectError: false, + enableDualStackAllocator: true, + expectedCountIPs: 2, + }, { + name: "Allocate dual stack - upgrade - v4, v6 - specific first IP", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakIPFamilies(api.IPv4Protocol), + tweakClusterIPs("1.2.3.4")), + expectError: false, + enableDualStackAllocator: true, + expectedCountIPs: 2, + expectedClusterIPs: []string{"1.2.3.4"}, + }, { + name: "Allocate dual stack - upgrade - v6, v4", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakIPFamilies(api.IPv6Protocol)), + expectError: false, + enableDualStackAllocator: true, + expectedCountIPs: 2, + }, { + name: "Allocate dual stack - v4, v6 - specific ips", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakClusterIPs("1.2.3.4", "2000:0:0:0:0:0:0:1")), + expectError: false, + enableDualStackAllocator: true, + expectedCountIPs: 2, + expectedClusterIPs: []string{"1.2.3.4", "2000:0:0:0:0:0:0:1"}, + }, { + name: "Allocate dual stack - upgrade - v6, v4 - specific ips", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), + expectError: false, + enableDualStackAllocator: true, + expectedCountIPs: 2, + expectedClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, + }, { + name: "Shouldn't allocate ClusterIP", + svc: makeService("foo", + tweakClusterIPs("None")), + expectError: false, + enableDualStackAllocator: false, + expectedCountIPs: 0, + }, { + name: "single stack, ip is pre allocated (ipv4)", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), + tweakIPFamilies(api.IPv4Protocol), + tweakClusterIPs("1.2.3.4")), + expectError: true, + enableDualStackAllocator: false, + expectedCountIPs: 0, + preAllocateClusterIPs: map[api.IPFamily]string{api.IPv4Protocol: "1.2.3.4"}, + }, { + name: "single stack, ip is pre allocated (ipv6)", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), + tweakIPFamilies(api.IPv6Protocol), + tweakClusterIPs("2000:0:0:0:0:0:0:1")), + expectError: true, + enableDualStackAllocator: true, // ipv6 allocator is always the second one during test + expectedCountIPs: 0, + preAllocateClusterIPs: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, + }, { + name: "Allocate dual stack - upgrade - v6, v4 - specific ips (first ip can't be allocated)", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), + expectError: true, + enableDualStackAllocator: true, + expectedCountIPs: 0, + preAllocateClusterIPs: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, + }, { + name: "Allocate dual stack - upgrade - v6, v4 - specific ips (second ip can't be allocated)", + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), + expectError: true, + enableDualStackAllocator: true, + expectedCountIPs: 0, + preAllocateClusterIPs: map[api.IPFamily]string{api.IPv4Protocol: "1.2.3.4"}, + }} for _, test := range testCases { t.Run(test.name, func(t *testing.T) { @@ -2727,152 +2005,94 @@ func TestInitNodePorts(t *testing.T) { name string service *api.Service expectSpecifiedNodePorts []int - }{ - { - name: "Service doesn't have specified NodePort", - service: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{}, - }, - { - name: "Service has one specified NodePort", - service: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }}, - }, - }, - expectSpecifiedNodePorts: []int{30053}, - }, - { - name: "Service has two same ports with different protocols and specifies same NodePorts", - service: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30054, - }, - { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30054, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30054, 30054}, - }, - { - name: "Service has two same ports with different protocols and specifies different NodePorts", - service: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30055, - }, - { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30056, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30055, 30056}, - }, - { - name: "Service has two different ports with different protocols and specifies different NodePorts", - service: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30057, - }, - { - Name: "port-udp", - Port: 54, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30058, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30057, 30058}, - }, - { - name: "Service has two same ports with different protocols but only specifies one NodePort", - service: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30059, - }, - { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30059, 30059}, - }, - } + }{{ + name: "Service doesn't have specified NodePort", + service: makeService("foo", tweakTypeNodePort), + expectSpecifiedNodePorts: []int{}, + }, { + name: "Service has one specified NodePort", + service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30053, + }} + }), + expectSpecifiedNodePorts: []int{30053}, + }, { + name: "Service has two same ports with different protocols and specifies same NodePorts", + service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30054, + }, { + Name: "port-udp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + NodePort: 30054, + }} + }), + expectSpecifiedNodePorts: []int{30054, 30054}, + }, { + name: "Service has two same ports with different protocols and specifies different NodePorts", + service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30055, + }, { + Name: "port-udp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + NodePort: 30056, + }} + }), + expectSpecifiedNodePorts: []int{30055, 30056}, + }, { + name: "Service has two different ports with different protocols and specifies different NodePorts", + service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30057, + }, { + Name: "port-udp", + Port: 54, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + NodePort: 30058, + }} + }), + expectSpecifiedNodePorts: []int{30057, 30058}, + }, { + name: "Service has two same ports with different protocols but only specifies one NodePort", + service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30059, + }, { + Name: "port-udp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + }} + }), + expectSpecifiedNodePorts: []int{30059, 30059}, + }} for _, test := range testCases { err := initNodePorts(test.service, nodePortOp) @@ -2910,239 +2130,143 @@ func TestUpdateNodePorts(t *testing.T) { oldService *api.Service newService *api.Service expectSpecifiedNodePorts []int - }{ - { - name: "Old service and new service have the same NodePort", - oldService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - NodePort: 30053, - }}, - }, - }, - newService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - NodePort: 30053, - }}, - }, - }, - expectSpecifiedNodePorts: []int{30053}, - }, - { - name: "Old service has more NodePorts than new service has", - oldService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, - { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }, - }, - }, - }, - newService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30053}, - }, - { - name: "Change protocol of ServicePort without changing NodePort", - oldService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, - }, - }, - }, - newService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30053}, - }, - { - name: "Should allocate NodePort when changing service type to NodePort", - oldService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - newService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - expectSpecifiedNodePorts: []int{}, - }, - { - name: "Add new ServicePort with a different protocol without changing port numbers", - oldService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, - }, - }, - }, - newService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, - { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30053, 30053}, - }, - { - name: "Change service type from ClusterIP to NodePort with same NodePort number but different protocols", - oldService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 53, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - newService: &api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo"}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeNodePort, - Ports: []api.ServicePort{ - { - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, - { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }, - }, - }, - }, - expectSpecifiedNodePorts: []int{30053, 30053}, - }, - } + }{{ + name: "Old service and new service have the same NodePort", + oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Port: 6502, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6502), + NodePort: 30053, + }} + }), + newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Port: 6502, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6502), + NodePort: 30053, + }} + }), + expectSpecifiedNodePorts: []int{30053}, + }, { + name: "Old service has more NodePorts than new service has", + oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30053, + }, { + Name: "port-udp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + NodePort: 30053, + }} + }), + newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30053, + }} + }), + expectSpecifiedNodePorts: []int{30053}, + }, { + name: "Change protocol of ServicePort without changing NodePort", + oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30053, + }} + }), + newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-udp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + NodePort: 30053, + }} + }), + expectSpecifiedNodePorts: []int{30053}, + }, { + name: "Should allocate NodePort when changing service type to NodePort", + oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Port: 6502, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6502), + }} + }), + newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Port: 6502, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6502), + }} + }), + expectSpecifiedNodePorts: []int{}, + }, { + name: "Add new ServicePort with a different protocol without changing port numbers", + oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30053, + }} + }), + newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30053, + }, { + Name: "port-udp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + NodePort: 30053, + }} + }), + expectSpecifiedNodePorts: []int{30053, 30053}, + }, { + name: "Change service type from ClusterIP to NodePort with same NodePort number but different protocols", + oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Port: 53, + Protocol: api.ProtocolTCP, + TargetPort: intstr.FromInt(6502), + }} + }), + newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { + s.Spec.Ports = []api.ServicePort{{ + Name: "port-tcp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolTCP, + NodePort: 30053, + }, { + Name: "port-udp", + Port: 53, + TargetPort: intstr.FromInt(6502), + Protocol: api.ProtocolUDP, + NodePort: 30053, + }} + }), + expectSpecifiedNodePorts: []int{30053, 30053}, + }} for _, test := range testCases { err := updateNodePorts(test.oldService, test.newService, nodePortOp) @@ -3180,230 +2304,129 @@ func TestServiceUpgrade(t *testing.T) { enableDualStackGate bool allocateIPsBeforeUpdate map[api.IPFamily]string expectUpgradeError bool - svc api.Service - }{ - { - name: "normal, no upgrade needed", - enableDualStackAllocator: false, - enableDualStackGate: true, - allocateIPsBeforeUpdate: nil, - expectUpgradeError: false, + svc *api.Service + }{{ + name: "normal, no upgrade needed", + enableDualStackAllocator: false, + enableDualStackGate: true, + allocateIPsBeforeUpdate: nil, + expectUpgradeError: false, - updateFunc: func(s *api.Service) { - s.Spec.Selector = map[string]string{"bar": "baz2"} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "error, no upgrade (has single allocator)", - enableDualStackAllocator: false, - enableDualStackGate: true, - allocateIPsBeforeUpdate: nil, - expectUpgradeError: true, - - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &requireDualStack - s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "upgrade to v4,6", - enableDualStackAllocator: true, - enableDualStackGate: true, - allocateIPsBeforeUpdate: nil, - expectUpgradeError: false, - - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &requireDualStack - s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "upgrade to v4,6 (specific ip)", - enableDualStackAllocator: true, - enableDualStackGate: true, - allocateIPsBeforeUpdate: nil, - expectUpgradeError: false, - - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &requireDualStack - s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "2000:0:0:0:0:0:0:1") - s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "upgrade to v4,6 (specific ip) - fail, ip is not available", - enableDualStackAllocator: true, - enableDualStackGate: true, - allocateIPsBeforeUpdate: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, - expectUpgradeError: true, - - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &requireDualStack - s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "2000:0:0:0:0:0:0:1") - s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, + updateFunc: func(s *api.Service) { + s.Spec.Selector = map[string]string{"bar": "baz2"} }, - { - name: "upgrade to v6,4", - enableDualStackAllocator: true, - enableDualStackGate: true, - allocateIPsBeforeUpdate: nil, - expectUpgradeError: false, + svc: makeService("foo"), + }, { + name: "error, no upgrade (has single allocator)", + enableDualStackAllocator: false, + enableDualStackGate: true, + allocateIPsBeforeUpdate: nil, + expectUpgradeError: true, - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &requireDualStack - s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requireDualStack + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }, - { - name: "upgrade to v6,4 (specific ip)", - enableDualStackAllocator: true, - enableDualStackGate: true, - allocateIPsBeforeUpdate: nil, - expectUpgradeError: false, + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} + }), + }, { + name: "upgrade to v4,6", + enableDualStackAllocator: true, + enableDualStackGate: true, + allocateIPsBeforeUpdate: nil, + expectUpgradeError: false, - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &requireDualStack - s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "1.2.3.4") - s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requireDualStack + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }, - { - name: "upgrade to v6,4 (specific ip) - fail ip is already allocated", - enableDualStackAllocator: true, - enableDualStackGate: true, - allocateIPsBeforeUpdate: map[api.IPFamily]string{api.IPv4Protocol: "1.2.3.4"}, - expectUpgradeError: true, + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} + }), + }, { + name: "upgrade to v4,6 (specific ip)", + enableDualStackAllocator: true, + enableDualStackGate: true, + allocateIPsBeforeUpdate: nil, + expectUpgradeError: false, - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &requireDualStack - s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "1.2.3.4") - s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requireDualStack + s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "2000:0:0:0:0:0:0:1") + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }, - } + + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} + }), + }, { + name: "upgrade to v4,6 (specific ip) - fail, ip is not available", + enableDualStackAllocator: true, + enableDualStackGate: true, + allocateIPsBeforeUpdate: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, + expectUpgradeError: true, + + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requireDualStack + s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "2000:0:0:0:0:0:0:1") + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} + }, + + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} + }), + }, { + name: "upgrade to v6,4", + enableDualStackAllocator: true, + enableDualStackGate: true, + allocateIPsBeforeUpdate: nil, + expectUpgradeError: false, + + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requireDualStack + s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} + }, + + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol} + }), + }, { + name: "upgrade to v6,4 (specific ip)", + enableDualStackAllocator: true, + enableDualStackGate: true, + allocateIPsBeforeUpdate: nil, + expectUpgradeError: false, + + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requireDualStack + s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "1.2.3.4") + s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} + }, + + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol} + }), + }, { + name: "upgrade to v6,4 (specific ip) - fail ip is already allocated", + enableDualStackAllocator: true, + enableDualStackGate: true, + allocateIPsBeforeUpdate: map[api.IPFamily]string{api.IPv4Protocol: "1.2.3.4"}, + expectUpgradeError: true, + + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requireDualStack + s.Spec.ClusterIPs = append(s.Spec.ClusterIPs, "1.2.3.4") + s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} + }, + + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol} + }), + }} for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { @@ -3415,7 +2438,7 @@ func TestServiceUpgrade(t *testing.T) { defer server.Terminate(t) defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, testCase.enableDualStackGate)() - obj, err := storage.Create(ctx, &testCase.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err := storage.Create(ctx, testCase.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error is unexpected: %v", err) } @@ -3487,115 +2510,64 @@ func TestServiceDowngrade(t *testing.T) { enableDualStackAllocator bool enableDualStackGate bool expectDowngradeError bool - svc api.Service - }{ - { - name: "normal, no downgrade needed. single stack => single stack", - enableDualStackAllocator: true, - enableDualStackGate: true, - expectDowngradeError: false, + svc *api.Service + }{{ + name: "normal, no downgrade needed. single stack => single stack", + enableDualStackAllocator: true, + enableDualStackGate: true, + expectDowngradeError: false, - updateFunc: func(s *api.Service) { s.Spec.Selector = map[string]string{"bar": "baz2"} }, + updateFunc: func(s *api.Service) { s.Spec.Selector = map[string]string{"bar": "baz2"} }, - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requiredDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - { - name: "normal, no downgrade needed. dual stack => dual stack", - enableDualStackAllocator: true, - enableDualStackGate: true, - expectDowngradeError: false, + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requiredDualStack + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} + }), + }, { + name: "normal, no downgrade needed. dual stack => dual stack", + enableDualStackAllocator: true, + enableDualStackGate: true, + expectDowngradeError: false, - updateFunc: func(s *api.Service) { s.Spec.Selector = map[string]string{"bar": "baz2"} }, + updateFunc: func(s *api.Service) { s.Spec.Selector = map[string]string{"bar": "baz2"} }, - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requiredDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requiredDualStack + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} + }), + }, { + name: "normal, downgrade v4,v6 => v4", + enableDualStackAllocator: true, + enableDualStackGate: true, + expectDowngradeError: false, + + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &singleStack + s.Spec.ClusterIPs = s.Spec.ClusterIPs[0:1] + s.Spec.IPFamilies = s.Spec.IPFamilies[0:1] }, - { - name: "normal, downgrade v4,v6 => v4", - enableDualStackAllocator: true, - enableDualStackGate: true, - expectDowngradeError: false, + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requiredDualStack + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} + }), + }, { + name: "normal, downgrade v6,v4 => v6", + enableDualStackAllocator: true, + enableDualStackGate: true, + expectDowngradeError: false, - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &singleStack - s.Spec.ClusterIPs = s.Spec.ClusterIPs[0:1] - s.Spec.IPFamilies = s.Spec.IPFamilies[0:1] - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requiredDualStack, - - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, + updateFunc: func(s *api.Service) { + s.Spec.IPFamilyPolicy = &singleStack + s.Spec.ClusterIPs = s.Spec.ClusterIPs[0:1] + s.Spec.IPFamilies = s.Spec.IPFamilies[0:1] }, - { - name: "normal, downgrade v6,v4 => v6", - enableDualStackAllocator: true, - enableDualStackGate: true, - expectDowngradeError: false, - updateFunc: func(s *api.Service) { - s.Spec.IPFamilyPolicy = &singleStack - s.Spec.ClusterIPs = s.Spec.ClusterIPs[0:1] - s.Spec.IPFamilies = s.Spec.IPFamilies[0:1] - }, - - svc: api.Service{ - ObjectMeta: metav1.ObjectMeta{Name: "foo", ResourceVersion: "1", Namespace: metav1.NamespaceDefault}, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requiredDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - Ports: []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }}, - }, - }, - }, - } + svc: makeService("foo", func(s *api.Service) { + s.Spec.IPFamilyPolicy = &requiredDualStack + s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} + }), + }} for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { @@ -3603,7 +2575,7 @@ func TestServiceDowngrade(t *testing.T) { defer server.Terminate(t) defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, testCase.enableDualStackGate)() - obj, err := storage.Create(ctx, &testCase.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err := storage.Create(ctx, testCase.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error is unexpected: %v", err) } @@ -3697,7 +2669,7 @@ func TestDefaultingValidation(t *testing.T) { name string modifyRest func(rest *REST) oldSvc *api.Service - svc api.Service + svc *api.Service expectedIPFamilyPolicy *api.IPFamilyPolicyType expectedIPFamilies []api.IPFamily @@ -3707,25 +2679,17 @@ func TestDefaultingValidation(t *testing.T) { // cluster configured as single stack v4 //////////////////////////// { - name: "[singlestack:v4] set: externalname on a single stack - v4", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeExternalName, - }, - }, + name: "[singlestack:v4] set: externalname on a single stack - v4", + modifyRest: fnMakeSingleStackIPv4Allocator, + svc: makeService("foo", tweakTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, }, { - name: "[singlestack:v4] set: nothing", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - }, - }, + name: "[singlestack:v4] set: nothing", + modifyRest: fnMakeSingleStackIPv4Allocator, + svc: makeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3734,12 +2698,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v4Cluster IPSet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3747,12 +2707,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v4IPFamilySet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3760,13 +2716,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v4IPFamilySet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"10.0.0.4"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("10.0.0.4"), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3774,12 +2726,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: PreferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3787,13 +2735,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: PreferDualStack + v4ClusterIPSet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3801,14 +2745,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakIPFamilies(api.IPv4Protocol), + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3816,12 +2756,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v6IPSet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3829,12 +2765,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v6IPFamily", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3842,12 +2774,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: RequireDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3855,13 +2783,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: RequireDualStack + family", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3870,13 +2794,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, families are ignored", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3884,12 +2805,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, no families", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3897,13 +2815,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, user selected", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3911,13 +2826,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, user set to preferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3926,14 +2838,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: multifamily set to preferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3941,14 +2848,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: multifamily set to singleStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3956,14 +2858,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: mult clusterips set to preferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3971,14 +2868,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: multi clusterips set to singleStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3988,25 +2880,17 @@ func TestDefaultingValidation(t *testing.T) { // cluster configured as single stack v6 //////////////////////////// { - name: "[singlestack:v6] set: externalname on a single stack - v4", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeExternalName, - }, - }, + name: "[singlestack:v6] set: externalname on a single stack - v4", + modifyRest: fnMakeSingleStackIPv6Allocator, + svc: makeService("foo", tweakTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, }, { - name: "[singlestack:v6] set: nothing", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - }, - }, + name: "[singlestack:v6] set: nothing", + modifyRest: fnMakeSingleStackIPv6Allocator, + svc: makeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4014,12 +2898,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v6Cluster IPSet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4027,12 +2907,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v4IPFamilySet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4040,13 +2916,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v6IPFamilySet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000::1"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("2000::1"), + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4054,12 +2926,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: PreferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4067,13 +2935,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: PreferDualStack + v6ClusterIPSet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4081,14 +2945,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: PreferDualStack + v6ClusterIPSet + v6FamilySet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakIPFamilies(api.IPv6Protocol), + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4096,12 +2956,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v4IPSet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"10.0.0.10"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4109,12 +2965,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v4IPFamily", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4122,12 +2974,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: RequireDualStack (on single stack ipv6 cluster)", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4135,13 +2983,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: RequireDualStack + family (on single stack ipv6 cluster)", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4151,13 +2995,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, families are ignored", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4165,12 +3006,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, no families", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - ClusterIPs: []string{"None"}, - Type: api.ServiceTypeClusterIP, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4178,13 +3016,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, user selected", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4192,13 +3027,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, user set to preferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4207,14 +3039,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: multifamily set to preferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4222,14 +3049,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: multifamily set to singleStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4237,14 +3059,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: mult clusterips set to preferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4252,14 +3069,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: multi clusterips set to singleStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4269,25 +3081,17 @@ func TestDefaultingValidation(t *testing.T) { // cluster configured as dual stack v4,6 //////////////////////////// { - name: "[dualstack:v4,v6] set: externalname on a dual stack - v4,v6", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeExternalName, - }, - }, + name: "[dualstack:v4,v6] set: externalname on a dual stack - v4,v6", + modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, + svc: makeService("foo", tweakTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, }, { - name: "[dualstack:v4,v6] set: nothing", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - }, - }, + name: "[dualstack:v4,v6] set: nothing", + modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, + svc: makeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -4296,12 +3100,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -4309,12 +3109,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -4322,13 +3118,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"10.0.0.4"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("10.0.0.4"), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -4336,12 +3128,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v6ClusterIPSet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4349,12 +3137,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4362,13 +3146,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000::1"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("2000::1"), + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4377,12 +3157,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: PreferDualStack.", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4390,13 +3166,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: PreferDualStack + v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4404,14 +3176,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakIPFamilies(api.IPv4Protocol), + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4420,12 +3188,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4433,13 +3197,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4447,13 +3207,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4462,14 +3218,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family +ip v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10"), + tweakIPFamilies(api.IPv4Protocol)), // expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, @@ -4478,14 +3230,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family +ip v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1"), + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4493,13 +3241,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ip v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4507,13 +3251,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ip v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4521,13 +3261,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10", "2000::1"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10", "2000::1")), // expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, @@ -4536,13 +3272,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1", "10.0.0.10"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1", "10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4550,14 +3282,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ips + families v6,v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1", "10.0.0.10"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1", "10.0.0.10"), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4565,14 +3293,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v4,v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10", "2000::1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10", "2000::1"), + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4580,12 +3304,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: selectorless, no families", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4593,13 +3314,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: selectorless, user selected", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -4607,13 +3324,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: selectorless, user set to prefer", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4622,14 +3335,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[duakstack:v4,6] set: multifamily set to preferDualStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4637,14 +3345,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: multifamily set to singleStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4652,14 +3355,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: mult clusterips set to preferDualStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4667,14 +3365,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: multi clusterips set to singleStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -4684,25 +3377,17 @@ func TestDefaultingValidation(t *testing.T) { // cluster configured as dual stack v6,4 //////////////////////////// { - name: "[dualstack:v6,v4] set: externalname on a dual stack - v6,v4", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeExternalName, - }, - }, + name: "[dualstack:v6,v4] set: externalname on a dual stack - v6,v4", + modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, + svc: makeService("foo", tweakTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, }, { - name: "[dualstack:v6,v4] set: nothing", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - }, - }, + name: "[dualstack:v6,v4] set: nothing", + modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, + svc: makeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4710,12 +3395,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -4723,12 +3404,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol)), // expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, @@ -4737,13 +3414,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"10.0.0.4"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("10.0.0.4"), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -4751,12 +3424,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v6ClusterIPSet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4764,12 +3433,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4777,13 +3442,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"2000::1"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("2000::1"), + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -4792,12 +3453,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: PreferDualStack.", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4805,13 +3462,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: PreferDualStack + v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4819,14 +3472,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &preferDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - ClusterIPs: []string{"10.0.0.4"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + tweakIPFamilies(api.IPv4Protocol), + tweakClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4835,12 +3484,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4848,13 +3493,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4862,13 +3503,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4876,14 +3513,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family +ip v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10"), + tweakIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4891,14 +3524,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family +ip v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1"), + tweakIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4906,13 +3535,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ip v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4920,13 +3545,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ip v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4934,13 +3555,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ip v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4948,13 +3565,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10", "2000::1"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10", "2000::1")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -4962,13 +3575,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1", "10.0.0.10"}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1", "10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4976,14 +3585,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v6,v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"2000::1", "10.0.0.10"}, - IPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("2000::1", "10.0.0.10"), + tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -4991,14 +3596,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v4,v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - IPFamilyPolicy: &requireDualStack, - ClusterIPs: []string{"10.0.0.10", "2000::1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - }, - }, + svc: makeService("foo", + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + tweakClusterIPs("10.0.0.10", "2000::1"), + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -5006,12 +3607,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: selectorless, no families", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -5019,13 +3617,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: selectorless, user selected", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, @@ -5034,13 +3628,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: selectorless, user set to prefer", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"None"}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("None"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, @@ -5050,14 +3640,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[duakstack:v6,5] set: multifamily set to preferDualStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -5065,14 +3650,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: multifamily set to singleStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -5080,14 +3660,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,4] set: mult clusterips set to preferDualStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -5095,14 +3670,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,4] set: multi clusterips set to singleStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: nil, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -5114,23 +3684,15 @@ func TestDefaultingValidation(t *testing.T) { { name: "unchanged preferDualStack-1-ClusterUpgraded", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - oldSvc: &api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + oldSvc: makeService("foo", + tweakClusterIPs("1.1.1.1"), + tweakIPFamilies(api.IPv4Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1"), + tweakIPFamilies(api.IPv4Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -5139,23 +3701,15 @@ func TestDefaultingValidation(t *testing.T) { { name: "unchanged preferDualStack-2-ClusterDowngraded", modifyRest: fnMakeSingleStackIPv4Allocator, - oldSvc: &api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + oldSvc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -5164,23 +3718,14 @@ func TestDefaultingValidation(t *testing.T) { { name: "changed preferDualStack-1 (cluster upgraded)", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - oldSvc: &api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + oldSvc: makeService("foo", + tweakClusterIPs("1.1.1.1"), + tweakIPFamilies(api.IPv4Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: nil, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - IPFamilyPolicy: &requireDualStack, - }, - }, + svc: makeService("foo", + tweakIPFamilies(api.IPv4Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -5189,23 +3734,15 @@ func TestDefaultingValidation(t *testing.T) { { name: "changed preferDualStack-2-ClusterDowngraded", modifyRest: fnMakeSingleStackIPv4Allocator, - oldSvc: &api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1", "2001::1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - IPFamilyPolicy: &preferDualStack, - }, - }, + oldSvc: makeService("foo", + tweakClusterIPs("1.1.1.1", "2001::1"), + tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: api.Service{ - Spec: api.ServiceSpec{ - Type: api.ServiceTypeClusterIP, - ClusterIPs: []string{"1.1.1.1"}, - IPFamilies: []api.IPFamily{api.IPv4Protocol}, - IPFamilyPolicy: &singleStack, - }, - }, + svc: makeService("foo", + tweakClusterIPs("1.1.1.1"), + tweakIPFamilies(api.IPv4Protocol), + tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -5228,7 +3765,7 @@ func TestDefaultingValidation(t *testing.T) { testCase.modifyRest(storage) } - err := storage.tryDefaultValidateServiceClusterIPFields(testCase.oldSvc, &testCase.svc) + err := storage.tryDefaultValidateServiceClusterIPFields(testCase.oldSvc, testCase.svc) if err != nil && !testCase.expectError { t.Fatalf("error %v was not expected", err) } From b1fcbab80145915ad88debb82e2892f750162366 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Thu, 1 Jul 2021 10:36:08 -0700 Subject: [PATCH 08/20] Service REST test: helper funcs for ports, too --- .../core/service/storage/rest_test.go | 434 ++++++------------ 1 file changed, 137 insertions(+), 297 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 4f956034458..e31fddb593e 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -284,15 +284,12 @@ func makeService(name string, tweaks ...serviceTweak) *api.Service { Spec: api.ServiceSpec{ Selector: map[string]string{"bar": "baz"}, SessionAffinity: api.ServiceAffinityNone, - Ports: []api.ServicePort{{ - Port: 93, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(76), - }}, }, } // Default to ClusterIP tweakTypeClusterIP(svc) + // Default to 1 port + tweakPorts(makeServicePort("", 93, intstr.FromInt(76), api.ProtocolTCP))(svc) for _, tweak := range tweaks { tweak(svc) @@ -327,12 +324,12 @@ func tweakPorts(ports ...api.ServicePort) serviceTweak { } } -func makeServicePort(name string, port int, tgtPort intstr.IntOrString) api.ServicePort { +func makeServicePort(name string, port int, tgtPort intstr.IntOrString, proto api.Protocol) api.ServicePort { return api.ServicePort{ Name: name, Port: int32(port), TargetPort: tgtPort, - Protocol: api.ProtocolTCP, + Protocol: proto, } } @@ -355,6 +352,17 @@ func tweakIPFamilyPolicy(policy api.IPFamilyPolicyType) serviceTweak { } } +func tweakNodePorts(values ...int) serviceTweak { + return func(svc *api.Service) { + for i := range svc.Spec.Ports { + if i >= len(values) { + break + } + svc.Spec.Ports[i].NodePort = int32(values[i]) + } + } +} + func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, rest *REST, registry ServiceStorage) { obj, err := registry.Get(ctx, svcName, &metav1.GetOptions{}) if err != nil { @@ -541,21 +549,10 @@ func TestDryRunNodePort(t *testing.T) { // Test dry run create request with multi node port svc = makeService("foo", tweakTypeNodePort, - func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolTCP, - }, { - Name: "port-udp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolUDP, - }} - }) + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6503), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6503), api.ProtocolUDP)), + tweakNodePorts(30053, 30053)) expectNodePorts := collectServiceNodePorts(svc) obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { @@ -583,19 +580,9 @@ func TestDryRunNodePort(t *testing.T) { // so PortAllocationOperation.AllocateNext() will be called multiple times. svc = makeService("foo", tweakTypeNodePort, - func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-a", - Port: 53, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6503), - }, { - Name: "port-b", - Port: 54, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6504), - }} - }) + tweakPorts( + makeServicePort("port-a", 53, intstr.FromInt(6503), api.ProtocolTCP), + makeServicePort("port-b", 54, intstr.FromInt(6504), api.ProtocolUDP))) obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Unexpected error: %v", err) @@ -626,60 +613,28 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { }{{ svc: makeService("foo1", tweakTypeNodePort, - func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolTCP, - }, { - Name: "port-udp", - Port: 53, - NodePort: 30053, - TargetPort: intstr.FromInt(6503), - Protocol: api.ProtocolUDP, - }} - }), + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6503), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6503), api.ProtocolUDP)), + tweakNodePorts(30053, 30053)), name: "foo1", expectNodePorts: []int{30053, 30053}, }, { svc: makeService("foo2", tweakTypeNodePort, - func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 54, - TargetPort: intstr.FromInt(6504), - Protocol: api.ProtocolTCP, - }, { - Name: "port-udp", - Port: 54, - NodePort: 30054, - TargetPort: intstr.FromInt(6504), - Protocol: api.ProtocolUDP, - }} - }), + tweakPorts( + makeServicePort("port-tcp", 54, intstr.FromInt(6504), api.ProtocolTCP), + makeServicePort("port-udp", 54, intstr.FromInt(6504), api.ProtocolUDP)), + tweakNodePorts(30054, 30054)), name: "foo2", expectNodePorts: []int{30054, 30054}, }, { svc: makeService("foo3", tweakTypeNodePort, - func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 55, - NodePort: 30055, - TargetPort: intstr.FromInt(6505), - Protocol: api.ProtocolTCP, - }, { - Name: "port-udp", - Port: 55, - NodePort: 30056, - TargetPort: intstr.FromInt(6506), - Protocol: api.ProtocolUDP, - }} - }), + tweakPorts( + makeServicePort("port-tcp", 55, intstr.FromInt(6505), api.ProtocolTCP), + makeServicePort("port-udp", 55, intstr.FromInt(6506), api.ProtocolUDP)), + tweakNodePorts(30055, 30056)), name: "foo3", expectNodePorts: []int{30055, 30056}, }} @@ -725,17 +680,10 @@ func TestServiceStorageValidatesCreate(t *testing.T) { defer server.Terminate(t) failureCases := map[string]*api.Service{ "empty ID": makeService(""), - "empty port": makeService("foo", func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Protocol: api.ProtocolTCP, - }} - }), - "missing targetPort": makeService("foo", func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - }} - }), + "empty port": makeService("foo", tweakPorts( + makeServicePort("p", 0, intstr.FromInt(80), api.ProtocolTCP))), + "missing targetPort": makeService("foo", tweakPorts( + makeServicePort("p", 80, intstr.IntOrString{}, api.ProtocolTCP))), } ctx := genericapirequest.NewDefaultContext() for _, failureCase := range failureCases { @@ -1154,20 +1102,11 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { defer server.Terminate(t) // Create external load balancer. - svc1 := makeService("foo", func(s *api.Service) { - s.Spec.Type = api.ServiceTypeLoadBalancer - s.Spec.Ports = []api.ServicePort{{ - Name: "p", - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }, { - Name: "q", - Port: 8086, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(8086), - }} - }) + svc1 := makeService("foo", + tweakTypeLoadBalancer, + tweakPorts( + makeServicePort("p", 6502, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("q", 8086, intstr.FromInt(8086), api.ProtocolTCP))) obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) @@ -1271,16 +1210,14 @@ func TestServiceRegistryResourceLocation(t *testing.T) { storage, registry, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) defer server.Terminate(t) for _, name := range []string{"foo", "bad"} { - _, err := registry.Create(ctx, makeService(name, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{ + _, err := registry.Create(ctx, makeService(name, + tweakPorts( // Service port 9393 should route to endpoint port "p", which is port 93 - {Name: "p", Port: 9393, TargetPort: intstr.FromString("p")}, - + makeServicePort("p", 9393, intstr.FromString("p"), api.ProtocolTCP), // Service port 93 should route to unnamed endpoint port, which is port 80 // This is to test that the service port definition is used when determining resource location - {Name: "", Port: 93, TargetPort: intstr.FromInt(80)}, - } - }), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + makeServicePort("", 93, intstr.FromInt(80), api.ProtocolTCP))), + rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } @@ -2011,86 +1948,47 @@ func TestInitNodePorts(t *testing.T) { expectSpecifiedNodePorts: []int{}, }, { name: "Service has one specified NodePort", - service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }} - }), + service: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + tweakNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Service has two same ports with different protocols and specifies same NodePorts", - service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30054, - }, { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30054, - }} - }), + service: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30054, 30054)), expectSpecifiedNodePorts: []int{30054, 30054}, }, { name: "Service has two same ports with different protocols and specifies different NodePorts", - service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30055, - }, { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30056, - }} - }), + service: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30055, 30056)), expectSpecifiedNodePorts: []int{30055, 30056}, }, { name: "Service has two different ports with different protocols and specifies different NodePorts", - service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30057, - }, { - Name: "port-udp", - Port: 54, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30058, - }} - }), + service: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("port-udp", 54, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30057, 30058)), expectSpecifiedNodePorts: []int{30057, 30058}, }, { name: "Service has two same ports with different protocols but only specifies one NodePort", - service: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30059, - }, { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - }} - }), + service: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30059)), expectSpecifiedNodePorts: []int{30059, 30059}, }} @@ -2132,139 +2030,81 @@ func TestUpdateNodePorts(t *testing.T) { expectSpecifiedNodePorts []int }{{ name: "Old service and new service have the same NodePort", - oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - NodePort: 30053, - }} - }), - newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - NodePort: 30053, - }} - }), + oldService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolTCP)), + tweakNodePorts(30053)), + newService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolTCP)), + tweakNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Old service has more NodePorts than new service has", - oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }} - }), - newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }} - }), + oldService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30053, 30053)), + newService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + tweakNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Change protocol of ServicePort without changing NodePort", - oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }} - }), - newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }} - }), + oldService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + tweakNodePorts(30053)), + newService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Should allocate NodePort when changing service type to NodePort", - oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }} - }), - newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Port: 6502, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }} - }), + oldService: makeService("foo", + tweakTypeClusterIP, + tweakPorts( + makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolUDP))), + newService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolUDP))), expectSpecifiedNodePorts: []int{}, }, { name: "Add new ServicePort with a different protocol without changing port numbers", - oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }} - }), - newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }} - }), + oldService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + tweakNodePorts(30053)), + newService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30053, 30053)), expectSpecifiedNodePorts: []int{30053, 30053}, }, { name: "Change service type from ClusterIP to NodePort with same NodePort number but different protocols", - oldService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Port: 53, - Protocol: api.ProtocolTCP, - TargetPort: intstr.FromInt(6502), - }} - }), - newService: makeService("foo", tweakTypeNodePort, func(s *api.Service) { - s.Spec.Ports = []api.ServicePort{{ - Name: "port-tcp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolTCP, - NodePort: 30053, - }, { - Name: "port-udp", - Port: 53, - TargetPort: intstr.FromInt(6502), - Protocol: api.ProtocolUDP, - NodePort: 30053, - }} - }), + oldService: makeService("foo", + tweakTypeClusterIP, + tweakPorts( + makeServicePort("", 53, intstr.FromInt(6502), api.ProtocolTCP))), + newService: makeService("foo", + tweakTypeNodePort, + tweakPorts( + makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + tweakNodePorts(30053, 30053)), expectSpecifiedNodePorts: []int{30053, 30053}, }} From 175f4f3387353fd45d77837060e233b9f0bbdb08 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 29 Jun 2021 22:22:28 -0700 Subject: [PATCH 09/20] Move service test-helper funcs to a package --- pkg/api/service/testing/make.go | 141 ++ .../core/service/storage/rest_test.go | 1200 ++++++++--------- 2 files changed, 693 insertions(+), 648 deletions(-) create mode 100644 pkg/api/service/testing/make.go diff --git a/pkg/api/service/testing/make.go b/pkg/api/service/testing/make.go new file mode 100644 index 00000000000..a3e2b7b3883 --- /dev/null +++ b/pkg/api/service/testing/make.go @@ -0,0 +1,141 @@ +/* +Copyright 2021 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 ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" + + api "k8s.io/kubernetes/pkg/apis/core" +) + +// Tweak is a function that modifies a Service. +type Tweak func(*api.Service) + +// MakeService helps construct Service objects (which pass API validation) more +// legibly and tersely than a Go struct definition. By default this produces +// a ClusterIP service with a single port and a trivial selector. The caller +// can pass any number of tweak functions to further modify the result. +func MakeService(name string, tweaks ...Tweak) *api.Service { + // NOTE: Any field that would be populated by defaulting needs to be + // present and valid here. + svc := &api.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Spec: api.ServiceSpec{ + Selector: map[string]string{"k": "v"}, + SessionAffinity: api.ServiceAffinityNone, + }, + } + // Default to ClusterIP + SetTypeClusterIP(svc) + // Default to 1 port + SetPorts(MakeServicePort("", 93, intstr.FromInt(76), api.ProtocolTCP))(svc) + + for _, tweak := range tweaks { + tweak(svc) + } + + return svc +} + +// SetTypeClusterIP sets the service type to ClusterIP and clears other fields. +func SetTypeClusterIP(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeClusterIP + for i := range svc.Spec.Ports { + svc.Spec.Ports[i].NodePort = 0 + } + svc.Spec.ExternalName = "" +} + +// SetTypeNodePort sets the service type to NodePort and clears other fields. +func SetTypeNodePort(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeNodePort + svc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster + svc.Spec.ExternalName = "" +} + +// SetTypeLoadBalancer sets the service type to LoadBalancer and clears other fields. +func SetTypeLoadBalancer(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeLoadBalancer + svc.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster + svc.Spec.ExternalName = "" +} + +// SetTypeExternalName sets the service type to ExternalName and clears other fields. +func SetTypeExternalName(svc *api.Service) { + svc.Spec.Type = api.ServiceTypeExternalName + svc.Spec.ExternalName = "example.com" + svc.Spec.ExternalTrafficPolicy = "" + svc.Spec.ClusterIP = "" + svc.Spec.ClusterIPs = nil +} + +// SetPorts sets the service ports list. +func SetPorts(ports ...api.ServicePort) Tweak { + return func(svc *api.Service) { + svc.Spec.Ports = ports + } +} + +// MakeServicePort helps construct ServicePort objects which pass API +// validation. +func MakeServicePort(name string, port int, tgtPort intstr.IntOrString, proto api.Protocol) api.ServicePort { + return api.ServicePort{ + Name: name, + Port: int32(port), + TargetPort: tgtPort, + Protocol: proto, + } +} + +// SetClusterIPs sets the service ClusterIP and ClusterIPs fields. +func SetClusterIPs(ips ...string) Tweak { + return func(svc *api.Service) { + svc.Spec.ClusterIP = ips[0] + svc.Spec.ClusterIPs = ips + } +} + +// SetIPFamilies sets the service IPFamilies field. +func SetIPFamilies(families ...api.IPFamily) Tweak { + return func(svc *api.Service) { + svc.Spec.IPFamilies = families + } +} + +// SetIPFamilyPolicy sets the service IPFamilyPolicy field. +func SetIPFamilyPolicy(policy api.IPFamilyPolicyType) Tweak { + return func(svc *api.Service) { + svc.Spec.IPFamilyPolicy = &policy + } +} + +// SetNodePorts sets the values for each node port, in order. If less values +// are specified than there are ports, the rest are untouched. +func SetNodePorts(values ...int) Tweak { + return func(svc *api.Service) { + for i := range svc.Spec.Ports { + if i >= len(values) { + break + } + svc.Spec.Ports[i].NodePort = int32(values[i]) + } + } +} diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index e31fddb593e..f1359339621 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -36,22 +36,20 @@ import ( "k8s.io/apiserver/pkg/registry/rest" etcd3testing "k8s.io/apiserver/pkg/storage/etcd3/testing" "k8s.io/apiserver/pkg/util/dryrun" - + utilfeature "k8s.io/apiserver/pkg/util/feature" + featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/kubernetes/pkg/api/service" + svctest "k8s.io/kubernetes/pkg/api/service/testing" api "k8s.io/kubernetes/pkg/apis/core" + "k8s.io/kubernetes/pkg/features" endpointstore "k8s.io/kubernetes/pkg/registry/core/endpoint/storage" podstore "k8s.io/kubernetes/pkg/registry/core/pod/storage" "k8s.io/kubernetes/pkg/registry/core/service/ipallocator" "k8s.io/kubernetes/pkg/registry/core/service/portallocator" "k8s.io/kubernetes/pkg/registry/registrytest" - "sigs.k8s.io/structured-merge-diff/v4/fieldpath" - - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" - "k8s.io/kubernetes/pkg/features" - netutil "k8s.io/utils/net" utilpointer "k8s.io/utils/pointer" + "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) var ( @@ -269,100 +267,6 @@ func makeIPNet6(t *testing.T) *net.IPNet { return net } -// For clarity. -type serviceTweak func(*api.Service) - -// This is used to clarify test sites. -func makeService(name string, tweaks ...serviceTweak) *api.Service { - // NOTE: Any field that would be populated by defaulting needs to be - // present and valid here. - svc := &api.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: metav1.NamespaceDefault, - }, - Spec: api.ServiceSpec{ - Selector: map[string]string{"bar": "baz"}, - SessionAffinity: api.ServiceAffinityNone, - }, - } - // Default to ClusterIP - tweakTypeClusterIP(svc) - // Default to 1 port - tweakPorts(makeServicePort("", 93, intstr.FromInt(76), api.ProtocolTCP))(svc) - - for _, tweak := range tweaks { - tweak(svc) - } - - return svc -} - -func tweakTypeClusterIP(svc *api.Service) { - svc.Spec.Type = api.ServiceTypeClusterIP -} - -func tweakTypeNodePort(svc *api.Service) { - svc.Spec.Type = api.ServiceTypeNodePort -} - -func tweakTypeLoadBalancer(svc *api.Service) { - svc.Spec.Type = api.ServiceTypeLoadBalancer -} - -func tweakTypeExternalName(svc *api.Service) { - svc.Spec.Type = api.ServiceTypeExternalName - svc.Spec.ExternalName = "example.com" - svc.Spec.ExternalTrafficPolicy = "" - svc.Spec.ClusterIP = "" - svc.Spec.ClusterIPs = nil -} - -func tweakPorts(ports ...api.ServicePort) serviceTweak { - return func(svc *api.Service) { - svc.Spec.Ports = ports - } -} - -func makeServicePort(name string, port int, tgtPort intstr.IntOrString, proto api.Protocol) api.ServicePort { - return api.ServicePort{ - Name: name, - Port: int32(port), - TargetPort: tgtPort, - Protocol: proto, - } -} - -func tweakClusterIPs(ips ...string) serviceTweak { - return func(svc *api.Service) { - svc.Spec.ClusterIP = ips[0] - svc.Spec.ClusterIPs = ips - } -} - -func tweakIPFamilies(families ...api.IPFamily) serviceTweak { - return func(svc *api.Service) { - svc.Spec.IPFamilies = families - } -} - -func tweakIPFamilyPolicy(policy api.IPFamilyPolicyType) serviceTweak { - return func(svc *api.Service) { - svc.Spec.IPFamilyPolicy = &policy - } -} - -func tweakNodePorts(values ...int) serviceTweak { - return func(svc *api.Service) { - for i := range svc.Spec.Ports { - if i >= len(values) { - break - } - svc.Spec.Ports[i].NodePort = int32(values[i]) - } - } -} - func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, rest *REST, registry ServiceStorage) { obj, err := registry.Get(ctx, svcName, &metav1.GetOptions{}) if err != nil { @@ -392,22 +296,22 @@ func TestServiceRegistryCreate(t *testing.T) { name: "Service IPFamily default cluster dualstack:off", enableDualStack: false, families: []api.IPFamily{api.IPv4Protocol}, - svc: makeService("foo"), + svc: svctest.MakeService("foo"), }, { name: "Service IPFamily:v4 dualstack off", enableDualStack: false, families: []api.IPFamily{api.IPv4Protocol}, - svc: makeService("foo", tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", svctest.SetIPFamilies(api.IPv4Protocol)), }, { name: "Service IPFamily:v4 dualstack on", enableDualStack: true, families: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - svc: makeService("foo", tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", svctest.SetIPFamilies(api.IPv4Protocol)), }, { name: "Service IPFamily:v6 dualstack on", enableDualStack: true, families: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - svc: makeService("foo", tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", svctest.SetIPFamilies(api.IPv6Protocol)), }} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -461,27 +365,27 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { }{{ name: "v4 service featuregate off", enableDualStack: false, - svc: makeService("foo", tweakClusterIPs("1.2.3.4")), + svc: svctest.MakeService("foo", svctest.SetClusterIPs("1.2.3.4")), }, { name: "v6 service featuregate on but singlestack", enableDualStack: true, - svc: makeService("foo", - tweakIPFamilies(api.IPv6Protocol), - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv6Protocol), + svctest.SetClusterIPs("2000::1")), }, { name: "dualstack v4,v6 service", enableDualStack: true, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakClusterIPs("1.2.3.4", "2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetClusterIPs("1.2.3.4", "2000::1")), }, { name: "dualstack v6,v4 service", enableDualStack: true, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), - tweakClusterIPs("2000::1", "1.2.3.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + svctest.SetClusterIPs("2000::1", "1.2.3.4")), }} for _, tc := range testCases { @@ -524,7 +428,7 @@ func TestDryRunNodePort(t *testing.T) { defer server.Terminate(t) // Test dry run create request with a node port - svc := makeService("foo", tweakTypeNodePort) + svc := svctest.MakeService("foo", svctest.SetTypeNodePort) ctx := genericapirequest.NewDefaultContext() obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) @@ -547,12 +451,12 @@ func TestDryRunNodePort(t *testing.T) { } // Test dry run create request with multi node port - svc = makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6503), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6503), api.ProtocolUDP)), - tweakNodePorts(30053, 30053)) + svc = svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6503), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6503), api.ProtocolUDP)), + svctest.SetNodePorts(30053, 30053)) expectNodePorts := collectServiceNodePorts(svc) obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { @@ -578,11 +482,11 @@ func TestDryRunNodePort(t *testing.T) { // Test dry run create request with multiple unspecified node ports, // so PortAllocationOperation.AllocateNext() will be called multiple times. - svc = makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-a", 53, intstr.FromInt(6503), api.ProtocolTCP), - makeServicePort("port-b", 54, intstr.FromInt(6504), api.ProtocolUDP))) + svc = svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-a", 53, intstr.FromInt(6503), api.ProtocolTCP), + svctest.MakeServicePort("port-b", 54, intstr.FromInt(6504), api.ProtocolUDP))) obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Unexpected error: %v", err) @@ -611,30 +515,30 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { name string expectNodePorts []int }{{ - svc: makeService("foo1", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6503), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6503), api.ProtocolUDP)), - tweakNodePorts(30053, 30053)), + svc: svctest.MakeService("foo1", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6503), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6503), api.ProtocolUDP)), + svctest.SetNodePorts(30053, 30053)), name: "foo1", expectNodePorts: []int{30053, 30053}, }, { - svc: makeService("foo2", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 54, intstr.FromInt(6504), api.ProtocolTCP), - makeServicePort("port-udp", 54, intstr.FromInt(6504), api.ProtocolUDP)), - tweakNodePorts(30054, 30054)), + svc: svctest.MakeService("foo2", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 54, intstr.FromInt(6504), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 54, intstr.FromInt(6504), api.ProtocolUDP)), + svctest.SetNodePorts(30054, 30054)), name: "foo2", expectNodePorts: []int{30054, 30054}, }, { - svc: makeService("foo3", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 55, intstr.FromInt(6505), api.ProtocolTCP), - makeServicePort("port-udp", 55, intstr.FromInt(6506), api.ProtocolUDP)), - tweakNodePorts(30055, 30056)), + svc: svctest.MakeService("foo3", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 55, intstr.FromInt(6505), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 55, intstr.FromInt(6506), api.ProtocolUDP)), + svctest.SetNodePorts(30055, 30056)), name: "foo3", expectNodePorts: []int{30055, 30056}, }} @@ -679,11 +583,11 @@ func TestServiceStorageValidatesCreate(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) failureCases := map[string]*api.Service{ - "empty ID": makeService(""), - "empty port": makeService("foo", tweakPorts( - makeServicePort("p", 0, intstr.FromInt(80), api.ProtocolTCP))), - "missing targetPort": makeService("foo", tweakPorts( - makeServicePort("p", 80, intstr.IntOrString{}, api.ProtocolTCP))), + "empty ID": svctest.MakeService(""), + "empty port": svctest.MakeService("foo", svctest.SetPorts( + svctest.MakeServicePort("p", 0, intstr.FromInt(80), api.ProtocolTCP))), + "missing targetPort": svctest.MakeService("foo", svctest.SetPorts( + svctest.MakeServicePort("p", 80, intstr.IntOrString{}, api.ProtocolTCP))), } ctx := genericapirequest.NewDefaultContext() for _, failureCase := range failureCases { @@ -702,7 +606,7 @@ func TestServiceRegistryUpdate(t *testing.T) { storage, registry, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) - _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -740,7 +644,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - obj, err := registry.Create(ctx, makeService("foo", tweakTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err := registry.Create(ctx, svctest.MakeService("foo", svctest.SetTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -748,7 +652,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { // Test dry run update request external name to node port new1 := svc.DeepCopy() - tweakTypeNodePort(new1) + svctest.SetTypeNodePort(new1) updatedSvc, created, err := storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new1), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { @@ -769,7 +673,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { // Test dry run update request external name to cluster ip new2 := svc.DeepCopy() - tweakTypeClusterIP(new2) + svctest.SetTypeClusterIP(new2) _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { @@ -780,7 +684,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { } // Test dry run update request remove node port - obj, err = storage.Create(ctx, makeService("foo2", tweakTypeNodePort), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, svctest.MakeService("foo2", svctest.SetTypeNodePort), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -793,7 +697,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { } new3 := svc.DeepCopy() - tweakTypeExternalName(new3) + svctest.SetTypeExternalName(new3) _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new3), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { @@ -804,14 +708,14 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { } // Test dry run update request remove cluster ip - obj, err = storage.Create(ctx, makeService("foo3"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, svctest.MakeService("foo3"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("expected no error: %v", err) } svc = obj.(*api.Service) new4 := svc.DeepCopy() - tweakTypeExternalName(new4) + svctest.SetTypeExternalName(new4) _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new4), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { @@ -826,13 +730,13 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } failureCases := map[string]*api.Service{ - "empty ID": makeService(""), - "invalid selector": makeService("", func(svc *api.Service) { + "empty ID": svctest.MakeService(""), + "invalid selector": svctest.MakeService("", func(svc *api.Service) { svc.Spec.Selector = map[string]string{"ThisSelectorFailsValidation": "ok"} }), } @@ -851,7 +755,7 @@ func TestServiceRegistryExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("foo", tweakTypeLoadBalancer) + svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create service: %#v", err) @@ -875,7 +779,7 @@ func TestServiceRegistryExternalService(t *testing.T) { } func TestAllocateLoadBalancerNodePorts(t *testing.T) { - setAlloc := func(val bool) serviceTweak { + setAlloc := func(val bool) svctest.Tweak { return func(s *api.Service) { s.Spec.AllocateLoadBalancerNodePorts = utilpointer.BoolPtr(val) } @@ -889,27 +793,27 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { expectError bool }{{ name: "allocate false, gate on", - svc: makeService("alloc-false", tweakTypeLoadBalancer, setAlloc(false)), + svc: svctest.MakeService("alloc-false", svctest.SetTypeLoadBalancer, setAlloc(false)), expectNodePorts: false, allocateNodePortGate: true, }, { name: "allocate true, gate on", - svc: makeService("alloc-true", tweakTypeLoadBalancer, setAlloc(true)), + svc: svctest.MakeService("alloc-true", svctest.SetTypeLoadBalancer, setAlloc(true)), expectNodePorts: true, allocateNodePortGate: true, }, { name: "allocate nil, gate off", - svc: makeService("alloc-nil", tweakTypeLoadBalancer), + svc: svctest.MakeService("alloc-nil", svctest.SetTypeLoadBalancer), expectNodePorts: true, allocateNodePortGate: false, }, { name: "allocate false, gate off", - svc: makeService("alloc-false", tweakTypeLoadBalancer, setAlloc(false)), + svc: svctest.MakeService("alloc-false", svctest.SetTypeLoadBalancer, setAlloc(false)), expectNodePorts: true, allocateNodePortGate: false, }, { name: "allocate true, gate off", - svc: makeService("alloc-true", tweakTypeLoadBalancer, setAlloc(true)), + svc: svctest.MakeService("alloc-true", svctest.SetTypeLoadBalancer, setAlloc(true)), expectNodePorts: true, allocateNodePortGate: false, }} @@ -953,7 +857,7 @@ func TestServiceRegistryDelete(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("foo") + svc := svctest.MakeService("foo") _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -970,7 +874,7 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { defer server.Terminate(t) // Test dry run delete request with cluster ip - svc := makeService("foo") + svc := svctest.MakeService("foo") obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) @@ -994,7 +898,7 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { } // Test dry run delete request with node port - svc = makeService("foo2", tweakTypeNodePort) + svc = svctest.MakeService("foo2", svctest.SetTypeNodePort) obj, err = storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) @@ -1029,10 +933,10 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { dualstack_storage, dualstack_registry, dualstack_server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer dualstack_server.Terminate(t) // Test dry run delete request with cluster ip - dualstack_svc := makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), - tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")) + dualstack_svc := svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + svctest.SetClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")) _, err := dualstack_storage.Create(ctx, dualstack_svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1057,7 +961,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("foo", tweakTypeExternalName) + svc := svctest.MakeService("foo", svctest.SetTypeExternalName) _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -1074,7 +978,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { defer server.Terminate(t) // Create non-external load balancer. - svc1 := makeService("foo") + svc1 := svctest.MakeService("foo") obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) @@ -1102,11 +1006,11 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { defer server.Terminate(t) // Create external load balancer. - svc1 := makeService("foo", - tweakTypeLoadBalancer, - tweakPorts( - makeServicePort("p", 6502, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("q", 8086, intstr.FromInt(8086), api.ProtocolTCP))) + svc1 := svctest.MakeService("foo", + svctest.SetTypeLoadBalancer, + svctest.SetPorts( + svctest.MakeServicePort("p", 6502, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("q", 8086, intstr.FromInt(8086), api.ProtocolTCP))) obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) @@ -1125,7 +1029,7 @@ func TestServiceRegistryGet(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } @@ -1210,13 +1114,13 @@ func TestServiceRegistryResourceLocation(t *testing.T) { storage, registry, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) defer server.Terminate(t) for _, name := range []string{"foo", "bad"} { - _, err := registry.Create(ctx, makeService(name, - tweakPorts( + _, err := registry.Create(ctx, svctest.MakeService(name, + svctest.SetPorts( // Service port 9393 should route to endpoint port "p", which is port 93 - makeServicePort("p", 9393, intstr.FromString("p"), api.ProtocolTCP), + svctest.MakeServicePort("p", 9393, intstr.FromString("p"), api.ProtocolTCP), // Service port 93 should route to unnamed endpoint port, which is port 80 // This is to test that the service port definition is used when determining resource location - makeServicePort("", 93, intstr.FromInt(80), api.ProtocolTCP))), + svctest.MakeServicePort("", 93, intstr.FromInt(80), api.ProtocolTCP))), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) @@ -1372,11 +1276,11 @@ func TestServiceRegistryList(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, makeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } - _, err = registry.Create(ctx, makeService("foo2"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err = registry.Create(ctx, svctest.MakeService("foo2"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -1401,7 +1305,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc1 := makeService("foo") + svc1 := svctest.MakeService("foo") ctx := genericapirequest.NewDefaultContext() obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1415,7 +1319,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { t.Errorf("Unexpected ClusterIP: %s", createdSvc1.Spec.ClusterIPs[0]) } - svc2 := makeService("bar") + svc2 := svctest.MakeService("bar") ctx = genericapirequest.NewDefaultContext() obj, err = storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1438,7 +1342,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { } } - svc3 := makeService("qux", tweakClusterIPs(testIP)) + svc3 := svctest.MakeService("qux", svctest.SetClusterIPs(testIP)) ctx = genericapirequest.NewDefaultContext() obj, err = storage.Create(ctx, svc3, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1454,7 +1358,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc1 := makeService("foo") + svc1 := svctest.MakeService("foo") ctx := genericapirequest.NewDefaultContext() obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1473,7 +1377,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { t.Errorf("Unexpected error deleting service: %v", err) } - svc2 := makeService("bar", tweakClusterIPs(svc1.Spec.ClusterIP)) + svc2 := svctest.MakeService("bar", svctest.SetClusterIPs(svc1.Spec.ClusterIP)) ctx = genericapirequest.NewDefaultContext() obj, err = storage.Create(ctx, svc2, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1492,7 +1396,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("foo") + svc := svctest.MakeService("foo") ctx := genericapirequest.NewDefaultContext() createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1542,7 +1446,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("foo", tweakTypeLoadBalancer) + svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) ctx := genericapirequest.NewDefaultContext() createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if createdSvc == nil || err != nil { @@ -1569,7 +1473,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { func TestUpdateServiceWithConflictingNamespace(t *testing.T) { storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - service := makeService("test", func(s *api.Service) { s.Namespace = "not-default" }) + service := svctest.MakeService("test", func(s *api.Service) { s.Namespace = "not-default" }) ctx := genericapirequest.NewDefaultContext() obj, created, err := storage.Update(ctx, service.Name, rest.DefaultUpdatedObjectInfo(service), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) @@ -1589,7 +1493,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal }) obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -1617,7 +1521,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { // hard-code NodePort to make sure it doesn't conflict with the healthport. // TODO: remove this once http://issue.k8s.io/93922 fixes auto-allocation conflicting with user-specified health check ports s.Spec.Ports[0].NodePort = 30500 @@ -1652,7 +1556,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) ctx := genericapirequest.NewDefaultContext() storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal s.Spec.HealthCheckNodePort = int32(-1) }) @@ -1668,7 +1572,7 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, registry, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - svc := makeService("external-lb-esipp", tweakTypeLoadBalancer, func(s *api.Service) { + svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster }) obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -1702,24 +1606,24 @@ func TestInitClusterIP(t *testing.T) { expectedClusterIPs []string }{{ name: "Allocate single stack ClusterIP (v4)", - svc: makeService("foo"), + svc: svctest.MakeService("foo"), enableDualStackAllocator: false, expectError: false, preAllocateClusterIPs: nil, expectedCountIPs: 1, }, { name: "Allocate single ClusterIP (v6)", - svc: makeService("foo", - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv6Protocol)), expectError: false, enableDualStackAllocator: true, preAllocateClusterIPs: nil, expectedCountIPs: 1, }, { name: "Allocate specified ClusterIP (v4)", - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol), - tweakClusterIPs("1.2.3.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetClusterIPs("1.2.3.4")), expectError: false, enableDualStackAllocator: true, preAllocateClusterIPs: nil, @@ -1727,109 +1631,109 @@ func TestInitClusterIP(t *testing.T) { expectedClusterIPs: []string{"1.2.3.4"}, }, { name: "Allocate specified ClusterIP-v6", - svc: makeService("foo", - tweakIPFamilies(api.IPv6Protocol), - tweakClusterIPs("2000:0:0:0:0:0:0:1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv6Protocol), + svctest.SetClusterIPs("2000:0:0:0:0:0:0:1")), expectError: false, enableDualStackAllocator: true, expectedCountIPs: 1, expectedClusterIPs: []string{"2000:0:0:0:0:0:0:1"}, }, { name: "Allocate dual stack - on a non dual stack ", - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol)), expectError: false, enableDualStackAllocator: false, expectedCountIPs: 1, }, { name: "Allocate dual stack - upgrade - v4, v6", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetIPFamilies(api.IPv4Protocol)), expectError: false, enableDualStackAllocator: true, expectedCountIPs: 2, }, { name: "Allocate dual stack - upgrade - v4, v6 - specific first IP", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakIPFamilies(api.IPv4Protocol), - tweakClusterIPs("1.2.3.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetClusterIPs("1.2.3.4")), expectError: false, enableDualStackAllocator: true, expectedCountIPs: 2, expectedClusterIPs: []string{"1.2.3.4"}, }, { name: "Allocate dual stack - upgrade - v6, v4", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetIPFamilies(api.IPv6Protocol)), expectError: false, enableDualStackAllocator: true, expectedCountIPs: 2, }, { name: "Allocate dual stack - v4, v6 - specific ips", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakClusterIPs("1.2.3.4", "2000:0:0:0:0:0:0:1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetClusterIPs("1.2.3.4", "2000:0:0:0:0:0:0:1")), expectError: false, enableDualStackAllocator: true, expectedCountIPs: 2, expectedClusterIPs: []string{"1.2.3.4", "2000:0:0:0:0:0:0:1"}, }, { name: "Allocate dual stack - upgrade - v6, v4 - specific ips", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), - tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + svctest.SetClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), expectError: false, enableDualStackAllocator: true, expectedCountIPs: 2, expectedClusterIPs: []string{"2000:0:0:0:0:0:0:1", "1.2.3.4"}, }, { name: "Shouldn't allocate ClusterIP", - svc: makeService("foo", - tweakClusterIPs("None")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None")), expectError: false, enableDualStackAllocator: false, expectedCountIPs: 0, }, { name: "single stack, ip is pre allocated (ipv4)", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), - tweakIPFamilies(api.IPv4Protocol), - tweakClusterIPs("1.2.3.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetClusterIPs("1.2.3.4")), expectError: true, enableDualStackAllocator: false, expectedCountIPs: 0, preAllocateClusterIPs: map[api.IPFamily]string{api.IPv4Protocol: "1.2.3.4"}, }, { name: "single stack, ip is pre allocated (ipv6)", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), - tweakIPFamilies(api.IPv6Protocol), - tweakClusterIPs("2000:0:0:0:0:0:0:1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack), + svctest.SetIPFamilies(api.IPv6Protocol), + svctest.SetClusterIPs("2000:0:0:0:0:0:0:1")), expectError: true, enableDualStackAllocator: true, // ipv6 allocator is always the second one during test expectedCountIPs: 0, preAllocateClusterIPs: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, }, { name: "Allocate dual stack - upgrade - v6, v4 - specific ips (first ip can't be allocated)", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), - tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + svctest.SetClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), expectError: true, enableDualStackAllocator: true, expectedCountIPs: 0, preAllocateClusterIPs: map[api.IPFamily]string{api.IPv6Protocol: "2000:0:0:0:0:0:0:1"}, }, { name: "Allocate dual stack - upgrade - v6, v4 - specific ips (second ip can't be allocated)", - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), - tweakClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + svctest.SetClusterIPs("2000:0:0:0:0:0:0:1", "1.2.3.4")), expectError: true, enableDualStackAllocator: true, expectedCountIPs: 0, @@ -1944,51 +1848,51 @@ func TestInitNodePorts(t *testing.T) { expectSpecifiedNodePorts []int }{{ name: "Service doesn't have specified NodePort", - service: makeService("foo", tweakTypeNodePort), + service: svctest.MakeService("foo", svctest.SetTypeNodePort), expectSpecifiedNodePorts: []int{}, }, { name: "Service has one specified NodePort", - service: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), - tweakNodePorts(30053)), + service: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + svctest.SetNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Service has two same ports with different protocols and specifies same NodePorts", - service: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30054, 30054)), + service: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30054, 30054)), expectSpecifiedNodePorts: []int{30054, 30054}, }, { name: "Service has two same ports with different protocols and specifies different NodePorts", - service: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30055, 30056)), + service: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30055, 30056)), expectSpecifiedNodePorts: []int{30055, 30056}, }, { name: "Service has two different ports with different protocols and specifies different NodePorts", - service: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("port-udp", 54, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30057, 30058)), + service: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 54, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30057, 30058)), expectSpecifiedNodePorts: []int{30057, 30058}, }, { name: "Service has two same ports with different protocols but only specifies one NodePort", - service: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30059)), + service: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30059)), expectSpecifiedNodePorts: []int{30059, 30059}, }} @@ -2030,81 +1934,81 @@ func TestUpdateNodePorts(t *testing.T) { expectSpecifiedNodePorts []int }{{ name: "Old service and new service have the same NodePort", - oldService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolTCP)), - tweakNodePorts(30053)), - newService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolTCP)), - tweakNodePorts(30053)), + oldService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolTCP)), + svctest.SetNodePorts(30053)), + newService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolTCP)), + svctest.SetNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Old service has more NodePorts than new service has", - oldService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30053, 30053)), - newService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), - tweakNodePorts(30053)), + oldService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30053, 30053)), + newService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + svctest.SetNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Change protocol of ServicePort without changing NodePort", - oldService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), - tweakNodePorts(30053)), - newService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30053)), + oldService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + svctest.SetNodePorts(30053)), + newService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30053)), expectSpecifiedNodePorts: []int{30053}, }, { name: "Should allocate NodePort when changing service type to NodePort", - oldService: makeService("foo", - tweakTypeClusterIP, - tweakPorts( - makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolUDP))), - newService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolUDP))), + oldService: svctest.MakeService("foo", + svctest.SetTypeClusterIP, + svctest.SetPorts( + svctest.MakeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolUDP))), + newService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("", 6502, intstr.FromInt(6502), api.ProtocolUDP))), expectSpecifiedNodePorts: []int{}, }, { name: "Add new ServicePort with a different protocol without changing port numbers", - oldService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), - tweakNodePorts(30053)), - newService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30053, 30053)), + oldService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP)), + svctest.SetNodePorts(30053)), + newService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30053, 30053)), expectSpecifiedNodePorts: []int{30053, 30053}, }, { name: "Change service type from ClusterIP to NodePort with same NodePort number but different protocols", - oldService: makeService("foo", - tweakTypeClusterIP, - tweakPorts( - makeServicePort("", 53, intstr.FromInt(6502), api.ProtocolTCP))), - newService: makeService("foo", - tweakTypeNodePort, - tweakPorts( - makeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), - makeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), - tweakNodePorts(30053, 30053)), + oldService: svctest.MakeService("foo", + svctest.SetTypeClusterIP, + svctest.SetPorts( + svctest.MakeServicePort("", 53, intstr.FromInt(6502), api.ProtocolTCP))), + newService: svctest.MakeService("foo", + svctest.SetTypeNodePort, + svctest.SetPorts( + svctest.MakeServicePort("port-tcp", 53, intstr.FromInt(6502), api.ProtocolTCP), + svctest.MakeServicePort("port-udp", 53, intstr.FromInt(6502), api.ProtocolUDP)), + svctest.SetNodePorts(30053, 30053)), expectSpecifiedNodePorts: []int{30053, 30053}, }} @@ -2156,7 +2060,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.Selector = map[string]string{"bar": "baz2"} }, - svc: makeService("foo"), + svc: svctest.MakeService("foo"), }, { name: "error, no upgrade (has single allocator)", enableDualStackAllocator: false, @@ -2169,7 +2073,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} }), }, { @@ -2184,7 +2088,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} }), }, { @@ -2200,7 +2104,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} }), }, { @@ -2216,7 +2120,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} }), }, { @@ -2231,7 +2135,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol} }), }, { @@ -2247,7 +2151,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol} }), }, { @@ -2263,7 +2167,7 @@ func TestServiceUpgrade(t *testing.T) { s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilies = []api.IPFamily{api.IPv6Protocol} }), }} @@ -2359,7 +2263,7 @@ func TestServiceDowngrade(t *testing.T) { updateFunc: func(s *api.Service) { s.Spec.Selector = map[string]string{"bar": "baz2"} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilyPolicy = &requiredDualStack s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol} }), @@ -2371,7 +2275,7 @@ func TestServiceDowngrade(t *testing.T) { updateFunc: func(s *api.Service) { s.Spec.Selector = map[string]string{"bar": "baz2"} }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilyPolicy = &requiredDualStack s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }), @@ -2387,7 +2291,7 @@ func TestServiceDowngrade(t *testing.T) { s.Spec.IPFamilies = s.Spec.IPFamilies[0:1] }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilyPolicy = &requiredDualStack s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }), @@ -2403,7 +2307,7 @@ func TestServiceDowngrade(t *testing.T) { s.Spec.IPFamilies = s.Spec.IPFamilies[0:1] }, - svc: makeService("foo", func(s *api.Service) { + svc: svctest.MakeService("foo", func(s *api.Service) { s.Spec.IPFamilyPolicy = &requiredDualStack s.Spec.IPFamilies = []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol} }), @@ -2521,7 +2425,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: externalname on a single stack - v4", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", tweakTypeExternalName), + svc: svctest.MakeService("foo", svctest.SetTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, @@ -2529,7 +2433,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: nothing", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo"), + svc: svctest.MakeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2538,8 +2442,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v4Cluster IPSet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2547,8 +2451,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v4IPFamilySet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2556,9 +2460,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v4IPFamilySet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("10.0.0.4"), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("10.0.0.4"), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2566,8 +2470,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: PreferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2575,9 +2479,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: PreferDualStack + v4ClusterIPSet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2585,10 +2489,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakIPFamilies(api.IPv4Protocol), - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2596,8 +2500,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v6IPSet", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2605,8 +2509,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: v6IPFamily", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2614,8 +2518,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: RequireDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2623,9 +2527,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: RequireDualStack + family", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2634,9 +2538,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, families are ignored", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, @@ -2645,8 +2549,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, no families", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, @@ -2655,9 +2559,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, user selected", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, @@ -2666,9 +2570,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: selectorless, user set to preferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, @@ -2678,9 +2582,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: multifamily set to preferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2688,9 +2592,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: multifamily set to singleStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2698,9 +2602,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: mult clusterips set to preferDualStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2708,9 +2612,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v4] set: multi clusterips set to singleStack", modifyRest: fnMakeSingleStackIPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2722,7 +2626,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: externalname on a single stack - v4", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", tweakTypeExternalName), + svc: svctest.MakeService("foo", svctest.SetTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, @@ -2730,7 +2634,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: nothing", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo"), + svc: svctest.MakeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2738,8 +2642,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v6Cluster IPSet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2747,8 +2651,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v4IPFamilySet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2756,9 +2660,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v6IPFamilySet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("2000::1"), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("2000::1"), + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2766,8 +2670,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: PreferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2775,9 +2679,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: PreferDualStack + v6ClusterIPSet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2785,10 +2689,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: PreferDualStack + v6ClusterIPSet + v6FamilySet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakIPFamilies(api.IPv6Protocol), - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetIPFamilies(api.IPv6Protocol), + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2796,8 +2700,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v4IPSet", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("10.0.0.10")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2805,8 +2709,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: v4IPFamily", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2814,8 +2718,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: RequireDualStack (on single stack ipv6 cluster)", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2823,9 +2727,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: RequireDualStack + family (on single stack ipv6 cluster)", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2835,9 +2739,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, families are ignored", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, @@ -2846,8 +2750,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, no families", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, @@ -2856,9 +2760,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, user selected", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, @@ -2867,9 +2771,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: selectorless, user set to preferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, @@ -2879,9 +2783,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: multifamily set to preferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2889,9 +2793,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: multifamily set to singleStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2899,9 +2803,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: mult clusterips set to preferDualStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2909,9 +2813,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[singlestack:v6] set: multi clusterips set to singleStack", modifyRest: fnMakeSingleStackIPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -2923,7 +2827,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: externalname on a dual stack - v4,v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", tweakTypeExternalName), + svc: svctest.MakeService("foo", svctest.SetTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, @@ -2931,7 +2835,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: nothing", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo"), + svc: svctest.MakeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2940,8 +2844,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2949,8 +2853,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2958,9 +2862,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("10.0.0.4"), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("10.0.0.4"), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -2968,8 +2872,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v6ClusterIPSet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2977,8 +2881,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2986,9 +2890,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("2000::1"), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("2000::1"), + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -2997,8 +2901,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: PreferDualStack.", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3006,9 +2910,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: PreferDualStack + v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3016,10 +2920,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakIPFamilies(api.IPv4Protocol), - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3028,8 +2932,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3037,9 +2941,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3047,9 +2951,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3058,10 +2962,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family +ip v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10"), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10"), + svctest.SetIPFamilies(api.IPv4Protocol)), // expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, @@ -3070,10 +2974,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + family +ip v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1"), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1"), + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3081,9 +2985,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ip v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3091,9 +2995,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ip v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3101,9 +3005,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10", "2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10", "2000::1")), // expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, @@ -3112,9 +3016,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1", "10.0.0.10")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1", "10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3122,10 +3026,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: RequireDualStack + ips + families v6,v4", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1", "10.0.0.10"), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1", "10.0.0.10"), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3133,10 +3037,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v4,v6", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10", "2000::1"), - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10", "2000::1"), + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3144,8 +3048,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,v6] set: selectorless, no families", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, @@ -3154,9 +3058,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: selectorless, user selected", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3164,9 +3068,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: selectorless, user set to prefer", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3175,9 +3079,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[duakstack:v4,6] set: multifamily set to preferDualStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3185,9 +3089,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: multifamily set to singleStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3195,9 +3099,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: mult clusterips set to preferDualStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3205,9 +3109,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: multi clusterips set to singleStack", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3219,7 +3123,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: externalname on a dual stack - v6,v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", tweakTypeExternalName), + svc: svctest.MakeService("foo", svctest.SetTypeExternalName), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: false, @@ -3227,7 +3131,7 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: nothing", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo"), + svc: svctest.MakeService("foo"), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -3235,8 +3139,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3244,8 +3148,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol)), // expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, @@ -3254,9 +3158,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v4IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("10.0.0.4"), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("10.0.0.4"), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3264,8 +3168,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v6ClusterIPSet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -3273,8 +3177,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -3282,9 +3186,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: v6IPFamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("2000::1"), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("2000::1"), + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, expectError: false, @@ -3293,8 +3197,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: PreferDualStack.", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3302,9 +3206,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: PreferDualStack + v4ClusterIPSet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3312,10 +3216,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - tweakIPFamilies(api.IPv4Protocol), - tweakClusterIPs("10.0.0.4")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetClusterIPs("10.0.0.4")), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3324,8 +3228,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3333,9 +3237,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3343,9 +3247,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3353,10 +3257,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family +ip v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10"), - tweakIPFamilies(api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10"), + svctest.SetIPFamilies(api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3364,10 +3268,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + family +ip v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1"), - tweakIPFamilies(api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1"), + svctest.SetIPFamilies(api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3375,9 +3279,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ip v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3385,9 +3289,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ip v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3395,9 +3299,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ip v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3405,9 +3309,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10", "2000::1")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10", "2000::1")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3415,9 +3319,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1", "10.0.0.10")), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1", "10.0.0.10")), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3425,10 +3329,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v6,v4", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("2000::1", "10.0.0.10"), - tweakIPFamilies(api.IPv6Protocol, api.IPv4Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("2000::1", "10.0.0.10"), + svctest.SetIPFamilies(api.IPv6Protocol, api.IPv4Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, expectError: false, @@ -3436,10 +3340,10 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v4,v6", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - tweakClusterIPs("10.0.0.10", "2000::1"), - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), + svctest.SetClusterIPs("10.0.0.10", "2000::1"), + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3447,8 +3351,8 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: selectorless, no families", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), func(s *api.Service) { s.Spec.Selector = nil }), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, @@ -3457,9 +3361,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: selectorless, user selected", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, @@ -3468,9 +3372,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,v4] set: selectorless, user set to prefer", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("None"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("None"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, @@ -3480,9 +3384,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[duakstack:v6,5] set: multifamily set to preferDualStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3490,9 +3394,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v4,6] set: multifamily set to singleStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3500,9 +3404,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,4] set: mult clusterips set to preferDualStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3510,9 +3414,9 @@ func TestDefaultingValidation(t *testing.T) { { name: "[dualstack:v6,4] set: multi clusterips set to singleStack", modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: nil, expectedIPFamilies: nil, expectError: true, @@ -3524,15 +3428,15 @@ func TestDefaultingValidation(t *testing.T) { { name: "unchanged preferDualStack-1-ClusterUpgraded", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - oldSvc: makeService("foo", - tweakClusterIPs("1.1.1.1"), - tweakIPFamilies(api.IPv4Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + oldSvc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1"), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: makeService("foo", - tweakClusterIPs("1.1.1.1"), - tweakIPFamilies(api.IPv4Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1"), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, @@ -3541,15 +3445,15 @@ func TestDefaultingValidation(t *testing.T) { { name: "unchanged preferDualStack-2-ClusterDowngraded", modifyRest: fnMakeSingleStackIPv4Allocator, - oldSvc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + oldSvc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), expectedIPFamilyPolicy: &preferDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3558,14 +3462,14 @@ func TestDefaultingValidation(t *testing.T) { { name: "changed preferDualStack-1 (cluster upgraded)", modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - oldSvc: makeService("foo", - tweakClusterIPs("1.1.1.1"), - tweakIPFamilies(api.IPv4Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + oldSvc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1"), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: makeService("foo", - tweakIPFamilies(api.IPv4Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), + svc: svctest.MakeService("foo", + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), expectedIPFamilyPolicy: &requireDualStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, expectError: false, @@ -3574,15 +3478,15 @@ func TestDefaultingValidation(t *testing.T) { { name: "changed preferDualStack-2-ClusterDowngraded", modifyRest: fnMakeSingleStackIPv4Allocator, - oldSvc: makeService("foo", - tweakClusterIPs("1.1.1.1", "2001::1"), - tweakIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), + oldSvc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1", "2001::1"), + svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - svc: makeService("foo", - tweakClusterIPs("1.1.1.1"), - tweakIPFamilies(api.IPv4Protocol), - tweakIPFamilyPolicy(api.IPFamilyPolicySingleStack)), + svc: svctest.MakeService("foo", + svctest.SetClusterIPs("1.1.1.1"), + svctest.SetIPFamilies(api.IPv4Protocol), + svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), expectedIPFamilyPolicy: &singleStack, expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, expectError: false, From 7e8882d189fa3caf1be1fd68de31aeb5bfc52e8f Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Mon, 28 Jun 2021 20:11:16 -0700 Subject: [PATCH 10/20] Service REST test: Remove pointless scaffolding These fields don't add much value in actually proving it all works, and they make the upcoming de-layering hard. --- .../core/service/storage/rest_test.go | 68 +++++++------------ 1 file changed, 24 insertions(+), 44 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index f1359339621..bac0c27909e 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -61,10 +61,6 @@ var ( // in a completely different way. We should unify it. type serviceStorage struct { - GottenID string - UpdatedID string - CreatedID string - DeletedID string Service *api.Service ServiceList *api.ServiceList } @@ -74,12 +70,15 @@ func (s *serviceStorage) NamespaceScoped() bool { } func (s *serviceStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { - s.GottenID = name return s.Service, nil } -func (s *serviceStorage) GetService(ctx context.Context, name string, options *metav1.GetOptions) (*api.Service, error) { - return s.Service, nil +func getService(getter rest.Getter, ctx context.Context, name string, options *metav1.GetOptions) (*api.Service, error) { + obj, err := getter.Get(ctx, name, options) + if err != nil { + return nil, err + } + return obj.(*api.Service), nil } func (s *serviceStorage) NewList() runtime.Object { @@ -116,7 +115,6 @@ func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createV return obj, nil } svc := obj.(*api.Service) - s.CreatedID = obj.(metav1.Object).GetName() s.Service = svc.DeepCopy() s.Service.ResourceVersion = "1" @@ -134,16 +132,12 @@ func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.U return nil, false, err } if !dryrun.IsDryRun(options.DryRun) { - s.UpdatedID = name s.Service = obj.(*api.Service) } return obj, false, nil } func (s *serviceStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { - if !dryrun.IsDryRun(options.DryRun) { - s.DeletedID = name - } return s.Service, false, nil } @@ -346,7 +340,7 @@ func TestServiceRegistryCreate(t *testing.T) { t.Errorf("Unexpected ClusterIP: %s", createdService.Spec.ClusterIPs[i]) } } - srv, err := registry.GetService(ctx, tc.svc.Name, &metav1.GetOptions{}) + srv, err := getService(registry, ctx, tc.svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -412,7 +406,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { } } - srv, err := registry.GetService(ctx, tc.svc.Name, &metav1.GetOptions{}) + srv, err := getService(registry, ctx, tc.svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -442,7 +436,7 @@ func TestDryRunNodePort(t *testing.T) { if storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort allocated") } - srv, err := registry.GetService(ctx, svc.Name, &metav1.GetOptions{}) + srv, err := getService(registry, ctx, svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -472,7 +466,7 @@ func TestDryRunNodePort(t *testing.T) { t.Errorf("unexpected side effect: NodePort allocated") } } - srv, err = registry.GetService(ctx, svc.Name, &metav1.GetOptions{}) + srv, err = getService(registry, ctx, svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -564,7 +558,7 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { if !reflect.DeepEqual(serviceNodePorts, test.expectNodePorts) { t.Errorf("Expected %v, but got %v", test.expectNodePorts, serviceNodePorts) } - srv, err := registry.GetService(ctx, test.name, &metav1.GetOptions{}) + srv, err := getService(registry, ctx, test.name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -634,9 +628,6 @@ func TestServiceRegistryUpdate(t *testing.T) { if updatedService.Name != "foo" { t.Errorf("Expected foo, but got %v", updatedService.Name) } - if e, a := "foo", registry.UpdatedID; e != a { - t.Errorf("Expected %v, but got %v", e, a) - } } func TestServiceRegistryUpdateDryRun(t *testing.T) { @@ -667,9 +658,6 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { if storage.serviceNodePorts.Has(int(svc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort allocated") } - if e, a := "", registry.UpdatedID; e != a { - t.Errorf("Expected %q, but got %q", e, a) - } // Test dry run update request external name to cluster ip new2 := svc.DeepCopy() @@ -760,7 +748,7 @@ func TestServiceRegistryExternalService(t *testing.T) { if err != nil { t.Errorf("Failed to create service: %#v", err) } - srv, err := registry.GetService(ctx, svc.Name, &metav1.GetOptions{}) + srv, err := getService(registry, ctx, svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -832,7 +820,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { } t.Errorf("%s; Failed to create service: %#v", tc.name, err) } - srv, err := registry.GetService(ctx, tc.svc.Name, &metav1.GetOptions{}) + srv, err := getService(registry, ctx, tc.svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("%s; Unexpected error: %v", tc.name, err) } @@ -862,15 +850,15 @@ func TestServiceRegistryDelete(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) - if e, a := "foo", registry.DeletedID; e != a { - t.Errorf("Expected %v, but got %v", e, a) + _, _, err = storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) + if err != nil { + t.Fatalf("unexpected error: %v", err) } } func TestServiceRegistryDeleteDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) // Test dry run delete request with cluster ip @@ -890,9 +878,6 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { if err != nil { t.Fatalf("Expected no error: %v", err) } - if e, a := "", registry.DeletedID; e != a { - t.Errorf("Expected %v, but got %v", e, a) - } if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(createdSvc.Spec.ClusterIP)) { t.Errorf("unexpected side effect: ip unallocated") } @@ -917,9 +902,6 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { if err != nil { t.Fatalf("Expected no error: %v", err) } - if e, a := "", registry.DeletedID; e != a { - t.Errorf("Expected %v, but got %v", e, a) - } if !storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort unallocated") } @@ -930,7 +912,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { // dry run for non dualstack defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)() - dualstack_storage, dualstack_registry, dualstack_server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) + dualstack_storage, _, dualstack_server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer dualstack_server.Terminate(t) // Test dry run delete request with cluster ip dualstack_svc := svctest.MakeService("foo", @@ -947,9 +929,6 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { if err != nil { t.Fatalf("Expected no error: %v", err) } - if e, a := "", dualstack_registry.DeletedID; e != a { - t.Errorf("Expected %v, but got %v", e, a) - } for i, family := range dualstack_svc.Spec.IPFamilies { if !dualstack_storage.serviceIPAllocatorsByFamily[family].Has(net.ParseIP(dualstack_svc.Spec.ClusterIPs[i])) { t.Errorf("unexpected side effect: ip unallocated %v", dualstack_svc.Spec.ClusterIPs[i]) @@ -966,9 +945,9 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { if err != nil { t.Fatalf("unexpected error: %v", err) } - storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) - if e, a := "foo", registry.DeletedID; e != a { - t.Errorf("Expected %v, but got %v", e, a) + _, _, err = storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{}) + if err != nil { + t.Fatalf("Expected no error: %v", err) } } @@ -1033,8 +1012,9 @@ func TestServiceRegistryGet(t *testing.T) { if err != nil { t.Fatalf("error creating service: %v", err) } - storage.Get(ctx, "foo", &metav1.GetOptions{}) - if e, a := "foo", registry.GottenID; e != a { + obj, _ := storage.Get(ctx, "foo", &metav1.GetOptions{}) + svc := obj.(*api.Service) + if e, a := "foo", svc.Name; e != a { t.Errorf("Expected %v, but got %v", e, a) } } From 22ed090e73480eaffcee96ffa51a73c69baf6615 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 29 Jun 2021 15:27:34 -0700 Subject: [PATCH 11/20] Service REST test: mostly remove tests of "inner" This test was sometimes using the "inner" REST and sometimes using the "outer" REST. This commit changes all but one test to use the outer. The remaining test needs rework. --- .../core/service/storage/rest_test.go | 92 +++++++++---------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index bac0c27909e..f37755ca429 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -261,10 +261,10 @@ func makeIPNet6(t *testing.T) *net.IPNet { return net } -func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, rest *REST, registry ServiceStorage) { - obj, err := registry.Get(ctx, svcName, &metav1.GetOptions{}) +func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, rest *REST) { + obj, err := rest.Get(ctx, svcName, &metav1.GetOptions{}) if err != nil { - t.Errorf("Unexpected error: %v", err) + t.Fatalf("Unexpected error: %v", err) } srv := obj.(*api.Service) if srv == nil { @@ -272,7 +272,7 @@ func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, } serviceNodePorts := collectServiceNodePorts(srv) if len(serviceNodePorts) == 0 { - t.Errorf("Failed to find NodePorts of service : %s", srv.Name) + t.Fatalf("Failed to find NodePorts of service : %s", srv.Name) } for i := range serviceNodePorts { nodePort := serviceNodePorts[i] @@ -309,7 +309,7 @@ func TestServiceRegistryCreate(t *testing.T) { }} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - storage, registry, server := NewTestREST(t, nil, tc.families) + storage, _, server := NewTestREST(t, nil, tc.families) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -340,7 +340,7 @@ func TestServiceRegistryCreate(t *testing.T) { t.Errorf("Unexpected ClusterIP: %s", createdService.Spec.ClusterIPs[i]) } } - srv, err := getService(registry, ctx, tc.svc.Name, &metav1.GetOptions{}) + srv, err := getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -390,7 +390,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { if tc.enableDualStack { families = append(families, api.IPv6Protocol) } - storage, registry, server := NewTestREST(t, nil, families) + storage, _, server := NewTestREST(t, nil, families) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -406,7 +406,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { } } - srv, err := getService(registry, ctx, tc.svc.Name, &metav1.GetOptions{}) + srv, err := getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -418,7 +418,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { } func TestDryRunNodePort(t *testing.T) { - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) // Test dry run create request with a node port @@ -436,7 +436,7 @@ func TestDryRunNodePort(t *testing.T) { if storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort allocated") } - srv, err := getService(registry, ctx, svc.Name, &metav1.GetOptions{}) + srv, err := getService(storage, ctx, svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -466,7 +466,7 @@ func TestDryRunNodePort(t *testing.T) { t.Errorf("unexpected side effect: NodePort allocated") } } - srv, err = getService(registry, ctx, svc.Name, &metav1.GetOptions{}) + srv, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -501,7 +501,7 @@ func TestDryRunNodePort(t *testing.T) { } func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) testCases := []struct { @@ -558,7 +558,7 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { if !reflect.DeepEqual(serviceNodePorts, test.expectNodePorts) { t.Errorf("Expected %v, but got %v", test.expectNodePorts, serviceNodePorts) } - srv, err := getService(registry, ctx, test.name, &metav1.GetOptions{}) + srv, err := getService(storage, ctx, test.name, &metav1.GetOptions{}) if err != nil { t.Errorf("unexpected error: %v", err) } @@ -597,10 +597,10 @@ func TestServiceStorageValidatesCreate(t *testing.T) { func TestServiceRegistryUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol}) + storage, _, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) - _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -632,10 +632,10 @@ func TestServiceRegistryUpdate(t *testing.T) { func TestServiceRegistryUpdateDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - obj, err := registry.Create(ctx, svctest.MakeService("foo", svctest.SetTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err := storage.Create(ctx, svctest.MakeService("foo", svctest.SetTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } @@ -716,9 +716,9 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -741,14 +741,14 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { func TestServiceRegistryExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Errorf("Failed to create service: %#v", err) } - srv, err := getService(registry, ctx, svc.Name, &metav1.GetOptions{}) + srv, err := getService(storage, ctx, svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -810,7 +810,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { ctx := genericapirequest.NewDefaultContext() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceLBNodePortControl, tc.allocateNodePortGate)() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -820,7 +820,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { } t.Errorf("%s; Failed to create service: %#v", tc.name, err) } - srv, err := getService(registry, ctx, tc.svc.Name, &metav1.GetOptions{}) + srv, err := getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) if err != nil { t.Errorf("%s; Unexpected error: %v", tc.name, err) } @@ -843,10 +843,10 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { func TestServiceRegistryDelete(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo") - _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -938,10 +938,10 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { func TestServiceRegistryDeleteExternal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeExternalName) - _, err := registry.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -953,7 +953,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { func TestServiceRegistryUpdateExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) // Create non-external load balancer. @@ -969,7 +969,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } - defer releaseServiceNodePorts(t, ctx, svc2.Name, storage, registry) + defer releaseServiceNodePorts(t, ctx, svc2.Name, storage) // Change port. svc3 := svc2.DeepCopy() @@ -981,7 +981,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) // Create external load balancer. @@ -994,7 +994,7 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { if err != nil { t.Fatalf("Unexpected error: %v", err) } - defer releaseServiceNodePorts(t, ctx, svc1.Name, storage, registry) + defer releaseServiceNodePorts(t, ctx, svc1.Name, storage) // Modify ports svc2 := obj.(*api.Service).DeepCopy() @@ -1006,9 +1006,9 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { func TestServiceRegistryGet(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("error creating service: %v", err) } @@ -1254,17 +1254,16 @@ func TestServiceRegistryResourceLocation(t *testing.T) { func TestServiceRegistryList(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) - _, err := registry.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } - _, err = registry.Create(ctx, svctest.MakeService("foo2"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + _, err = storage.Create(ctx, svctest.MakeService("foo2"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("unexpected error: %v", err) } - registry.ServiceList.ResourceVersion = "1" s, _ := storage.List(ctx, nil) sl := s.(*api.ServiceList) if len(sl.Items) != 2 { @@ -1276,9 +1275,6 @@ func TestServiceRegistryList(t *testing.T) { if e, a := "foo2", sl.Items[1].Name; e != a { t.Errorf("Expected %v, but got %v", e, a) } - if sl.ResourceVersion != "1" { - t.Errorf("Unexpected resource version: %#v", sl) - } } func TestServiceRegistryIPAllocation(t *testing.T) { @@ -1423,7 +1419,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { } func TestServiceRegistryIPLoadBalancer(t *testing.T) { - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) @@ -1432,7 +1428,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { if createdSvc == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) + defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdService := createdSvc.(*api.Service) if createdService.Spec.Ports[0].Port != svc.Spec.Ports[0].Port { @@ -1471,7 +1467,7 @@ func TestUpdateServiceWithConflictingNamespace(t *testing.T) { // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal @@ -1480,7 +1476,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. if obj == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) + defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdSvc := obj.(*api.Service) if !service.NeedsHealthCheck(createdSvc) { @@ -1499,7 +1495,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { // hard-code NodePort to make sure it doesn't conflict with the healthport. @@ -1512,7 +1508,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test if obj == nil || err != nil { t.Fatalf("Unexpected failure creating service :%v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) + defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdSvc := obj.(*api.Service) if !service.NeedsHealthCheck(createdSvc) { @@ -1550,7 +1546,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) // Validate that the health check nodePort is not allocated when ExternalTrafficPolicy is set to Global. func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, registry, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, nil, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster @@ -1559,7 +1555,7 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { if obj == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage, registry) + defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdSvc := obj.(*api.Service) if service.NeedsHealthCheck(createdSvc) { From 012bfaf98d3d077d30b51e52d9e73af51eb8c514 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 29 Jun 2021 16:28:40 -0700 Subject: [PATCH 12/20] Service REST test: remove last use of "inner" This required making a more hi-fidelity fake. That, in turn, required fixing some tests which were just not correct. --- .../core/service/storage/rest_test.go | 492 ++++++++---------- 1 file changed, 213 insertions(+), 279 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index f37755ca429..8aab224460e 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -18,9 +18,9 @@ package storage import ( "context" + "fmt" "net" "reflect" - "strings" "testing" "k8s.io/apimachinery/pkg/api/errors" @@ -61,16 +61,26 @@ var ( // in a completely different way. We should unify it. type serviceStorage struct { - Service *api.Service + Services map[string]*api.Service ServiceList *api.ServiceList } +func (s *serviceStorage) saveService(svc *api.Service) { + if s.Services == nil { + s.Services = map[string]*api.Service{} + } + s.Services[svc.Name] = svc.DeepCopy() +} + func (s *serviceStorage) NamespaceScoped() bool { return true } func (s *serviceStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { - return s.Service, nil + if s.Services[name] == nil { + return nil, fmt.Errorf("service %q not found", name) + } + return s.Services[name].DeepCopy(), nil } func getService(getter rest.Getter, ctx context.Context, name string, options *metav1.GetOptions) (*api.Service, error) { @@ -115,15 +125,15 @@ func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createV return obj, nil } svc := obj.(*api.Service) - s.Service = svc.DeepCopy() - s.Service.ResourceVersion = "1" + s.saveService(svc) + s.Services[svc.Name].ResourceVersion = "1" if s.ServiceList == nil { s.ServiceList = &api.ServiceList{} } s.ServiceList.Items = append(s.ServiceList.Items, *svc) - return s.Service.DeepCopy(), nil + return s.Services[svc.Name].DeepCopy(), nil } func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { @@ -132,13 +142,15 @@ func (s *serviceStorage) Update(ctx context.Context, name string, objInfo rest.U return nil, false, err } if !dryrun.IsDryRun(options.DryRun) { - s.Service = obj.(*api.Service) + s.saveService(obj.(*api.Service)) } return obj, false, nil } func (s *serviceStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { - return s.Service, false, nil + ret := s.Services[name] + delete(s.Services, name) + return ret, false, nil } func (s *serviceStorage) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *metainternalversion.ListOptions) (runtime.Object, error) { @@ -162,11 +174,11 @@ func (s *serviceStorage) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Se return nil } -func NewTestREST(t *testing.T, endpoints *api.EndpointsList, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { +func NewTestREST(t *testing.T, endpoints []*api.Endpoints, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { return NewTestRESTWithPods(t, endpoints, nil, ipFamilies) } -func NewTestRESTWithPods(t *testing.T, endpoints *api.EndpointsList, pods *api.PodList, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { +func NewTestRESTWithPods(t *testing.T, endpoints []*api.Endpoints, pods []api.Pod, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { etcdStorage, server := registrytest.NewEtcdStorage(t, "") serviceStorage := &serviceStorage{} @@ -180,13 +192,11 @@ func NewTestRESTWithPods(t *testing.T, endpoints *api.EndpointsList, pods *api.P if err != nil { t.Fatalf("unexpected error from REST storage: %v", err) } - if pods != nil && len(pods.Items) > 0 { - ctx := genericapirequest.NewDefaultContext() - for ix := range pods.Items { - key, _ := podStorage.Pod.KeyFunc(ctx, pods.Items[ix].Name) - if err := podStorage.Pod.Storage.Create(ctx, key, &pods.Items[ix], nil, 0, false); err != nil { - t.Fatalf("Couldn't create pod: %v", err) - } + ctx := genericapirequest.NewDefaultContext() + for ix := range pods { + key, _ := podStorage.Pod.KeyFunc(ctx, pods[ix].Name) + if err := podStorage.Pod.Storage.Create(ctx, key, &pods[ix], nil, 0, false); err != nil { + t.Fatalf("Couldn't create pod: %v", err) } } endpointStorage, err := endpointstore.NewREST(generic.RESTOptions{ @@ -197,13 +207,10 @@ func NewTestRESTWithPods(t *testing.T, endpoints *api.EndpointsList, pods *api.P if err != nil { t.Fatalf("unexpected error from REST storage: %v", err) } - if endpoints != nil && len(endpoints.Items) > 0 { - ctx := genericapirequest.NewDefaultContext() - for ix := range endpoints.Items { - key, _ := endpointStorage.KeyFunc(ctx, endpoints.Items[ix].Name) - if err := endpointStorage.Store.Storage.Create(ctx, key, &endpoints.Items[ix], nil, 0, false); err != nil { - t.Fatalf("Couldn't create endpoint: %v", err) - } + for ix := range endpoints { + key, _ := endpointStorage.KeyFunc(ctx, endpoints[ix].Name) + if err := endpointStorage.Store.Storage.Create(ctx, key, endpoints[ix], nil, 0, false); err != nil { + t.Fatalf("Couldn't create endpoint: %v", err) } } @@ -406,12 +413,9 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { } } - srv, err := getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if srv != nil { - t.Errorf("unexpected service found: %v", srv) + _, err = getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) + if err == nil { + t.Errorf("expected error") } }) } @@ -436,12 +440,10 @@ func TestDryRunNodePort(t *testing.T) { if storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { t.Errorf("unexpected side effect: NodePort allocated") } - srv, err := getService(storage, ctx, svc.Name, &metav1.GetOptions{}) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if srv != nil { - t.Errorf("unexpected service found: %v", srv) + _, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) + if err == nil { + // Should get a not-found. + t.Errorf("expected error") } // Test dry run create request with multi node port @@ -466,12 +468,10 @@ func TestDryRunNodePort(t *testing.T) { t.Errorf("unexpected side effect: NodePort allocated") } } - srv, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if srv != nil { - t.Errorf("unexpected service found: %v", srv) + _, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) + if err == nil { + // Should get a not-found. + t.Errorf("expected error") } // Test dry run create request with multiple unspecified node ports, @@ -730,12 +730,12 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { } for _, failureCase := range failureCases { c, created, err := storage.Update(ctx, failureCase.Name, rest.DefaultUpdatedObjectInfo(failureCase), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) + if err == nil { + t.Errorf("expected error") + } if c != nil || created { t.Errorf("Expected nil object or created false") } - if !errors.IsInvalid(err) { - t.Errorf("Expected to get an invalid resource error, got %v", err) - } } } @@ -1019,236 +1019,187 @@ func TestServiceRegistryGet(t *testing.T) { } } +func makeEndpoints(name string, addrs []api.EndpointAddress, ports []api.EndpointPort) *api.Endpoints { + return &api.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Subsets: []api.EndpointSubset{{ + Addresses: addrs, + Ports: ports, + }}, + } +} + +func makeEndpointAddress(ip string, pod string) api.EndpointAddress { + return api.EndpointAddress{ + IP: ip, + TargetRef: &api.ObjectReference{ + Name: pod, + Namespace: metav1.NamespaceDefault, + }, + } +} + +func makeEndpointPort(name string, port int) api.EndpointPort { + return api.EndpointPort{ + Name: name, + Port: int32(port), + } +} + +func makePod(name string, ips ...string) api.Pod { + p := api.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Spec: api.PodSpec{ + RestartPolicy: api.RestartPolicyAlways, + DNSPolicy: api.DNSDefault, + Containers: []api.Container{{Name: "ctr", Image: "img", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePolicy: api.TerminationMessageReadFile}}, + }, + Status: api.PodStatus{ + PodIPs: []api.PodIP{}, + }, + } + + for _, ip := range ips { + p.Status.PodIPs = append(p.Status.PodIPs, api.PodIP{IP: ip}) + } + + return p +} + func TestServiceRegistryResourceLocation(t *testing.T) { - ctx := genericapirequest.NewDefaultContext() - endpoints := &api.EndpointsList{ - Items: []api.Endpoints{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "bad", - Namespace: metav1.NamespaceDefault, - }, - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{ - {IP: "1.2.3.4", TargetRef: &api.ObjectReference{Name: "foo", Namespace: "doesn't exist"}}, - {IP: "1.2.3.4", TargetRef: &api.ObjectReference{Name: "doesn't exist", Namespace: metav1.NamespaceDefault}}, - {IP: "23.2.3.4", TargetRef: &api.ObjectReference{Name: "foo", Namespace: metav1.NamespaceDefault}}, - }, - Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, - }}, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: metav1.NamespaceDefault, - }, - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "1.2.3.4", TargetRef: &api.ObjectReference{Name: "foo", Namespace: metav1.NamespaceDefault}}}, - Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, - }}, - }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "foo-second-ip", - Namespace: metav1.NamespaceDefault, - }, - Subsets: []api.EndpointSubset{{ - Addresses: []api.EndpointAddress{{IP: "2001:db7::", TargetRef: &api.ObjectReference{Name: "foo", Namespace: metav1.NamespaceDefault}}}, - Ports: []api.EndpointPort{{Name: "", Port: 80}, {Name: "p", Port: 93}}, - }}, - }, - }, + pods := []api.Pod{ + makePod("unnamed", "1.2.3.4", "1.2.3.5"), + makePod("named", "1.2.3.6", "1.2.3.7"), + makePod("no-endpoints", "9.9.9.9"), // to prove this does not get chosen } - pods := &api.PodList{ - Items: []api.Pod{ - { - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: metav1.NamespaceDefault, - }, - Spec: api.PodSpec{ - RestartPolicy: "Always", - DNSPolicy: "Default", - Containers: []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - Status: api.PodStatus{ - PodIPs: []api.PodIP{{IP: "1.2.3.4"}, {IP: "2001:db7::"}}, - }, + + endpoints := []*api.Endpoints{ + makeEndpoints("unnamed", + []api.EndpointAddress{ + makeEndpointAddress("1.2.3.4", "unnamed"), }, - { - ObjectMeta: metav1.ObjectMeta{ - Name: "bar", - Namespace: metav1.NamespaceDefault, - }, - Spec: api.PodSpec{ - RestartPolicy: "Always", - DNSPolicy: "Default", - Containers: []api.Container{{Name: "bar", Image: "test", ImagePullPolicy: api.PullIfNotPresent, TerminationMessagePolicy: api.TerminationMessageReadFile}}, - }, - Status: api.PodStatus{ - PodIPs: []api.PodIP{{IP: "1.2.3.5"}, {IP: "2001:db8::"}}, - }, + []api.EndpointPort{ + makeEndpointPort("", 80), + }), + makeEndpoints("unnamed2", + []api.EndpointAddress{ + makeEndpointAddress("1.2.3.5", "unnamed"), }, - }, + []api.EndpointPort{ + makeEndpointPort("", 80), + }), + makeEndpoints("named", + []api.EndpointAddress{ + makeEndpointAddress("1.2.3.6", "named"), + }, + []api.EndpointPort{ + makeEndpointPort("p", 80), + makeEndpointPort("q", 81), + }), + makeEndpoints("no-endpoints", nil, nil), // to prove this does not get chosen } - storage, registry, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) + + storage, _, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) defer server.Terminate(t) - for _, name := range []string{"foo", "bad"} { - _, err := registry.Create(ctx, svctest.MakeService(name, - svctest.SetPorts( - // Service port 9393 should route to endpoint port "p", which is port 93 - svctest.MakeServicePort("p", 9393, intstr.FromString("p"), api.ProtocolTCP), - // Service port 93 should route to unnamed endpoint port, which is port 80 - // This is to test that the service port definition is used when determining resource location + + ctx := genericapirequest.NewDefaultContext() + for _, name := range []string{"unnamed", "unnamed2", "no-endpoints"} { + _, err := storage.Create(ctx, + svctest.MakeService(name, svctest.SetPorts( svctest.MakeServicePort("", 93, intstr.FromInt(80), api.ProtocolTCP))), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { - t.Fatalf("error creating service: %v", err) + t.Fatalf("unexpected error creating service %q: %v", name, err) } + + } + _, err := storage.Create(ctx, + svctest.MakeService("named", svctest.SetPorts( + svctest.MakeServicePort("p", 93, intstr.FromInt(80), api.ProtocolTCP), + svctest.MakeServicePort("q", 76, intstr.FromInt(81), api.ProtocolTCP))), + rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + if err != nil { + t.Fatalf("unexpected error creating service %q: %v", "named", err) } redirector := rest.Redirector(storage) - // Test a simple id. - location, _, err := redirector.ResourceLocation(ctx, "foo") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//1.2.3.4:80", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a simple id (using second ip). - location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//[2001:db7::]:80", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a name + port. - location, _, err = redirector.ResourceLocation(ctx, "foo:p") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//1.2.3.4:93", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a name + port (using second ip). - location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:p") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//[2001:db7::]:93", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a name + port number (service port 93 -> target port 80) - location, _, err = redirector.ResourceLocation(ctx, "foo:93") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//1.2.3.4:80", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a name + port number (service port 93 -> target port 80, using second ip) - location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:93") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//[2001:db7::]:80", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a name + port number (service port 9393 -> target port "p" -> endpoint port 93) - location, _, err = redirector.ResourceLocation(ctx, "foo:9393") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//1.2.3.4:93", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a name + port number (service port 9393 -> target port "p" -> endpoint port 93, using second ip) - location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:9393") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "//[2001:db7::]:93", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a scheme + name + port. - location, _, err = redirector.ResourceLocation(ctx, "https:foo:p") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "https://1.2.3.4:93", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a scheme + name + port (using second ip). - location, _, err = redirector.ResourceLocation(ctx, "https:foo-second-ip:p") - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if location == nil { - t.Errorf("Unexpected nil: %v", location) - } - if e, a := "https://[2001:db7::]:93", location.String(); e != a { - t.Errorf("Expected %v, but got %v", e, a) - } - - // Test a non-existent name + port. - _, _, err = redirector.ResourceLocation(ctx, "foo:q") - if err == nil { - t.Errorf("Unexpected nil error") - } - - // Test a non-existent name + port (using second ip). - _, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:q") - if err == nil { - t.Errorf("Unexpected nil error") - } - - // Test error path - if _, _, err = redirector.ResourceLocation(ctx, "bar"); err == nil { - t.Errorf("unexpected nil error") - } - - // Test a simple id. - _, _, err = redirector.ResourceLocation(ctx, "bad") - if err == nil { - t.Errorf("Unexpected nil error") + cases := []struct { + query string + err bool + expect string + }{{ + query: "unnamed", + expect: "//1.2.3.4:80", + }, { + query: "unnamed:", + expect: "//1.2.3.4:80", + }, { + query: "unnamed:93", + expect: "//1.2.3.4:80", + }, { + query: "http:unnamed:", + expect: "http://1.2.3.4:80", + }, { + query: "http:unnamed:93", + expect: "http://1.2.3.4:80", + }, { + query: "unnamed:80", + err: true, + }, { + query: "unnamed2", + expect: "//1.2.3.5:80", + }, { + query: "named:p", + expect: "//1.2.3.6:80", + }, { + query: "named:q", + expect: "//1.2.3.6:81", + }, { + query: "named:93", + expect: "//1.2.3.6:80", + }, { + query: "named:76", + expect: "//1.2.3.6:81", + }, { + query: "http:named:p", + expect: "http://1.2.3.6:80", + }, { + query: "http:named:q", + expect: "http://1.2.3.6:81", + }, { + query: "named:bad", + err: true, + }, { + query: "no-endpoints", + err: true, + }, { + query: "non-existent", + err: true, + }} + for _, tc := range cases { + t.Run(tc.query, func(t *testing.T) { + location, _, err := redirector.ResourceLocation(ctx, tc.query) + if tc.err == false && err != nil { + t.Fatalf("unexpected error: %v", err) + } + if tc.err == true && err == nil { + t.Fatalf("unexpected success") + } + if !tc.err { + if location == nil { + t.Errorf("unexpected location: %v", location) + } + if e, a := tc.expect, location.String(); e != a { + t.Errorf("expected %q, but got %q", e, a) + } + } + }) } } @@ -1446,23 +1397,6 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { } } -func TestUpdateServiceWithConflictingNamespace(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) - defer server.Terminate(t) - service := svctest.MakeService("test", func(s *api.Service) { s.Namespace = "not-default" }) - - ctx := genericapirequest.NewDefaultContext() - obj, created, err := storage.Update(ctx, service.Name, rest.DefaultUpdatedObjectInfo(service), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) - if obj != nil || created { - t.Error("Expected a nil object, but we got a value or created was true") - } - if err == nil { - t.Errorf("Expected an error, but we didn't get one") - } else if strings.Index(err.Error(), "Service.Namespace does not match the provided context") == -1 { - t.Errorf("Expected 'Service.Namespace does not match the provided context' error, got '%s'", err.Error()) - } -} - // Validate allocation of a nodePort when ExternalTrafficPolicy is set to Local // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { From a3b05033f669f1b7944f4df9a2b0d9c3256a14f8 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 29 Jun 2021 22:48:44 -0700 Subject: [PATCH 13/20] Move endpoints test-helper funcs to a package --- pkg/api/endpoints/testing/make.go | 70 +++++++++++++++++++ .../core/service/storage/rest_test.go | 54 ++++---------- 2 files changed, 83 insertions(+), 41 deletions(-) create mode 100644 pkg/api/endpoints/testing/make.go diff --git a/pkg/api/endpoints/testing/make.go b/pkg/api/endpoints/testing/make.go new file mode 100644 index 00000000000..0b397c919bf --- /dev/null +++ b/pkg/api/endpoints/testing/make.go @@ -0,0 +1,70 @@ +/* +Copyright 2021 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 ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + api "k8s.io/kubernetes/pkg/apis/core" +) + +// Tweak is a function that modifies a Endpoints. +type Tweak func(*api.Endpoints) + +// MakeEndpoints helps construct Endpoints objects (which pass API validation) +// more legibly and tersely than a Go struct definition. +func MakeEndpoints(name string, addrs []api.EndpointAddress, ports []api.EndpointPort, tweaks ...Tweak) *api.Endpoints { + // NOTE: Any field that would be populated by defaulting needs to be + // present and valid here. + eps := &api.Endpoints{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: metav1.NamespaceDefault, + }, + Subsets: []api.EndpointSubset{{ + Addresses: addrs, + Ports: ports, + }}, + } + + for _, tweak := range tweaks { + tweak(eps) + } + + return eps +} + +// MakeEndpointAddress helps construct EndpointAddress objects which pass API +// validation. +func MakeEndpointAddress(ip string, pod string) api.EndpointAddress { + return api.EndpointAddress{ + IP: ip, + TargetRef: &api.ObjectReference{ + Name: pod, + Namespace: metav1.NamespaceDefault, + }, + } +} + +// MakeEndpointPort helps construct EndpointPort objects which pass API +// validation. +func MakeEndpointPort(name string, port int) api.EndpointPort { + return api.EndpointPort{ + Name: name, + Port: int32(port), + } +} diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 8aab224460e..fa696749597 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -38,6 +38,7 @@ import ( "k8s.io/apiserver/pkg/util/dryrun" utilfeature "k8s.io/apiserver/pkg/util/feature" featuregatetesting "k8s.io/component-base/featuregate/testing" + epstest "k8s.io/kubernetes/pkg/api/endpoints/testing" "k8s.io/kubernetes/pkg/api/service" svctest "k8s.io/kubernetes/pkg/api/service/testing" api "k8s.io/kubernetes/pkg/apis/core" @@ -1019,36 +1020,7 @@ func TestServiceRegistryGet(t *testing.T) { } } -func makeEndpoints(name string, addrs []api.EndpointAddress, ports []api.EndpointPort) *api.Endpoints { - return &api.Endpoints{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: metav1.NamespaceDefault, - }, - Subsets: []api.EndpointSubset{{ - Addresses: addrs, - Ports: ports, - }}, - } -} - -func makeEndpointAddress(ip string, pod string) api.EndpointAddress { - return api.EndpointAddress{ - IP: ip, - TargetRef: &api.ObjectReference{ - Name: pod, - Namespace: metav1.NamespaceDefault, - }, - } -} - -func makeEndpointPort(name string, port int) api.EndpointPort { - return api.EndpointPort{ - Name: name, - Port: int32(port), - } -} - +// this is local because it's not fully fleshed out enough for general use. func makePod(name string, ips ...string) api.Pod { p := api.Pod{ ObjectMeta: metav1.ObjectMeta{ @@ -1080,29 +1052,29 @@ func TestServiceRegistryResourceLocation(t *testing.T) { } endpoints := []*api.Endpoints{ - makeEndpoints("unnamed", + epstest.MakeEndpoints("unnamed", []api.EndpointAddress{ - makeEndpointAddress("1.2.3.4", "unnamed"), + epstest.MakeEndpointAddress("1.2.3.4", "unnamed"), }, []api.EndpointPort{ - makeEndpointPort("", 80), + epstest.MakeEndpointPort("", 80), }), - makeEndpoints("unnamed2", + epstest.MakeEndpoints("unnamed2", []api.EndpointAddress{ - makeEndpointAddress("1.2.3.5", "unnamed"), + epstest.MakeEndpointAddress("1.2.3.5", "unnamed"), }, []api.EndpointPort{ - makeEndpointPort("", 80), + epstest.MakeEndpointPort("", 80), }), - makeEndpoints("named", + epstest.MakeEndpoints("named", []api.EndpointAddress{ - makeEndpointAddress("1.2.3.6", "named"), + epstest.MakeEndpointAddress("1.2.3.6", "named"), }, []api.EndpointPort{ - makeEndpointPort("p", 80), - makeEndpointPort("q", 81), + epstest.MakeEndpointPort("p", 80), + epstest.MakeEndpointPort("q", 81), }), - makeEndpoints("no-endpoints", nil, nil), // to prove this does not get chosen + epstest.MakeEndpoints("no-endpoints", nil, nil), // to prove this does not get chosen } storage, _, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) From 48e591eba23f3fc8ddb4c5aa556f4e2de9844a43 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Wed, 30 Jun 2021 10:51:30 -0700 Subject: [PATCH 14/20] Service REST test: remove obsolete setup param --- .../core/service/storage/rest_test.go | 68 +++++++++---------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index fa696749597..e6f0177379c 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -175,8 +175,8 @@ func (s *serviceStorage) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Se return nil } -func NewTestREST(t *testing.T, endpoints []*api.Endpoints, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { - return NewTestRESTWithPods(t, endpoints, nil, ipFamilies) +func NewTestREST(t *testing.T, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { + return NewTestRESTWithPods(t, nil, nil, ipFamilies) } func NewTestRESTWithPods(t *testing.T, endpoints []*api.Endpoints, pods []api.Pod, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { @@ -317,7 +317,7 @@ func TestServiceRegistryCreate(t *testing.T) { }} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - storage, _, server := NewTestREST(t, nil, tc.families) + storage, _, server := NewTestREST(t, tc.families) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -398,7 +398,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { if tc.enableDualStack { families = append(families, api.IPv6Protocol) } - storage, _, server := NewTestREST(t, nil, families) + storage, _, server := NewTestREST(t, families) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -423,7 +423,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { } func TestDryRunNodePort(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Test dry run create request with a node port @@ -502,7 +502,7 @@ func TestDryRunNodePort(t *testing.T) { } func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) testCases := []struct { @@ -575,7 +575,7 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { } func TestServiceStorageValidatesCreate(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) failureCases := map[string]*api.Service{ "empty ID": svctest.MakeService(""), @@ -598,7 +598,7 @@ func TestServiceStorageValidatesCreate(t *testing.T) { func TestServiceRegistryUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol}) + storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -633,7 +633,7 @@ func TestServiceRegistryUpdate(t *testing.T) { func TestServiceRegistryUpdateDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) obj, err := storage.Create(ctx, svctest.MakeService("foo", svctest.SetTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -717,7 +717,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -742,7 +742,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { func TestServiceRegistryExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -811,7 +811,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { ctx := genericapirequest.NewDefaultContext() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceLBNodePortControl, tc.allocateNodePortGate)() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -844,7 +844,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { func TestServiceRegistryDelete(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo") _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -859,7 +859,7 @@ func TestServiceRegistryDelete(t *testing.T) { func TestServiceRegistryDeleteDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Test dry run delete request with cluster ip @@ -913,7 +913,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { // dry run for non dualstack defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)() - dualstack_storage, _, dualstack_server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) + dualstack_storage, _, dualstack_server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer dualstack_server.Terminate(t) // Test dry run delete request with cluster ip dualstack_svc := svctest.MakeService("foo", @@ -939,7 +939,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { func TestServiceRegistryDeleteExternal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeExternalName) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -954,7 +954,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { func TestServiceRegistryUpdateExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Create non-external load balancer. @@ -982,7 +982,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Create external load balancer. @@ -1007,7 +1007,7 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { func TestServiceRegistryGet(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1177,7 +1177,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { func TestServiceRegistryList(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1201,7 +1201,7 @@ func TestServiceRegistryList(t *testing.T) { } func TestServiceRegistryIPAllocation(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc1 := svctest.MakeService("foo") @@ -1254,7 +1254,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { } func TestServiceRegistryIPReallocation(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc1 := svctest.MakeService("foo") @@ -1292,7 +1292,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { } func TestServiceRegistryIPUpdate(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo") @@ -1342,7 +1342,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { } func TestServiceRegistryIPLoadBalancer(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) @@ -1373,7 +1373,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal @@ -1401,7 +1401,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { // hard-code NodePort to make sure it doesn't conflict with the healthport. @@ -1436,7 +1436,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test // Validate that the service creation fails when the requested port number is -1. func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal @@ -1452,7 +1452,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) // Validate that the health check nodePort is not allocated when ExternalTrafficPolicy is set to Global. func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster @@ -1631,7 +1631,7 @@ func TestInitClusterIP(t *testing.T) { if test.enableDualStackAllocator { families = append(families, api.IPv6Protocol) } - storage, _, server := NewTestREST(t, nil, families) + storage, _, server := NewTestREST(t, families) defer server.Terminate(t) copySvc := test.svc.DeepCopy() @@ -1719,7 +1719,7 @@ func TestInitClusterIP(t *testing.T) { } func TestInitNodePorts(t *testing.T) { - storage, _, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol}) + storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.serviceNodePorts, false) defer nodePortOp.Finish() @@ -1804,7 +1804,7 @@ func TestInitNodePorts(t *testing.T) { } func TestUpdateNodePorts(t *testing.T) { - storage, _, server := NewTestREST(t, nil, singleStackIPv4) + storage, _, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.serviceNodePorts, false) defer nodePortOp.Finish() @@ -2060,7 +2060,7 @@ func TestServiceUpgrade(t *testing.T) { if testCase.enableDualStackAllocator { families = append(families, api.IPv6Protocol) } - storage, _, server := NewTestREST(t, nil, families) + storage, _, server := NewTestREST(t, families) defer server.Terminate(t) defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, testCase.enableDualStackGate)() @@ -2197,7 +2197,7 @@ func TestServiceDowngrade(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - storage, _, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) + storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer server.Terminate(t) defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, testCase.enableDualStackGate)() @@ -3378,7 +3378,7 @@ func TestDefaultingValidation(t *testing.T) { // This func only runs when feature gate is on defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)() - storage, _, server := NewTestREST(t, nil, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) + storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer server.Terminate(t) for _, testCase := range testCases { From d6208606f33c6b88fa3871b2a7413cd4a675dee1 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 29 Jun 2021 16:40:38 -0700 Subject: [PATCH 15/20] Service REST test: remove pointless scaffolding --- .../core/service/storage/rest_test.go | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index e6f0177379c..7fbc70aeb2d 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -21,6 +21,7 @@ import ( "fmt" "net" "reflect" + "sort" "testing" "k8s.io/apimachinery/pkg/api/errors" @@ -62,8 +63,7 @@ var ( // in a completely different way. We should unify it. type serviceStorage struct { - Services map[string]*api.Service - ServiceList *api.ServiceList + Services map[string]*api.Service } func (s *serviceStorage) saveService(svc *api.Service) { @@ -99,19 +99,18 @@ func (s *serviceStorage) NewList() runtime.Object { func (s *serviceStorage) List(ctx context.Context, options *metainternalversion.ListOptions) (runtime.Object, error) { ns, _ := genericapirequest.NamespaceFrom(ctx) - // Copy metadata from internal list into result - res := new(api.ServiceList) - res.TypeMeta = s.ServiceList.TypeMeta - res.ListMeta = s.ServiceList.ListMeta + keys := make([]string, 0, len(s.Services)) + for k := range s.Services { + keys = append(keys, k) + } + sort.Strings(keys) - if ns != metav1.NamespaceAll { - for _, service := range s.ServiceList.Items { - if ns == service.Namespace { - res.Items = append(res.Items, service) - } + res := new(api.ServiceList) + for _, k := range keys { + svc := s.Services[k] + if ns == metav1.NamespaceAll || ns == svc.Namespace { + res.Items = append(res.Items, *svc) } - } else { - res.Items = append([]api.Service{}, s.ServiceList.Items...) } return res, nil @@ -129,11 +128,6 @@ func (s *serviceStorage) Create(ctx context.Context, obj runtime.Object, createV s.saveService(svc) s.Services[svc.Name].ResourceVersion = "1" - if s.ServiceList == nil { - s.ServiceList = &api.ServiceList{} - } - - s.ServiceList.Items = append(s.ServiceList.Items, *svc) return s.Services[svc.Name].DeepCopy(), nil } From 44eb475b1014968b7263edfb8a31fdb9afb7e3fc Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Tue, 29 Jun 2021 16:44:21 -0700 Subject: [PATCH 16/20] Service REST test: remove unused return value --- .../core/service/storage/rest_test.go | 72 +++++++++---------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 7fbc70aeb2d..0167933913d 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -169,11 +169,11 @@ func (s *serviceStorage) GetResetFields() map[fieldpath.APIVersion]*fieldpath.Se return nil } -func NewTestREST(t *testing.T, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { +func NewTestREST(t *testing.T, ipFamilies []api.IPFamily) (*REST, *etcd3testing.EtcdTestServer) { return NewTestRESTWithPods(t, nil, nil, ipFamilies) } -func NewTestRESTWithPods(t *testing.T, endpoints []*api.Endpoints, pods []api.Pod, ipFamilies []api.IPFamily) (*REST, *serviceStorage, *etcd3testing.EtcdTestServer) { +func NewTestRESTWithPods(t *testing.T, endpoints []*api.Endpoints, pods []api.Pod, ipFamilies []api.IPFamily) (*REST, *etcd3testing.EtcdTestServer) { etcdStorage, server := registrytest.NewEtcdStorage(t, "") serviceStorage := &serviceStorage{} @@ -245,7 +245,7 @@ func NewTestRESTWithPods(t *testing.T, endpoints []*api.Endpoints, pods []api.Po rest, _ := NewREST(serviceStorage, endpointStorage, podStorage.Pod, rPrimary, rSecondary, portAllocator, nil) - return rest, serviceStorage, server + return rest, server } func makeIPNet(t *testing.T) *net.IPNet { @@ -311,7 +311,7 @@ func TestServiceRegistryCreate(t *testing.T) { }} for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - storage, _, server := NewTestREST(t, tc.families) + storage, server := NewTestREST(t, tc.families) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -392,7 +392,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { if tc.enableDualStack { families = append(families, api.IPv6Protocol) } - storage, _, server := NewTestREST(t, families) + storage, server := NewTestREST(t, families) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -417,7 +417,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { } func TestDryRunNodePort(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Test dry run create request with a node port @@ -496,7 +496,7 @@ func TestDryRunNodePort(t *testing.T) { } func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) testCases := []struct { @@ -569,7 +569,7 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { } func TestServiceStorageValidatesCreate(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) failureCases := map[string]*api.Service{ "empty ID": svctest.MakeService(""), @@ -592,7 +592,7 @@ func TestServiceStorageValidatesCreate(t *testing.T) { func TestServiceRegistryUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -627,7 +627,7 @@ func TestServiceRegistryUpdate(t *testing.T) { func TestServiceRegistryUpdateDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) obj, err := storage.Create(ctx, svctest.MakeService("foo", svctest.SetTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -711,7 +711,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -736,7 +736,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { func TestServiceRegistryExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -805,7 +805,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { ctx := genericapirequest.NewDefaultContext() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceLBNodePortControl, tc.allocateNodePortGate)() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -838,7 +838,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { func TestServiceRegistryDelete(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo") _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -853,7 +853,7 @@ func TestServiceRegistryDelete(t *testing.T) { func TestServiceRegistryDeleteDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Test dry run delete request with cluster ip @@ -907,7 +907,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { // dry run for non dualstack defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)() - dualstack_storage, _, dualstack_server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) + dualstack_storage, dualstack_server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer dualstack_server.Terminate(t) // Test dry run delete request with cluster ip dualstack_svc := svctest.MakeService("foo", @@ -933,7 +933,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { func TestServiceRegistryDeleteExternal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeExternalName) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -948,7 +948,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { func TestServiceRegistryUpdateExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Create non-external load balancer. @@ -976,7 +976,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) // Create external load balancer. @@ -1001,7 +1001,7 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { func TestServiceRegistryGet(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1071,7 +1071,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { epstest.MakeEndpoints("no-endpoints", nil, nil), // to prove this does not get chosen } - storage, _, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) + storage, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -1171,7 +1171,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { func TestServiceRegistryList(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1195,7 +1195,7 @@ func TestServiceRegistryList(t *testing.T) { } func TestServiceRegistryIPAllocation(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc1 := svctest.MakeService("foo") @@ -1248,7 +1248,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { } func TestServiceRegistryIPReallocation(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc1 := svctest.MakeService("foo") @@ -1286,7 +1286,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { } func TestServiceRegistryIPUpdate(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo") @@ -1336,7 +1336,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { } func TestServiceRegistryIPLoadBalancer(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) @@ -1367,7 +1367,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal @@ -1395,7 +1395,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { // hard-code NodePort to make sure it doesn't conflict with the healthport. @@ -1430,7 +1430,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test // Validate that the service creation fails when the requested port number is -1. func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal @@ -1446,7 +1446,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) // Validate that the health check nodePort is not allocated when ExternalTrafficPolicy is set to Global. func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster @@ -1625,7 +1625,7 @@ func TestInitClusterIP(t *testing.T) { if test.enableDualStackAllocator { families = append(families, api.IPv6Protocol) } - storage, _, server := NewTestREST(t, families) + storage, server := NewTestREST(t, families) defer server.Terminate(t) copySvc := test.svc.DeepCopy() @@ -1713,7 +1713,7 @@ func TestInitClusterIP(t *testing.T) { } func TestInitNodePorts(t *testing.T) { - storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.serviceNodePorts, false) defer nodePortOp.Finish() @@ -1798,7 +1798,7 @@ func TestInitNodePorts(t *testing.T) { } func TestUpdateNodePorts(t *testing.T) { - storage, _, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, singleStackIPv4) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.serviceNodePorts, false) defer nodePortOp.Finish() @@ -2054,7 +2054,7 @@ func TestServiceUpgrade(t *testing.T) { if testCase.enableDualStackAllocator { families = append(families, api.IPv6Protocol) } - storage, _, server := NewTestREST(t, families) + storage, server := NewTestREST(t, families) defer server.Terminate(t) defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, testCase.enableDualStackGate)() @@ -2191,7 +2191,7 @@ func TestServiceDowngrade(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { - storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer server.Terminate(t) defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, testCase.enableDualStackGate)() @@ -3372,7 +3372,7 @@ func TestDefaultingValidation(t *testing.T) { // This func only runs when feature gate is on defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)() - storage, _, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}) defer server.Terminate(t) for _, testCase := range testCases { From 43b13840db5cbe86b13dbb393ed8870a372749d6 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Thu, 1 Jul 2021 12:01:50 -0700 Subject: [PATCH 17/20] Service REST test: remove obscure const --- .../core/service/storage/rest_test.go | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 0167933913d..1db155effbb 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -54,10 +54,6 @@ import ( "sigs.k8s.io/structured-merge-diff/v4/fieldpath" ) -var ( - singleStackIPv4 = []api.IPFamily{api.IPv4Protocol} -) - // TODO(wojtek-t): Cleanup this file. // It is now testing mostly the same things as other resources but // in a completely different way. We should unify it. @@ -417,7 +413,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { } func TestDryRunNodePort(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) // Test dry run create request with a node port @@ -496,7 +492,7 @@ func TestDryRunNodePort(t *testing.T) { } func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) testCases := []struct { @@ -569,7 +565,7 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { } func TestServiceStorageValidatesCreate(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) failureCases := map[string]*api.Service{ "empty ID": svctest.MakeService(""), @@ -627,7 +623,7 @@ func TestServiceRegistryUpdate(t *testing.T) { func TestServiceRegistryUpdateDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) obj, err := storage.Create(ctx, svctest.MakeService("foo", svctest.SetTypeExternalName), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -711,7 +707,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { func TestServiceStorageValidatesUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -736,7 +732,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { func TestServiceRegistryExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -805,7 +801,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { ctx := genericapirequest.NewDefaultContext() defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceLBNodePortControl, tc.allocateNodePortGate)() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) _, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -838,7 +834,7 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { func TestServiceRegistryDelete(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("foo") _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -853,7 +849,7 @@ func TestServiceRegistryDelete(t *testing.T) { func TestServiceRegistryDeleteDryRun(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) // Test dry run delete request with cluster ip @@ -933,7 +929,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { func TestServiceRegistryDeleteExternal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeExternalName) _, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) @@ -948,7 +944,7 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { func TestServiceRegistryUpdateExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) // Create non-external load balancer. @@ -976,7 +972,7 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) // Create external load balancer. @@ -1001,7 +997,7 @@ func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { func TestServiceRegistryGet(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1071,7 +1067,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { epstest.MakeEndpoints("no-endpoints", nil, nil), // to prove this does not get chosen } - storage, server := NewTestRESTWithPods(t, endpoints, pods, singleStackIPv4) + storage, server := NewTestRESTWithPods(t, endpoints, pods, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) ctx := genericapirequest.NewDefaultContext() @@ -1171,7 +1167,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) { func TestServiceRegistryList(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) _, err := storage.Create(ctx, svctest.MakeService("foo"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { @@ -1195,7 +1191,7 @@ func TestServiceRegistryList(t *testing.T) { } func TestServiceRegistryIPAllocation(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc1 := svctest.MakeService("foo") @@ -1248,7 +1244,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { } func TestServiceRegistryIPReallocation(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc1 := svctest.MakeService("foo") @@ -1286,7 +1282,7 @@ func TestServiceRegistryIPReallocation(t *testing.T) { } func TestServiceRegistryIPUpdate(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("foo") @@ -1336,7 +1332,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { } func TestServiceRegistryIPLoadBalancer(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) @@ -1367,7 +1363,7 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal @@ -1395,7 +1391,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. // and type is LoadBalancer. func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { // hard-code NodePort to make sure it doesn't conflict with the healthport. @@ -1430,7 +1426,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test // Validate that the service creation fails when the requested port number is -1. func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeLocal @@ -1446,7 +1442,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) // Validate that the health check nodePort is not allocated when ExternalTrafficPolicy is set to Global. func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) svc := svctest.MakeService("external-lb-esipp", svctest.SetTypeLoadBalancer, func(s *api.Service) { s.Spec.ExternalTrafficPolicy = api.ServiceExternalTrafficPolicyTypeCluster @@ -1798,7 +1794,7 @@ func TestInitNodePorts(t *testing.T) { } func TestUpdateNodePorts(t *testing.T) { - storage, server := NewTestREST(t, singleStackIPv4) + storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.serviceNodePorts, false) defer nodePortOp.Finish() From 54b6a416fba22f193dafccac16011ce9fed967b7 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Thu, 1 Jul 2021 23:01:36 -0700 Subject: [PATCH 18/20] Service REST test: better IP and port alloc checks --- pkg/api/service/testing/make.go | 1 + .../core/service/ipallocator/allocator.go | 2 - .../core/service/portallocator/allocator.go | 2 - .../core/service/storage/rest_test.go | 70 ++++++++++++------- 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/pkg/api/service/testing/make.go b/pkg/api/service/testing/make.go index a3e2b7b3883..bb4d2b8c761 100644 --- a/pkg/api/service/testing/make.go +++ b/pkg/api/service/testing/make.go @@ -62,6 +62,7 @@ func SetTypeClusterIP(svc *api.Service) { svc.Spec.Ports[i].NodePort = 0 } svc.Spec.ExternalName = "" + svc.Spec.ExternalTrafficPolicy = "" } // SetTypeNodePort sets the service type to NodePort and clears other fields. diff --git a/pkg/registry/core/service/ipallocator/allocator.go b/pkg/registry/core/service/ipallocator/allocator.go index e42b3401ca4..7e57dc23d5b 100644 --- a/pkg/registry/core/service/ipallocator/allocator.go +++ b/pkg/registry/core/service/ipallocator/allocator.go @@ -36,8 +36,6 @@ type Interface interface { ForEach(func(net.IP)) CIDR() net.IPNet IPFamily() api.IPFamily - - // For testing Has(ip net.IP) bool } diff --git a/pkg/registry/core/service/portallocator/allocator.go b/pkg/registry/core/service/portallocator/allocator.go index 13eea2d275e..d344aa894da 100644 --- a/pkg/registry/core/service/portallocator/allocator.go +++ b/pkg/registry/core/service/portallocator/allocator.go @@ -34,8 +34,6 @@ type Interface interface { AllocateNext() (int, error) Release(int) error ForEach(func(int)) - - // For testing Has(int) bool } diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 1db155effbb..71f91222be6 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -259,7 +259,27 @@ func makeIPNet6(t *testing.T) *net.IPNet { return net } +func ipIsAllocated(t *testing.T, alloc ipallocator.Interface, ipstr string) bool { + t.Helper() + ip := net.ParseIP(ipstr) + if ip == nil { + t.Errorf("error parsing IP %q", ipstr) + return false + } + return alloc.Has(ip) +} + +func portIsAllocated(t *testing.T, alloc portallocator.Interface, port int32) bool { + t.Helper() + if port == 0 { + t.Errorf("port is 0") + return false + } + return alloc.Has(int(port)) +} + func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, rest *REST) { + t.Helper() obj, err := rest.Get(ctx, svcName, &metav1.GetOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) @@ -399,7 +419,7 @@ func TestServiceRegistryCreateDryRun(t *testing.T) { for i, family := range tc.svc.Spec.IPFamilies { alloc := storage.serviceIPAllocatorsByFamily[family] - if alloc.Has(net.ParseIP(tc.svc.Spec.ClusterIPs[i])) { + if ipIsAllocated(t, alloc, tc.svc.Spec.ClusterIPs[i]) { t.Errorf("unexpected side effect: ip allocated %v", tc.svc.Spec.ClusterIPs[i]) } } @@ -428,7 +448,7 @@ func TestDryRunNodePort(t *testing.T) { if createdSvc.Spec.Ports[0].NodePort == 0 { t.Errorf("expected NodePort value assigned") } - if storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { + if portIsAllocated(t, storage.serviceNodePorts, createdSvc.Spec.Ports[0].NodePort) { t.Errorf("unexpected side effect: NodePort allocated") } _, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) @@ -455,7 +475,7 @@ func TestDryRunNodePort(t *testing.T) { t.Errorf("Expected %v, but got %v", expectNodePorts, actualNodePorts) } for i := range svc.Spec.Ports { - if storage.serviceNodePorts.Has(int(svc.Spec.Ports[i].NodePort)) { + if portIsAllocated(t, storage.serviceNodePorts, svc.Spec.Ports[i].NodePort) { t.Errorf("unexpected side effect: NodePort allocated") } } @@ -635,43 +655,45 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { // Test dry run update request external name to node port new1 := svc.DeepCopy() svctest.SetTypeNodePort(new1) - updatedSvc, created, err := storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new1), + svctest.SetNodePorts(30001)(new1) // DryRun does not set port values yet + obj, created, err := storage.Update(ctx, new1.Name, rest.DefaultUpdatedObjectInfo(new1), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Expected no error: %v", err) } - if updatedSvc == nil { + if obj == nil { t.Errorf("Expected non-nil object") } if created { t.Errorf("expected not created") } - if storage.serviceNodePorts.Has(int(svc.Spec.Ports[0].NodePort)) { + if portIsAllocated(t, storage.serviceNodePorts, new1.Spec.Ports[0].NodePort) { t.Errorf("unexpected side effect: NodePort allocated") } // Test dry run update request external name to cluster ip new2 := svc.DeepCopy() svctest.SetTypeClusterIP(new2) + svctest.SetClusterIPs("1.2.3.4")(new2) // DryRun does not set IP values yet _, _, err = storage.Update(ctx, svc.Name, rest.DefaultUpdatedObjectInfo(new2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Expected no error: %v", err) } - if storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(svc.Spec.ClusterIP)) { + if ipIsAllocated(t, storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily], new2.Spec.ClusterIP) { t.Errorf("unexpected side effect: ip allocated") } // Test dry run update request remove node port - obj, err = storage.Create(ctx, svctest.MakeService("foo2", svctest.SetTypeNodePort), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, svctest.MakeService("foo2", svctest.SetTypeNodePort, svctest.SetNodePorts(30001)), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Expected no error: %v", err) } svc = obj.(*api.Service) - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(svc.Spec.ClusterIP)) { + if !ipIsAllocated(t, storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily], svc.Spec.ClusterIP) { t.Errorf("expected IP to be allocated") } - if !storage.serviceNodePorts.Has(int(svc.Spec.Ports[0].NodePort)) { + if !portIsAllocated(t, storage.serviceNodePorts, svc.Spec.Ports[0].NodePort) { t.Errorf("expected NodePort to be allocated") } @@ -682,12 +704,12 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { if err != nil { t.Fatalf("Expected no error: %v", err) } - if !storage.serviceNodePorts.Has(int(svc.Spec.Ports[0].NodePort)) { + if !portIsAllocated(t, storage.serviceNodePorts, svc.Spec.Ports[0].NodePort) { t.Errorf("unexpected side effect: NodePort unallocated") } // Test dry run update request remove cluster ip - obj, err = storage.Create(ctx, svctest.MakeService("foo3"), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) + obj, err = storage.Create(ctx, svctest.MakeService("foo3", svctest.SetClusterIPs("1.2.3.4")), rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("expected no error: %v", err) } @@ -700,7 +722,7 @@ func TestServiceRegistryUpdateDryRun(t *testing.T) { if err != nil { t.Fatalf("expected no error: %v", err) } - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(svc.Spec.ClusterIP)) { + if !ipIsAllocated(t, storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily], svc.Spec.ClusterIP) { t.Errorf("unexpected side effect: ip unallocated") } } @@ -862,14 +884,14 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { if createdSvc.Spec.ClusterIP == "" { t.Fatalf("expected ClusterIP to be set") } - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(createdSvc.Spec.ClusterIP)) { + if !ipIsAllocated(t, storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily], createdSvc.Spec.ClusterIP) { t.Errorf("expected ClusterIP to be allocated") } _, _, err = storage.Delete(ctx, svc.Name, rest.ValidateAllObjectFunc, &metav1.DeleteOptions{DryRun: []string{metav1.DryRunAll}}) if err != nil { t.Fatalf("Expected no error: %v", err) } - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].Has(net.ParseIP(createdSvc.Spec.ClusterIP)) { + if !ipIsAllocated(t, storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily], createdSvc.Spec.ClusterIP) { t.Errorf("unexpected side effect: ip unallocated") } @@ -883,7 +905,7 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { if createdSvc.Spec.Ports[0].NodePort == 0 { t.Fatalf("expected NodePort to be set") } - if !storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { + if !portIsAllocated(t, storage.serviceNodePorts, createdSvc.Spec.Ports[0].NodePort) { t.Errorf("expected NodePort to be allocated") } @@ -893,7 +915,7 @@ func TestServiceRegistryDeleteDryRun(t *testing.T) { if err != nil { t.Fatalf("Expected no error: %v", err) } - if !storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { + if !portIsAllocated(t, storage.serviceNodePorts, createdSvc.Spec.Ports[0].NodePort) { t.Errorf("unexpected side effect: NodePort unallocated") } } @@ -921,7 +943,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { t.Fatalf("Expected no error: %v", err) } for i, family := range dualstack_svc.Spec.IPFamilies { - if !dualstack_storage.serviceIPAllocatorsByFamily[family].Has(net.ParseIP(dualstack_svc.Spec.ClusterIPs[i])) { + if !ipIsAllocated(t, dualstack_storage.serviceIPAllocatorsByFamily[family], dualstack_svc.Spec.ClusterIPs[i]) { t.Errorf("unexpected side effect: ip unallocated %v", dualstack_svc.Spec.ClusterIPs[i]) } } @@ -1225,7 +1247,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { testIPs := []string{"1.2.3.93", "1.2.3.94", "1.2.3.95", "1.2.3.96"} testIP := "not-an-ip" for _, ip := range testIPs { - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].(*ipallocator.Range).Has(net.ParseIP(ip)) { + if !ipIsAllocated(t, storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].(*ipallocator.Range), ip) { testIP = ip break } @@ -1314,7 +1336,7 @@ func TestServiceRegistryIPUpdate(t *testing.T) { testIPs := []string{"1.2.3.93", "1.2.3.94", "1.2.3.95", "1.2.3.96"} testIP := "" for _, ip := range testIPs { - if !storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].(*ipallocator.Range).Has(net.ParseIP(ip)) { + if !ipIsAllocated(t, storage.serviceIPAllocatorsByFamily[storage.defaultServiceIPFamily].(*ipallocator.Range), ip) { testIP = ip break } @@ -1660,8 +1682,7 @@ func TestInitClusterIP(t *testing.T) { family = api.IPv6Protocol } allocator := storage.serviceIPAllocatorsByFamily[family] - // has retruns true if it was allocated *sigh*.. - if !allocator.Has(net.ParseIP(ip)) { + if !ipIsAllocated(t, allocator, ip) { t.Fatalf("expected ip:%v to be allocated by %v allocator. it was not", ip, family) } } @@ -2107,8 +2128,7 @@ func TestServiceUpgrade(t *testing.T) { for i, family := range updatedSvc.Spec.IPFamilies { ip := updatedSvc.Spec.ClusterIPs[i] allocator := storage.serviceIPAllocatorsByFamily[family] - // has retruns true if it was allocated *sigh*.. - if !allocator.Has(net.ParseIP(ip)) { + if !ipIsAllocated(t, allocator, ip) { t.Fatalf("expected ip:%v to be allocated by %v allocator. it was not", ip, family) } } @@ -2241,7 +2261,7 @@ func TestServiceDowngrade(t *testing.T) { releasedIPFamily := copySvc.Spec.IPFamilies[1] allocator := storage.serviceIPAllocatorsByFamily[releasedIPFamily] - if allocator.Has(net.ParseIP(releasedIP)) { + if ipIsAllocated(t, allocator, releasedIP) { t.Fatalf("expected ip:%v to be released by %v allocator. it was not", releasedIP, releasedIPFamily) } } From ca708fa9ac3bfb4a7c8be369e12fd8d5897079ac Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Thu, 1 Jul 2021 23:05:57 -0700 Subject: [PATCH 19/20] Service REST test: Fix some names --- pkg/registry/core/service/storage/rest_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index 71f91222be6..dc983111036 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -752,7 +752,7 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { } } -func TestServiceRegistryExternalService(t *testing.T) { +func TestServiceRegistryLoadBalancerService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -949,7 +949,7 @@ func TestDualStackServiceRegistryDeleteDryRun(t *testing.T) { } } -func TestServiceRegistryDeleteExternal(t *testing.T) { +func TestServiceRegistryDeleteExternalName(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -964,19 +964,19 @@ func TestServiceRegistryDeleteExternal(t *testing.T) { } } -func TestServiceRegistryUpdateExternalService(t *testing.T) { +func TestServiceRegistryUpdateLoadBalancerService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) - // Create non-external load balancer. + // Create non-loadbalancer. svc1 := svctest.MakeService("foo") obj, err := storage.Create(ctx, svc1, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) if err != nil { t.Fatalf("Unexpected error: %v", err) } - // Modify load balancer to be external. + // Modify to be loadbalancer. svc2 := obj.(*api.Service).DeepCopy() svc2.Spec.Type = api.ServiceTypeLoadBalancer if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { @@ -992,12 +992,12 @@ func TestServiceRegistryUpdateExternalService(t *testing.T) { } } -func TestServiceRegistryUpdateMultiPortExternalService(t *testing.T) { +func TestServiceRegistryUpdateMultiPortLoadBalancerService(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) - // Create external load balancer. + // Create load balancer. svc1 := svctest.MakeService("foo", svctest.SetTypeLoadBalancer, svctest.SetPorts( From 2b84b49ea981533730539abf8bfc4e4a05ece3b8 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Thu, 1 Jul 2021 23:20:10 -0700 Subject: [PATCH 20/20] Service REST test: Remove pointless cleanup --- .../core/service/storage/rest_test.go | 48 ------------------- 1 file changed, 48 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index dc983111036..fcd41b5ec68 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -278,26 +278,6 @@ func portIsAllocated(t *testing.T, alloc portallocator.Interface, port int32) bo return alloc.Has(int(port)) } -func releaseServiceNodePorts(t *testing.T, ctx context.Context, svcName string, rest *REST) { - t.Helper() - obj, err := rest.Get(ctx, svcName, &metav1.GetOptions{}) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - srv := obj.(*api.Service) - if srv == nil { - t.Fatalf("Failed to find service: %s", svcName) - } - serviceNodePorts := collectServiceNodePorts(srv) - if len(serviceNodePorts) == 0 { - t.Fatalf("Failed to find NodePorts of service : %s", srv.Name) - } - for i := range serviceNodePorts { - nodePort := serviceNodePorts[i] - rest.serviceNodePorts.Release(nodePort) - } -} - func TestServiceRegistryCreate(t *testing.T) { testCases := []struct { svc *api.Service @@ -772,11 +752,6 @@ func TestServiceRegistryLoadBalancerService(t *testing.T) { if len(serviceNodePorts) == 0 { t.Errorf("Failed to find NodePorts of service : %s", srv.Name) } - for i := range serviceNodePorts { - nodePort := serviceNodePorts[i] - // Release the node port at the end of the test case. - storage.serviceNodePorts.Release(nodePort) - } } func TestAllocateLoadBalancerNodePorts(t *testing.T) { @@ -844,12 +819,6 @@ func TestAllocateLoadBalancerNodePorts(t *testing.T) { if (len(serviceNodePorts) != 0) != tc.expectNodePorts { t.Errorf("%s; Allocated NodePorts not as expected", tc.name) } - - for i := range serviceNodePorts { - nodePort := serviceNodePorts[i] - // Release the node port at the end of the test case. - storage.serviceNodePorts.Release(nodePort) - } }) } } @@ -982,7 +951,6 @@ func TestServiceRegistryUpdateLoadBalancerService(t *testing.T) { if _, _, err := storage.Update(ctx, svc2.Name, rest.DefaultUpdatedObjectInfo(svc2), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}); err != nil { t.Fatalf("Unexpected error: %v", err) } - defer releaseServiceNodePorts(t, ctx, svc2.Name, storage) // Change port. svc3 := svc2.DeepCopy() @@ -1007,7 +975,6 @@ func TestServiceRegistryUpdateMultiPortLoadBalancerService(t *testing.T) { if err != nil { t.Fatalf("Unexpected error: %v", err) } - defer releaseServiceNodePorts(t, ctx, svc1.Name, storage) // Modify ports svc2 := obj.(*api.Service).DeepCopy() @@ -1363,7 +1330,6 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) { if createdSvc == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdService := createdSvc.(*api.Service) if createdService.Spec.Ports[0].Port != svc.Spec.Ports[0].Port { @@ -1394,7 +1360,6 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. if obj == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdSvc := obj.(*api.Service) if !service.NeedsHealthCheck(createdSvc) { @@ -1403,9 +1368,6 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing. port := createdSvc.Spec.HealthCheckNodePort if port == 0 { t.Errorf("Failed to allocate health check node port and set the HealthCheckNodePort") - } else { - // Release the health check node port at the end of the test case. - storage.serviceNodePorts.Release(int(port)) } } @@ -1426,7 +1388,6 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test if obj == nil || err != nil { t.Fatalf("Unexpected failure creating service :%v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdSvc := obj.(*api.Service) if !service.NeedsHealthCheck(createdSvc) { @@ -1439,10 +1400,6 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test if port != 30501 { t.Errorf("Failed to allocate requested nodePort expected %d, got %d", 30501, port) } - if port != 0 { - // Release the health check node port at the end of the test case. - storage.serviceNodePorts.Release(int(port)) - } } // Validate that the service creation fails when the requested port number is -1. @@ -1473,7 +1430,6 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { if obj == nil || err != nil { t.Errorf("Unexpected failure creating service %v", err) } - defer releaseServiceNodePorts(t, ctx, svc.Name, storage) createdSvc := obj.(*api.Service) if service.NeedsHealthCheck(createdSvc) { @@ -1482,8 +1438,6 @@ func TestServiceRegistryExternalTrafficGlobal(t *testing.T) { // Make sure the service does not have the health check node port allocated port := createdSvc.Spec.HealthCheckNodePort if port != 0 { - // Release the health check node port at the end of the test case. - storage.serviceNodePorts.Release(int(port)) t.Errorf("Unexpected allocation of health check node port: %v", port) } } @@ -1733,7 +1687,6 @@ func TestInitNodePorts(t *testing.T) { storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.serviceNodePorts, false) - defer nodePortOp.Finish() testCases := []struct { name string @@ -1818,7 +1771,6 @@ func TestUpdateNodePorts(t *testing.T) { storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.serviceNodePorts, false) - defer nodePortOp.Finish() testCases := []struct { name string