mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-10-31 02:08:13 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			197 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2015 The Kubernetes Authors All rights reserved.
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|     http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| package main
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"testing"
 | |
| 
 | |
| 	"k8s.io/kubernetes/pkg/api"
 | |
| 	"k8s.io/kubernetes/pkg/client/cache"
 | |
| 	"k8s.io/kubernetes/pkg/util"
 | |
| 
 | |
| 	"github.com/golang/glog"
 | |
| )
 | |
| 
 | |
| const ns = "default"
 | |
| 
 | |
| // storeEps stores the given endpoints in a store.
 | |
| func storeEps(eps []*api.Endpoints) cache.Store {
 | |
| 	store := cache.NewStore(cache.MetaNamespaceKeyFunc)
 | |
| 	found := make([]interface{}, 0, len(eps))
 | |
| 	for i := range eps {
 | |
| 		found = append(found, eps[i])
 | |
| 	}
 | |
| 	if err := store.Replace(found); err != nil {
 | |
| 		glog.Fatalf("Unable to replace endpoints %v", err)
 | |
| 	}
 | |
| 	return store
 | |
| }
 | |
| 
 | |
| // storeServices stores the given services in a store.
 | |
| func storeServices(svcs []*api.Service) cache.Store {
 | |
| 	store := cache.NewStore(cache.MetaNamespaceKeyFunc)
 | |
| 	found := make([]interface{}, 0, len(svcs))
 | |
| 	for i := range svcs {
 | |
| 		found = append(found, svcs[i])
 | |
| 	}
 | |
| 	if err := store.Replace(found); err != nil {
 | |
| 		glog.Fatalf("Unable to replace services %v", err)
 | |
| 	}
 | |
| 	return store
 | |
| }
 | |
| 
 | |
| func getEndpoints(svc *api.Service, endpointAddresses []api.EndpointAddress, endpointPorts []api.EndpointPort) *api.Endpoints {
 | |
| 	return &api.Endpoints{
 | |
| 		ObjectMeta: api.ObjectMeta{
 | |
| 			Name:      svc.Name,
 | |
| 			Namespace: svc.Namespace,
 | |
| 		},
 | |
| 		Subsets: []api.EndpointSubset{{
 | |
| 			Addresses: endpointAddresses,
 | |
| 			Ports:     endpointPorts,
 | |
| 		}},
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getService(servicePorts []api.ServicePort) *api.Service {
 | |
| 	return &api.Service{
 | |
| 		ObjectMeta: api.ObjectMeta{
 | |
| 			Name: string(util.NewUUID()), Namespace: ns},
 | |
| 		Spec: api.ServiceSpec{
 | |
| 			Ports: servicePorts,
 | |
| 		},
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func newFakeLoadBalancerController(endpoints []*api.Endpoints, services []*api.Service) *loadBalancerController {
 | |
| 	flb := loadBalancerController{}
 | |
| 	flb.epLister.Store = storeEps(endpoints)
 | |
| 	flb.svcLister.Store = storeServices(services)
 | |
| 	flb.httpPort = 80
 | |
| 	return &flb
 | |
| }
 | |
| 
 | |
| func TestGetEndpoints(t *testing.T) {
 | |
| 	// 2 pods each of which have 3 targetPorts exposed via a single service
 | |
| 	endpointAddresses := []api.EndpointAddress{
 | |
| 		{IP: "1.2.3.4"},
 | |
| 		{IP: "6.7.8.9"},
 | |
| 	}
 | |
| 	ports := []int{80, 443, 3306}
 | |
| 	endpointPorts := []api.EndpointPort{
 | |
| 		{Port: ports[0], Protocol: "TCP"},
 | |
| 		{Port: ports[1], Protocol: "TCP"},
 | |
| 		{Port: ports[2], Protocol: "TCP", Name: "mysql"},
 | |
| 	}
 | |
| 	servicePorts := []api.ServicePort{
 | |
| 		{Port: 10, TargetPort: util.NewIntOrStringFromInt(ports[0])},
 | |
| 		{Port: 20, TargetPort: util.NewIntOrStringFromInt(ports[1])},
 | |
| 		{Port: 30, TargetPort: util.NewIntOrStringFromString("mysql")},
 | |
| 	}
 | |
| 
 | |
| 	svc := getService(servicePorts)
 | |
| 	endpoints := []*api.Endpoints{getEndpoints(svc, endpointAddresses, endpointPorts)}
 | |
| 	flb := newFakeLoadBalancerController(endpoints, []*api.Service{svc})
 | |
| 
 | |
| 	for i := range ports {
 | |
| 		eps := flb.getEndpoints(svc, &svc.Spec.Ports[i])
 | |
| 		expectedEps := util.NewStringSet()
 | |
| 		for _, address := range endpointAddresses {
 | |
| 			expectedEps.Insert(fmt.Sprintf("%v:%v", address.IP, ports[i]))
 | |
| 		}
 | |
| 
 | |
| 		receivedEps := util.NewStringSet()
 | |
| 		for _, ep := range eps {
 | |
| 			receivedEps.Insert(ep)
 | |
| 		}
 | |
| 		if len(receivedEps) != len(expectedEps) || !expectedEps.IsSuperset(receivedEps) {
 | |
| 			t.Fatalf("Unexpected endpoints, received %+v, expected %+v", receivedEps, expectedEps)
 | |
| 		}
 | |
| 		glog.Infof("Got endpoints %+v", receivedEps)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestGetServices(t *testing.T) {
 | |
| 	endpointAddresses := []api.EndpointAddress{
 | |
| 		{IP: "1.2.3.4"},
 | |
| 		{IP: "6.7.8.9"},
 | |
| 	}
 | |
| 	ports := []int{80, 443}
 | |
| 	endpointPorts := []api.EndpointPort{
 | |
| 		{Port: ports[0], Protocol: "TCP"},
 | |
| 		{Port: ports[1], Protocol: "TCP"},
 | |
| 	}
 | |
| 	servicePorts := []api.ServicePort{
 | |
| 		{Port: 10, TargetPort: util.NewIntOrStringFromInt(ports[0])},
 | |
| 		{Port: 20, TargetPort: util.NewIntOrStringFromInt(ports[1])},
 | |
| 	}
 | |
| 
 | |
| 	// 2 services targeting the same endpoints, one of which is declared as a tcp service.
 | |
| 	svc1 := getService(servicePorts)
 | |
| 	svc2 := getService(servicePorts)
 | |
| 	endpoints := []*api.Endpoints{
 | |
| 		getEndpoints(svc1, endpointAddresses, endpointPorts),
 | |
| 		getEndpoints(svc2, endpointAddresses, endpointPorts),
 | |
| 	}
 | |
| 	flb := newFakeLoadBalancerController(endpoints, []*api.Service{svc1, svc2})
 | |
| 	flb.tcpServices = map[string]int{
 | |
| 		svc1.Name: 20,
 | |
| 	}
 | |
| 	http, tcp := flb.getServices()
 | |
| 	serviceURLEp := fmt.Sprintf("%v:%v", svc1.Name, 20)
 | |
| 	if len(tcp) != 1 || tcp[0].Name != serviceURLEp || tcp[0].FrontendPort != 20 {
 | |
| 		t.Fatalf("Unexpected tcp service %+v expected %+v", tcp, svc1.Name)
 | |
| 	}
 | |
| 
 | |
| 	// All pods of svc1 exposed under servicePort 20 are tcp
 | |
| 	expectedTCPEps := util.NewStringSet()
 | |
| 	for _, address := range endpointAddresses {
 | |
| 		expectedTCPEps.Insert(fmt.Sprintf("%v:%v", address.IP, 443))
 | |
| 	}
 | |
| 	receivedTCPEps := util.NewStringSet()
 | |
| 	for _, ep := range tcp[0].Ep {
 | |
| 		receivedTCPEps.Insert(ep)
 | |
| 	}
 | |
| 	if len(receivedTCPEps) != len(expectedTCPEps) || !expectedTCPEps.IsSuperset(receivedTCPEps) {
 | |
| 		t.Fatalf("Unexpected tcp serice %+v", tcp)
 | |
| 	}
 | |
| 
 | |
| 	// All pods of either service not mentioned in the tcpmap are multiplexed on port  :80 as http services.
 | |
| 	expectedURLMapping := map[string]util.StringSet{
 | |
| 		fmt.Sprintf("%v:%v", svc1.Name, 10): util.NewStringSet("1.2.3.4:80", "6.7.8.9:80"),
 | |
| 		fmt.Sprintf("%v:%v", svc2.Name, 10): util.NewStringSet("1.2.3.4:80", "6.7.8.9:80"),
 | |
| 		fmt.Sprintf("%v:%v", svc2.Name, 20): util.NewStringSet("1.2.3.4:443", "6.7.8.9:443"),
 | |
| 	}
 | |
| 	for _, s := range http {
 | |
| 		if s.FrontendPort != 80 {
 | |
| 			t.Fatalf("All http services should get multiplexed via the same frontend port: %+v", s)
 | |
| 		}
 | |
| 		expectedEps, ok := expectedURLMapping[s.Name]
 | |
| 		if !ok {
 | |
| 			t.Fatalf("Expected url endpoint %v, found %+v", s.Name, expectedURLMapping)
 | |
| 		}
 | |
| 		receivedEp := util.NewStringSet()
 | |
| 		for i := range s.Ep {
 | |
| 			receivedEp.Insert(s.Ep[i])
 | |
| 		}
 | |
| 		if len(receivedEp) != len(expectedEps) && !receivedEp.IsSuperset(expectedEps) {
 | |
| 			t.Fatalf("Expected %+v, got %+v", expectedEps, receivedEp)
 | |
| 		}
 | |
| 	}
 | |
| }
 | 
