traefik/pkg/provider/kubernetes/gateway/httproute_test.go

282 lines
6.2 KiB
Go
Raw Normal View History

package gateway
import (
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/utils/ptr"
gatev1 "sigs.k8s.io/gateway-api/apis/v1"
)
func Test_hostRule(t *testing.T) {
testCases := []struct {
desc string
hostnames []gatev1.Hostname
expectedRule string
expectErr bool
}{
{
desc: "Empty rule and matches",
expectedRule: "",
},
{
desc: "One Host",
hostnames: []gatev1.Hostname{
"Foo",
},
expectedRule: "Host(`Foo`)",
},
{
desc: "Multiple Hosts",
hostnames: []gatev1.Hostname{
"Foo",
"Bar",
"Bir",
},
expectedRule: "(Host(`Foo`) || Host(`Bar`) || Host(`Bir`))",
},
{
desc: "Several Host and wildcard",
hostnames: []gatev1.Hostname{
"*.bar.foo",
"bar.foo",
"foo.foo",
},
expectedRule: "(HostRegexp(`^[a-z0-9-\\.]+\\.bar\\.foo$`) || Host(`bar.foo`) || Host(`foo.foo`))",
},
{
desc: "Host with wildcard",
hostnames: []gatev1.Hostname{
"*.bar.foo",
},
expectedRule: "HostRegexp(`^[a-z0-9-\\.]+\\.bar\\.foo$`)",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
rule := hostRule(test.hostnames)
assert.Equal(t, test.expectedRule, rule)
})
}
}
func Test_routerRule(t *testing.T) {
testCases := []struct {
desc string
routeRule gatev1.HTTPRouteRule
hostRule string
expectedRule string
expectedError bool
}{
{
desc: "Empty rule and matches",
expectedRule: "PathPrefix(`/`)",
},
{
desc: "One Host rule without matches",
hostRule: "Host(`foo.com`)",
expectedRule: "Host(`foo.com`) && PathPrefix(`/`)",
},
{
desc: "One HTTPRouteMatch with nil HTTPHeaderMatch",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: ptr.To(gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchPathPrefix),
Value: ptr.To("/"),
}),
Headers: nil,
},
},
},
expectedRule: "PathPrefix(`/`)",
},
{
desc: "One HTTPRouteMatch with nil HTTPHeaderMatch Type",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: ptr.To(gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchPathPrefix),
Value: ptr.To("/"),
}),
Headers: []gatev1.HTTPHeaderMatch{
{Name: "foo", Value: "bar"},
},
},
},
},
expectedRule: "PathPrefix(`/`) && Header(`foo`,`bar`)",
},
{
desc: "One HTTPRouteMatch with nil HTTPPathMatch",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{Path: nil},
},
},
expectedRule: "PathPrefix(`/`)",
},
{
desc: "One HTTPRouteMatch with nil HTTPPathMatch Type",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: nil,
Value: ptr.To("/foo/"),
},
},
},
},
expectedRule: "(Path(`/foo`) || PathPrefix(`/foo/`))",
},
{
desc: "One HTTPRouteMatch with nil HTTPPathMatch Values",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchExact),
Value: nil,
},
},
},
},
expectedRule: "Path(`/`)",
},
{
desc: "One Path in matches",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchExact),
Value: ptr.To("/foo/"),
},
},
},
},
expectedRule: "Path(`/foo/`)",
},
{
desc: "One Path in matches and another empty",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchExact),
Value: ptr.To("/foo/"),
},
},
{},
},
},
expectedRule: "Path(`/foo/`) || PathPrefix(`/`)",
},
{
desc: "Path OR Header rules",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchExact),
Value: ptr.To("/foo/"),
},
},
{
Headers: []gatev1.HTTPHeaderMatch{
{
Type: ptr.To(gatev1.HeaderMatchExact),
Name: "my-header",
Value: "foo",
},
},
},
},
},
expectedRule: "Path(`/foo/`) || PathPrefix(`/`) && Header(`my-header`,`foo`)",
},
{
desc: "Path && Header rules",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchExact),
Value: ptr.To("/foo/"),
},
Headers: []gatev1.HTTPHeaderMatch{
{
Type: ptr.To(gatev1.HeaderMatchExact),
Name: "my-header",
Value: "foo",
},
},
},
},
},
expectedRule: "Path(`/foo/`) && Header(`my-header`,`foo`)",
},
{
desc: "Host && Path && Header rules",
hostRule: "Host(`foo.com`)",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchExact),
Value: ptr.To("/foo/"),
},
Headers: []gatev1.HTTPHeaderMatch{
{
Type: ptr.To(gatev1.HeaderMatchExact),
Name: "my-header",
Value: "foo",
},
},
},
},
},
expectedRule: "Host(`foo.com`) && Path(`/foo/`) && Header(`my-header`,`foo`)",
},
{
desc: "Host && (Path || Header) rules",
hostRule: "Host(`foo.com`)",
routeRule: gatev1.HTTPRouteRule{
Matches: []gatev1.HTTPRouteMatch{
{
Path: &gatev1.HTTPPathMatch{
Type: ptr.To(gatev1.PathMatchExact),
Value: ptr.To("/foo/"),
},
},
{
Headers: []gatev1.HTTPHeaderMatch{
{
Type: ptr.To(gatev1.HeaderMatchExact),
Name: "my-header",
Value: "foo",
},
},
},
},
},
expectedRule: "Host(`foo.com`) && (Path(`/foo/`) || PathPrefix(`/`) && Header(`my-header`,`foo`))",
},
}
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
rule := routerRule(test.routeRule, test.hostRule)
assert.Equal(t, test.expectedRule, rule)
})
}
}