1 //
2 // Copyright 2022 gRPC 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 #include <google/protobuf/wrappers.pb.h>
18 #include <grpc/grpc.h>
19 #include <stdint.h>
20
21 #include <limits>
22 #include <map>
23 #include <memory>
24 #include <string>
25 #include <utility>
26 #include <vector>
27
28 #include "absl/status/status.h"
29 #include "absl/status/statusor.h"
30 #include "absl/strings/str_format.h"
31 #include "absl/types/optional.h"
32 #include "envoy/config/core/v3/address.pb.h"
33 #include "envoy/config/core/v3/base.pb.h"
34 #include "envoy/config/core/v3/health_check.pb.h"
35 #include "envoy/config/endpoint/v3/endpoint.pb.h"
36 #include "envoy/type/v3/percent.pb.h"
37 #include "gtest/gtest.h"
38 #include "src/core/lib/address_utils/sockaddr_utils.h"
39 #include "src/core/lib/channel/channel_args.h"
40 #include "src/core/lib/debug/trace.h"
41 #include "src/core/lib/iomgr/error.h"
42 #include "src/core/lib/iomgr/resolved_address.h"
43 #include "src/core/resolver/endpoint_addresses.h"
44 #include "src/core/util/crash.h"
45 #include "src/core/util/ref_counted_ptr.h"
46 #include "src/core/xds/grpc/xds_bootstrap_grpc.h"
47 #include "src/core/xds/grpc/xds_endpoint.h"
48 #include "src/core/xds/grpc/xds_endpoint_parser.h"
49 #include "src/core/xds/grpc/xds_health_status.h"
50 #include "src/core/xds/xds_client/xds_bootstrap.h"
51 #include "src/core/xds/xds_client/xds_client.h"
52 #include "src/core/xds/xds_client/xds_locality.h"
53 #include "src/core/xds/xds_client/xds_resource_type.h"
54 #include "test/core/test_util/scoped_env_var.h"
55 #include "test/core/test_util/test_config.h"
56 #include "upb/mem/arena.hpp"
57 #include "upb/reflection/def.hpp"
58
59 using envoy::config::endpoint::v3::ClusterLoadAssignment;
60
61 namespace grpc_core {
62 namespace testing {
63 namespace {
64
65 class XdsEndpointTest : public ::testing::Test {
66 protected:
XdsEndpointTest()67 XdsEndpointTest()
68 : xds_client_(MakeXdsClient()),
69 decode_context_{
70 xds_client_.get(), *xds_client_->bootstrap().servers().front(),
71 &xds_unittest_trace, upb_def_pool_.ptr(), upb_arena_.ptr()} {}
72
MakeXdsClient()73 static RefCountedPtr<XdsClient> MakeXdsClient() {
74 grpc_error_handle error;
75 auto bootstrap = GrpcXdsBootstrap::Create(
76 "{\n"
77 " \"xds_servers\": [\n"
78 " {\n"
79 " \"server_uri\": \"xds.example.com\",\n"
80 " \"channel_creds\": [\n"
81 " {\"type\": \"google_default\"}\n"
82 " ]\n"
83 " }\n"
84 " ]\n"
85 "}");
86 if (!bootstrap.ok()) {
87 Crash(absl::StrFormat("Error parsing bootstrap: %s",
88 bootstrap.status().ToString().c_str()));
89 }
90 return MakeRefCounted<XdsClient>(std::move(*bootstrap),
91 /*transport_factory=*/nullptr,
92 /*event_engine=*/nullptr,
93 /*metrics_reporter=*/nullptr, "foo agent",
94 "foo version");
95 }
96
97 RefCountedPtr<XdsClient> xds_client_;
98 upb::DefPool upb_def_pool_;
99 upb::Arena upb_arena_;
100 XdsResourceType::DecodeContext decode_context_;
101 };
102
TEST_F(XdsEndpointTest,Definition)103 TEST_F(XdsEndpointTest, Definition) {
104 auto* resource_type = XdsEndpointResourceType::Get();
105 ASSERT_NE(resource_type, nullptr);
106 EXPECT_EQ(resource_type->type_url(),
107 "envoy.config.endpoint.v3.ClusterLoadAssignment");
108 EXPECT_FALSE(resource_type->AllResourcesRequiredInSotW());
109 }
110
TEST_F(XdsEndpointTest,UnparsableProto)111 TEST_F(XdsEndpointTest, UnparsableProto) {
112 std::string serialized_resource("\0", 1);
113 auto* resource_type = XdsEndpointResourceType::Get();
114 auto decode_result =
115 resource_type->Decode(decode_context_, serialized_resource);
116 EXPECT_EQ(decode_result.resource.status().code(),
117 absl::StatusCode::kInvalidArgument);
118 EXPECT_EQ(decode_result.resource.status().message(),
119 "Can't parse ClusterLoadAssignment resource.")
120 << decode_result.resource.status();
121 }
122
TEST_F(XdsEndpointTest,MinimumValidConfig)123 TEST_F(XdsEndpointTest, MinimumValidConfig) {
124 ClusterLoadAssignment cla;
125 cla.set_cluster_name("foo");
126 auto* locality = cla.add_endpoints();
127 locality->mutable_load_balancing_weight()->set_value(1);
128 auto* locality_name = locality->mutable_locality();
129 locality_name->set_region("myregion");
130 locality_name->set_zone("myzone");
131 locality_name->set_sub_zone("mysubzone");
132 auto* socket_address = locality->add_lb_endpoints()
133 ->mutable_endpoint()
134 ->mutable_address()
135 ->mutable_socket_address();
136 socket_address->set_address("127.0.0.1");
137 socket_address->set_port_value(443);
138 std::string serialized_resource;
139 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
140 auto* resource_type = XdsEndpointResourceType::Get();
141 auto decode_result =
142 resource_type->Decode(decode_context_, serialized_resource);
143 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
144 ASSERT_TRUE(decode_result.name.has_value());
145 EXPECT_EQ(*decode_result.name, "foo");
146 auto& resource =
147 static_cast<const XdsEndpointResource&>(**decode_result.resource);
148 ASSERT_EQ(resource.priorities.size(), 1);
149 const auto& priority = resource.priorities[0];
150 ASSERT_EQ(priority.localities.size(), 1);
151 const auto& p = *priority.localities.begin();
152 ASSERT_EQ(p.first, p.second.name.get());
153 EXPECT_EQ(p.first->region(), "myregion");
154 EXPECT_EQ(p.first->zone(), "myzone");
155 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
156 EXPECT_EQ(p.second.lb_weight, 1);
157 ASSERT_EQ(p.second.endpoints.size(), 1);
158 const auto& address = p.second.endpoints.front();
159 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
160 ASSERT_TRUE(addr.ok()) << addr.status();
161 EXPECT_EQ(*addr, "127.0.0.1:443");
162 EXPECT_EQ(address.args(), ChannelArgs()
163 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
164 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
165 XdsHealthStatus::HealthStatus::kUnknown));
166 EXPECT_EQ(resource.drop_config, nullptr);
167 }
168
TEST_F(XdsEndpointTest,EndpointWeight)169 TEST_F(XdsEndpointTest, EndpointWeight) {
170 ClusterLoadAssignment cla;
171 cla.set_cluster_name("foo");
172 auto* locality = cla.add_endpoints();
173 locality->mutable_load_balancing_weight()->set_value(1);
174 auto* locality_name = locality->mutable_locality();
175 locality_name->set_region("myregion");
176 locality_name->set_zone("myzone");
177 locality_name->set_sub_zone("mysubzone");
178 auto* endpoint = locality->add_lb_endpoints();
179 endpoint->mutable_load_balancing_weight()->set_value(3);
180 auto* socket_address =
181 endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
182 socket_address->set_address("127.0.0.1");
183 socket_address->set_port_value(443);
184 std::string serialized_resource;
185 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
186 auto* resource_type = XdsEndpointResourceType::Get();
187 auto decode_result =
188 resource_type->Decode(decode_context_, serialized_resource);
189 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
190 ASSERT_TRUE(decode_result.name.has_value());
191 EXPECT_EQ(*decode_result.name, "foo");
192 auto& resource =
193 static_cast<const XdsEndpointResource&>(**decode_result.resource);
194 ASSERT_EQ(resource.priorities.size(), 1);
195 const auto& priority = resource.priorities[0];
196 ASSERT_EQ(priority.localities.size(), 1);
197 const auto& p = *priority.localities.begin();
198 ASSERT_EQ(p.first, p.second.name.get());
199 EXPECT_EQ(p.first->region(), "myregion");
200 EXPECT_EQ(p.first->zone(), "myzone");
201 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
202 EXPECT_EQ(p.second.lb_weight, 1);
203 ASSERT_EQ(p.second.endpoints.size(), 1);
204 const auto& address = p.second.endpoints.front();
205 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
206 ASSERT_TRUE(addr.ok()) << addr.status();
207 EXPECT_EQ(*addr, "127.0.0.1:443");
208 EXPECT_EQ(address.args(), ChannelArgs()
209 .Set(GRPC_ARG_ADDRESS_WEIGHT, 3)
210 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
211 XdsHealthStatus::HealthStatus::kUnknown));
212 EXPECT_EQ(resource.drop_config, nullptr);
213 }
214
TEST_F(XdsEndpointTest,IgnoresLocalityWithNoWeight)215 TEST_F(XdsEndpointTest, IgnoresLocalityWithNoWeight) {
216 ClusterLoadAssignment cla;
217 cla.set_cluster_name("foo");
218 auto* locality = cla.add_endpoints();
219 auto* locality_name = locality->mutable_locality();
220 locality_name->set_region("myregion");
221 locality_name->set_zone("myzone");
222 locality_name->set_sub_zone("mysubzone");
223 auto* socket_address = locality->add_lb_endpoints()
224 ->mutable_endpoint()
225 ->mutable_address()
226 ->mutable_socket_address();
227 socket_address->set_address("127.0.0.1");
228 socket_address->set_port_value(443);
229 locality = cla.add_endpoints();
230 *locality = cla.endpoints(0);
231 locality->mutable_load_balancing_weight()->set_value(1);
232 std::string serialized_resource;
233 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
234 auto* resource_type = XdsEndpointResourceType::Get();
235 auto decode_result =
236 resource_type->Decode(decode_context_, serialized_resource);
237 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
238 ASSERT_TRUE(decode_result.name.has_value());
239 EXPECT_EQ(*decode_result.name, "foo");
240 auto& resource =
241 static_cast<const XdsEndpointResource&>(**decode_result.resource);
242 ASSERT_EQ(resource.priorities.size(), 1);
243 const auto& priority = resource.priorities[0];
244 ASSERT_EQ(priority.localities.size(), 1);
245 const auto& p = *priority.localities.begin();
246 ASSERT_EQ(p.first, p.second.name.get());
247 EXPECT_EQ(p.first->region(), "myregion");
248 EXPECT_EQ(p.first->zone(), "myzone");
249 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
250 EXPECT_EQ(p.second.lb_weight, 1);
251 ASSERT_EQ(p.second.endpoints.size(), 1);
252 const auto& address = p.second.endpoints.front();
253 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
254 ASSERT_TRUE(addr.ok()) << addr.status();
255 EXPECT_EQ(*addr, "127.0.0.1:443");
256 EXPECT_EQ(address.args(), ChannelArgs()
257 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
258 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
259 XdsHealthStatus::HealthStatus::kUnknown));
260 EXPECT_EQ(resource.drop_config, nullptr);
261 }
262
TEST_F(XdsEndpointTest,IgnoresLocalityWithZeroWeight)263 TEST_F(XdsEndpointTest, IgnoresLocalityWithZeroWeight) {
264 ClusterLoadAssignment cla;
265 cla.set_cluster_name("foo");
266 auto* locality = cla.add_endpoints();
267 locality->mutable_load_balancing_weight()->set_value(0);
268 auto* locality_name = locality->mutable_locality();
269 locality_name->set_region("myregion");
270 locality_name->set_zone("myzone");
271 locality_name->set_sub_zone("mysubzone");
272 auto* socket_address = locality->add_lb_endpoints()
273 ->mutable_endpoint()
274 ->mutable_address()
275 ->mutable_socket_address();
276 socket_address->set_address("127.0.0.1");
277 socket_address->set_port_value(443);
278 locality = cla.add_endpoints();
279 *locality = cla.endpoints(0);
280 locality->mutable_load_balancing_weight()->set_value(1);
281 std::string serialized_resource;
282 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
283 auto* resource_type = XdsEndpointResourceType::Get();
284 auto decode_result =
285 resource_type->Decode(decode_context_, serialized_resource);
286 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
287 ASSERT_TRUE(decode_result.name.has_value());
288 EXPECT_EQ(*decode_result.name, "foo");
289 auto& resource =
290 static_cast<const XdsEndpointResource&>(**decode_result.resource);
291 ASSERT_EQ(resource.priorities.size(), 1);
292 const auto& priority = resource.priorities[0];
293 ASSERT_EQ(priority.localities.size(), 1);
294 const auto& p = *priority.localities.begin();
295 ASSERT_EQ(p.first, p.second.name.get());
296 EXPECT_EQ(p.first->region(), "myregion");
297 EXPECT_EQ(p.first->zone(), "myzone");
298 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
299 EXPECT_EQ(p.second.lb_weight, 1);
300 ASSERT_EQ(p.second.endpoints.size(), 1);
301 const auto& address = p.second.endpoints.front();
302 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
303 ASSERT_TRUE(addr.ok()) << addr.status();
304 EXPECT_EQ(*addr, "127.0.0.1:443");
305 EXPECT_EQ(address.args(), ChannelArgs()
306 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
307 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
308 XdsHealthStatus::HealthStatus::kUnknown));
309 EXPECT_EQ(resource.drop_config, nullptr);
310 }
311
TEST_F(XdsEndpointTest,LocalityWithNoEndpoints)312 TEST_F(XdsEndpointTest, LocalityWithNoEndpoints) {
313 ClusterLoadAssignment cla;
314 cla.set_cluster_name("foo");
315 auto* locality = cla.add_endpoints();
316 locality->mutable_load_balancing_weight()->set_value(1);
317 auto* locality_name = locality->mutable_locality();
318 locality_name->set_region("myregion");
319 locality_name->set_zone("myzone");
320 locality_name->set_sub_zone("mysubzone");
321 std::string serialized_resource;
322 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
323 auto* resource_type = XdsEndpointResourceType::Get();
324 auto decode_result =
325 resource_type->Decode(decode_context_, serialized_resource);
326 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
327 ASSERT_TRUE(decode_result.name.has_value());
328 EXPECT_EQ(*decode_result.name, "foo");
329 auto& resource =
330 static_cast<const XdsEndpointResource&>(**decode_result.resource);
331 ASSERT_EQ(resource.priorities.size(), 1);
332 const auto& priority = resource.priorities[0];
333 ASSERT_EQ(priority.localities.size(), 1);
334 const auto& p = *priority.localities.begin();
335 ASSERT_EQ(p.first, p.second.name.get());
336 EXPECT_EQ(p.first->region(), "myregion");
337 EXPECT_EQ(p.first->zone(), "myzone");
338 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
339 EXPECT_EQ(p.second.lb_weight, 1);
340 EXPECT_EQ(p.second.endpoints.size(), 0);
341 EXPECT_EQ(resource.drop_config, nullptr);
342 }
343
TEST_F(XdsEndpointTest,NoLocality)344 TEST_F(XdsEndpointTest, NoLocality) {
345 ClusterLoadAssignment cla;
346 cla.set_cluster_name("foo");
347 auto* locality = cla.add_endpoints();
348 locality->mutable_load_balancing_weight()->set_value(1);
349 auto* socket_address = locality->add_lb_endpoints()
350 ->mutable_endpoint()
351 ->mutable_address()
352 ->mutable_socket_address();
353 socket_address->set_address("127.0.0.1");
354 socket_address->set_port_value(443);
355 std::string serialized_resource;
356 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
357 auto* resource_type = XdsEndpointResourceType::Get();
358 auto decode_result =
359 resource_type->Decode(decode_context_, serialized_resource);
360 ASSERT_TRUE(decode_result.name.has_value());
361 EXPECT_EQ(*decode_result.name, "foo");
362 EXPECT_EQ(decode_result.resource.status().code(),
363 absl::StatusCode::kInvalidArgument);
364 EXPECT_EQ(decode_result.resource.status().message(),
365 "errors parsing EDS resource: ["
366 "field:endpoints[0].locality error:field not present]")
367 << decode_result.resource.status();
368 }
369
TEST_F(XdsEndpointTest,InvalidPort)370 TEST_F(XdsEndpointTest, InvalidPort) {
371 ClusterLoadAssignment cla;
372 cla.set_cluster_name("foo");
373 auto* locality = cla.add_endpoints();
374 locality->mutable_load_balancing_weight()->set_value(1);
375 auto* locality_name = locality->mutable_locality();
376 locality_name->set_region("myregion");
377 locality_name->set_zone("myzone");
378 locality_name->set_sub_zone("mysubzone");
379 auto* socket_address = locality->add_lb_endpoints()
380 ->mutable_endpoint()
381 ->mutable_address()
382 ->mutable_socket_address();
383 socket_address->set_address("127.0.0.1");
384 socket_address->set_port_value(65537);
385 std::string serialized_resource;
386 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
387 auto* resource_type = XdsEndpointResourceType::Get();
388 auto decode_result =
389 resource_type->Decode(decode_context_, serialized_resource);
390 ASSERT_TRUE(decode_result.name.has_value());
391 EXPECT_EQ(*decode_result.name, "foo");
392 EXPECT_EQ(decode_result.resource.status().code(),
393 absl::StatusCode::kInvalidArgument);
394 EXPECT_EQ(decode_result.resource.status().message(),
395 "errors parsing EDS resource: ["
396 "field:endpoints[0].lb_endpoints[0].endpoint.address"
397 ".socket_address.port_value error:invalid port]")
398 << decode_result.resource.status();
399 }
400
TEST_F(XdsEndpointTest,InvalidAddress)401 TEST_F(XdsEndpointTest, InvalidAddress) {
402 ClusterLoadAssignment cla;
403 cla.set_cluster_name("foo");
404 auto* locality = cla.add_endpoints();
405 locality->mutable_load_balancing_weight()->set_value(1);
406 auto* locality_name = locality->mutable_locality();
407 locality_name->set_region("myregion");
408 locality_name->set_zone("myzone");
409 locality_name->set_sub_zone("mysubzone");
410 auto* socket_address = locality->add_lb_endpoints()
411 ->mutable_endpoint()
412 ->mutable_address()
413 ->mutable_socket_address();
414 socket_address->set_address("not_an_ip_address");
415 socket_address->set_port_value(443);
416 std::string serialized_resource;
417 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
418 auto* resource_type = XdsEndpointResourceType::Get();
419 auto decode_result =
420 resource_type->Decode(decode_context_, serialized_resource);
421 ASSERT_TRUE(decode_result.name.has_value());
422 EXPECT_EQ(*decode_result.name, "foo");
423 EXPECT_EQ(decode_result.resource.status().code(),
424 absl::StatusCode::kInvalidArgument);
425 EXPECT_EQ(decode_result.resource.status().message(),
426 "errors parsing EDS resource: ["
427 "field:endpoints[0].lb_endpoints[0].endpoint.address"
428 ".socket_address error:"
429 "Failed to parse address:not_an_ip_address:443]")
430 << decode_result.resource.status();
431 }
432
TEST_F(XdsEndpointTest,MissingSocketAddress)433 TEST_F(XdsEndpointTest, MissingSocketAddress) {
434 ClusterLoadAssignment cla;
435 cla.set_cluster_name("foo");
436 auto* locality = cla.add_endpoints();
437 locality->mutable_load_balancing_weight()->set_value(1);
438 auto* locality_name = locality->mutable_locality();
439 locality_name->set_region("myregion");
440 locality_name->set_zone("myzone");
441 locality_name->set_sub_zone("mysubzone");
442 locality->add_lb_endpoints()->mutable_endpoint()->mutable_address();
443 std::string serialized_resource;
444 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
445 auto* resource_type = XdsEndpointResourceType::Get();
446 auto decode_result =
447 resource_type->Decode(decode_context_, serialized_resource);
448 ASSERT_TRUE(decode_result.name.has_value());
449 EXPECT_EQ(*decode_result.name, "foo");
450 EXPECT_EQ(decode_result.resource.status().code(),
451 absl::StatusCode::kInvalidArgument);
452 EXPECT_EQ(decode_result.resource.status().message(),
453 "errors parsing EDS resource: ["
454 "field:endpoints[0].lb_endpoints[0].endpoint.address"
455 ".socket_address error:field not present]")
456 << decode_result.resource.status();
457 }
458
TEST_F(XdsEndpointTest,MissingAddress)459 TEST_F(XdsEndpointTest, MissingAddress) {
460 ClusterLoadAssignment cla;
461 cla.set_cluster_name("foo");
462 auto* locality = cla.add_endpoints();
463 locality->mutable_load_balancing_weight()->set_value(1);
464 auto* locality_name = locality->mutable_locality();
465 locality_name->set_region("myregion");
466 locality_name->set_zone("myzone");
467 locality_name->set_sub_zone("mysubzone");
468 locality->add_lb_endpoints()->mutable_endpoint();
469 std::string serialized_resource;
470 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
471 auto* resource_type = XdsEndpointResourceType::Get();
472 auto decode_result =
473 resource_type->Decode(decode_context_, serialized_resource);
474 ASSERT_TRUE(decode_result.name.has_value());
475 EXPECT_EQ(*decode_result.name, "foo");
476 EXPECT_EQ(decode_result.resource.status().code(),
477 absl::StatusCode::kInvalidArgument);
478 EXPECT_EQ(decode_result.resource.status().message(),
479 "errors parsing EDS resource: ["
480 "field:endpoints[0].lb_endpoints[0].endpoint.address "
481 "error:field not present]")
482 << decode_result.resource.status();
483 }
484
TEST_F(XdsEndpointTest,MultipleAddressesPerEndpoint)485 TEST_F(XdsEndpointTest, MultipleAddressesPerEndpoint) {
486 ClusterLoadAssignment cla;
487 cla.set_cluster_name("foo");
488 auto* locality = cla.add_endpoints();
489 locality->mutable_load_balancing_weight()->set_value(1);
490 auto* locality_name = locality->mutable_locality();
491 locality_name->set_region("myregion");
492 locality_name->set_zone("myzone");
493 locality_name->set_sub_zone("mysubzone");
494 auto* ep = locality->add_lb_endpoints()->mutable_endpoint();
495 auto* socket_address = ep->mutable_address()->mutable_socket_address();
496 socket_address->set_address("127.0.0.1");
497 socket_address->set_port_value(443);
498 socket_address = ep->add_additional_addresses()
499 ->mutable_address()
500 ->mutable_socket_address();
501 socket_address->set_address("127.0.0.1");
502 socket_address->set_port_value(444);
503 std::string serialized_resource;
504 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
505 auto* resource_type = XdsEndpointResourceType::Get();
506 auto decode_result =
507 resource_type->Decode(decode_context_, serialized_resource);
508 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
509 ASSERT_TRUE(decode_result.name.has_value());
510 EXPECT_EQ(*decode_result.name, "foo");
511 auto& resource =
512 static_cast<const XdsEndpointResource&>(**decode_result.resource);
513 ASSERT_EQ(resource.priorities.size(), 1);
514 const auto& priority = resource.priorities[0];
515 ASSERT_EQ(priority.localities.size(), 1);
516 const auto& p = *priority.localities.begin();
517 ASSERT_EQ(p.first, p.second.name.get());
518 EXPECT_EQ(p.first->region(), "myregion");
519 EXPECT_EQ(p.first->zone(), "myzone");
520 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
521 EXPECT_EQ(p.second.lb_weight, 1);
522 ASSERT_EQ(p.second.endpoints.size(), 1);
523 const auto& endpoint = p.second.endpoints.front();
524 ASSERT_EQ(endpoint.addresses().size(), 2);
525 auto addr =
526 grpc_sockaddr_to_string(&endpoint.addresses()[0], /*normalize=*/false);
527 ASSERT_TRUE(addr.ok()) << addr.status();
528 EXPECT_EQ(*addr, "127.0.0.1:443");
529 addr = grpc_sockaddr_to_string(&endpoint.addresses()[1], /*normalize=*/false);
530 ASSERT_TRUE(addr.ok()) << addr.status();
531 EXPECT_EQ(*addr, "127.0.0.1:444");
532 EXPECT_EQ(endpoint.args(), ChannelArgs()
533 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
534 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
535 XdsHealthStatus::HealthStatus::kUnknown));
536 EXPECT_EQ(resource.drop_config, nullptr);
537 }
538
TEST_F(XdsEndpointTest,AdditionalAddressesMissingAddress)539 TEST_F(XdsEndpointTest, AdditionalAddressesMissingAddress) {
540 ClusterLoadAssignment cla;
541 cla.set_cluster_name("foo");
542 auto* locality = cla.add_endpoints();
543 locality->mutable_load_balancing_weight()->set_value(1);
544 auto* locality_name = locality->mutable_locality();
545 locality_name->set_region("myregion");
546 locality_name->set_zone("myzone");
547 locality_name->set_sub_zone("mysubzone");
548 auto* ep = locality->add_lb_endpoints()->mutable_endpoint();
549 auto* socket_address = ep->mutable_address()->mutable_socket_address();
550 socket_address->set_address("127.0.0.1");
551 socket_address->set_port_value(443);
552 ep->add_additional_addresses();
553 std::string serialized_resource;
554 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
555 auto* resource_type = XdsEndpointResourceType::Get();
556 auto decode_result =
557 resource_type->Decode(decode_context_, serialized_resource);
558 ASSERT_TRUE(decode_result.name.has_value());
559 EXPECT_EQ(*decode_result.name, "foo");
560 EXPECT_EQ(decode_result.resource.status().code(),
561 absl::StatusCode::kInvalidArgument);
562 EXPECT_EQ(decode_result.resource.status().message(),
563 "errors parsing EDS resource: ["
564 "field:endpoints[0].lb_endpoints[0].endpoint"
565 ".additional_addresses[0].address error:field not present]")
566 << decode_result.resource.status();
567 }
568
TEST_F(XdsEndpointTest,AdditionalAddressesMissingSocketAddress)569 TEST_F(XdsEndpointTest, AdditionalAddressesMissingSocketAddress) {
570 ClusterLoadAssignment cla;
571 cla.set_cluster_name("foo");
572 auto* locality = cla.add_endpoints();
573 locality->mutable_load_balancing_weight()->set_value(1);
574 auto* locality_name = locality->mutable_locality();
575 locality_name->set_region("myregion");
576 locality_name->set_zone("myzone");
577 locality_name->set_sub_zone("mysubzone");
578 auto* ep = locality->add_lb_endpoints()->mutable_endpoint();
579 auto* socket_address = ep->mutable_address()->mutable_socket_address();
580 socket_address->set_address("127.0.0.1");
581 socket_address->set_port_value(443);
582 ep->add_additional_addresses()->mutable_address();
583 std::string serialized_resource;
584 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
585 auto* resource_type = XdsEndpointResourceType::Get();
586 auto decode_result =
587 resource_type->Decode(decode_context_, serialized_resource);
588 ASSERT_TRUE(decode_result.name.has_value());
589 EXPECT_EQ(*decode_result.name, "foo");
590 EXPECT_EQ(decode_result.resource.status().code(),
591 absl::StatusCode::kInvalidArgument);
592 EXPECT_EQ(decode_result.resource.status().message(),
593 "errors parsing EDS resource: ["
594 "field:endpoints[0].lb_endpoints[0].endpoint"
595 ".additional_addresses[0].address.socket_address "
596 "error:field not present]")
597 << decode_result.resource.status();
598 }
599
TEST_F(XdsEndpointTest,AdditionalAddressesInvalidPort)600 TEST_F(XdsEndpointTest, AdditionalAddressesInvalidPort) {
601 ClusterLoadAssignment cla;
602 cla.set_cluster_name("foo");
603 auto* locality = cla.add_endpoints();
604 locality->mutable_load_balancing_weight()->set_value(1);
605 auto* locality_name = locality->mutable_locality();
606 locality_name->set_region("myregion");
607 locality_name->set_zone("myzone");
608 locality_name->set_sub_zone("mysubzone");
609 auto* ep = locality->add_lb_endpoints()->mutable_endpoint();
610 auto* socket_address = ep->mutable_address()->mutable_socket_address();
611 socket_address->set_address("127.0.0.1");
612 socket_address->set_port_value(443);
613 socket_address = ep->add_additional_addresses()
614 ->mutable_address()
615 ->mutable_socket_address();
616 socket_address->set_address("127.0.0.1");
617 socket_address->set_port_value(65537);
618 std::string serialized_resource;
619 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
620 auto* resource_type = XdsEndpointResourceType::Get();
621 auto decode_result =
622 resource_type->Decode(decode_context_, serialized_resource);
623 ASSERT_TRUE(decode_result.name.has_value());
624 EXPECT_EQ(*decode_result.name, "foo");
625 EXPECT_EQ(decode_result.resource.status().code(),
626 absl::StatusCode::kInvalidArgument);
627 EXPECT_EQ(decode_result.resource.status().message(),
628 "errors parsing EDS resource: ["
629 "field:endpoints[0].lb_endpoints[0].endpoint"
630 ".additional_addresses[0].address.socket_address.port_value "
631 "error:invalid port]")
632 << decode_result.resource.status();
633 }
634
TEST_F(XdsEndpointTest,AdditionalAddressesInvalidAddress)635 TEST_F(XdsEndpointTest, AdditionalAddressesInvalidAddress) {
636 ClusterLoadAssignment cla;
637 cla.set_cluster_name("foo");
638 auto* locality = cla.add_endpoints();
639 locality->mutable_load_balancing_weight()->set_value(1);
640 auto* locality_name = locality->mutable_locality();
641 locality_name->set_region("myregion");
642 locality_name->set_zone("myzone");
643 locality_name->set_sub_zone("mysubzone");
644 auto* ep = locality->add_lb_endpoints()->mutable_endpoint();
645 auto* socket_address = ep->mutable_address()->mutable_socket_address();
646 socket_address->set_address("127.0.0.1");
647 socket_address->set_port_value(443);
648 socket_address = ep->add_additional_addresses()
649 ->mutable_address()
650 ->mutable_socket_address();
651 socket_address->set_address("not_an_ip_address");
652 socket_address->set_port_value(444);
653 std::string serialized_resource;
654 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
655 auto* resource_type = XdsEndpointResourceType::Get();
656 auto decode_result =
657 resource_type->Decode(decode_context_, serialized_resource);
658 ASSERT_TRUE(decode_result.name.has_value());
659 EXPECT_EQ(*decode_result.name, "foo");
660 EXPECT_EQ(decode_result.resource.status().code(),
661 absl::StatusCode::kInvalidArgument);
662 EXPECT_EQ(decode_result.resource.status().message(),
663 "errors parsing EDS resource: ["
664 "field:endpoints[0].lb_endpoints[0].endpoint"
665 ".additional_addresses[0].address.socket_address error:"
666 "Failed to parse address:not_an_ip_address:444]")
667 << decode_result.resource.status();
668 }
669
TEST_F(XdsEndpointTest,IgnoresMultipleAddressesPerEndpointWhenDisabled)670 TEST_F(XdsEndpointTest, IgnoresMultipleAddressesPerEndpointWhenDisabled) {
671 testing::ScopedEnvVar env("GRPC_EXPERIMENTAL_XDS_DUALSTACK_ENDPOINTS",
672 "false");
673 ClusterLoadAssignment cla;
674 cla.set_cluster_name("foo");
675 auto* locality = cla.add_endpoints();
676 locality->mutable_load_balancing_weight()->set_value(1);
677 auto* locality_name = locality->mutable_locality();
678 locality_name->set_region("myregion");
679 locality_name->set_zone("myzone");
680 locality_name->set_sub_zone("mysubzone");
681 auto* ep = locality->add_lb_endpoints()->mutable_endpoint();
682 auto* socket_address = ep->mutable_address()->mutable_socket_address();
683 socket_address->set_address("127.0.0.1");
684 socket_address->set_port_value(443);
685 socket_address = ep->add_additional_addresses()
686 ->mutable_address()
687 ->mutable_socket_address();
688 socket_address->set_address("127.0.0.1");
689 socket_address->set_port_value(444);
690 std::string serialized_resource;
691 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
692 auto* resource_type = XdsEndpointResourceType::Get();
693 auto decode_result =
694 resource_type->Decode(decode_context_, serialized_resource);
695 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
696 ASSERT_TRUE(decode_result.name.has_value());
697 EXPECT_EQ(*decode_result.name, "foo");
698 auto& resource =
699 static_cast<const XdsEndpointResource&>(**decode_result.resource);
700 ASSERT_EQ(resource.priorities.size(), 1);
701 const auto& priority = resource.priorities[0];
702 ASSERT_EQ(priority.localities.size(), 1);
703 const auto& p = *priority.localities.begin();
704 ASSERT_EQ(p.first, p.second.name.get());
705 EXPECT_EQ(p.first->region(), "myregion");
706 EXPECT_EQ(p.first->zone(), "myzone");
707 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
708 EXPECT_EQ(p.second.lb_weight, 1);
709 ASSERT_EQ(p.second.endpoints.size(), 1);
710 const auto& endpoint = p.second.endpoints.front();
711 ASSERT_EQ(endpoint.addresses().size(), 1);
712 auto addr =
713 grpc_sockaddr_to_string(&endpoint.addresses()[0], /*normalize=*/false);
714 ASSERT_TRUE(addr.ok()) << addr.status();
715 EXPECT_EQ(*addr, "127.0.0.1:443");
716 EXPECT_EQ(endpoint.args(), ChannelArgs()
717 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
718 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
719 XdsHealthStatus::HealthStatus::kUnknown));
720 EXPECT_EQ(resource.drop_config, nullptr);
721 }
722
TEST_F(XdsEndpointTest,EndpointHostname)723 TEST_F(XdsEndpointTest, EndpointHostname) {
724 ClusterLoadAssignment cla;
725 cla.set_cluster_name("foo");
726 auto* locality = cla.add_endpoints();
727 locality->mutable_load_balancing_weight()->set_value(1);
728 auto* locality_name = locality->mutable_locality();
729 locality_name->set_region("myregion");
730 locality_name->set_zone("myzone");
731 locality_name->set_sub_zone("mysubzone");
732 auto* endpoint = locality->add_lb_endpoints()->mutable_endpoint();
733 endpoint->set_hostname("server.example.com");
734 auto* socket_address = endpoint->mutable_address()->mutable_socket_address();
735 socket_address->set_address("127.0.0.1");
736 socket_address->set_port_value(443);
737 std::string serialized_resource;
738 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
739 auto* resource_type = XdsEndpointResourceType::Get();
740 auto decode_result =
741 resource_type->Decode(decode_context_, serialized_resource);
742 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
743 ASSERT_TRUE(decode_result.name.has_value());
744 EXPECT_EQ(*decode_result.name, "foo");
745 auto& resource =
746 static_cast<const XdsEndpointResource&>(**decode_result.resource);
747 ASSERT_EQ(resource.priorities.size(), 1);
748 const auto& priority = resource.priorities[0];
749 ASSERT_EQ(priority.localities.size(), 1);
750 const auto& p = *priority.localities.begin();
751 ASSERT_EQ(p.first, p.second.name.get());
752 EXPECT_EQ(p.first->region(), "myregion");
753 EXPECT_EQ(p.first->zone(), "myzone");
754 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
755 EXPECT_EQ(p.second.lb_weight, 1);
756 ASSERT_EQ(p.second.endpoints.size(), 1);
757 const auto& address = p.second.endpoints.front();
758 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
759 ASSERT_TRUE(addr.ok()) << addr.status();
760 EXPECT_EQ(*addr, "127.0.0.1:443");
761 EXPECT_EQ(address.args(),
762 ChannelArgs()
763 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
764 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
765 XdsHealthStatus::HealthStatus::kUnknown)
766 .Set(GRPC_ARG_ADDRESS_NAME, "server.example.com"));
767 EXPECT_EQ(resource.drop_config, nullptr);
768 }
769
TEST_F(XdsEndpointTest,MissingEndpoint)770 TEST_F(XdsEndpointTest, MissingEndpoint) {
771 ClusterLoadAssignment cla;
772 cla.set_cluster_name("foo");
773 auto* locality = cla.add_endpoints();
774 locality->mutable_load_balancing_weight()->set_value(1);
775 auto* locality_name = locality->mutable_locality();
776 locality_name->set_region("myregion");
777 locality_name->set_zone("myzone");
778 locality_name->set_sub_zone("mysubzone");
779 locality->add_lb_endpoints();
780 std::string serialized_resource;
781 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
782 auto* resource_type = XdsEndpointResourceType::Get();
783 auto decode_result =
784 resource_type->Decode(decode_context_, serialized_resource);
785 ASSERT_TRUE(decode_result.name.has_value());
786 EXPECT_EQ(*decode_result.name, "foo");
787 EXPECT_EQ(decode_result.resource.status().code(),
788 absl::StatusCode::kInvalidArgument);
789 EXPECT_EQ(decode_result.resource.status().message(),
790 "errors parsing EDS resource: ["
791 "field:endpoints[0].lb_endpoints[0].endpoint "
792 "error:field not present]")
793 << decode_result.resource.status();
794 }
795
TEST_F(XdsEndpointTest,EndpointWeightZero)796 TEST_F(XdsEndpointTest, EndpointWeightZero) {
797 ClusterLoadAssignment cla;
798 cla.set_cluster_name("foo");
799 auto* locality = cla.add_endpoints();
800 locality->mutable_load_balancing_weight()->set_value(1);
801 auto* locality_name = locality->mutable_locality();
802 locality_name->set_region("myregion");
803 locality_name->set_zone("myzone");
804 locality_name->set_sub_zone("mysubzone");
805 auto* endpoint = locality->add_lb_endpoints();
806 endpoint->mutable_load_balancing_weight()->set_value(0);
807 auto* socket_address =
808 endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
809 socket_address->set_address("127.0.0.1");
810 socket_address->set_port_value(443);
811 std::string serialized_resource;
812 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
813 auto* resource_type = XdsEndpointResourceType::Get();
814 auto decode_result =
815 resource_type->Decode(decode_context_, serialized_resource);
816 ASSERT_TRUE(decode_result.name.has_value());
817 EXPECT_EQ(*decode_result.name, "foo");
818 EXPECT_EQ(decode_result.resource.status().code(),
819 absl::StatusCode::kInvalidArgument);
820 EXPECT_EQ(decode_result.resource.status().message(),
821 "errors parsing EDS resource: ["
822 "field:endpoints[0].lb_endpoints[0].load_balancing_weight "
823 "error:must be greater than 0]")
824 << decode_result.resource.status();
825 }
826
TEST_F(XdsEndpointTest,DuplicateLocalityName)827 TEST_F(XdsEndpointTest, DuplicateLocalityName) {
828 ClusterLoadAssignment cla;
829 cla.set_cluster_name("foo");
830 auto* locality = cla.add_endpoints();
831 locality->mutable_load_balancing_weight()->set_value(1);
832 auto* locality_name = locality->mutable_locality();
833 locality_name->set_region("myregion");
834 locality_name->set_zone("myzone");
835 locality_name->set_sub_zone("mysubzone");
836 auto* socket_address = locality->add_lb_endpoints()
837 ->mutable_endpoint()
838 ->mutable_address()
839 ->mutable_socket_address();
840 socket_address->set_address("127.0.0.1");
841 socket_address->set_port_value(443);
842 locality = cla.add_endpoints();
843 locality->mutable_load_balancing_weight()->set_value(1);
844 locality_name = locality->mutable_locality();
845 locality_name->set_region("myregion");
846 locality_name->set_zone("myzone");
847 locality_name->set_sub_zone("mysubzone");
848 socket_address = locality->add_lb_endpoints()
849 ->mutable_endpoint()
850 ->mutable_address()
851 ->mutable_socket_address();
852 socket_address->set_address("127.0.0.2");
853 socket_address->set_port_value(443);
854 std::string serialized_resource;
855 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
856 auto* resource_type = XdsEndpointResourceType::Get();
857 auto decode_result =
858 resource_type->Decode(decode_context_, serialized_resource);
859 ASSERT_TRUE(decode_result.name.has_value());
860 EXPECT_EQ(*decode_result.name, "foo");
861 EXPECT_EQ(decode_result.resource.status().code(),
862 absl::StatusCode::kInvalidArgument);
863 EXPECT_EQ(decode_result.resource.status().message(),
864 "errors parsing EDS resource: ["
865 "field:endpoints[1] error:duplicate locality {region=\"myregion\", "
866 "zone=\"myzone\", sub_zone=\"mysubzone\"} found in priority 0]")
867 << decode_result.resource.status();
868 }
869
TEST_F(XdsEndpointTest,SparsePriorityList)870 TEST_F(XdsEndpointTest, SparsePriorityList) {
871 ClusterLoadAssignment cla;
872 cla.set_cluster_name("foo");
873 auto* locality = cla.add_endpoints();
874 locality->mutable_load_balancing_weight()->set_value(1);
875 auto* locality_name = locality->mutable_locality();
876 locality_name->set_region("myregion");
877 locality_name->set_zone("myzone");
878 locality_name->set_sub_zone("mysubzone");
879 auto* socket_address = locality->add_lb_endpoints()
880 ->mutable_endpoint()
881 ->mutable_address()
882 ->mutable_socket_address();
883 socket_address->set_address("127.0.0.1");
884 socket_address->set_port_value(443);
885 locality->set_priority(1);
886 locality = cla.add_endpoints();
887 locality->mutable_load_balancing_weight()->set_value(1);
888 locality_name = locality->mutable_locality();
889 locality_name->set_region("myregion2");
890 locality_name->set_zone("myzone");
891 locality_name->set_sub_zone("mysubzone");
892 socket_address = locality->add_lb_endpoints()
893 ->mutable_endpoint()
894 ->mutable_address()
895 ->mutable_socket_address();
896 socket_address->set_address("127.0.0.2");
897 socket_address->set_port_value(443);
898 locality->set_priority(3);
899 std::string serialized_resource;
900 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
901 auto* resource_type = XdsEndpointResourceType::Get();
902 auto decode_result =
903 resource_type->Decode(decode_context_, serialized_resource);
904 ASSERT_TRUE(decode_result.name.has_value());
905 EXPECT_EQ(*decode_result.name, "foo");
906 EXPECT_EQ(decode_result.resource.status().code(),
907 absl::StatusCode::kInvalidArgument);
908 EXPECT_EQ(decode_result.resource.status().message(),
909 "errors parsing EDS resource: ["
910 "field:endpoints errors:[priority 0 empty; priority 2 empty]]")
911 << decode_result.resource.status();
912 }
913
TEST_F(XdsEndpointTest,LocalityWeightsWithinPriorityExceedUint32Max)914 TEST_F(XdsEndpointTest, LocalityWeightsWithinPriorityExceedUint32Max) {
915 ClusterLoadAssignment cla;
916 cla.set_cluster_name("foo");
917 // First locality has weight of 1.
918 auto* locality = cla.add_endpoints();
919 locality->mutable_load_balancing_weight()->set_value(1);
920 auto* locality_name = locality->mutable_locality();
921 locality_name->set_region("myregion");
922 locality_name->set_zone("myzone");
923 locality_name->set_sub_zone("mysubzone");
924 auto* socket_address = locality->add_lb_endpoints()
925 ->mutable_endpoint()
926 ->mutable_address()
927 ->mutable_socket_address();
928 socket_address->set_address("127.0.0.1");
929 socket_address->set_port_value(443);
930 locality->set_priority(0);
931 // Second locality has weight of uint32 max.
932 locality = cla.add_endpoints();
933 locality->mutable_load_balancing_weight()->set_value(
934 std::numeric_limits<uint32_t>::max());
935 locality_name = locality->mutable_locality();
936 locality_name->set_region("myregion2");
937 locality_name->set_zone("myzone");
938 locality_name->set_sub_zone("mysubzone");
939 socket_address = locality->add_lb_endpoints()
940 ->mutable_endpoint()
941 ->mutable_address()
942 ->mutable_socket_address();
943 socket_address->set_address("127.0.0.2");
944 socket_address->set_port_value(443);
945 locality->set_priority(0);
946 std::string serialized_resource;
947 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
948 auto* resource_type = XdsEndpointResourceType::Get();
949 auto decode_result =
950 resource_type->Decode(decode_context_, serialized_resource);
951 ASSERT_TRUE(decode_result.name.has_value());
952 EXPECT_EQ(*decode_result.name, "foo");
953 EXPECT_EQ(decode_result.resource.status().code(),
954 absl::StatusCode::kInvalidArgument);
955 EXPECT_EQ(decode_result.resource.status().message(),
956 "errors parsing EDS resource: ["
957 "field:endpoints error:sum of locality weights for priority 0 "
958 "exceeds uint32 max]")
959 << decode_result.resource.status();
960 }
961
TEST_F(XdsEndpointTest,DuplicateAddresses)962 TEST_F(XdsEndpointTest, DuplicateAddresses) {
963 ClusterLoadAssignment cla;
964 cla.set_cluster_name("foo");
965 auto* locality = cla.add_endpoints();
966 locality->mutable_load_balancing_weight()->set_value(1);
967 auto* locality_name = locality->mutable_locality();
968 locality_name->set_region("myregion");
969 locality_name->set_zone("myzone");
970 locality_name->set_sub_zone("mysubzone");
971 auto* socket_address = locality->add_lb_endpoints()
972 ->mutable_endpoint()
973 ->mutable_address()
974 ->mutable_socket_address();
975 socket_address->set_address("127.0.0.1");
976 socket_address->set_port_value(443);
977 locality->set_priority(0);
978 locality = cla.add_endpoints();
979 locality->mutable_load_balancing_weight()->set_value(1);
980 locality_name = locality->mutable_locality();
981 locality_name->set_region("myregion2");
982 locality_name->set_zone("myzone");
983 locality_name->set_sub_zone("mysubzone");
984 socket_address = locality->add_lb_endpoints()
985 ->mutable_endpoint()
986 ->mutable_address()
987 ->mutable_socket_address();
988 socket_address->set_address("127.0.0.1");
989 socket_address->set_port_value(443);
990 locality->set_priority(0);
991 std::string serialized_resource;
992 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
993 auto* resource_type = XdsEndpointResourceType::Get();
994 auto decode_result =
995 resource_type->Decode(decode_context_, serialized_resource);
996 ASSERT_TRUE(decode_result.name.has_value());
997 EXPECT_EQ(*decode_result.name, "foo");
998 EXPECT_EQ(decode_result.resource.status().code(),
999 absl::StatusCode::kInvalidArgument);
1000 EXPECT_EQ(decode_result.resource.status().message(),
1001 "errors parsing EDS resource: ["
1002 "field:endpoints[1].lb_endpoints[0] "
1003 "error:duplicate endpoint address \"ipv4:127.0.0.1:443\"]")
1004 << decode_result.resource.status();
1005 }
1006
TEST_F(XdsEndpointTest,DropConfig)1007 TEST_F(XdsEndpointTest, DropConfig) {
1008 ClusterLoadAssignment cla;
1009 cla.set_cluster_name("foo");
1010 auto* locality = cla.add_endpoints();
1011 locality->mutable_load_balancing_weight()->set_value(1);
1012 auto* locality_name = locality->mutable_locality();
1013 locality_name->set_region("myregion");
1014 locality_name->set_zone("myzone");
1015 locality_name->set_sub_zone("mysubzone");
1016 auto* socket_address = locality->add_lb_endpoints()
1017 ->mutable_endpoint()
1018 ->mutable_address()
1019 ->mutable_socket_address();
1020 socket_address->set_address("127.0.0.1");
1021 socket_address->set_port_value(443);
1022 auto* drop_overload = cla.mutable_policy()->add_drop_overloads();
1023 drop_overload->set_category("lb_drop");
1024 drop_overload->mutable_drop_percentage()->set_numerator(50);
1025 drop_overload = cla.mutable_policy()->add_drop_overloads();
1026 drop_overload->set_category("lb_overload");
1027 drop_overload->mutable_drop_percentage()->set_numerator(2500);
1028 drop_overload->mutable_drop_percentage()->set_denominator(
1029 envoy::type::v3::FractionalPercent::TEN_THOUSAND);
1030 drop_overload = cla.mutable_policy()->add_drop_overloads();
1031 drop_overload->set_category("why_not");
1032 drop_overload->mutable_drop_percentage()->set_numerator(750000);
1033 drop_overload->mutable_drop_percentage()->set_denominator(
1034 envoy::type::v3::FractionalPercent::MILLION);
1035 std::string serialized_resource;
1036 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1037 auto* resource_type = XdsEndpointResourceType::Get();
1038 auto decode_result =
1039 resource_type->Decode(decode_context_, serialized_resource);
1040 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
1041 ASSERT_TRUE(decode_result.name.has_value());
1042 EXPECT_EQ(*decode_result.name, "foo");
1043 auto& resource =
1044 static_cast<const XdsEndpointResource&>(**decode_result.resource);
1045 ASSERT_NE(resource.drop_config, nullptr);
1046 const auto& drop_list = resource.drop_config->drop_category_list();
1047 ASSERT_EQ(drop_list.size(), 3);
1048 EXPECT_EQ(drop_list[0].name, "lb_drop");
1049 EXPECT_EQ(drop_list[0].parts_per_million, 500000);
1050 EXPECT_EQ(drop_list[1].name, "lb_overload");
1051 EXPECT_EQ(drop_list[1].parts_per_million, 250000);
1052 EXPECT_EQ(drop_list[2].name, "why_not");
1053 EXPECT_EQ(drop_list[2].parts_per_million, 750000);
1054 }
1055
TEST_F(XdsEndpointTest,CapsDropPercentageAt100)1056 TEST_F(XdsEndpointTest, CapsDropPercentageAt100) {
1057 ClusterLoadAssignment cla;
1058 cla.set_cluster_name("foo");
1059 auto* locality = cla.add_endpoints();
1060 locality->mutable_load_balancing_weight()->set_value(1);
1061 auto* locality_name = locality->mutable_locality();
1062 locality_name->set_region("myregion");
1063 locality_name->set_zone("myzone");
1064 locality_name->set_sub_zone("mysubzone");
1065 auto* socket_address = locality->add_lb_endpoints()
1066 ->mutable_endpoint()
1067 ->mutable_address()
1068 ->mutable_socket_address();
1069 socket_address->set_address("127.0.0.1");
1070 socket_address->set_port_value(443);
1071 auto* drop_overload = cla.mutable_policy()->add_drop_overloads();
1072 drop_overload->set_category("lb_drop");
1073 drop_overload->mutable_drop_percentage()->set_numerator(10000001);
1074 std::string serialized_resource;
1075 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1076 auto* resource_type = XdsEndpointResourceType::Get();
1077 auto decode_result =
1078 resource_type->Decode(decode_context_, serialized_resource);
1079 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
1080 ASSERT_TRUE(decode_result.name.has_value());
1081 EXPECT_EQ(*decode_result.name, "foo");
1082 auto& resource =
1083 static_cast<const XdsEndpointResource&>(**decode_result.resource);
1084 ASSERT_NE(resource.drop_config, nullptr);
1085 const auto& drop_list = resource.drop_config->drop_category_list();
1086 ASSERT_EQ(drop_list.size(), 1);
1087 EXPECT_EQ(drop_list[0].name, "lb_drop");
1088 EXPECT_EQ(drop_list[0].parts_per_million, 1000000);
1089 EXPECT_TRUE(resource.drop_config->drop_all());
1090 }
1091
TEST_F(XdsEndpointTest,MissingDropCategoryName)1092 TEST_F(XdsEndpointTest, MissingDropCategoryName) {
1093 ClusterLoadAssignment cla;
1094 cla.set_cluster_name("foo");
1095 auto* locality = cla.add_endpoints();
1096 locality->mutable_load_balancing_weight()->set_value(1);
1097 auto* locality_name = locality->mutable_locality();
1098 locality_name->set_region("myregion");
1099 locality_name->set_zone("myzone");
1100 locality_name->set_sub_zone("mysubzone");
1101 auto* socket_address = locality->add_lb_endpoints()
1102 ->mutable_endpoint()
1103 ->mutable_address()
1104 ->mutable_socket_address();
1105 socket_address->set_address("127.0.0.1");
1106 socket_address->set_port_value(443);
1107 auto* drop_overload = cla.mutable_policy()->add_drop_overloads();
1108 drop_overload->mutable_drop_percentage()->set_numerator(50);
1109 std::string serialized_resource;
1110 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1111 auto* resource_type = XdsEndpointResourceType::Get();
1112 auto decode_result =
1113 resource_type->Decode(decode_context_, serialized_resource);
1114 ASSERT_TRUE(decode_result.name.has_value());
1115 EXPECT_EQ(*decode_result.name, "foo");
1116 EXPECT_EQ(decode_result.resource.status().code(),
1117 absl::StatusCode::kInvalidArgument);
1118 EXPECT_EQ(decode_result.resource.status().message(),
1119 "errors parsing EDS resource: ["
1120 "field:policy.drop_overloads[0].category "
1121 "error:empty drop category name]")
1122 << decode_result.resource.status();
1123 }
1124
TEST_F(XdsEndpointTest,MissingDropPercentage)1125 TEST_F(XdsEndpointTest, MissingDropPercentage) {
1126 ClusterLoadAssignment cla;
1127 cla.set_cluster_name("foo");
1128 auto* locality = cla.add_endpoints();
1129 locality->mutable_load_balancing_weight()->set_value(1);
1130 auto* locality_name = locality->mutable_locality();
1131 locality_name->set_region("myregion");
1132 locality_name->set_zone("myzone");
1133 locality_name->set_sub_zone("mysubzone");
1134 auto* socket_address = locality->add_lb_endpoints()
1135 ->mutable_endpoint()
1136 ->mutable_address()
1137 ->mutable_socket_address();
1138 socket_address->set_address("127.0.0.1");
1139 socket_address->set_port_value(443);
1140 auto* drop_overload = cla.mutable_policy()->add_drop_overloads();
1141 drop_overload->set_category("lb_drop");
1142 std::string serialized_resource;
1143 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1144 auto* resource_type = XdsEndpointResourceType::Get();
1145 auto decode_result =
1146 resource_type->Decode(decode_context_, serialized_resource);
1147 ASSERT_TRUE(decode_result.name.has_value());
1148 EXPECT_EQ(*decode_result.name, "foo");
1149 EXPECT_EQ(decode_result.resource.status().code(),
1150 absl::StatusCode::kInvalidArgument);
1151 EXPECT_EQ(decode_result.resource.status().message(),
1152 "errors parsing EDS resource: ["
1153 "field:policy.drop_overloads[0].drop_percentage "
1154 "error:field not present]")
1155 << decode_result.resource.status();
1156 }
1157
TEST_F(XdsEndpointTest,DropPercentageInvalidDenominator)1158 TEST_F(XdsEndpointTest, DropPercentageInvalidDenominator) {
1159 ClusterLoadAssignment cla;
1160 cla.set_cluster_name("foo");
1161 auto* locality = cla.add_endpoints();
1162 locality->mutable_load_balancing_weight()->set_value(1);
1163 auto* locality_name = locality->mutable_locality();
1164 locality_name->set_region("myregion");
1165 locality_name->set_zone("myzone");
1166 locality_name->set_sub_zone("mysubzone");
1167 auto* socket_address = locality->add_lb_endpoints()
1168 ->mutable_endpoint()
1169 ->mutable_address()
1170 ->mutable_socket_address();
1171 socket_address->set_address("127.0.0.1");
1172 socket_address->set_port_value(443);
1173 auto* drop_overload = cla.mutable_policy()->add_drop_overloads();
1174 drop_overload->set_category("lb_drop");
1175 drop_overload->mutable_drop_percentage()->set_numerator(750000);
1176 drop_overload->mutable_drop_percentage()->set_denominator(
1177 static_cast<envoy::type::v3::FractionalPercent_DenominatorType>(100));
1178 std::string serialized_resource;
1179 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1180 auto* resource_type = XdsEndpointResourceType::Get();
1181 auto decode_result =
1182 resource_type->Decode(decode_context_, serialized_resource);
1183 ASSERT_TRUE(decode_result.name.has_value());
1184 EXPECT_EQ(*decode_result.name, "foo");
1185 EXPECT_EQ(decode_result.resource.status().code(),
1186 absl::StatusCode::kInvalidArgument);
1187 EXPECT_EQ(decode_result.resource.status().message(),
1188 "errors parsing EDS resource: ["
1189 "field:policy.drop_overloads[0].drop_percentage.denominator "
1190 "error:unknown denominator type]")
1191 << decode_result.resource.status();
1192 }
1193
TEST_F(XdsEndpointTest,EndpointHealthStatus)1194 TEST_F(XdsEndpointTest, EndpointHealthStatus) {
1195 ClusterLoadAssignment cla;
1196 cla.set_cluster_name("foo");
1197 auto* locality = cla.add_endpoints();
1198 locality->mutable_load_balancing_weight()->set_value(1);
1199 auto* locality_name = locality->mutable_locality();
1200 locality_name->set_region("myregion");
1201 locality_name->set_zone("myzone");
1202 locality_name->set_sub_zone("mysubzone");
1203 auto* endpoint = locality->add_lb_endpoints();
1204 auto* socket_address =
1205 endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
1206 socket_address->set_address("127.0.0.1");
1207 socket_address->set_port_value(443);
1208 endpoint = locality->add_lb_endpoints();
1209 endpoint->set_health_status(envoy::config::core::v3::HealthStatus::DRAINING);
1210 socket_address =
1211 endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
1212 socket_address->set_address("127.0.0.2");
1213 socket_address->set_port_value(443);
1214 endpoint = locality->add_lb_endpoints();
1215 endpoint->set_health_status(envoy::config::core::v3::HealthStatus::UNHEALTHY);
1216 socket_address =
1217 endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
1218 socket_address->set_address("127.0.0.3");
1219 socket_address->set_port_value(443);
1220 std::string serialized_resource;
1221 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1222 auto* resource_type = XdsEndpointResourceType::Get();
1223 auto decode_result =
1224 resource_type->Decode(decode_context_, serialized_resource);
1225 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
1226 ASSERT_TRUE(decode_result.name.has_value());
1227 EXPECT_EQ(*decode_result.name, "foo");
1228 auto& resource =
1229 static_cast<const XdsEndpointResource&>(**decode_result.resource);
1230 ASSERT_EQ(resource.priorities.size(), 1);
1231 const auto& priority = resource.priorities[0];
1232 ASSERT_EQ(priority.localities.size(), 1);
1233 const auto& p = *priority.localities.begin();
1234 ASSERT_EQ(p.first, p.second.name.get());
1235 EXPECT_EQ(p.first->region(), "myregion");
1236 EXPECT_EQ(p.first->zone(), "myzone");
1237 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
1238 EXPECT_EQ(p.second.lb_weight, 1);
1239 ASSERT_EQ(p.second.endpoints.size(), 2);
1240 const auto* address = &p.second.endpoints[0];
1241 auto addr = grpc_sockaddr_to_string(&address->address(), /*normalize=*/false);
1242 ASSERT_TRUE(addr.ok()) << addr.status();
1243 EXPECT_EQ(*addr, "127.0.0.1:443");
1244 EXPECT_EQ(address->args().GetInt(GRPC_ARG_XDS_HEALTH_STATUS),
1245 XdsHealthStatus::kUnknown);
1246 address = &p.second.endpoints[1];
1247 addr = grpc_sockaddr_to_string(&address->address(), /*normalize=*/false);
1248 ASSERT_TRUE(addr.ok()) << addr.status();
1249 EXPECT_EQ(*addr, "127.0.0.2:443");
1250 EXPECT_EQ(address->args().GetInt(GRPC_ARG_XDS_HEALTH_STATUS),
1251 XdsHealthStatus::kDraining);
1252 }
1253
TEST_F(XdsEndpointTest,HttpProxyInEndpoint)1254 TEST_F(XdsEndpointTest, HttpProxyInEndpoint) {
1255 testing::ScopedExperimentalEnvVar env("GRPC_EXPERIMENTAL_XDS_HTTP_CONNECT");
1256 ClusterLoadAssignment cla;
1257 cla.set_cluster_name("foo");
1258 auto* locality = cla.add_endpoints();
1259 locality->mutable_load_balancing_weight()->set_value(1);
1260 auto* locality_name = locality->mutable_locality();
1261 locality_name->set_region("myregion");
1262 locality_name->set_zone("myzone");
1263 locality_name->set_sub_zone("mysubzone");
1264 auto* lb_endpoint = locality->add_lb_endpoints();
1265 envoy::config::core::v3::Address address_proto;
1266 auto* socket_address = address_proto.mutable_socket_address();
1267 socket_address->set_address("1.2.3.4");
1268 socket_address->set_port_value(123);
1269 auto& typed_metadata_map =
1270 *lb_endpoint->mutable_metadata()->mutable_typed_filter_metadata();
1271 typed_metadata_map["envoy.http11_proxy_transport_socket.proxy_address"]
1272 .PackFrom(address_proto);
1273 socket_address = lb_endpoint->mutable_endpoint()
1274 ->mutable_address()
1275 ->mutable_socket_address();
1276 socket_address->set_address("127.0.0.1");
1277 socket_address->set_port_value(443);
1278 std::string serialized_resource;
1279 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1280 auto* resource_type = XdsEndpointResourceType::Get();
1281 auto decode_result =
1282 resource_type->Decode(decode_context_, serialized_resource);
1283 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
1284 ASSERT_TRUE(decode_result.name.has_value());
1285 EXPECT_EQ(*decode_result.name, "foo");
1286 auto& resource =
1287 static_cast<const XdsEndpointResource&>(**decode_result.resource);
1288 ASSERT_EQ(resource.priorities.size(), 1);
1289 const auto& priority = resource.priorities[0];
1290 ASSERT_EQ(priority.localities.size(), 1);
1291 const auto& p = *priority.localities.begin();
1292 ASSERT_EQ(p.first, p.second.name.get());
1293 EXPECT_EQ(p.first->region(), "myregion");
1294 EXPECT_EQ(p.first->zone(), "myzone");
1295 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
1296 EXPECT_EQ(p.second.lb_weight, 1);
1297 ASSERT_EQ(p.second.endpoints.size(), 1);
1298 const auto& address = p.second.endpoints.front();
1299 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
1300 ASSERT_TRUE(addr.ok()) << addr.status();
1301 EXPECT_EQ(*addr, "127.0.0.1:443");
1302 EXPECT_EQ(address.args(), ChannelArgs()
1303 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
1304 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
1305 XdsHealthStatus::HealthStatus::kUnknown)
1306 .Set(GRPC_ARG_XDS_HTTP_PROXY, "1.2.3.4:123"));
1307 EXPECT_EQ(resource.drop_config, nullptr);
1308 }
1309
TEST_F(XdsEndpointTest,HttpProxyInLocality)1310 TEST_F(XdsEndpointTest, HttpProxyInLocality) {
1311 testing::ScopedExperimentalEnvVar env("GRPC_EXPERIMENTAL_XDS_HTTP_CONNECT");
1312 ClusterLoadAssignment cla;
1313 cla.set_cluster_name("foo");
1314 auto* locality = cla.add_endpoints();
1315 envoy::config::core::v3::Address address_proto;
1316 auto* socket_address = address_proto.mutable_socket_address();
1317 socket_address->set_address("1.2.3.4");
1318 socket_address->set_port_value(123);
1319 auto& typed_metadata_map =
1320 *locality->mutable_metadata()->mutable_typed_filter_metadata();
1321 typed_metadata_map["envoy.http11_proxy_transport_socket.proxy_address"]
1322 .PackFrom(address_proto);
1323 locality->mutable_load_balancing_weight()->set_value(1);
1324 auto* locality_name = locality->mutable_locality();
1325 locality_name->set_region("myregion");
1326 locality_name->set_zone("myzone");
1327 locality_name->set_sub_zone("mysubzone");
1328 auto* lb_endpoint = locality->add_lb_endpoints();
1329 socket_address = lb_endpoint->mutable_endpoint()
1330 ->mutable_address()
1331 ->mutable_socket_address();
1332 socket_address->set_address("127.0.0.1");
1333 socket_address->set_port_value(443);
1334 std::string serialized_resource;
1335 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1336 auto* resource_type = XdsEndpointResourceType::Get();
1337 auto decode_result =
1338 resource_type->Decode(decode_context_, serialized_resource);
1339 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
1340 ASSERT_TRUE(decode_result.name.has_value());
1341 EXPECT_EQ(*decode_result.name, "foo");
1342 auto& resource =
1343 static_cast<const XdsEndpointResource&>(**decode_result.resource);
1344 ASSERT_EQ(resource.priorities.size(), 1);
1345 const auto& priority = resource.priorities[0];
1346 ASSERT_EQ(priority.localities.size(), 1);
1347 const auto& p = *priority.localities.begin();
1348 ASSERT_EQ(p.first, p.second.name.get());
1349 EXPECT_EQ(p.first->region(), "myregion");
1350 EXPECT_EQ(p.first->zone(), "myzone");
1351 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
1352 EXPECT_EQ(p.second.lb_weight, 1);
1353 ASSERT_EQ(p.second.endpoints.size(), 1);
1354 const auto& address = p.second.endpoints.front();
1355 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
1356 ASSERT_TRUE(addr.ok()) << addr.status();
1357 EXPECT_EQ(*addr, "127.0.0.1:443");
1358 EXPECT_EQ(address.args(), ChannelArgs()
1359 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
1360 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
1361 XdsHealthStatus::HealthStatus::kUnknown)
1362 .Set(GRPC_ARG_XDS_HTTP_PROXY, "1.2.3.4:123"));
1363 EXPECT_EQ(resource.drop_config, nullptr);
1364 }
1365
TEST_F(XdsEndpointTest,HttpProxyEndpointSupercedesLocality)1366 TEST_F(XdsEndpointTest, HttpProxyEndpointSupercedesLocality) {
1367 testing::ScopedExperimentalEnvVar env("GRPC_EXPERIMENTAL_XDS_HTTP_CONNECT");
1368 ClusterLoadAssignment cla;
1369 cla.set_cluster_name("foo");
1370 auto* locality = cla.add_endpoints();
1371 envoy::config::core::v3::Address address_proto;
1372 auto* socket_address = address_proto.mutable_socket_address();
1373 socket_address->set_address("1.2.3.4");
1374 socket_address->set_port_value(123);
1375 auto& typed_metadata_map =
1376 *locality->mutable_metadata()->mutable_typed_filter_metadata();
1377 typed_metadata_map["envoy.http11_proxy_transport_socket.proxy_address"]
1378 .PackFrom(address_proto);
1379 locality->mutable_load_balancing_weight()->set_value(1);
1380 auto* locality_name = locality->mutable_locality();
1381 locality_name->set_region("myregion");
1382 locality_name->set_zone("myzone");
1383 locality_name->set_sub_zone("mysubzone");
1384 auto* lb_endpoint = locality->add_lb_endpoints();
1385 socket_address->set_address("4.5.6.7");
1386 socket_address->set_port_value(456);
1387 auto& endpoint_typed_metadata_map =
1388 *lb_endpoint->mutable_metadata()->mutable_typed_filter_metadata();
1389 endpoint_typed_metadata_map
1390 ["envoy.http11_proxy_transport_socket.proxy_address"]
1391 .PackFrom(address_proto);
1392 socket_address = lb_endpoint->mutable_endpoint()
1393 ->mutable_address()
1394 ->mutable_socket_address();
1395 socket_address->set_address("127.0.0.1");
1396 socket_address->set_port_value(443);
1397 std::string serialized_resource;
1398 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1399 auto* resource_type = XdsEndpointResourceType::Get();
1400 auto decode_result =
1401 resource_type->Decode(decode_context_, serialized_resource);
1402 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
1403 ASSERT_TRUE(decode_result.name.has_value());
1404 EXPECT_EQ(*decode_result.name, "foo");
1405 auto& resource =
1406 static_cast<const XdsEndpointResource&>(**decode_result.resource);
1407 ASSERT_EQ(resource.priorities.size(), 1);
1408 const auto& priority = resource.priorities[0];
1409 ASSERT_EQ(priority.localities.size(), 1);
1410 const auto& p = *priority.localities.begin();
1411 ASSERT_EQ(p.first, p.second.name.get());
1412 EXPECT_EQ(p.first->region(), "myregion");
1413 EXPECT_EQ(p.first->zone(), "myzone");
1414 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
1415 EXPECT_EQ(p.second.lb_weight, 1);
1416 ASSERT_EQ(p.second.endpoints.size(), 1);
1417 const auto& address = p.second.endpoints.front();
1418 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
1419 ASSERT_TRUE(addr.ok()) << addr.status();
1420 EXPECT_EQ(*addr, "127.0.0.1:443");
1421 EXPECT_EQ(address.args(), ChannelArgs()
1422 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
1423 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
1424 XdsHealthStatus::HealthStatus::kUnknown)
1425 .Set(GRPC_ARG_XDS_HTTP_PROXY, "4.5.6.7:456"));
1426 EXPECT_EQ(resource.drop_config, nullptr);
1427 }
1428
TEST_F(XdsEndpointTest,HttpProxyIgnoredIfNotEnabled)1429 TEST_F(XdsEndpointTest, HttpProxyIgnoredIfNotEnabled) {
1430 ClusterLoadAssignment cla;
1431 cla.set_cluster_name("foo");
1432 auto* locality = cla.add_endpoints();
1433 envoy::config::core::v3::Address address_proto;
1434 auto* socket_address = address_proto.mutable_socket_address();
1435 socket_address->set_address("1.2.3.4");
1436 socket_address->set_port_value(123);
1437 auto& typed_metadata_map =
1438 *locality->mutable_metadata()->mutable_typed_filter_metadata();
1439 typed_metadata_map["envoy.http11_proxy_transport_socket.proxy_address"]
1440 .PackFrom(address_proto);
1441 locality->mutable_load_balancing_weight()->set_value(1);
1442 auto* locality_name = locality->mutable_locality();
1443 locality_name->set_region("myregion");
1444 locality_name->set_zone("myzone");
1445 locality_name->set_sub_zone("mysubzone");
1446 auto* lb_endpoint = locality->add_lb_endpoints();
1447 socket_address->set_address("4.5.6.7");
1448 socket_address->set_port_value(456);
1449 auto& endpoint_typed_metadata_map =
1450 *lb_endpoint->mutable_metadata()->mutable_typed_filter_metadata();
1451 endpoint_typed_metadata_map
1452 ["envoy.http11_proxy_transport_socket.proxy_address"]
1453 .PackFrom(address_proto);
1454 socket_address = lb_endpoint->mutable_endpoint()
1455 ->mutable_address()
1456 ->mutable_socket_address();
1457 socket_address->set_address("127.0.0.1");
1458 socket_address->set_port_value(443);
1459 std::string serialized_resource;
1460 ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
1461 auto* resource_type = XdsEndpointResourceType::Get();
1462 auto decode_result =
1463 resource_type->Decode(decode_context_, serialized_resource);
1464 ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
1465 ASSERT_TRUE(decode_result.name.has_value());
1466 EXPECT_EQ(*decode_result.name, "foo");
1467 auto& resource =
1468 static_cast<const XdsEndpointResource&>(**decode_result.resource);
1469 ASSERT_EQ(resource.priorities.size(), 1);
1470 const auto& priority = resource.priorities[0];
1471 ASSERT_EQ(priority.localities.size(), 1);
1472 const auto& p = *priority.localities.begin();
1473 ASSERT_EQ(p.first, p.second.name.get());
1474 EXPECT_EQ(p.first->region(), "myregion");
1475 EXPECT_EQ(p.first->zone(), "myzone");
1476 EXPECT_EQ(p.first->sub_zone(), "mysubzone");
1477 EXPECT_EQ(p.second.lb_weight, 1);
1478 ASSERT_EQ(p.second.endpoints.size(), 1);
1479 const auto& address = p.second.endpoints.front();
1480 auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
1481 ASSERT_TRUE(addr.ok()) << addr.status();
1482 EXPECT_EQ(*addr, "127.0.0.1:443");
1483 EXPECT_EQ(address.args(), ChannelArgs()
1484 .Set(GRPC_ARG_ADDRESS_WEIGHT, 1)
1485 .Set(GRPC_ARG_XDS_HEALTH_STATUS,
1486 XdsHealthStatus::HealthStatus::kUnknown));
1487 EXPECT_EQ(resource.drop_config, nullptr);
1488 }
1489
1490 } // namespace
1491 } // namespace testing
1492 } // namespace grpc_core
1493
main(int argc,char ** argv)1494 int main(int argc, char** argv) {
1495 ::testing::InitGoogleTest(&argc, argv);
1496 grpc::testing::TestEnvironment env(&argc, argv);
1497 grpc_init();
1498 int ret = RUN_ALL_TESTS();
1499 grpc_shutdown();
1500 return ret;
1501 }
1502