...

Source file src/sigs.k8s.io/gateway-api/conformance/tests/httproute-query-param-matching.go

Documentation: sigs.k8s.io/gateway-api/conformance/tests

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package tests
    18  
    19  import (
    20  	"testing"
    21  
    22  	"k8s.io/apimachinery/pkg/types"
    23  
    24  	"sigs.k8s.io/gateway-api/conformance/utils/http"
    25  	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
    26  	"sigs.k8s.io/gateway-api/conformance/utils/suite"
    27  )
    28  
    29  func init() {
    30  	ConformanceTests = append(ConformanceTests, HTTPRouteQueryParamMatching)
    31  }
    32  
    33  var HTTPRouteQueryParamMatching = suite.ConformanceTest{
    34  	ShortName:   "HTTPRouteQueryParamMatching",
    35  	Description: "A single HTTPRoute with query param matching for different backends",
    36  	Manifests:   []string{"tests/httproute-query-param-matching.yaml"},
    37  	Features: []suite.SupportedFeature{
    38  		suite.SupportGateway,
    39  		suite.SupportHTTPRoute,
    40  		suite.SupportHTTPRouteQueryParamMatching,
    41  	},
    42  	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
    43  		ns := "gateway-conformance-infra"
    44  		routeNN := types.NamespacedName{Namespace: ns, Name: "query-param-matching"}
    45  		gwNN := types.NamespacedName{Namespace: ns, Name: "same-namespace"}
    46  		gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
    47  		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
    48  
    49  		testCases := []http.ExpectedResponse{{
    50  			Request:   http.Request{Path: "/?animal=whale"},
    51  			Backend:   "infra-backend-v1",
    52  			Namespace: ns,
    53  		}, {
    54  			Request:   http.Request{Path: "/?animal=dolphin"},
    55  			Backend:   "infra-backend-v2",
    56  			Namespace: ns,
    57  		}, {
    58  			Request:   http.Request{Path: "/?animal=dolphin&color=blue"},
    59  			Backend:   "infra-backend-v3",
    60  			Namespace: ns,
    61  		}, {
    62  			Request:   http.Request{Path: "/?ANIMAL=Whale"},
    63  			Backend:   "infra-backend-v3",
    64  			Namespace: ns,
    65  		}, {
    66  			Request:   http.Request{Path: "/?animal=whale&otherparam=irrelevant"},
    67  			Backend:   "infra-backend-v1",
    68  			Namespace: ns,
    69  		}, {
    70  			Request:   http.Request{Path: "/?animal=dolphin&color=yellow"},
    71  			Backend:   "infra-backend-v2",
    72  			Namespace: ns,
    73  		}, {
    74  			Request:  http.Request{Path: "/?color=blue"},
    75  			Response: http.Response{StatusCode: 404},
    76  		}, {
    77  			Request:  http.Request{Path: "/?animal=dog"},
    78  			Response: http.Response{StatusCode: 404},
    79  		}, {
    80  			Request:  http.Request{Path: "/?animal=whaledolphin"},
    81  			Response: http.Response{StatusCode: 404},
    82  		}, {
    83  			Request:  http.Request{Path: "/"},
    84  			Response: http.Response{StatusCode: 404},
    85  		}}
    86  
    87  		// Combinations of query param matching with other core matches.
    88  		testCases = append(testCases, []http.ExpectedResponse{
    89  			{
    90  				Request:   http.Request{Path: "/path1?animal=whale"},
    91  				Backend:   "infra-backend-v1",
    92  				Namespace: ns,
    93  			},
    94  			{
    95  				Request:   http.Request{Headers: map[string]string{"version": "one"}, Path: "/?animal=whale"},
    96  				Backend:   "infra-backend-v2",
    97  				Namespace: ns,
    98  			},
    99  			{
   100  				Request:   http.Request{Headers: map[string]string{"version": "two"}, Path: "/path2?animal=whale"},
   101  				Backend:   "infra-backend-v3",
   102  				Namespace: ns,
   103  			},
   104  		}...)
   105  
   106  		// Ensure that combinations of matches which are OR'd together match
   107  		// even if only one of them is used in the request.
   108  		testCases = append(testCases, []http.ExpectedResponse{
   109  			{
   110  				Request:   http.Request{Path: "/path3?animal=shark"},
   111  				Backend:   "infra-backend-v1",
   112  				Namespace: ns,
   113  			},
   114  			{
   115  				Request:   http.Request{Headers: map[string]string{"version": "three"}, Path: "/path4?animal=kraken"},
   116  				Backend:   "infra-backend-v1",
   117  				Namespace: ns,
   118  			},
   119  		}...)
   120  
   121  		// Ensure that combinations of match types which are ANDed together do not match
   122  		// when only a subset of match types is used in the request.
   123  		testCases = append(testCases, []http.ExpectedResponse{
   124  			{
   125  				Request:  http.Request{Path: "/?animal=shark"},
   126  				Response: http.Response{StatusCode: 404},
   127  			},
   128  			{
   129  				Request:  http.Request{Path: "/path4?animal=kraken"},
   130  				Response: http.Response{StatusCode: 404},
   131  			},
   132  		}...)
   133  
   134  		// For requests that satisfy multiple matches, ensure precedence order
   135  		// defined by the Gateway API spec is maintained.
   136  		testCases = append(testCases, []http.ExpectedResponse{
   137  			{
   138  				Request:   http.Request{Path: "/path5?animal=hydra"},
   139  				Backend:   "infra-backend-v1",
   140  				Namespace: ns,
   141  			},
   142  			{
   143  				Request:   http.Request{Headers: map[string]string{"version": "four"}, Path: "/?animal=hydra"},
   144  				Backend:   "infra-backend-v3",
   145  				Namespace: ns,
   146  			},
   147  		}...)
   148  
   149  		for i := range testCases {
   150  			tc := testCases[i]
   151  			t.Run(tc.GetTestCaseName(i), func(t *testing.T) {
   152  				t.Parallel()
   153  				http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc)
   154  			})
   155  		}
   156  	},
   157  }
   158  

View as plain text