mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	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.
This commit is contained in:
		| @@ -18,9 +18,9 @@ package storage | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
| 	"net" | 	"net" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"strings" |  | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
| @@ -61,16 +61,26 @@ var ( | |||||||
| // in a completely different way. We should unify it. | // in a completely different way. We should unify it. | ||||||
|  |  | ||||||
| type serviceStorage struct { | type serviceStorage struct { | ||||||
| 	Service     *api.Service | 	Services    map[string]*api.Service | ||||||
| 	ServiceList *api.ServiceList | 	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 { | func (s *serviceStorage) NamespaceScoped() bool { | ||||||
| 	return true | 	return true | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *serviceStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { | 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) { | 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 | 		return obj, nil | ||||||
| 	} | 	} | ||||||
| 	svc := obj.(*api.Service) | 	svc := obj.(*api.Service) | ||||||
| 	s.Service = svc.DeepCopy() | 	s.saveService(svc) | ||||||
| 	s.Service.ResourceVersion = "1" | 	s.Services[svc.Name].ResourceVersion = "1" | ||||||
|  |  | ||||||
| 	if s.ServiceList == nil { | 	if s.ServiceList == nil { | ||||||
| 		s.ServiceList = &api.ServiceList{} | 		s.ServiceList = &api.ServiceList{} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	s.ServiceList.Items = append(s.ServiceList.Items, *svc) | 	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) { | 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 | 		return nil, false, err | ||||||
| 	} | 	} | ||||||
| 	if !dryrun.IsDryRun(options.DryRun) { | 	if !dryrun.IsDryRun(options.DryRun) { | ||||||
| 		s.Service = obj.(*api.Service) | 		s.saveService(obj.(*api.Service)) | ||||||
| 	} | 	} | ||||||
| 	return obj, false, nil | 	return obj, false, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (s *serviceStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { | 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) { | 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 | 	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) | 	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, "") | 	etcdStorage, server := registrytest.NewEtcdStorage(t, "") | ||||||
|  |  | ||||||
| 	serviceStorage := &serviceStorage{} | 	serviceStorage := &serviceStorage{} | ||||||
| @@ -180,13 +192,11 @@ func NewTestRESTWithPods(t *testing.T, endpoints *api.EndpointsList, pods *api.P | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error from REST storage: %v", err) | 		t.Fatalf("unexpected error from REST storage: %v", err) | ||||||
| 	} | 	} | ||||||
| 	if pods != nil && len(pods.Items) > 0 { | 	ctx := genericapirequest.NewDefaultContext() | ||||||
| 		ctx := genericapirequest.NewDefaultContext() | 	for ix := range pods { | ||||||
| 		for ix := range pods.Items { | 		key, _ := podStorage.Pod.KeyFunc(ctx, pods[ix].Name) | ||||||
| 			key, _ := podStorage.Pod.KeyFunc(ctx, pods.Items[ix].Name) | 		if err := podStorage.Pod.Storage.Create(ctx, key, &pods[ix], nil, 0, false); err != nil { | ||||||
| 			if err := podStorage.Pod.Storage.Create(ctx, key, &pods.Items[ix], nil, 0, false); err != nil { | 			t.Fatalf("Couldn't create pod: %v", err) | ||||||
| 				t.Fatalf("Couldn't create pod: %v", err) |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	endpointStorage, err := endpointstore.NewREST(generic.RESTOptions{ | 	endpointStorage, err := endpointstore.NewREST(generic.RESTOptions{ | ||||||
| @@ -197,13 +207,10 @@ func NewTestRESTWithPods(t *testing.T, endpoints *api.EndpointsList, pods *api.P | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unexpected error from REST storage: %v", err) | 		t.Fatalf("unexpected error from REST storage: %v", err) | ||||||
| 	} | 	} | ||||||
| 	if endpoints != nil && len(endpoints.Items) > 0 { | 	for ix := range endpoints { | ||||||
| 		ctx := genericapirequest.NewDefaultContext() | 		key, _ := endpointStorage.KeyFunc(ctx, endpoints[ix].Name) | ||||||
| 		for ix := range endpoints.Items { | 		if err := endpointStorage.Store.Storage.Create(ctx, key, endpoints[ix], nil, 0, false); err != nil { | ||||||
| 			key, _ := endpointStorage.KeyFunc(ctx, endpoints.Items[ix].Name) | 			t.Fatalf("Couldn't create endpoint: %v", err) | ||||||
| 			if err := endpointStorage.Store.Storage.Create(ctx, key, &endpoints.Items[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{}) | 			_, err = getService(storage, ctx, tc.svc.Name, &metav1.GetOptions{}) | ||||||
| 			if err != nil { | 			if err == nil { | ||||||
| 				t.Errorf("unexpected error: %v", err) | 				t.Errorf("expected error") | ||||||
| 			} |  | ||||||
| 			if srv != nil { |  | ||||||
| 				t.Errorf("unexpected service found: %v", srv) |  | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| @@ -436,12 +440,10 @@ func TestDryRunNodePort(t *testing.T) { | |||||||
| 	if storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { | 	if storage.serviceNodePorts.Has(int(createdSvc.Spec.Ports[0].NodePort)) { | ||||||
| 		t.Errorf("unexpected side effect: NodePort allocated") | 		t.Errorf("unexpected side effect: NodePort allocated") | ||||||
| 	} | 	} | ||||||
| 	srv, err := getService(storage, ctx, svc.Name, &metav1.GetOptions{}) | 	_, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) | ||||||
| 	if err != nil { | 	if err == nil { | ||||||
| 		t.Errorf("unexpected error: %v", err) | 		// Should get a not-found. | ||||||
| 	} | 		t.Errorf("expected error") | ||||||
| 	if srv != nil { |  | ||||||
| 		t.Errorf("unexpected service found: %v", srv) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Test dry run create request with multi node port | 	// 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") | 			t.Errorf("unexpected side effect: NodePort allocated") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	srv, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) | 	_, err = getService(storage, ctx, svc.Name, &metav1.GetOptions{}) | ||||||
| 	if err != nil { | 	if err == nil { | ||||||
| 		t.Errorf("unexpected error: %v", err) | 		// Should get a not-found. | ||||||
| 	} | 		t.Errorf("expected error") | ||||||
| 	if srv != nil { |  | ||||||
| 		t.Errorf("unexpected service found: %v", srv) |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Test dry run create request with multiple unspecified node ports, | 	// Test dry run create request with multiple unspecified node ports, | ||||||
| @@ -730,12 +730,12 @@ func TestServiceStorageValidatesUpdate(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 	for _, failureCase := range failureCases { | 	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 err == nil { | ||||||
|  | 			t.Errorf("expected error") | ||||||
|  | 		} | ||||||
| 		if c != nil || created { | 		if c != nil || created { | ||||||
| 			t.Errorf("Expected nil object or created false") | 			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) { | func TestServiceRegistryResourceLocation(t *testing.T) { | ||||||
| 	ctx := genericapirequest.NewDefaultContext() | 	pods := []api.Pod{ | ||||||
| 	endpoints := &api.EndpointsList{ | 		makePod("unnamed", "1.2.3.4", "1.2.3.5"), | ||||||
| 		Items: []api.Endpoints{ | 		makePod("named", "1.2.3.6", "1.2.3.7"), | ||||||
| 			{ | 		makePod("no-endpoints", "9.9.9.9"), // to prove this does not get chosen | ||||||
| 				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.PodList{ |  | ||||||
| 		Items: []api.Pod{ | 	endpoints := []*api.Endpoints{ | ||||||
| 			{ | 		makeEndpoints("unnamed", | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 			[]api.EndpointAddress{ | ||||||
| 					Name:      "foo", | 				makeEndpointAddress("1.2.3.4", "unnamed"), | ||||||
| 					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::"}}, |  | ||||||
| 				}, |  | ||||||
| 			}, | 			}, | ||||||
| 			{ | 			[]api.EndpointPort{ | ||||||
| 				ObjectMeta: metav1.ObjectMeta{ | 				makeEndpointPort("", 80), | ||||||
| 					Name:      "bar", | 			}), | ||||||
| 					Namespace: metav1.NamespaceDefault, | 		makeEndpoints("unnamed2", | ||||||
| 				}, | 			[]api.EndpointAddress{ | ||||||
| 				Spec: api.PodSpec{ | 				makeEndpointAddress("1.2.3.5", "unnamed"), | ||||||
| 					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("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) | 	defer server.Terminate(t) | ||||||
| 	for _, name := range []string{"foo", "bad"} { |  | ||||||
| 		_, err := registry.Create(ctx, svctest.MakeService(name, | 	ctx := genericapirequest.NewDefaultContext() | ||||||
| 			svctest.SetPorts( | 	for _, name := range []string{"unnamed", "unnamed2", "no-endpoints"} { | ||||||
| 				// Service port 9393 should route to endpoint port "p", which is port 93 | 		_, err := storage.Create(ctx, | ||||||
| 				svctest.MakeServicePort("p", 9393, intstr.FromString("p"), api.ProtocolTCP), | 			svctest.MakeService(name, svctest.SetPorts( | ||||||
| 				// 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 |  | ||||||
| 				svctest.MakeServicePort("", 93, intstr.FromInt(80), api.ProtocolTCP))), | 				svctest.MakeServicePort("", 93, intstr.FromInt(80), api.ProtocolTCP))), | ||||||
| 			rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) | 			rest.ValidateAllObjectFunc, &metav1.CreateOptions{}) | ||||||
| 		if err != nil { | 		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) | 	redirector := rest.Redirector(storage) | ||||||
|  |  | ||||||
| 	// Test a simple id. | 	cases := []struct { | ||||||
| 	location, _, err := redirector.ResourceLocation(ctx, "foo") | 		query  string | ||||||
| 	if err != nil { | 		err    bool | ||||||
| 		t.Errorf("Unexpected error: %v", err) | 		expect string | ||||||
| 	} | 	}{{ | ||||||
| 	if location == nil { | 		query:  "unnamed", | ||||||
| 		t.Errorf("Unexpected nil: %v", location) | 		expect: "//1.2.3.4:80", | ||||||
| 	} | 	}, { | ||||||
| 	if e, a := "//1.2.3.4:80", location.String(); e != a { | 		query:  "unnamed:", | ||||||
| 		t.Errorf("Expected %v, but got %v", e, a) | 		expect: "//1.2.3.4:80", | ||||||
| 	} | 	}, { | ||||||
|  | 		query:  "unnamed:93", | ||||||
| 	// Test a simple id (using second ip). | 		expect: "//1.2.3.4:80", | ||||||
| 	location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip") | 	}, { | ||||||
| 	if err != nil { | 		query:  "http:unnamed:", | ||||||
| 		t.Errorf("Unexpected error: %v", err) | 		expect: "http://1.2.3.4:80", | ||||||
| 	} | 	}, { | ||||||
| 	if location == nil { | 		query:  "http:unnamed:93", | ||||||
| 		t.Errorf("Unexpected nil: %v", location) | 		expect: "http://1.2.3.4:80", | ||||||
| 	} | 	}, { | ||||||
| 	if e, a := "//[2001:db7::]:80", location.String(); e != a { | 		query: "unnamed:80", | ||||||
| 		t.Errorf("Expected %v, but got %v", e, a) | 		err:   true, | ||||||
| 	} | 	}, { | ||||||
|  | 		query:  "unnamed2", | ||||||
| 	// Test a name + port. | 		expect: "//1.2.3.5:80", | ||||||
| 	location, _, err = redirector.ResourceLocation(ctx, "foo:p") | 	}, { | ||||||
| 	if err != nil { | 		query:  "named:p", | ||||||
| 		t.Errorf("Unexpected error: %v", err) | 		expect: "//1.2.3.6:80", | ||||||
| 	} | 	}, { | ||||||
| 	if location == nil { | 		query:  "named:q", | ||||||
| 		t.Errorf("Unexpected nil: %v", location) | 		expect: "//1.2.3.6:81", | ||||||
| 	} | 	}, { | ||||||
| 	if e, a := "//1.2.3.4:93", location.String(); e != a { | 		query:  "named:93", | ||||||
| 		t.Errorf("Expected %v, but got %v", e, a) | 		expect: "//1.2.3.6:80", | ||||||
| 	} | 	}, { | ||||||
|  | 		query:  "named:76", | ||||||
| 	// Test a name + port (using second ip). | 		expect: "//1.2.3.6:81", | ||||||
| 	location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:p") | 	}, { | ||||||
| 	if err != nil { | 		query:  "http:named:p", | ||||||
| 		t.Errorf("Unexpected error: %v", err) | 		expect: "http://1.2.3.6:80", | ||||||
| 	} | 	}, { | ||||||
| 	if location == nil { | 		query:  "http:named:q", | ||||||
| 		t.Errorf("Unexpected nil: %v", location) | 		expect: "http://1.2.3.6:81", | ||||||
| 	} | 	}, { | ||||||
| 	if e, a := "//[2001:db7::]:93", location.String(); e != a { | 		query: "named:bad", | ||||||
| 		t.Errorf("Expected %v, but got %v", e, a) | 		err:   true, | ||||||
| 	} | 	}, { | ||||||
|  | 		query: "no-endpoints", | ||||||
| 	// Test a name + port number (service port 93 -> target port 80) | 		err:   true, | ||||||
| 	location, _, err = redirector.ResourceLocation(ctx, "foo:93") | 	}, { | ||||||
| 	if err != nil { | 		query: "non-existent", | ||||||
| 		t.Errorf("Unexpected error: %v", err) | 		err:   true, | ||||||
| 	} | 	}} | ||||||
| 	if location == nil { | 	for _, tc := range cases { | ||||||
| 		t.Errorf("Unexpected nil: %v", location) | 		t.Run(tc.query, func(t *testing.T) { | ||||||
| 	} | 			location, _, err := redirector.ResourceLocation(ctx, tc.query) | ||||||
| 	if e, a := "//1.2.3.4:80", location.String(); e != a { | 			if tc.err == false && err != nil { | ||||||
| 		t.Errorf("Expected %v, but got %v", e, a) | 				t.Fatalf("unexpected error: %v", err) | ||||||
| 	} | 			} | ||||||
|  | 			if tc.err == true && err == nil { | ||||||
| 	// Test a name + port number (service port 93 -> target port 80, using second ip) | 				t.Fatalf("unexpected success") | ||||||
| 	location, _, err = redirector.ResourceLocation(ctx, "foo-second-ip:93") | 			} | ||||||
| 	if err != nil { | 			if !tc.err { | ||||||
| 		t.Errorf("Unexpected error: %v", err) | 				if location == nil { | ||||||
| 	} | 					t.Errorf("unexpected location: %v", location) | ||||||
| 	if location == nil { | 				} | ||||||
| 		t.Errorf("Unexpected nil: %v", location) | 				if e, a := tc.expect, location.String(); e != a { | ||||||
| 	} | 					t.Errorf("expected %q, but got %q", e, a) | ||||||
| 	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") |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -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 | // Validate allocation of a nodePort when ExternalTrafficPolicy is set to Local | ||||||
| // and type is LoadBalancer. | // and type is LoadBalancer. | ||||||
| func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { | func TestServiceRegistryExternalTrafficHealthCheckNodePortAllocation(t *testing.T) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user