Skip to content

Commit

Permalink
tests: add unittest.
Browse files Browse the repository at this point in the history
  • Loading branch information
rodman10 committed Jul 30, 2023
1 parent 9d48287 commit ee52341
Showing 1 changed file with 241 additions and 0 deletions.
241 changes: 241 additions & 0 deletions internal/dataplane/parser/translate_kong_l4_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package parser

import (
"strings"
"testing"

"github.com/kong/go-kong/kong"
"github.com/samber/lo"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/kong/kubernetes-ingress-controller/v2/internal/annotations"
"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/failures"
"github.com/kong/kubernetes-ingress-controller/v2/internal/dataplane/kongstate"
"github.com/kong/kubernetes-ingress-controller/v2/internal/store"
configurationv1beta1 "github.com/kong/kubernetes-ingress-controller/v2/pkg/apis/configuration/v1beta1"
Expand Down Expand Up @@ -208,3 +213,239 @@ func TestFromTCPIngressV1beta1(t *testing.T) {
assert.Equal(2, len(parsedInfo.SecretNameToSNIs.Hosts("default/sooper-secret2")))
})
}

func TestIngressRulesFromTCPIngressV1beta1UsingExpressionRoutes(t *testing.T) {
testCases := []struct {
name string
tcpIngresses []*configurationv1beta1.TCPIngress
expectedKongServices []kongstate.Service
expectedKongRoutes map[string][]kongstate.Route
expectedFailures []failures.ResourceFailure
}{
{
name: "tcpingress with single rule",
tcpIngresses: []*configurationv1beta1.TCPIngress{
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "default",
Annotations: map[string]string{
annotations.IngressClassKey: annotations.DefaultIngressClass,
},
},
Spec: configurationv1beta1.TCPIngressSpec{
Rules: []configurationv1beta1.IngressRule{
{
Port: 9000,
Backend: configurationv1beta1.IngressBackend{
ServiceName: "foo-svc",
ServicePort: 80,
},
},
},
},
},
},
expectedKongServices: []kongstate.Service{
{
Service: kong.Service{
Name: kong.String("default.foo-svc.80"),
},
Backends: []kongstate.ServiceBackend{
{
Name: "foo-svc",
PortDef: kongstate.PortDef{Mode: kongstate.PortModeByNumber, Number: int32(80)},
},
},
},
},
expectedKongRoutes: map[string][]kongstate.Route{
"default.foo-svc.80": {
{
Route: kong.Route{
Name: kong.String("default.foo.0"),
Expression: kong.String(`((net.protocol == "tcp") || (net.protocol == "tls")) && (net.dst.port == 9000)`),
PreserveHost: kong.Bool(true),
},
ExpressionRoutes: true,
},
},
},
},
{
name: "tcpingress with multiple rules",
tcpIngresses: []*configurationv1beta1.TCPIngress{
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "default",
Annotations: map[string]string{
annotations.IngressClassKey: annotations.DefaultIngressClass,
},
},
Spec: configurationv1beta1.TCPIngressSpec{
Rules: []configurationv1beta1.IngressRule{
{
Port: 9000,
Backend: configurationv1beta1.IngressBackend{
ServiceName: "foo-svc1",
ServicePort: 80,
},
},
{
Port: 9090,
Backend: configurationv1beta1.IngressBackend{
ServiceName: "foo-svc2",
ServicePort: 8080,
},
},
},
},
},
},
expectedKongServices: []kongstate.Service{
{
Service: kong.Service{
Name: kong.String("default.foo-svc1.80"),
},
Backends: []kongstate.ServiceBackend{
{
Name: "foo-svc1",
PortDef: kongstate.PortDef{Mode: kongstate.PortModeByNumber, Number: int32(80)},
},
},
},
{
Service: kong.Service{
Name: kong.String("default.foo-svc2.8080"),
},
Backends: []kongstate.ServiceBackend{
{
Name: "foo-svc2",
PortDef: kongstate.PortDef{Mode: kongstate.PortModeByNumber, Number: int32(8080)},
},
},
},
},
expectedKongRoutes: map[string][]kongstate.Route{
"default.foo-svc1.80": {
{
Route: kong.Route{
Name: kong.String("default.foo.0"),
Expression: kong.String(`((net.protocol == "tcp") || (net.protocol == "tls")) && (net.dst.port == 9000)`),
PreserveHost: kong.Bool(true),
},
ExpressionRoutes: true,
},
},
"default.foo-svc2.8080": {
{
Route: kong.Route{
Name: kong.String("default.foo.1"),
Expression: kong.String(`((net.protocol == "tcp") || (net.protocol == "tls")) && (net.dst.port == 9090)`),
PreserveHost: kong.Bool(true),
},
ExpressionRoutes: true,
},
},
},
},
{
name: "tcpingress with sni",
tcpIngresses: []*configurationv1beta1.TCPIngress{
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "default",
Annotations: map[string]string{
annotations.IngressClassKey: annotations.DefaultIngressClass,
},
},
Spec: configurationv1beta1.TCPIngressSpec{
Rules: []configurationv1beta1.IngressRule{
{
Host: "www.foo-bar.com",
Port: 9000,
Backend: configurationv1beta1.IngressBackend{
ServiceName: "foo-svc",
ServicePort: 80,
},
},
},
},
},
},
expectedKongServices: []kongstate.Service{
{
Service: kong.Service{
Name: kong.String("default.foo-svc.80"),
},
Backends: []kongstate.ServiceBackend{
{
Name: "foo-svc",
PortDef: kongstate.PortDef{Mode: kongstate.PortModeByNumber, Number: int32(80)},
},
},
},
},
expectedKongRoutes: map[string][]kongstate.Route{
"default.foo-svc.80": {
{
Route: kong.Route{
Name: kong.String("default.foo.0"),
Expression: kong.String(`((net.protocol == "tcp") || (net.protocol == "tls")) && (tls.sni == "www.foo-bar.com") && (net.dst.port == 9000)`),
PreserveHost: kong.Bool(true),
},
ExpressionRoutes: true,
},
},
},
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
fakestore, err := store.NewFakeStore(store.FakeObjects{TCPIngresses: tc.tcpIngresses})
require.NoError(t, err)
parser := mustNewParser(t, fakestore)
parser.featureFlags.ExpressionRoutes = true

failureCollector, err := failures.NewResourceFailuresCollector(logrus.New())
require.NoError(t, err)
parser.failuresCollector = failureCollector

result := parser.ingressRulesFromTCPIngressV1beta1()
// check services
require.Equal(t, len(tc.expectedKongServices), len(result.ServiceNameToServices),
"should have expected number of services")
for _, expectedKongService := range tc.expectedKongServices {
kongService, ok := result.ServiceNameToServices[*expectedKongService.Name]
require.Truef(t, ok, "should find service %s", expectedKongService.Name)
require.Equal(t, expectedKongService.Backends, kongService.Backends)
// check routes
expectedKongRoutes := tc.expectedKongRoutes[*kongService.Name]
require.Equal(t, len(expectedKongRoutes), len(kongService.Routes))

kongRouteNameToRoute := lo.SliceToMap(kongService.Routes, func(r kongstate.Route) (string, kongstate.Route) {
return *r.Name, r
})
for _, expectedRoute := range expectedKongRoutes {
routeName := expectedRoute.Name
r, ok := kongRouteNameToRoute[*routeName]
require.Truef(t, ok, "should find route %s", *routeName)
require.Equal(t, expectedRoute.Expression, r.Expression)
}
}
// check translation failures
translationFailures := failureCollector.PopResourceFailures()
require.Equal(t, len(tc.expectedFailures), len(translationFailures))
for _, expectedTranslationFailure := range tc.expectedFailures {
expectedFailureMessage := expectedTranslationFailure.Message()
require.True(t, lo.ContainsBy(translationFailures, func(failure failures.ResourceFailure) bool {
return strings.Contains(failure.Message(), expectedFailureMessage)
}))
}
})
}
}

0 comments on commit ee52341

Please sign in to comment.