From 46d72896550a109f82577ef5fb8888de958129da Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Fri, 2 Jul 2021 23:10:44 -0700 Subject: [PATCH] Svc REST: Remove redundant Create tests These cases are all covered in storage_test. --- .../core/service/storage/rest_test.go | 1804 +---------------- 1 file changed, 6 insertions(+), 1798 deletions(-) diff --git a/pkg/registry/core/service/storage/rest_test.go b/pkg/registry/core/service/storage/rest_test.go index edcc8157bcb..94609e50b5b 100644 --- a/pkg/registry/core/service/storage/rest_test.go +++ b/pkg/registry/core/service/storage/rest_test.go @@ -288,219 +288,6 @@ func makeIPNet6(t *testing.T) *net.IPNet { return net } -func TestServiceRegistryCreate(t *testing.T) { - testCases := []struct { - svc *api.Service - name string - families []api.IPFamily - enableDualStack bool - }{{ - name: "Service IPFamily default cluster dualstack:off", - enableDualStack: false, - families: []api.IPFamily{api.IPv4Protocol}, - svc: svctest.MakeService("foo"), - }, { - name: "Service IPFamily:v4 dualstack off", - enableDualStack: false, - families: []api.IPFamily{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: svctest.MakeService("foo", svctest.SetIPFamilies(api.IPv4Protocol)), - }, { - name: "Service IPFamily:v6 dualstack on", - enableDualStack: true, - families: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - svc: svctest.MakeService("foo", svctest.SetIPFamilies(api.IPv6Protocol)), - }} - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - storage, server := NewTestREST(t, tc.families) - defer server.Terminate(t) - - ctx := genericapirequest.NewDefaultContext() - createdSvc, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if err != nil { - t.Fatalf("error creating service %v", err) - } - createdService := createdSvc.(*api.Service) - objMeta, err := meta.Accessor(createdService) - if err != nil { - t.Fatal(err) - } - if !metav1.HasObjectMetaSystemFieldValues(objMeta) { - t.Errorf("storage did not populate object meta field values") - } - if createdService.Name != "foo" { - t.Errorf("Expected foo, but got %v", createdService.Name) - } - if createdService.CreationTimestamp.IsZero() { - t.Errorf("Expected timestamp to be set, got: %v", createdService.CreationTimestamp) - } - - for i, family := range createdService.Spec.IPFamilies { - allocator := storage.alloc.serviceIPAllocatorsByFamily[family] - c := allocator.CIDR() - cidr := &c - if !cidr.Contains(netutils.ParseIPSloppy(createdService.Spec.ClusterIPs[i])) { - t.Errorf("Unexpected ClusterIP: %s", createdService.Spec.ClusterIPs[i]) - } - } - srv, err := getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if srv == nil { - t.Errorf("Failed to find service: %s", tc.svc.Name) - } - }) - } -} - -func TestServiceRegistryCreateDryRun(t *testing.T) { - testCases := []struct { - name string - svc *api.Service - enableDualStack bool - }{{ - name: "v4 service featuregate off", - enableDualStack: false, - svc: svctest.MakeService("foo", svctest.SetClusterIPs("1.2.3.4")), - }, { - name: "v6 service featuregate on but singlestack", - enableDualStack: true, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv6Protocol), - svctest.SetClusterIPs("2000::1")), - }, { - name: "dualstack v4,v6 service", - enableDualStack: true, - 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: 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 { - t.Run(tc.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, tc.enableDualStack)() - - families := []api.IPFamily{api.IPv4Protocol} - if tc.enableDualStack { - families = append(families, api.IPv6Protocol) - } - storage, server := NewTestREST(t, families) - defer server.Terminate(t) - - ctx := genericapirequest.NewDefaultContext() - _, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - for i, family := range tc.svc.Spec.IPFamilies { - alloc := storage.alloc.serviceIPAllocatorsByFamily[family] - if ipIsAllocated(t, alloc, tc.svc.Spec.ClusterIPs[i]) { - t.Errorf("unexpected side effect: ip allocated %v", tc.svc.Spec.ClusterIPs[i]) - } - } - - _, err = getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) - if err == nil { - t.Errorf("expected error") - } - }) - } -} - -func TestDryRunNodePort(t *testing.T) { - storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) - defer server.Terminate(t) - - // Test dry run create request with a node port - svc := svctest.MakeService("foo", svctest.SetTypeNodePort) - ctx := genericapirequest.NewDefaultContext() - - obj, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - createdSvc := obj.(*api.Service) - if createdSvc.Spec.Ports[0].NodePort == 0 { - t.Errorf("expected NodePort value assigned") - } - if portIsAllocated(t, storage.alloc.serviceNodePorts, createdSvc.Spec.Ports[0].NodePort) { - t.Errorf("unexpected side effect: NodePort allocated") - } - _, 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 - 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 { - t.Fatalf("Unexpected error: %v", err) - } - createdSvc = obj.(*api.Service) - actualNodePorts := collectServiceNodePorts(createdSvc) - if !reflect.DeepEqual(actualNodePorts, expectNodePorts) { - t.Errorf("Expected %v, but got %v", expectNodePorts, actualNodePorts) - } - for i := range svc.Spec.Ports { - if portIsAllocated(t, storage.alloc.serviceNodePorts, svc.Spec.Ports[i].NodePort) { - t.Errorf("unexpected side effect: NodePort allocated") - } - } - _, 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, - // so PortAllocationOperation.AllocateNext() will be called multiple times. - 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) - } - 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, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -574,28 +361,6 @@ func TestServiceRegistryCreateMultiNodePortsService(t *testing.T) { } } -func TestServiceStorageValidatesCreate(t *testing.T) { - storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) - defer server.Terminate(t) - failureCases := map[string]*api.Service{ - "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 { - c, err := storage.Create(ctx, failureCase, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if c != nil { - t.Errorf("Expected nil object") - } - if !errors.IsInvalid(err) { - t.Errorf("Expected to get an invalid resource error, got %v", err) - } - } -} - func TestServiceRegistryUpdate(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) @@ -996,123 +761,6 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { } } -func TestServiceRegistryLoadBalancerService(t *testing.T) { - ctx := genericapirequest.NewDefaultContext() - 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{}) - if err != nil { - t.Errorf("Failed to create service: %#v", err) - } - srv, err := getService(storage, ctx, svc.Name, &metav1.GetOptions{}) - if err != nil { - t.Errorf("Unexpected error: %v", err) - } - if srv == nil { - t.Fatalf("Failed to find service: %s", svc.Name) - } - serviceNodePorts := collectServiceNodePorts(srv) - if len(serviceNodePorts) == 0 { - t.Errorf("Failed to find NodePorts of service : %s", srv.Name) - } -} - -func TestAllocateLoadBalancerNodePorts(t *testing.T) { - testcases := []struct { - name string - svc *api.Service - expectNodePorts bool - allocateNodePortGate bool - expectError bool - }{{ - name: "allocate false, gate on, not specified", - svc: svctest.MakeService("alloc-false", - svctest.SetTypeLoadBalancer, - svctest.SetAllocateLoadBalancerNodePorts(false)), - expectNodePorts: false, - allocateNodePortGate: true, - }, { - name: "allocate true, gate on, not specified", - svc: svctest.MakeService("alloc-true", - svctest.SetTypeLoadBalancer, - svctest.SetAllocateLoadBalancerNodePorts(true)), - expectNodePorts: true, - allocateNodePortGate: true, - }, { - name: "allocate false, gate on, port specified", - svc: svctest.MakeService("alloc-false-specific", - svctest.SetTypeLoadBalancer, - svctest.SetUniqueNodePorts, - svctest.SetAllocateLoadBalancerNodePorts(false)), - expectNodePorts: true, - allocateNodePortGate: true, - }, { - name: "allocate true, gate on, port specified", - svc: svctest.MakeService("alloc-true-specific", - svctest.SetTypeLoadBalancer, - svctest.SetUniqueNodePorts, - svctest.SetAllocateLoadBalancerNodePorts(true)), - expectNodePorts: true, - allocateNodePortGate: true, - }, { - name: "allocate nil, gate off", - svc: svctest.MakeService("alloc-nil", - svctest.SetTypeLoadBalancer, - func(s *api.Service) { - s.Spec.AllocateLoadBalancerNodePorts = nil - }), - expectNodePorts: true, - allocateNodePortGate: false, - }, { - name: "allocate false, gate off", - svc: svctest.MakeService("alloc-false", - svctest.SetTypeLoadBalancer, - svctest.SetAllocateLoadBalancerNodePorts(false)), - expectNodePorts: true, - allocateNodePortGate: false, - }, { - name: "allocate true, gate off", - svc: svctest.MakeService("alloc-true", - svctest.SetTypeLoadBalancer, - svctest.SetAllocateLoadBalancerNodePorts(true)), - expectNodePorts: true, - allocateNodePortGate: false, - }} - for _, tc := range testcases { - t.Run(tc.name, func(t *testing.T) { - ctx := genericapirequest.NewDefaultContext() - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ServiceLBNodePortControl, tc.allocateNodePortGate)() - - storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) - defer server.Terminate(t) - - _, err := storage.Create(ctx, tc.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if err != nil { - if tc.expectError { - return - } - t.Errorf("failed to create service: %#v", err) - } - srv, err := getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if srv == nil { - t.Fatalf("failed to find service: %s", tc.svc.Name) - } - serviceNodePorts := collectServiceNodePorts(srv) - if (len(serviceNodePorts) != 0) != tc.expectNodePorts { - exp := "0" - if tc.expectNodePorts { - exp = ">0" - } - t.Errorf("allocated NodePorts not as expected: expected %v, got %v", exp, len(serviceNodePorts)) - } - }) - } -} - func TestServiceRegistryDelete(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) @@ -1470,7 +1118,7 @@ func TestServiceRegistryList(t *testing.T) { } } -func TestServiceRegistryIPAllocation(t *testing.T) { +func TestServiceRegistryCreateIPAllocation(t *testing.T) { storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -1523,7 +1171,7 @@ func TestServiceRegistryIPAllocation(t *testing.T) { } } -func TestServiceRegistryIPReallocation(t *testing.T) { +func TestServiceRegistryCreateIPReallocation(t *testing.T) { storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -1611,36 +1259,9 @@ func TestServiceRegistryIPUpdate(t *testing.T) { } } -func TestServiceRegistryIPLoadBalancer(t *testing.T) { - storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) - defer server.Terminate(t) - - svc := svctest.MakeService("foo", svctest.SetTypeLoadBalancer) - ctx := genericapirequest.NewDefaultContext() - createdSvc, err := storage.Create(ctx, svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if createdSvc == nil || err != nil { - t.Errorf("Unexpected failure creating service %v", err) - } - - createdService := createdSvc.(*api.Service) - 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(netutils.ParseIPSloppy(createdService.Spec.ClusterIPs[0])) { - t.Errorf("Unexpected ClusterIP: %s", createdService.Spec.ClusterIPs[0]) - } - - update := createdService.DeepCopy() - - _, _, err = storage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(update), rest.ValidateAllObjectFunc, rest.ValidateAllObjectUpdateFunc, false, &metav1.UpdateOptions{}) - if err != nil { - t.Errorf("Unexpected error %v", err) - } -} - // Validate allocation of a nodePort when ExternalTrafficPolicy is set to Local // and type is LoadBalancer. -func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { +func TestServiceRegistryCreateExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -1700,7 +1321,7 @@ func TestServiceRegistryExternalTrafficHealthCheckNodePortUserAllocation(t *test } // Validate that the service creation fails when the requested port number is -1. -func TestServiceRegistryExternalTrafficHealthCheckNodePortNegative(t *testing.T) { +func TestServiceRegistryCreateExternalTrafficHealthCheckNodePortNegative(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -1716,7 +1337,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) { +func TestServiceRegistryCreateExternalTrafficGlobal(t *testing.T) { ctx := genericapirequest.NewDefaultContext() storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) @@ -1806,248 +1427,7 @@ func TestServiceRegistryInternalTrafficPolicyLocalThenCluster(t *testing.T) { } } -func TestInitClusterIP(t *testing.T) { - testCases := []struct { - name string - svc *api.Service - - enableDualStackAllocator bool - preAllocateClusterIPs map[api.IPFamily]string - expectError bool - expectedCountIPs int - expectedClusterIPs []string - }{{ - name: "Allocate single stack ClusterIP (v4)", - svc: svctest.MakeService("foo"), - enableDualStackAllocator: false, - expectError: false, - preAllocateClusterIPs: nil, - expectedCountIPs: 1, - }, { - name: "Allocate single ClusterIP (v6)", - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv6Protocol)), - expectError: false, - enableDualStackAllocator: true, - preAllocateClusterIPs: nil, - expectedCountIPs: 1, - }, { - name: "Allocate specified ClusterIP (v4)", - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol), - svctest.SetClusterIPs("1.2.3.4")), - expectError: false, - enableDualStackAllocator: true, - preAllocateClusterIPs: nil, - expectedCountIPs: 1, - expectedClusterIPs: []string{"1.2.3.4"}, - }, { - name: "Allocate specified ClusterIP-v6", - 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: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol)), - expectError: false, - enableDualStackAllocator: false, - expectedCountIPs: 1, - }, { - name: "Allocate dual stack - upgrade - v4, v6", - 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: 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: 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: 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: 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: svctest.MakeService("foo", - svctest.SetClusterIPs("None")), - expectError: false, - enableDualStackAllocator: false, - expectedCountIPs: 0, - }, { - name: "single stack, ip is pre allocated (ipv4)", - 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: 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: 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: 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.IPv4Protocol: "1.2.3.4"}, - }} - - for _, test := range testCases { - t.Run(test.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.IPv6DualStack, true)() - - // create the rest stack - families := []api.IPFamily{api.IPv4Protocol} - if test.enableDualStackAllocator { - families = append(families, api.IPv6Protocol) - } - storage, server := NewTestREST(t, families) - defer server.Terminate(t) - - copySvc := test.svc.DeepCopy() - - // pre allocate ips if any - for family, ip := range test.preAllocateClusterIPs { - allocator, ok := storage.alloc.serviceIPAllocatorsByFamily[family] - if !ok { - t.Fatalf("test is incorrect, allocator does not exist on rest") - } - if err := allocator.Allocate(netutils.ParseIPSloppy(ip)); err != nil { - t.Fatalf("test is incorrect, allocator failed to pre allocate IP with error:%v", err) - } - } - ctx := genericapirequest.NewDefaultContext() - createdSvc, err := storage.Create(ctx, test.svc, rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) - if test.expectError && err == nil { - t.Fatalf("error was expected, but no error was returned") - } - - if !test.expectError && err != nil { - t.Fatalf("error was not expected, but got error %v", err) - } - - if err != nil { - return // no more testing needed for this case - } - newSvc := createdSvc.(*api.Service) - isValidClusterIPFields(t, storage, copySvc, newSvc) - - // if it has ips then let us check they have been correctly allocated - if newSvc.Spec.ClusterIPs[0] != api.ClusterIPNone { - for _, ip := range newSvc.Spec.ClusterIPs { - family := api.IPv4Protocol - if netutils.IsIPv6String(ip) { - family = api.IPv6Protocol - } - allocator := storage.alloc.serviceIPAllocatorsByFamily[family] - if !ipIsAllocated(t, allocator, ip) { - t.Fatalf("expected ip:%v to be allocated by %v allocator. it was not", ip, family) - } - } - } - - allocatedIPs := 0 - for _, ip := range newSvc.Spec.ClusterIPs { - if ip != api.ClusterIPNone { - allocatedIPs++ - } - } - - if allocatedIPs != test.expectedCountIPs { - t.Fatalf("incorrect allocated IP count expected %v got %v", test.expectedCountIPs, allocatedIPs) - } - - for i, ip := range test.expectedClusterIPs { - if i >= len(newSvc.Spec.ClusterIPs) { - t.Fatalf("incorrect ips were assigne. expected to find %+v in %+v", - ip, newSvc.Spec.ClusterIPs) - } - - if ip != newSvc.Spec.ClusterIPs[i] { - t.Fatalf("incorrect ips were assigne. expected to find %+v == %+v at position %v", - ip, newSvc.Spec.ClusterIPs[i], i) - } - } - - // the following apply only on dual stack - if !utilfeature.DefaultFeatureGate.Enabled(features.IPv6DualStack) { - return - } - - shouldUpgrade := len(newSvc.Spec.IPFamilies) == 2 && *(newSvc.Spec.IPFamilyPolicy) != api.IPFamilyPolicySingleStack && len(storage.alloc.serviceIPAllocatorsByFamily) == 2 - if shouldUpgrade && len(newSvc.Spec.ClusterIPs) < 2 { - t.Fatalf("Service should have been upgraded %+v", newSvc) - } - - if !shouldUpgrade && len(newSvc.Spec.ClusterIPs) > 1 { - t.Fatalf("Service should not have been upgraded %+v", newSvc) - } - - }) - } -} - -func TestInitNodePorts(t *testing.T) { +func TestCreateInitNodePorts(t *testing.T) { storage, server := NewTestREST(t, []api.IPFamily{api.IPv4Protocol}) defer server.Terminate(t) nodePortOp := portallocator.StartOperation(storage.alloc.serviceNodePorts, false) @@ -2585,1178 +1965,6 @@ func TestServiceDowngrade(t *testing.T) { } } -func TestDefaultingValidation(t *testing.T) { - singleStack := api.IPFamilyPolicySingleStack - preferDualStack := api.IPFamilyPolicyPreferDualStack - requireDualStack := api.IPFamilyPolicyRequireDualStack - - // takes in REST and modify it for a specific config - fnMakeSingleStackIPv4Allocator := func(rest *REST) { - rest.alloc.defaultServiceIPFamily = api.IPv4Protocol - rest.alloc.serviceIPAllocatorsByFamily = map[api.IPFamily]ipallocator.Interface{api.IPv4Protocol: rest.alloc.serviceIPAllocatorsByFamily[api.IPv4Protocol]} - } - - fnMakeSingleStackIPv6Allocator := func(rest *REST) { - rest.alloc.defaultServiceIPFamily = api.IPv6Protocol - rest.alloc.serviceIPAllocatorsByFamily = map[api.IPFamily]ipallocator.Interface{api.IPv6Protocol: rest.alloc.serviceIPAllocatorsByFamily[api.IPv6Protocol]} - } - - fnMakeDualStackStackIPv4IPv6Allocator := func(rest *REST) { - rest.alloc.defaultServiceIPFamily = api.IPv4Protocol - rest.alloc.serviceIPAllocatorsByFamily = map[api.IPFamily]ipallocator.Interface{ - api.IPv6Protocol: rest.alloc.serviceIPAllocatorsByFamily[api.IPv6Protocol], - api.IPv4Protocol: rest.alloc.serviceIPAllocatorsByFamily[api.IPv4Protocol], - } - } - - fnMakeDualStackStackIPv6IPv4Allocator := func(rest *REST) { - rest.alloc.defaultServiceIPFamily = api.IPv6Protocol - rest.alloc.serviceIPAllocatorsByFamily = map[api.IPFamily]ipallocator.Interface{ - api.IPv6Protocol: rest.alloc.serviceIPAllocatorsByFamily[api.IPv6Protocol], - api.IPv4Protocol: rest.alloc.serviceIPAllocatorsByFamily[api.IPv4Protocol], - } - } - - testCases := []struct { - name string - modifyRest func(rest *REST) - oldSvc *api.Service - svc *api.Service - - expectedIPFamilyPolicy *api.IPFamilyPolicyType - expectedIPFamilies []api.IPFamily - expectError bool - }{ - //////////////////////////// - // cluster configured as single stack v4 - //////////////////////////// - { - name: "[singlestack:v4] set: externalname on a single stack - v4", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", svctest.SetTypeExternalName), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: false, - }, - { - name: "[singlestack:v4] set: nothing", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo"), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - - { - name: "[singlestack:v4] set: v4Cluster IPSet", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("10.0.0.4")), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[singlestack:v4] set: v4IPFamilySet", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[singlestack:v4] set: v4IPFamilySet", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("10.0.0.4"), - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[singlestack:v4] set: PreferDualStack", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[singlestack:v4] set: PreferDualStack + v4ClusterIPSet", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - svctest.SetClusterIPs("10.0.0.4")), - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[singlestack:v4] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", - modifyRest: fnMakeSingleStackIPv4Allocator, - 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, - }, - { - name: "[singlestack:v4] set: v6IPSet", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("2000::1")), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v4] set: v6IPFamily", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v4] set: RequireDualStack", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v4] set: RequireDualStack + family", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - // selector less - { - name: "[singlestack:v4] set: selectorless, families are ignored", - modifyRest: fnMakeSingleStackIPv4Allocator, - 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}, - expectError: false, - }, - { - name: "[singlestack:v4] set: selectorless, no families", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - func(s *api.Service) { s.Spec.Selector = nil }), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - { - name: "[singlestack:v4] set: selectorless, user selected", - modifyRest: fnMakeSingleStackIPv4Allocator, - 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}, - expectError: false, - }, - { - name: "[singlestack:v4] set: selectorless, user set to preferDualStack", - modifyRest: fnMakeSingleStackIPv4Allocator, - 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}, - expectError: false, - }, - // tests incorrect setting for IPFamilyPolicy - { - name: "[singlestack:v4] set: multifamily set to preferDualStack", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v4] set: multifamily set to singleStack", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v4] set: mult clusterips set to preferDualStack", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v4] set: multi clusterips set to singleStack", - modifyRest: fnMakeSingleStackIPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - - //////////////////////////// - // cluster configured as single stack v6 - //////////////////////////// - { - name: "[singlestack:v6] set: externalname on a single stack - v4", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", svctest.SetTypeExternalName), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: false, - }, - { - name: "[singlestack:v6] set: nothing", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo"), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[singlestack:v6] set: v6Cluster IPSet", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("2000::1")), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[singlestack:v6] set: v4IPFamilySet", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[singlestack:v6] set: v6IPFamilySet", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("2000::1"), - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[singlestack:v6] set: PreferDualStack", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[singlestack:v6] set: PreferDualStack + v6ClusterIPSet", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack), - svctest.SetClusterIPs("2000::1")), - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[singlestack:v6] set: PreferDualStack + v6ClusterIPSet + v6FamilySet", - modifyRest: fnMakeSingleStackIPv6Allocator, - 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, - }, - { - name: "[singlestack:v6] set: v4IPSet", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("10.0.0.10")), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v6] set: v4IPFamily", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v6] set: RequireDualStack (on single stack ipv6 cluster)", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v6] set: RequireDualStack + family (on single stack ipv6 cluster)", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - - // selector less - { - name: "[singlestack:v6] set: selectorless, families are ignored", - modifyRest: fnMakeSingleStackIPv6Allocator, - 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}, - expectError: false, - }, - { - name: "[singlestack:v6] set: selectorless, no families", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - func(s *api.Service) { s.Spec.Selector = nil }), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - { - name: "[singlestack:v6] set: selectorless, user selected", - modifyRest: fnMakeSingleStackIPv6Allocator, - 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}, - expectError: false, - }, - { - name: "[singlestack:v6] set: selectorless, user set to preferDualStack", - modifyRest: fnMakeSingleStackIPv6Allocator, - 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}, - expectError: false, - }, - // tests incorrect setting for IPFamilyPolicy - { - name: "[singlestack:v6] set: multifamily set to preferDualStack", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v6] set: multifamily set to singleStack", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v6] set: mult clusterips set to preferDualStack", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[singlestack:v6] set: multi clusterips set to singleStack", - modifyRest: fnMakeSingleStackIPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - - //////////////////////////// - // cluster configured as dual stack v4,6 - //////////////////////////// - { - name: "[dualstack:v4,v6] set: externalname on a dual stack - v4,v6", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", svctest.SetTypeExternalName), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: nothing", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo"), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - - { - name: "[dualstack:v4,v6] set: v4ClusterIPSet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("10.0.0.4")), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: v4IPFamilySet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: v4IPFamilySet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("10.0.0.4"), - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: v6ClusterIPSet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("2000::1")), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: v6IPFamilySet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: v6IPFamilySet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("2000::1"), - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - // prefer dual stack - { - name: "[dualstack:v4,v6] set: PreferDualStack.", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: PreferDualStack + v4ClusterIPSet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,v6] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - // require dual stack - { - name: "[dualstack:v4,v6] set: RequireDualStack", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + family v4", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + family v6", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - - { - name: "[dualstack:v4,v6] set: RequireDualStack + family +ip v4", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + family +ip v6", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + ip v6", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetClusterIPs("2000::1")), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + ip v4", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + ips", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + ips", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,v6] set: RequireDualStack + ips + families v6,v4", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v4,v6", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,v6] set: selectorless, no families", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - func(s *api.Service) { s.Spec.Selector = nil }), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,6] set: selectorless, user selected", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v4,6] set: selectorless, user set to prefer", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - // tests incorrect setting for IPFamilyPolicy - { - name: "[duakstack:v4,6] set: multifamily set to preferDualStack", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,6] set: multifamily set to singleStack", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[dualstack:v4,6] set: mult clusterips set to preferDualStack", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - 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, - }, - { - name: "[dualstack:v4,6] set: multi clusterips set to singleStack", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - - //////////////////////////// - // cluster configured as dual stack v6,4 - //////////////////////////// - { - name: "[dualstack:v6,v4] set: externalname on a dual stack - v6,v4", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", svctest.SetTypeExternalName), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: nothing", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo"), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: v4ClusterIPSet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("10.0.0.4")), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: v4IPFamilySet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol)), - // - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: v4IPFamilySet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("10.0.0.4"), - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: v6ClusterIPSet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("2000::1")), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: v6IPFamilySet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: v6IPFamilySet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("2000::1"), - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - // prefer dual stack - { - name: "[dualstack:v6,v4] set: PreferDualStack.", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: PreferDualStack + v4ClusterIPSet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: PreferDualStack + v4ClusterIPSet + v4FamilySet", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - // require dual stack - { - name: "[dualstack:v6,v4] set: RequireDualStack", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + family v4", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetIPFamilies(api.IPv4Protocol)), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + family v6", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetIPFamilies(api.IPv6Protocol)), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + family +ip v4", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + family +ip v6", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ip v6", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack), - svctest.SetClusterIPs("2000::1")), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ip v4", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ip v4", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ips", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ips", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v6,v4", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: RequireDualStack + ips + families v4,v6", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,v4] set: selectorless, no families", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - func(s *api.Service) { s.Spec.Selector = nil }), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: selectorless, user selected", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - - expectedIPFamilyPolicy: &singleStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol}, - expectError: false, - }, - { - name: "[dualstack:v6,v4] set: selectorless, user set to prefer", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("None"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - - expectedIPFamilyPolicy: &preferDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv6Protocol, api.IPv4Protocol}, - expectError: false, - }, - // tests incorrect setting for IPFamilyPolicy - { - name: "[duakstack:v6,5] set: multifamily set to preferDualStack", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v4,6] set: multifamily set to singleStack", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - { - name: "[dualstack:v6,4] set: mult clusterips set to preferDualStack", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - 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, - }, - { - name: "[dualstack:v6,4] set: multi clusterips set to singleStack", - modifyRest: fnMakeDualStackStackIPv6IPv4Allocator, - svc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicySingleStack)), - expectedIPFamilyPolicy: nil, - expectedIPFamilies: nil, - expectError: true, - }, - - // preferDualStack services should not be updated - // to match cluster config if the user didn't change any - // ClusterIPs related fields - { - name: "unchanged preferDualStack-1-ClusterUpgraded", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - oldSvc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1"), - svctest.SetIPFamilies(api.IPv4Protocol), - svctest.SetIPFamilyPolicy(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, - }, - - { - name: "unchanged preferDualStack-2-ClusterDowngraded", - modifyRest: fnMakeSingleStackIPv4Allocator, - oldSvc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(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, - }, - - { - name: "changed preferDualStack-1 (cluster upgraded)", - modifyRest: fnMakeDualStackStackIPv4IPv6Allocator, - oldSvc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1"), - svctest.SetIPFamilies(api.IPv4Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - - svc: svctest.MakeService("foo", - svctest.SetIPFamilies(api.IPv4Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyRequireDualStack)), - expectedIPFamilyPolicy: &requireDualStack, - expectedIPFamilies: []api.IPFamily{api.IPv4Protocol, api.IPv6Protocol}, - expectError: false, - }, - - { - name: "changed preferDualStack-2-ClusterDowngraded", - modifyRest: fnMakeSingleStackIPv4Allocator, - oldSvc: svctest.MakeService("foo", - svctest.SetClusterIPs("1.1.1.1", "2001::1"), - svctest.SetIPFamilies(api.IPv4Protocol, api.IPv6Protocol), - svctest.SetIPFamilyPolicy(api.IPFamilyPolicyPreferDualStack)), - - 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, - }, - } - - // 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}) - defer server.Terminate(t) - - for _, testCase := range testCases { - t.Run(testCase.name, func(t *testing.T) { - - // reset to defaults - fnMakeDualStackStackIPv4IPv6Allocator(storage) - // optionally apply test-specific changes - if testCase.modifyRest != nil { - testCase.modifyRest(storage) - } - - err := storage.alloc.initIPFamilyFields(testCase.oldSvc, testCase.svc) - if err != nil && !testCase.expectError { - t.Fatalf("error %v was not expected", err) - } - - if err == nil && testCase.expectError { - t.Fatalf("error was expected, but no error returned") - } - - if err != nil { - t.Logf("test concluded successfully with terminal error %v", err) - return - } - - // IPFamily Policy - if (testCase.expectedIPFamilyPolicy == nil && testCase.svc.Spec.IPFamilyPolicy != nil) || - (testCase.expectedIPFamilyPolicy != nil && testCase.svc.Spec.IPFamilyPolicy == nil) { - t.Fatalf("ipFamilyPolicy expected:%v got %v", testCase.expectedIPFamilyPolicy, testCase.svc.Spec.IPFamilyPolicy) - } - - if testCase.expectedIPFamilyPolicy != nil { - if *testCase.expectedIPFamilyPolicy != *testCase.svc.Spec.IPFamilyPolicy { - t.Fatalf("ipFamilyPolicy expected:%s got %s", *testCase.expectedIPFamilyPolicy, *testCase.svc.Spec.IPFamilyPolicy) - } - } - - if len(testCase.expectedIPFamilies) != len(testCase.svc.Spec.IPFamilies) { - t.Fatalf("expected len of IPFamilies %v got %v", len(testCase.expectedIPFamilies), len(testCase.svc.Spec.IPFamilies)) - } - - // match families - for i, family := range testCase.expectedIPFamilies { - if testCase.svc.Spec.IPFamilies[i] != family { - t.Fatalf("expected ip family %v at %v got %v", family, i, testCase.svc.Spec.IPFamilies) - } - } - }) - } -} - // validates that the service created, updated by REST // has correct ClusterIPs related fields func isValidClusterIPFields(t *testing.T, storage *REST, pre *api.Service, post *api.Service) {