mirror of
https://github.com/optim-enterprises-bv/kubernetes.git
synced 2025-11-02 03:08:15 +00:00
Bare metal loadblancers
This commit is contained in:
196
contrib/service-loadbalancer/service_loadbalancer_test.go
Normal file
196
contrib/service-loadbalancer/service_loadbalancer_test.go
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
||||
"github.com/GoogleCloudPlatform/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 targetting 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user