• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2022 The gRPC Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14import logging
15from typing import Tuple
16
17from absl import flags
18from absl.testing import absltest
19
20from framework import xds_url_map_testcase
21from framework.test_app import client_app
22
23# Type aliases
24HostRule = xds_url_map_testcase.HostRule
25PathMatcher = xds_url_map_testcase.PathMatcher
26GcpResourceManager = xds_url_map_testcase.GcpResourceManager
27DumpedXdsConfig = xds_url_map_testcase.DumpedXdsConfig
28RpcTypeUnaryCall = xds_url_map_testcase.RpcTypeUnaryCall
29RpcTypeEmptyCall = xds_url_map_testcase.RpcTypeEmptyCall
30XdsTestClient = client_app.XdsTestClient
31
32logger = logging.getLogger(__name__)
33flags.adopt_module_key_flags(xds_url_map_testcase)
34
35_NUM_RPCS = 150
36_TEST_METADATA_KEY = 'xds_md'
37_TEST_METADATA_VALUE_EMPTY = 'empty_ytpme'
38_TEST_METADATA = ((RpcTypeEmptyCall, _TEST_METADATA_KEY,
39                   _TEST_METADATA_VALUE_EMPTY),)
40match_labels = [{
41    'name': 'TRAFFICDIRECTOR_NETWORK_NAME',
42    'value': 'default-vpc'
43}]
44not_match_labels = [{'name': 'fake', 'value': 'fail'}]
45
46
47class TestMetadataFilterMatchAll(xds_url_map_testcase.XdsUrlMapTestCase):
48    """" The test url-map has two routeRules: the higher priority routes to
49    the default backends, but is supposed to be filtered out by TD because
50    of non-matching metadata filters. The lower priority routes to alternative
51    backends and metadata filter matches. Thus, it verifies that TD evaluates
52    metadata filters correctly."""
53
54    @staticmethod
55    def url_map_change(
56            host_rule: HostRule,
57            path_matcher: PathMatcher) -> Tuple[HostRule, PathMatcher]:
58        path_matcher["routeRules"] = [{
59            'priority': 0,
60            'matchRules': [{
61                'prefixMatch':
62                    '/',
63                'metadataFilters': [{
64                    'filterMatchCriteria': 'MATCH_ALL',
65                    'filterLabels': not_match_labels
66                }]
67            }],
68            'service': GcpResourceManager().default_backend_service()
69        }, {
70            'priority': 1,
71            'matchRules': [{
72                'prefixMatch':
73                    '/grpc.testing.TestService/Empty',
74                'headerMatches': [{
75                    'headerName': _TEST_METADATA_KEY,
76                    'exactMatch': _TEST_METADATA_VALUE_EMPTY
77                }],
78                'metadataFilters': [{
79                    'filterMatchCriteria': 'MATCH_ALL',
80                    'filterLabels': match_labels
81                }]
82            }],
83            'service': GcpResourceManager().alternative_backend_service()
84        }]
85        return host_rule, path_matcher
86
87    def xds_config_validate(self, xds_config: DumpedXdsConfig):
88        self.assertNumEndpoints(xds_config, 2)
89        self.assertEqual(len(xds_config.rds['virtualHosts'][0]['routes']), 2)
90        self.assertEqual(
91            xds_config.rds['virtualHosts'][0]['routes'][0]['match']['prefix'],
92            "/grpc.testing.TestService/Empty")
93        self.assertEqual(
94            xds_config.rds['virtualHosts'][0]['routes'][0]['match']['headers']
95            [0]['name'], _TEST_METADATA_KEY)
96        self.assertEqual(
97            xds_config.rds['virtualHosts'][0]['routes'][0]['match']['headers']
98            [0]['exactMatch'], _TEST_METADATA_VALUE_EMPTY)
99        self.assertEqual(
100            xds_config.rds['virtualHosts'][0]['routes'][1]['match']['prefix'],
101            "")
102
103    def rpc_distribution_validate(self, test_client: XdsTestClient):
104        rpc_distribution = self.configure_and_send(test_client,
105                                                   rpc_types=[RpcTypeEmptyCall],
106                                                   metadata=_TEST_METADATA,
107                                                   num_rpcs=_NUM_RPCS)
108        self.assertEqual(
109            _NUM_RPCS,
110            rpc_distribution.empty_call_alternative_service_rpc_count)
111
112
113class TestMetadataFilterMatchAny(xds_url_map_testcase.XdsUrlMapTestCase):
114
115    @staticmethod
116    def url_map_change(
117            host_rule: HostRule,
118            path_matcher: PathMatcher) -> Tuple[HostRule, PathMatcher]:
119        path_matcher["routeRules"] = [{
120            'priority': 0,
121            'matchRules': [{
122                'prefixMatch':
123                    '/',
124                'metadataFilters': [{
125                    'filterMatchCriteria': 'MATCH_ANY',
126                    'filterLabels': not_match_labels
127                }]
128            }],
129            'service': GcpResourceManager().default_backend_service()
130        }, {
131            'priority': 1,
132            'matchRules': [{
133                'prefixMatch':
134                    '/grpc.testing.TestService/Unary',
135                'metadataFilters': [{
136                    'filterMatchCriteria': 'MATCH_ANY',
137                    'filterLabels': not_match_labels + match_labels
138                }]
139            }],
140            'service': GcpResourceManager().alternative_backend_service()
141        }]
142        return host_rule, path_matcher
143
144    def xds_config_validate(self, xds_config: DumpedXdsConfig):
145        self.assertNumEndpoints(xds_config, 2)
146        self.assertEqual(len(xds_config.rds['virtualHosts'][0]['routes']), 2)
147        self.assertEqual(
148            xds_config.rds['virtualHosts'][0]['routes'][0]['match']['prefix'],
149            "/grpc.testing.TestService/Unary")
150        self.assertEqual(
151            xds_config.rds['virtualHosts'][0]['routes'][1]['match']['prefix'],
152            "")
153
154    def rpc_distribution_validate(self, test_client: XdsTestClient):
155        rpc_distribution = self.configure_and_send(
156            test_client, rpc_types=(RpcTypeUnaryCall,), num_rpcs=_NUM_RPCS)
157        self.assertEqual(
158            _NUM_RPCS,
159            rpc_distribution.unary_call_alternative_service_rpc_count)
160
161
162class TestMetadataFilterMatchAnyAndAll(xds_url_map_testcase.XdsUrlMapTestCase):
163
164    @staticmethod
165    def url_map_change(
166            host_rule: HostRule,
167            path_matcher: PathMatcher) -> Tuple[HostRule, PathMatcher]:
168        path_matcher["routeRules"] = [{
169            'priority': 0,
170            'matchRules': [{
171                'prefixMatch':
172                    '/',
173                'metadataFilters': [{
174                    'filterMatchCriteria': 'MATCH_ALL',
175                    'filterLabels': not_match_labels + match_labels
176                }]
177            }],
178            'service': GcpResourceManager().default_backend_service()
179        }, {
180            'priority': 1,
181            'matchRules': [{
182                'prefixMatch':
183                    '/grpc.testing.TestService/Unary',
184                'metadataFilters': [{
185                    'filterMatchCriteria': 'MATCH_ANY',
186                    'filterLabels': not_match_labels + match_labels
187                }]
188            }],
189            'service': GcpResourceManager().alternative_backend_service()
190        }]
191        return host_rule, path_matcher
192
193    def xds_config_validate(self, xds_config: DumpedXdsConfig):
194        self.assertNumEndpoints(xds_config, 2)
195        self.assertEqual(len(xds_config.rds['virtualHosts'][0]['routes']), 2)
196        self.assertEqual(
197            xds_config.rds['virtualHosts'][0]['routes'][0]['match']['prefix'],
198            "/grpc.testing.TestService/Unary")
199        self.assertEqual(
200            xds_config.rds['virtualHosts'][0]['routes'][1]['match']['prefix'],
201            "")
202
203    def rpc_distribution_validate(self, test_client: XdsTestClient):
204        rpc_distribution = self.configure_and_send(
205            test_client, rpc_types=(RpcTypeUnaryCall,), num_rpcs=_NUM_RPCS)
206        self.assertEqual(
207            _NUM_RPCS,
208            rpc_distribution.unary_call_alternative_service_rpc_count)
209
210
211class TestMetadataFilterMatchMultipleRules(
212        xds_url_map_testcase.XdsUrlMapTestCase):
213
214    @staticmethod
215    def url_map_change(
216            host_rule: HostRule,
217            path_matcher: PathMatcher) -> Tuple[HostRule, PathMatcher]:
218        path_matcher["routeRules"] = [{
219            'priority': 0,
220            'matchRules': [{
221                'prefixMatch':
222                    '/',
223                'headerMatches': [{
224                    'headerName': _TEST_METADATA_KEY,
225                    'exactMatch': _TEST_METADATA_VALUE_EMPTY
226                }],
227                'metadataFilters': [{
228                    'filterMatchCriteria': 'MATCH_ANY',
229                    'filterLabels': match_labels
230                }]
231            }],
232            'service': GcpResourceManager().alternative_backend_service()
233        }, {
234            'priority': 1,
235            'matchRules': [{
236                'prefixMatch':
237                    '/grpc.testing.TestService/Unary',
238                'metadataFilters': [{
239                    'filterMatchCriteria': 'MATCH_ALL',
240                    'filterLabels': match_labels
241                }]
242            }],
243            'service': GcpResourceManager().default_backend_service()
244        }]
245        return host_rule, path_matcher
246
247    def xds_config_validate(self, xds_config: DumpedXdsConfig):
248        self.assertNumEndpoints(xds_config, 2)
249        self.assertEqual(len(xds_config.rds['virtualHosts'][0]['routes']), 3)
250        self.assertEqual(
251            xds_config.rds['virtualHosts'][0]['routes'][0]['match']['headers']
252            [0]['name'], _TEST_METADATA_KEY)
253        self.assertEqual(
254            xds_config.rds['virtualHosts'][0]['routes'][0]['match']['headers']
255            [0]['exactMatch'], _TEST_METADATA_VALUE_EMPTY)
256        self.assertEqual(
257            xds_config.rds['virtualHosts'][0]['routes'][1]['match']['prefix'],
258            "/grpc.testing.TestService/Unary")
259        self.assertEqual(
260            xds_config.rds['virtualHosts'][0]['routes'][2]['match']['prefix'],
261            "")
262
263    def rpc_distribution_validate(self, test_client: XdsTestClient):
264        rpc_distribution = self.configure_and_send(test_client,
265                                                   rpc_types=[RpcTypeEmptyCall],
266                                                   metadata=_TEST_METADATA,
267                                                   num_rpcs=_NUM_RPCS)
268        self.assertEqual(
269            _NUM_RPCS,
270            rpc_distribution.empty_call_alternative_service_rpc_count)
271
272
273if __name__ == '__main__':
274    absltest.main()
275