Skip to content

Commit 796f443

Browse files
Add conformance tests for checking combinations of multiple HTTPRoute matches
1 parent 6efcfdf commit 796f443

File tree

2 files changed

+218
-0
lines changed

2 files changed

+218
-0
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
Copyright 2023 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+
"sigs.k8s.io/gateway-api/conformance/utils/http"
24+
"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
25+
"sigs.k8s.io/gateway-api/conformance/utils/suite"
26+
)
27+
28+
func init() {
29+
ConformanceTests = append(ConformanceTests, HTTPRouteMatchingCombinations)
30+
}
31+
32+
var HTTPRouteMatchingCombinations = suite.ConformanceTest{
33+
ShortName: "HTTPRouteMatchingCombinations",
34+
Description: "An HTTPRoute containing combinations of multiple match types",
35+
Manifests: []string{"tests/httproute-matching-combinations.yaml"},
36+
Features: []suite.SupportedFeature{
37+
suite.SupportGateway,
38+
suite.SupportHTTPRoute,
39+
suite.SupportHTTPRouteQueryParamMatching,
40+
suite.SupportHTTPRouteMethodMatching,
41+
},
42+
Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
43+
ns := "gateway-conformance-infra"
44+
routeNN := types.NamespacedName{Namespace: ns, Name: "matching-combinations"}
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+
{
51+
Request: http.Request{Path: "/path1?animal=whale"},
52+
Backend: "infra-backend-v1",
53+
Namespace: ns,
54+
},
55+
{
56+
Request: http.Request{Path: "/path2", Method: "POST"},
57+
Backend: "infra-backend-v2",
58+
Namespace: ns,
59+
},
60+
{
61+
Request: http.Request{Path: "/path3?animal=whale", Method: "POST"},
62+
Backend: "infra-backend-v3",
63+
Namespace: ns,
64+
},
65+
{
66+
Request: http.Request{Headers: map[string]string{"version": "one"}, Path: "/?animal=whale"},
67+
Backend: "infra-backend-v1",
68+
Namespace: ns,
69+
},
70+
{
71+
Request: http.Request{Headers: map[string]string{"version": "two"}, Path: "/", Method: "POST"},
72+
Backend: "infra-backend-v2",
73+
Namespace: ns,
74+
},
75+
{
76+
Request: http.Request{Headers: map[string]string{"version": "three"}, Path: "/?animal=whale", Method: "POST"},
77+
Backend: "infra-backend-v3",
78+
Namespace: ns,
79+
},
80+
}
81+
82+
// Ensure that combinations of matches which are OR'd together match
83+
// even if only one of them is used in the request.
84+
testCases = append(testCases, []http.ExpectedResponse{
85+
{
86+
Request: http.Request{Path: "/path-with-header", Headers: map[string]string{"version": "four"}},
87+
Backend: "infra-backend-v1",
88+
Namespace: ns,
89+
},
90+
{
91+
Request: http.Request{Path: "/path-with-queryparam?animal=dolphin"},
92+
Backend: "infra-backend-v1",
93+
Namespace: ns,
94+
},
95+
}...)
96+
97+
// Ensure that combinations of match types which are ANDed together do not match
98+
// when only a subset of match types is used in the request.
99+
testCases = append(testCases, []http.ExpectedResponse{
100+
{
101+
Request: http.Request{Path: "/path1"},
102+
Response: http.Response{StatusCode: 404},
103+
},
104+
{
105+
Request: http.Request{Headers: map[string]string{"version": "one"}},
106+
Response: http.Response{StatusCode: 404},
107+
},
108+
{
109+
Request: http.Request{Path: "/?animal=whale"},
110+
Response: http.Response{StatusCode: 404},
111+
},
112+
{
113+
Request: http.Request{Method: "POST"},
114+
Response: http.Response{StatusCode: 404},
115+
},
116+
{
117+
Request: http.Request{Path: "/path-with-header"},
118+
Response: http.Response{StatusCode: 404},
119+
},
120+
{
121+
Request: http.Request{Path: "/?animal=dolphin"},
122+
Response: http.Response{StatusCode: 404},
123+
},
124+
}...)
125+
126+
for i := range testCases {
127+
tc := testCases[i]
128+
t.Run(tc.GetTestCaseName(i), func(t *testing.T) {
129+
t.Parallel()
130+
http.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, tc)
131+
})
132+
}
133+
},
134+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
apiVersion: gateway.networking.k8s.io/v1beta1
2+
kind: HTTPRoute
3+
metadata:
4+
name: matching-combinations
5+
namespace: gateway-conformance-infra
6+
spec:
7+
parentRefs:
8+
- name: same-namespace
9+
rules:
10+
- matches:
11+
- path:
12+
type: PathPrefix
13+
value: /path1
14+
queryParams:
15+
- name: animal
16+
value: whale
17+
backendRefs:
18+
- name: infra-backend-v1
19+
port: 8080
20+
- matches:
21+
- path:
22+
type: PathPrefix
23+
value: /path2
24+
method: POST
25+
backendRefs:
26+
- name: infra-backend-v2
27+
port: 8080
28+
- matches:
29+
- path:
30+
type: PathPrefix
31+
value: /path3
32+
queryParams:
33+
- name: animal
34+
value: whale
35+
method: POST
36+
backendRefs:
37+
- name: infra-backend-v3
38+
port: 8080
39+
- matches:
40+
- headers:
41+
- name: version
42+
value: one
43+
queryParams:
44+
- name: animal
45+
value: whale
46+
backendRefs:
47+
- name: infra-backend-v1
48+
port: 8080
49+
- matches:
50+
- headers:
51+
- name: version
52+
value: two
53+
method: POST
54+
backendRefs:
55+
- name: infra-backend-v2
56+
port: 8080
57+
- matches:
58+
- headers:
59+
- name: version
60+
value: three
61+
queryParams:
62+
- name: animal
63+
value: whale
64+
method: POST
65+
backendRefs:
66+
- name: infra-backend-v3
67+
port: 8080
68+
# Match of the form (cond1 AND cond2) OR (cond3 AND cond4)
69+
- matches:
70+
- path:
71+
type: PathPrefix
72+
value: /path-with-header
73+
headers:
74+
- name: version
75+
value: four
76+
- path:
77+
type: PathPrefix
78+
value: /path-with-queryparam
79+
queryParams:
80+
- name: animal
81+
value: dolphin
82+
backendRefs:
83+
- name: infra-backend-v1
84+
port: 8080

0 commit comments

Comments
 (0)