diff --git a/pkg/rlptools/limit_index_test.go b/pkg/rlptools/limit_index_test.go index f29016168..0fb961664 100644 --- a/pkg/rlptools/limit_index_test.go +++ b/pkg/rlptools/limit_index_test.go @@ -11,7 +11,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/controller-runtime/pkg/client" - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" "github.com/kuadrant/kuadrant-operator/pkg/common" "github.com/kuadrant/kuadrant-operator/pkg/log" ) @@ -371,7 +370,7 @@ func TestLimitIndexAddLimit(t *testing.T) { variables = []string{"c", "d"} ) - limit := &kuadrantv1beta1.Limit{ + limit := &Limit{ Conditions: conditions, MaxValue: maxValue, Seconds: seconds, Variables: variables, } diff --git a/pkg/rlptools/utils_test.go b/pkg/rlptools/utils_test.go index c0c1eac9e..20877f6f7 100644 --- a/pkg/rlptools/utils_test.go +++ b/pkg/rlptools/utils_test.go @@ -11,8 +11,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func rlp_1limit_1rate(ns, name string) kuadrantv1beta2.RateLimitPolicy { - return kuadrantv1beta2.RateLimitPolicy{ +func rlp_1limit_1rate(ns, name string) *kuadrantv1beta2.RateLimitPolicy { + return &kuadrantv1beta2.RateLimitPolicy{ TypeMeta: metav1.TypeMeta{ Kind: "RateLimitPolicy", APIVersion: kuadrantv1beta2.GroupVersion.String(), @@ -37,8 +37,8 @@ func rlp_1limit_1rate(ns, name string) kuadrantv1beta2.RateLimitPolicy { } } -func rlp_2limit_1rate(ns, name string) kuadrantv1beta2.RateLimitPolicy { - return kuadrantv1beta2.RateLimitPolicy{ +func rlp_2limit_1rate(ns, name string) *kuadrantv1beta2.RateLimitPolicy { + return &kuadrantv1beta2.RateLimitPolicy{ TypeMeta: metav1.TypeMeta{ Kind: "RateLimitPolicy", APIVersion: kuadrantv1beta2.GroupVersion.String(), @@ -72,8 +72,8 @@ func rlp_2limit_1rate(ns, name string) kuadrantv1beta2.RateLimitPolicy { } } -func rlp_1limit_2rate(ns, name string) kuadrantv1beta2.RateLimitPolicy { - return kuadrantv1beta2.RateLimitPolicy{ +func rlp_1limit_2rate(ns, name string) *kuadrantv1beta2.RateLimitPolicy { + return &kuadrantv1beta2.RateLimitPolicy{ TypeMeta: metav1.TypeMeta{ Kind: "RateLimitPolicy", APIVersion: kuadrantv1beta2.GroupVersion.String(), @@ -103,8 +103,8 @@ func rlp_1limit_2rate(ns, name string) kuadrantv1beta2.RateLimitPolicy { } } -func rlp_1limit_1rate_1counter(ns, name string) kuadrantv1beta2.RateLimitPolicy { - return kuadrantv1beta2.RateLimitPolicy{ +func rlp_1limit_1rate_1counter(ns, name string) *kuadrantv1beta2.RateLimitPolicy { + return &kuadrantv1beta2.RateLimitPolicy{ TypeMeta: metav1.TypeMeta{ Kind: "RateLimitPolicy", APIVersion: kuadrantv1beta2.GroupVersion.String(), @@ -135,7 +135,7 @@ func rlp_1limit_1rate_1counter(ns, name string) kuadrantv1beta2.RateLimitPolicy func TestReadLimitsFromRLP(t *testing.T) { testCases := []struct { name string - rlp kuadrantv1beta2.RateLimitPolicy + rlp *kuadrantv1beta2.RateLimitPolicy expectedLimits []Limit }{ { @@ -222,72 +222,72 @@ func TestConvertRateIntoSeconds(t *testing.T) { }{ { name: "seconds", - rate: { - Limit: 5, Duration: 2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("second"), + rate: kuadrantv1beta2.Rate{ + Limit: 5, Duration: 2, Unit: kuadrantv1beta2.TimeUnit("second"), }, expectedMaxValue: 5, expectedSeconds: 2, }, { name: "minutes", - rate: { - Limit: 5, Duration: 2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("minute"), + rate: kuadrantv1beta2.Rate{ + Limit: 5, Duration: 2, Unit: kuadrantv1beta2.TimeUnit("minute"), }, expectedMaxValue: 5, expectedSeconds: 2 * 60, }, { name: "hours", - rate: { - Limit: 5, Duration: 2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("hour"), + rate: kuadrantv1beta2.Rate{ + Limit: 5, Duration: 2, Unit: kuadrantv1beta2.TimeUnit("hour"), }, expectedMaxValue: 5, expectedSeconds: 2 * 60 * 60, }, { name: "day", - rate: { - Limit: 5, Duration: 2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("day"), + rate: kuadrantv1beta2.Rate{ + Limit: 5, Duration: 2, Unit: kuadrantv1beta2.TimeUnit("day"), }, expectedMaxValue: 5, expectedSeconds: 2 * 60 * 60 * 24, }, { name: "negative limit", - rate: { - Limit: -5, Duration: 2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("second"), + rate: kuadrantv1beta2.Rate{ + Limit: -5, Duration: 2, Unit: kuadrantv1beta2.TimeUnit("second"), }, expectedMaxValue: 0, expectedSeconds: 2, }, { name: "negative duration", - rate: { - Limit: 5, Duration: -2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("second"), + rate: kuadrantv1beta2.Rate{ + Limit: 5, Duration: -2, Unit: kuadrantv1beta2.TimeUnit("second"), }, expectedMaxValue: 5, expectedSeconds: 0, }, { name: "limit is 0", - rate: { - Limit: 0, Duration: 2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("second"), + rate: kuadrantv1beta2.Rate{ + Limit: 0, Duration: 2, Unit: kuadrantv1beta2.TimeUnit("second"), }, expectedMaxValue: 0, expectedSeconds: 2, }, { name: "rate is 0", - rate: { - Limit: 5, Duration: 0, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("second"), + rate: kuadrantv1beta2.Rate{ + Limit: 5, Duration: 0, Unit: kuadrantv1beta2.TimeUnit("second"), }, expectedMaxValue: 5, expectedSeconds: 0, }, { name: "unexpected time unit", - rate: { - Limit: 5, Duration: 2, Unit: kuadrantv1beta2.kuadrantv1beta2.TimeUnit("unknown"), + rate: kuadrantv1beta2.Rate{ + Limit: 5, Duration: 2, Unit: kuadrantv1beta2.TimeUnit("unknown"), }, expectedMaxValue: 5, expectedSeconds: 0, diff --git a/pkg/rlptools/wasm_utils_test.go b/pkg/rlptools/wasm_utils_test.go index cf31ea005..a3773bca2 100644 --- a/pkg/rlptools/wasm_utils_test.go +++ b/pkg/rlptools/wasm_utils_test.go @@ -7,53 +7,16 @@ import ( "testing" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime/pkg/client" gatewayapiv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - kuadrantv1beta1 "github.com/kuadrant/kuadrant-operator/api/v1beta1" + "github.com/google/go-cmp/cmp" kuadrantv1beta2 "github.com/kuadrant/kuadrant-operator/api/v1beta2" - "github.com/kuadrant/kuadrant-operator/pkg/common" ) -func TestHTTPRouteRulesToRLPRules(t *testing.T) { - testCases := []struct { - name string - routeRules []common.HTTPRouteRule - expectedRLPRules []kuadrantv1beta1.Rule - }{ - { - "nil rules", nil, make([]kuadrantv1beta1.Rule, 0), - }, - { - "rule with paths methods and hosts", - []common.HTTPRouteRule{ - { - Hosts: []string{"*", "*.example.com"}, - Paths: []string{"/admin/*", "/cats"}, - Methods: []string{"GET", "POST"}, - }, - }, []kuadrantv1beta1.Rule{ - { - Hosts: []string{"*", "*.example.com"}, - Paths: []string{"/admin/*", "/cats"}, - Methods: []string{"GET", "POST"}, - }, - }, - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(subT *testing.T) { - rules := HTTPRouteRulesToRLPRules(tc.routeRules) - if !reflect.DeepEqual(rules, tc.expectedRLPRules) { - subT.Errorf("expected rules (%+v), got (%+v)", tc.expectedRLPRules, rules) - } - }) - } -} - -func TestGatewayActionsFromRateLimitPolicy(t *testing.T) { +// TODO(eastizle): missing WASMPluginMutator tests +// TODO(eastizle): missing TestWasmRules use cases tests. Only happy path +func TestWasmRules(t *testing.T) { httpRoute := &gatewayapiv1alpha2.HTTPRoute{ Spec: gatewayapiv1alpha2.HTTPRouteSpec{ Hostnames: []gatewayapiv1alpha2.Hostname{"*.example.com"}, @@ -73,7 +36,7 @@ func TestGatewayActionsFromRateLimitPolicy(t *testing.T) { }, } - t.Run("empty rate limits return empty actions", func(subT *testing.T) { + t.Run("minimal RLP", func(subT *testing.T) { rlp := &kuadrantv1beta2.RateLimitPolicy{ TypeMeta: metav1.TypeMeta{ Kind: "RateLimitPolicy", APIVersion: kuadrantv1beta2.GroupVersion.String()}, @@ -82,194 +45,50 @@ func TestGatewayActionsFromRateLimitPolicy(t *testing.T) { Limits: map[string]kuadrantv1beta2.Limit{ "l1": kuadrantv1beta2.Limit{ Rates: []kuadrantv1beta2.Rate{ - Limit: 1, Duration: 3, Unit: kuadrantv1beta2.TimeUnit("minute"), - }, - }, - }, - }, - } - - expectedGatewayActions := []GatewayAction{ - { - Configurations: []Configuration{ - { - Actions: []ActionSpecifier{ { - GenericKey: &GenericKeySpec{ - DescriptorKey: "nsA/rlpA/l1", - DescriptorValue: "1", - }, + Limit: 1, Duration: 3, Unit: kuadrantv1beta2.TimeUnit("minute"), }, }, }, }, - Rules: []Rule{ - { - Paths: []string{"/toy*"}, - Methods: []string{"GET"}, - Hosts: []string{"*.example.com"}, - }, - }, }, } - gatewayActions := GatewayActionsFromRateLimitPolicy(rlp, httpRoute) - if !reflect.DeepEqual(gatewayActions, expectedGatewayActions) { - t.Errorf("expected gw actions (%+v), got (%+v)", expectedGatewayActions, gatewayActions) - } - }) - - t.Run("basic test", func(subT *testing.T) { - rlp := &kuadrantv1beta1.RateLimitPolicy{ - Spec: kuadrantv1beta1.RateLimitPolicySpec{ - RateLimits: []kuadrantv1beta1.RateLimit{ - { - Configurations: defaultConfigurations(), - Rules: []kuadrantv1beta1.Rule{ - { - Hosts: []string{"*.protected.example.com"}, - }, + expectedRule := Rule{ + Conditions: []Condition{ + { + AllOf: []PatternExpression{ + { + Selector: "request.url_path", + Operator: PatternOperator(kuadrantv1beta2.StartsWithOperator), + Value: "/toy", + }, + { + Selector: "request.method", + Operator: PatternOperator(kuadrantv1beta2.EqualOperator), + Value: "GET", }, - }, - { - Configurations: defaultConfigurations(), - Rules: nil, - }, - }, - }, - } - - expectedGatewayActions := []GatewayAction{ - { - Configurations: defaultConfigurations(), - Rules: []kuadrantv1beta1.Rule{ - { - Hosts: []string{"*.protected.example.com"}, - }, - }, - }, - { - Configurations: defaultConfigurations(), - Rules: []kuadrantv1beta1.Rule{ - { - Hosts: []string{"*.example.com"}, - Paths: []string{"/toy*"}, - Methods: []string{"GET"}, - }, - }, - }, - } - gatewayActions := GatewayActionsFromRateLimitPolicy(rlp, httpRoute) - if !reflect.DeepEqual(gatewayActions, expectedGatewayActions) { - t.Errorf("expected gw actions (%+v), got (%+v)", expectedGatewayActions, gatewayActions) - } - }) - - t.Run("when the configuration obj is missing skip it", func(subT *testing.T) { - rlp := &kuadrantv1beta1.RateLimitPolicy{ - Spec: kuadrantv1beta1.RateLimitPolicySpec{ - RateLimits: []kuadrantv1beta1.RateLimit{ - { - // configurations object is missing - Rules: []kuadrantv1beta1.Rule{{Hosts: []string{"a.example.com"}}}, - }, - { - Configurations: defaultConfigurations(), - Rules: []kuadrantv1beta1.Rule{{Hosts: []string{"b.example.com"}}}, - }, - }, - }, - } - - expectedGatewayActions := []GatewayAction{ - { - Configurations: defaultConfigurations(), - Rules: []kuadrantv1beta1.Rule{{Hosts: []string{"b.example.com"}}}, - }, - } - - gatewayActions := GatewayActionsFromRateLimitPolicy(rlp, httpRoute) - if !reflect.DeepEqual(gatewayActions, expectedGatewayActions) { - t.Errorf("expected gw actions (%+v), got (%+v)", expectedGatewayActions, gatewayActions) - } - }) - - t.Run("when rlp targeting a httproute does not have any configuration obj then default is applied", func(subT *testing.T) { - rlp := &kuadrantv1beta1.RateLimitPolicy{ - Spec: kuadrantv1beta1.RateLimitPolicySpec{ - RateLimits: []kuadrantv1beta1.RateLimit{ - { - // configurations object is missing - Rules: []kuadrantv1beta1.Rule{{Hosts: []string{"a.example.com"}}}, - }, - { - // configurations object is missing - Rules: []kuadrantv1beta1.Rule{{Hosts: []string{"b.example.com"}}}, - }, - }, - }, - } - - expectedGatewayActions := []GatewayAction{ - { - Configurations: DefaultGatewayConfiguration(client.ObjectKeyFromObject(rlp)), - Rules: []kuadrantv1beta1.Rule{ - { - Hosts: []string{"*.example.com"}, - Paths: []string{"/toy*"}, - Methods: []string{"GET"}, }, }, }, - } - - gatewayActions := GatewayActionsFromRateLimitPolicy(rlp, httpRoute) - if !reflect.DeepEqual(gatewayActions, expectedGatewayActions) { - t.Errorf("expected gw actions (%+v), got (%+v)", expectedGatewayActions, gatewayActions) - } - }) - - t.Run("when rlp targeting a gateway does not have any configuration obj then default is applied", func(subT *testing.T) { - rlp := &kuadrantv1beta1.RateLimitPolicy{ - Spec: kuadrantv1beta1.RateLimitPolicySpec{ - RateLimits: []kuadrantv1beta1.RateLimit{ - { - // configurations object is missing - Rules: []kuadrantv1beta1.Rule{{Hosts: []string{"a.example.com"}}}, - }, - { - // configurations object is missing - Rules: []kuadrantv1beta1.Rule{{Hosts: []string{"b.example.com"}}}, + Data: []DataItem{ + { + Static: &StaticSpec{ + Key: "nsA/rlpA/l1", + Value: "1", }, }, }, } - expectedGatewayActions := []GatewayAction{ - { - Configurations: DefaultGatewayConfiguration(client.ObjectKeyFromObject(rlp)), - Rules: []kuadrantv1beta1.Rule{}, - }, + rules := WasmRules(rlp, httpRoute) + if len(rules) != 1 { + subT.Errorf("expected 1 rule, got (%d)", len(rules)) } - gatewayActions := GatewayActionsFromRateLimitPolicy(rlp, nil) - if !reflect.DeepEqual(gatewayActions, expectedGatewayActions) { - t.Errorf("expected gw actions (%+v), got (%+v)", expectedGatewayActions, gatewayActions) + if !reflect.DeepEqual(rules[0], expectedRule) { + diff := cmp.Diff(rules[0], expectedRule) + subT.Errorf("expected rule not found: %s", diff) } }) } - -func defaultConfigurations() []kuadrantv1beta1.Configuration { - return []kuadrantv1beta1.Configuration{ - { - Actions: []kuadrantv1beta1.ActionSpecifier{ - { - GenericKey: &kuadrantv1beta1.GenericKeySpec{ - DescriptorValue: "some value", - DescriptorKey: &[]string{"some key"}[0], - }, - }, - }, - }, - } -}