mirror of
https://github.com/traefik/traefik.git
synced 2025-08-11 09:07:07 +02:00
337 lines
8.1 KiB
Go
337 lines
8.1 KiB
Go
package kubernetes
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
|
|
)
|
|
|
|
func TestString(t *testing.T) {
|
|
pv1 := newPercentageValueFromFloat64(0.5)
|
|
pv2 := newPercentageValueFromFloat64(0.2)
|
|
pv3 := newPercentageValueFromFloat64(0.3)
|
|
f := fractionalWeightAllocator(
|
|
map[ingressService]int{
|
|
{
|
|
host: "host2",
|
|
path: "path2",
|
|
service: "service2",
|
|
}: int(pv2),
|
|
{
|
|
host: "host3",
|
|
path: "path3",
|
|
service: "service3",
|
|
}: int(pv3),
|
|
{
|
|
host: "host1",
|
|
path: "path1",
|
|
service: "service1",
|
|
}: int(pv1),
|
|
},
|
|
)
|
|
|
|
expected := fmt.Sprintf("[service1: %s service2: %s service3: %s]", pv1, pv2, pv3)
|
|
actual := f.String()
|
|
assert.Equal(t, expected, actual)
|
|
}
|
|
|
|
func TestGetServicesPercentageWeights(t *testing.T) {
|
|
testCases := []struct {
|
|
desc string
|
|
annotationValue string
|
|
expectError bool
|
|
expectedWeights map[string]percentageValue
|
|
}{
|
|
{
|
|
desc: "empty annotation",
|
|
annotationValue: ``,
|
|
expectedWeights: map[string]percentageValue{},
|
|
},
|
|
{
|
|
desc: "50% fraction",
|
|
annotationValue: `
|
|
service1: 10%
|
|
service2: 20%
|
|
service3: 20%
|
|
`,
|
|
expectedWeights: map[string]percentageValue{
|
|
"service1": newPercentageValueFromFloat64(0.1),
|
|
"service2": newPercentageValueFromFloat64(0.2),
|
|
"service3": newPercentageValueFromFloat64(0.2),
|
|
},
|
|
},
|
|
{
|
|
desc: "50% fraction with empty fraction",
|
|
annotationValue: `
|
|
service1: 10%
|
|
service2: 20%
|
|
service3: 20%
|
|
service4:
|
|
`,
|
|
expectError: true,
|
|
},
|
|
{
|
|
desc: "50% fraction float form",
|
|
annotationValue: `
|
|
service1: 0.1
|
|
service2: 0.2
|
|
service3: 0.2
|
|
`,
|
|
expectedWeights: map[string]percentageValue{
|
|
"service1": newPercentageValueFromFloat64(0.001),
|
|
"service2": newPercentageValueFromFloat64(0.002),
|
|
"service3": newPercentageValueFromFloat64(0.002),
|
|
},
|
|
},
|
|
{
|
|
desc: "no fraction",
|
|
annotationValue: `
|
|
service1: 10%
|
|
service2: 90%
|
|
`,
|
|
expectedWeights: map[string]percentageValue{
|
|
"service1": newPercentageValueFromFloat64(0.1),
|
|
"service2": newPercentageValueFromFloat64(0.9),
|
|
},
|
|
},
|
|
{
|
|
desc: "extra weight specification",
|
|
annotationValue: `
|
|
service1: 90%
|
|
service5: 90%
|
|
`,
|
|
expectedWeights: map[string]percentageValue{
|
|
"service1": newPercentageValueFromFloat64(0.9),
|
|
"service5": newPercentageValueFromFloat64(0.9),
|
|
},
|
|
},
|
|
{
|
|
desc: "malformed annotation",
|
|
annotationValue: `
|
|
service1- 90%
|
|
service5- 90%
|
|
`,
|
|
expectError: true,
|
|
expectedWeights: nil,
|
|
},
|
|
{
|
|
desc: "more than one hundred percentaged service",
|
|
annotationValue: `
|
|
service1: 100%
|
|
service2: 1%
|
|
`,
|
|
expectedWeights: map[string]percentageValue{
|
|
"service1": newPercentageValueFromFloat64(1),
|
|
"service2": newPercentageValueFromFloat64(0.01),
|
|
},
|
|
},
|
|
{
|
|
desc: "incorrect percentage value",
|
|
annotationValue: `
|
|
service1: 1000%
|
|
`,
|
|
expectedWeights: map[string]percentageValue{
|
|
"service1": newPercentageValueFromFloat64(10),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
test := test
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
ingress := buildIngress(
|
|
iAnnotation(annotationKubernetesServiceWeights, test.annotationValue),
|
|
)
|
|
|
|
weights, err := getServicesPercentageWeights(ingress)
|
|
|
|
if test.expectError {
|
|
require.Error(t, err)
|
|
} else {
|
|
require.NoError(t, err)
|
|
assert.Equal(t, test.expectedWeights, weights)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestComputeServiceWeights(t *testing.T) {
|
|
client := newClientMock(
|
|
filepath.Join("fixtures", "computeServiceWeights_endpoints.yml"),
|
|
filepath.Join("fixtures", "computeServiceWeights_services.yml"),
|
|
)
|
|
|
|
testCases := []struct {
|
|
desc string
|
|
ingress string
|
|
expectError bool
|
|
expectedWeights map[ingressService]percentageValue
|
|
}{
|
|
{
|
|
desc: "1 path 2 service",
|
|
ingress: filepath.Join("fixtures", "computeServiceWeights", "1_path_2_service_ingresses.yml"),
|
|
expectError: false,
|
|
expectedWeights: map[ingressService]percentageValue{
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service1",
|
|
}: newPercentageValueFromFloat64(0.05),
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service2",
|
|
}: newPercentageValueFromFloat64(0.90),
|
|
},
|
|
},
|
|
{
|
|
desc: "2 path 2 service",
|
|
ingress: filepath.Join("fixtures", "computeServiceWeights", "2_path_2_service_ingresses.yml"),
|
|
expectError: false,
|
|
expectedWeights: map[ingressService]percentageValue{
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service1",
|
|
}: newPercentageValueFromFloat64(0.30),
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service2",
|
|
}: newPercentageValueFromFloat64(0.40),
|
|
{
|
|
host: "foo.test",
|
|
path: "/bar",
|
|
service: "service1",
|
|
}: newPercentageValueFromFloat64(0.30),
|
|
{
|
|
host: "foo.test",
|
|
path: "/bar",
|
|
service: "service3",
|
|
}: newPercentageValueFromFloat64(0.10),
|
|
},
|
|
},
|
|
{
|
|
desc: "2 path 3 service",
|
|
ingress: filepath.Join("fixtures", "computeServiceWeights", "2_path_3_service_ingresses.yml"),
|
|
expectError: false,
|
|
expectedWeights: map[ingressService]percentageValue{
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service1",
|
|
}: newPercentageValueFromFloat64(0.10),
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service2",
|
|
}: newPercentageValueFromFloat64(0.80),
|
|
{
|
|
host: "foo.test",
|
|
path: "/bar",
|
|
service: "service3",
|
|
}: newPercentageValueFromFloat64(0.05),
|
|
{
|
|
host: "foo.test",
|
|
path: "/bar",
|
|
service: "service2",
|
|
}: newPercentageValueFromFloat64(0.80),
|
|
},
|
|
},
|
|
{
|
|
desc: "1 path 4 service",
|
|
ingress: filepath.Join("fixtures", "computeServiceWeights", "1_path_4_service_ingresses.yml"),
|
|
expectError: false,
|
|
expectedWeights: map[ingressService]percentageValue{
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service1",
|
|
}: newPercentageValueFromFloat64(0.10),
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service2",
|
|
}: newPercentageValueFromFloat64(0.40),
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service3",
|
|
}: newPercentageValueFromFloat64(0.10),
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service4",
|
|
}: newPercentageValueFromFloat64(0.00),
|
|
},
|
|
},
|
|
{
|
|
desc: "2 path no service",
|
|
ingress: filepath.Join("fixtures", "computeServiceWeights", "2_path_no_service_ingresses.yml"),
|
|
expectError: true,
|
|
},
|
|
{
|
|
desc: "2 path without weight",
|
|
ingress: filepath.Join("fixtures", "computeServiceWeights", "2_path_without_weight_ingresses.yml"),
|
|
expectError: false,
|
|
expectedWeights: map[ingressService]percentageValue{
|
|
{
|
|
host: "foo.test",
|
|
path: "/foo",
|
|
service: "service1",
|
|
}: newPercentageValueFromFloat64(0.50),
|
|
{
|
|
host: "foo.test",
|
|
path: "/bar",
|
|
service: "service2",
|
|
}: newPercentageValueFromFloat64(1.00),
|
|
},
|
|
},
|
|
{
|
|
desc: "2 path overflow",
|
|
ingress: filepath.Join("fixtures", "computeServiceWeights", "2_path_overflow_ingresses.yml"),
|
|
expectError: true,
|
|
},
|
|
}
|
|
|
|
for _, test := range testCases {
|
|
test := test
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
yamlContent, err := ioutil.ReadFile(test.ingress)
|
|
require.NoError(t, err)
|
|
k8sObjects := MustDecodeYaml(yamlContent)
|
|
require.Len(t, k8sObjects, 1)
|
|
|
|
var ingress *extensionsv1beta1.Ingress
|
|
switch o := k8sObjects[0].(type) {
|
|
case *extensionsv1beta1.Ingress:
|
|
ingress = o
|
|
default:
|
|
require.Fail(t, fmt.Sprintf("Unknown runtime object %+v %T", o, o))
|
|
}
|
|
|
|
weightAllocator, err := newFractionalWeightAllocator(ingress, client)
|
|
if test.expectError {
|
|
require.Error(t, err)
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("%v failed: %v", test.desc, err)
|
|
} else {
|
|
for ingSvc, percentage := range test.expectedWeights {
|
|
assert.Equal(t, int(percentage), weightAllocator.getWeight(ingSvc.host, ingSvc.path, ingSvc.service))
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|