1 //
2 //
3 // Copyright 2017 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18
19 #include <errno.h>
20 #include <fcntl.h>
21 #include <gmock/gmock.h>
22 #include <grpc/grpc.h>
23 #include <grpc/impl/grpc_types.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/port_platform.h>
26 #include <grpc/support/sync.h>
27 #include <grpc/support/time.h>
28 #include <string.h>
29
30 #include <string>
31 #include <thread>
32 #include <vector>
33
34 #include "absl/flags/flag.h"
35 #include "absl/log/check.h"
36 #include "absl/log/log.h"
37 #include "absl/memory/memory.h"
38 #include "absl/strings/str_cat.h"
39 #include "absl/strings/str_format.h"
40 #include "src/core/client_channel/client_channel_filter.h"
41 #include "src/core/config/core_configuration.h"
42 #include "src/core/lib/address_utils/parse_address.h"
43 #include "src/core/lib/address_utils/sockaddr_utils.h"
44 #include "src/core/lib/channel/channel_args.h"
45 #include "src/core/lib/event_engine/ares_resolver.h"
46 #include "src/core/lib/event_engine/default_event_engine.h"
47 #include "src/core/lib/experiments/experiments.h"
48 #include "src/core/lib/iomgr/executor.h"
49 #include "src/core/lib/iomgr/iomgr.h"
50 #include "src/core/lib/iomgr/resolve_address.h"
51 #include "src/core/lib/iomgr/socket_utils.h"
52 #include "src/core/load_balancing/grpclb/grpclb_balancer_addresses.h"
53 #include "src/core/resolver/dns/c_ares/grpc_ares_wrapper.h"
54 #include "src/core/resolver/endpoint_addresses.h"
55 #include "src/core/resolver/resolver.h"
56 #include "src/core/resolver/resolver_registry.h"
57 #include "src/core/util/crash.h"
58 #include "src/core/util/host_port.h"
59 #include "src/core/util/orphanable.h"
60 #include "src/core/util/string.h"
61 #include "src/core/util/work_serializer.h"
62 #include "test/core/test_util/fake_udp_and_tcp_server.h"
63 #include "test/core/test_util/port.h"
64 #include "test/core/test_util/socket_use_after_close_detector.h"
65 #include "test/core/test_util/test_config.h"
66 #include "test/cpp/util/subprocess.h"
67 #include "test/cpp/util/test_config.h"
68
69 using ::grpc_event_engine::experimental::GetDefaultEventEngine;
70 using std::vector;
71 using testing::UnorderedElementsAreArray;
72
73 ABSL_FLAG(std::string, target_name, "", "Target name to resolve.");
74 ABSL_FLAG(std::string, do_ordered_address_comparison, "",
75 "Whether or not to compare resolved addresses to expected "
76 "addresses using an ordered comparison. This is useful for "
77 "testing certain behaviors that involve sorting of resolved "
78 "addresses. Note it would be better if this argument was a "
79 "bool flag, but it's a string for ease of invocation from "
80 "the generated python test runner.");
81 ABSL_FLAG(std::string, expected_addrs, "",
82 "List of expected backend or balancer addresses in the form "
83 "'<ip0:port0>,<is_balancer0>;<ip1:port1>,<is_balancer1>;...'. "
84 "'is_balancer' should be bool, i.e. true or false.");
85 ABSL_FLAG(std::string, expected_chosen_service_config, "",
86 "Expected service config json string that gets chosen (no "
87 "whitespace). Empty for none.");
88 ABSL_FLAG(std::string, expected_service_config_error, "",
89 "Expected service config error. Empty for none.");
90 ABSL_FLAG(std::string, local_dns_server_address, "",
91 "Optional. This address is placed as the uri authority if present.");
92 // TODO(Capstan): Is this worth making `bool` now with Abseil flags?
93 ABSL_FLAG(
94 std::string, enable_srv_queries, "",
95 "Whether or not to enable SRV queries for the ares resolver instance."
96 "It would be better if this arg could be bool, but the way that we "
97 "generate "
98 "the python script runner doesn't allow us to pass a gflags bool to this "
99 "binary.");
100 // TODO(Capstan): Is this worth making `bool` now with Abseil flags?
101 ABSL_FLAG(
102 std::string, enable_txt_queries, "",
103 "Whether or not to enable TXT queries for the ares resolver instance."
104 "It would be better if this arg could be bool, but the way that we "
105 "generate "
106 "the python script runner doesn't allow us to pass a gflags bool to this "
107 "binary.");
108 // TODO(Capstan): Is this worth making `bool` now with Abseil flags?
109 ABSL_FLAG(
110 std::string, inject_broken_nameserver_list, "",
111 "Whether or not to configure c-ares to use a broken nameserver list, in "
112 "which "
113 "the first nameserver in the list is non-responsive, but the second one "
114 "works, i.e "
115 "serves the expected DNS records; using for testing such a real scenario."
116 "It would be better if this arg could be bool, but the way that we "
117 "generate "
118 "the python script runner doesn't allow us to pass a gflags bool to this "
119 "binary.");
120 ABSL_FLAG(std::string, expected_lb_policy, "",
121 "Expected lb policy name that appears in resolver result channel "
122 "arg. Empty for none.");
123
124 namespace {
125
126 class GrpcLBAddress final {
127 public:
GrpcLBAddress(std::string address,bool is_balancer)128 GrpcLBAddress(std::string address, bool is_balancer)
129 : is_balancer(is_balancer), address(std::move(address)) {}
130
operator ==(const GrpcLBAddress & other) const131 bool operator==(const GrpcLBAddress& other) const {
132 return this->is_balancer == other.is_balancer &&
133 this->address == other.address;
134 }
135
operator !=(const GrpcLBAddress & other) const136 bool operator!=(const GrpcLBAddress& other) const {
137 return !(*this == other);
138 }
139
140 bool is_balancer;
141 std::string address;
142 };
143
ParseExpectedAddrs(std::string expected_addrs)144 vector<GrpcLBAddress> ParseExpectedAddrs(std::string expected_addrs) {
145 std::vector<GrpcLBAddress> out;
146 while (!expected_addrs.empty()) {
147 // get the next <ip>,<port> (v4 or v6)
148 size_t next_comma = expected_addrs.find(',');
149 if (next_comma == std::string::npos) {
150 grpc_core::Crash(absl::StrFormat(
151 "Missing ','. Expected_addrs arg should be a semicolon-separated "
152 "list of <ip-port>,<bool> pairs. Left-to-be-parsed arg is |%s|",
153 expected_addrs.c_str()));
154 }
155 std::string next_addr = expected_addrs.substr(0, next_comma);
156 expected_addrs = expected_addrs.substr(next_comma + 1, std::string::npos);
157 // get the next is_balancer 'bool' associated with this address
158 size_t next_semicolon = expected_addrs.find(';');
159 bool is_balancer = false;
160 gpr_parse_bool_value(expected_addrs.substr(0, next_semicolon).c_str(),
161 &is_balancer);
162 out.emplace_back(GrpcLBAddress(next_addr, is_balancer));
163 if (next_semicolon == std::string::npos) {
164 break;
165 }
166 expected_addrs =
167 expected_addrs.substr(next_semicolon + 1, std::string::npos);
168 }
169 if (out.empty()) {
170 grpc_core::Crash(
171 "expected_addrs arg should be a semicolon-separated list of "
172 "<ip-port>,<bool> pairs");
173 }
174 return out;
175 }
176
TestDeadline(void)177 gpr_timespec TestDeadline(void) {
178 return grpc_timeout_seconds_to_deadline(100);
179 }
180
181 struct ArgsStruct {
182 gpr_event ev;
183 gpr_mu* mu;
184 bool done; // guarded by mu
185 grpc_pollset* pollset; // guarded by mu
186 grpc_pollset_set* pollset_set;
187 std::shared_ptr<grpc_core::WorkSerializer> lock;
188 grpc_channel_args* channel_args;
189 vector<GrpcLBAddress> expected_addrs;
190 std::string expected_service_config_string;
191 std::string expected_service_config_error;
192 std::string expected_lb_policy;
193 };
194
ArgsInit(ArgsStruct * args)195 void ArgsInit(ArgsStruct* args) {
196 gpr_event_init(&args->ev);
197 args->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
198 grpc_pollset_init(args->pollset, &args->mu);
199 args->pollset_set = grpc_pollset_set_create();
200 grpc_pollset_set_add_pollset(args->pollset_set, args->pollset);
201 args->lock = std::make_shared<grpc_core::WorkSerializer>(
202 grpc_event_engine::experimental::GetDefaultEventEngine());
203 args->done = false;
204 args->channel_args = nullptr;
205 }
206
DoNothing(void *,grpc_error_handle)207 void DoNothing(void* /*arg*/, grpc_error_handle /*error*/) {}
208
ArgsFinish(ArgsStruct * args)209 void ArgsFinish(ArgsStruct* args) {
210 CHECK(gpr_event_wait(&args->ev, TestDeadline()));
211 grpc_pollset_set_del_pollset(args->pollset_set, args->pollset);
212 grpc_pollset_set_destroy(args->pollset_set);
213 grpc_closure DoNothing_cb;
214 GRPC_CLOSURE_INIT(&DoNothing_cb, DoNothing, nullptr,
215 grpc_schedule_on_exec_ctx);
216 grpc_pollset_shutdown(args->pollset, &DoNothing_cb);
217 // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
218 grpc_channel_args_destroy(args->channel_args);
219 grpc_core::ExecCtx::Get()->Flush();
220 grpc_pollset_destroy(args->pollset);
221 gpr_free(args->pollset);
222 }
223
NSecondDeadline(int seconds)224 gpr_timespec NSecondDeadline(int seconds) {
225 return gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
226 gpr_time_from_seconds(seconds, GPR_TIMESPAN));
227 }
228
PollPollsetUntilRequestDone(ArgsStruct * args)229 void PollPollsetUntilRequestDone(ArgsStruct* args) {
230 // Use a 20-second timeout to give room for the tests that involve
231 // a non-responsive name server (c-ares uses a ~5 second query timeout
232 // for that server before succeeding with the healthy one).
233 gpr_timespec deadline = NSecondDeadline(20);
234 while (true) {
235 grpc_core::MutexLockForGprMu lock(args->mu);
236 if (args->done) {
237 break;
238 }
239 gpr_timespec time_left =
240 gpr_time_sub(deadline, gpr_now(GPR_CLOCK_REALTIME));
241 VLOG(2) << "done=" << args->done << ", time_left=" << time_left.tv_sec
242 << "." << absl::StrFormat("%09d", time_left.tv_nsec);
243 CHECK_GE(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)), 0);
244 grpc_pollset_worker* worker = nullptr;
245 grpc_core::ExecCtx exec_ctx;
246 if (grpc_core::IsEventEngineDnsEnabled()) {
247 // This essentially becomes a condition variable.
248 GRPC_LOG_IF_ERROR(
249 "pollset_work",
250 grpc_pollset_work(
251 args->pollset, &worker,
252 grpc_core::Timestamp::FromTimespecRoundUp(deadline)));
253 } else {
254 GRPC_LOG_IF_ERROR(
255 "pollset_work",
256 grpc_pollset_work(
257 args->pollset, &worker,
258 grpc_core::Timestamp::FromTimespecRoundUp(NSecondDeadline(1))));
259 }
260 }
261 gpr_event_set(&args->ev, reinterpret_cast<void*>(1));
262 }
263
CheckServiceConfigResultLocked(const char * service_config_json,absl::Status service_config_error,ArgsStruct * args)264 void CheckServiceConfigResultLocked(const char* service_config_json,
265 absl::Status service_config_error,
266 ArgsStruct* args) {
267 if (!args->expected_service_config_string.empty()) {
268 ASSERT_NE(service_config_json, nullptr);
269 EXPECT_EQ(service_config_json, args->expected_service_config_string);
270 }
271 if (args->expected_service_config_error.empty()) {
272 EXPECT_TRUE(service_config_error.ok())
273 << "Actual error: " << service_config_error.ToString();
274 } else {
275 EXPECT_THAT(service_config_error.ToString(),
276 testing::HasSubstr(args->expected_service_config_error));
277 }
278 }
279
CheckLBPolicyResultLocked(const grpc_core::ChannelArgs channel_args,ArgsStruct * args)280 void CheckLBPolicyResultLocked(const grpc_core::ChannelArgs channel_args,
281 ArgsStruct* args) {
282 absl::optional<absl::string_view> lb_policy_arg =
283 channel_args.GetString(GRPC_ARG_LB_POLICY_NAME);
284 if (!args->expected_lb_policy.empty()) {
285 EXPECT_TRUE(lb_policy_arg.has_value());
286 EXPECT_EQ(*lb_policy_arg, args->expected_lb_policy);
287 } else {
288 EXPECT_FALSE(lb_policy_arg.has_value());
289 }
290 }
291
292 class ResultHandler : public grpc_core::Resolver::ResultHandler {
293 public:
Create(ArgsStruct * args)294 static std::unique_ptr<grpc_core::Resolver::ResultHandler> Create(
295 ArgsStruct* args) {
296 return std::unique_ptr<grpc_core::Resolver::ResultHandler>(
297 new ResultHandler(args));
298 }
299
ResultHandler(ArgsStruct * args)300 explicit ResultHandler(ArgsStruct* args) : args_(args) {}
301
ReportResult(grpc_core::Resolver::Result result)302 void ReportResult(grpc_core::Resolver::Result result) override {
303 CheckResult(result);
304 grpc_core::MutexLockForGprMu lock(args_->mu);
305 CHECK(!args_->done);
306 args_->done = true;
307 GRPC_LOG_IF_ERROR("pollset_kick",
308 grpc_pollset_kick(args_->pollset, nullptr));
309 }
310
CheckResult(const grpc_core::Resolver::Result &)311 virtual void CheckResult(const grpc_core::Resolver::Result& /*result*/) {}
312
313 protected:
args_struct() const314 ArgsStruct* args_struct() const { return args_; }
315
316 private:
317 ArgsStruct* args_;
318 };
319
320 class CheckingResultHandler : public ResultHandler {
321 public:
Create(ArgsStruct * args)322 static std::unique_ptr<grpc_core::Resolver::ResultHandler> Create(
323 ArgsStruct* args) {
324 return std::unique_ptr<grpc_core::Resolver::ResultHandler>(
325 new CheckingResultHandler(args));
326 }
327
CheckingResultHandler(ArgsStruct * args)328 explicit CheckingResultHandler(ArgsStruct* args) : ResultHandler(args) {}
329
CheckResult(const grpc_core::Resolver::Result & result)330 void CheckResult(const grpc_core::Resolver::Result& result) override {
331 ASSERT_TRUE(result.addresses.ok()) << result.addresses.status().ToString();
332 ArgsStruct* args = args_struct();
333 std::vector<GrpcLBAddress> found_lb_addrs;
334 AddActualAddresses(*result.addresses, /*is_balancer=*/false,
335 &found_lb_addrs);
336 const grpc_core::EndpointAddressesList* balancer_addresses =
337 grpc_core::FindGrpclbBalancerAddressesInChannelArgs(result.args);
338 if (balancer_addresses != nullptr) {
339 AddActualAddresses(*balancer_addresses, /*is_balancer=*/true,
340 &found_lb_addrs);
341 }
342 LOG(INFO) << "found " << result.addresses->size()
343 << " backend addresses and "
344 << (balancer_addresses == nullptr ? 0L
345 : balancer_addresses->size())
346 << " balancer addresses";
347 if (args->expected_addrs.size() != found_lb_addrs.size()) {
348 grpc_core::Crash(absl::StrFormat("found lb addrs size is: %" PRIdPTR
349 ". expected addrs size is %" PRIdPTR,
350 found_lb_addrs.size(),
351 args->expected_addrs.size()));
352 }
353 if (absl::GetFlag(FLAGS_do_ordered_address_comparison) == "True") {
354 EXPECT_EQ(args->expected_addrs, found_lb_addrs);
355 } else if (absl::GetFlag(FLAGS_do_ordered_address_comparison) == "False") {
356 EXPECT_THAT(args->expected_addrs,
357 UnorderedElementsAreArray(found_lb_addrs));
358 } else {
359 LOG(ERROR) << "Invalid for setting for --do_ordered_address_comparison. "
360 "Have "
361 << absl::GetFlag(FLAGS_do_ordered_address_comparison)
362 << ", want True or False";
363 CHECK(0);
364 }
365 if (!result.service_config.ok()) {
366 CheckServiceConfigResultLocked(nullptr, result.service_config.status(),
367 args);
368 } else if (*result.service_config == nullptr) {
369 CheckServiceConfigResultLocked(nullptr, absl::OkStatus(), args);
370 } else {
371 CheckServiceConfigResultLocked(
372 std::string((*result.service_config)->json_string()).c_str(),
373 absl::OkStatus(), args);
374 }
375 if (args->expected_service_config_string.empty()) {
376 CheckLBPolicyResultLocked(result.args, args);
377 }
378 }
379
380 private:
AddActualAddresses(const grpc_core::EndpointAddressesList & addresses,bool is_balancer,std::vector<GrpcLBAddress> * out)381 static void AddActualAddresses(
382 const grpc_core::EndpointAddressesList& addresses, bool is_balancer,
383 std::vector<GrpcLBAddress>* out) {
384 for (size_t i = 0; i < addresses.size(); i++) {
385 const grpc_core::EndpointAddresses& addr = addresses[i];
386 std::string str =
387 grpc_sockaddr_to_string(&addr.address(), true /* normalize */)
388 .value();
389 LOG(INFO) << str;
390 out->emplace_back(GrpcLBAddress(std::move(str), is_balancer));
391 }
392 }
393 };
394
395 int g_fake_non_responsive_dns_server_port = -1;
396
397 // This function will configure any ares_channel created by the c-ares based
398 // resolver. This is useful to effectively mock /etc/resolv.conf settings
399 // (and equivalent on Windows), which unit tests don't have write permissions.
400 //
InjectBrokenNameServerList(ares_channel * channel)401 void InjectBrokenNameServerList(ares_channel* channel) {
402 struct ares_addr_port_node dns_server_addrs[2];
403 memset(dns_server_addrs, 0, sizeof(dns_server_addrs));
404 std::string unused_host;
405 std::string local_dns_server_port;
406 CHECK(grpc_core::SplitHostPort(
407 absl::GetFlag(FLAGS_local_dns_server_address).c_str(), &unused_host,
408 &local_dns_server_port));
409 VLOG(2) << "Injecting broken nameserver list. Bad server address:|[::1]:"
410 << g_fake_non_responsive_dns_server_port << "|. Good server address:"
411 << absl::GetFlag(FLAGS_local_dns_server_address);
412 // Put the non-responsive DNS server at the front of c-ares's nameserver list.
413 dns_server_addrs[0].family = AF_INET6;
414 (reinterpret_cast<char*>(&dns_server_addrs[0].addr.addr6))[15] = 0x1;
415 dns_server_addrs[0].tcp_port = g_fake_non_responsive_dns_server_port;
416 dns_server_addrs[0].udp_port = g_fake_non_responsive_dns_server_port;
417 dns_server_addrs[0].next = &dns_server_addrs[1];
418 // Put the actual healthy DNS server after the first one. The expectation is
419 // that the resolver will timeout the query to the non-responsive DNS server
420 // and will skip over to this healthy DNS server, without causing any DNS
421 // resolution errors.
422 dns_server_addrs[1].family = AF_INET;
423 (reinterpret_cast<char*>(&dns_server_addrs[1].addr.addr4))[0] = 0x7f;
424 (reinterpret_cast<char*>(&dns_server_addrs[1].addr.addr4))[3] = 0x1;
425 dns_server_addrs[1].tcp_port = atoi(local_dns_server_port.c_str());
426 dns_server_addrs[1].udp_port = atoi(local_dns_server_port.c_str());
427 dns_server_addrs[1].next = nullptr;
428 CHECK(ares_set_servers_ports(*channel, dns_server_addrs) == ARES_SUCCESS);
429 }
430
StartResolvingLocked(grpc_core::Resolver * r)431 void StartResolvingLocked(grpc_core::Resolver* r) { r->StartLocked(); }
432
RunResolvesRelevantRecordsTest(std::unique_ptr<grpc_core::Resolver::ResultHandler> (* CreateResultHandler)(ArgsStruct * args),grpc_core::ChannelArgs resolver_args)433 void RunResolvesRelevantRecordsTest(
434 std::unique_ptr<grpc_core::Resolver::ResultHandler> (*CreateResultHandler)(
435 ArgsStruct* args),
436 grpc_core::ChannelArgs resolver_args) {
437 grpc_core::ExecCtx exec_ctx;
438 ArgsStruct args;
439 ArgsInit(&args);
440 args.expected_addrs = ParseExpectedAddrs(absl::GetFlag(FLAGS_expected_addrs));
441 args.expected_service_config_string =
442 absl::GetFlag(FLAGS_expected_chosen_service_config);
443 args.expected_service_config_error =
444 absl::GetFlag(FLAGS_expected_service_config_error);
445 args.expected_lb_policy = absl::GetFlag(FLAGS_expected_lb_policy);
446 // maybe build the address with an authority
447 std::string whole_uri;
448 VLOG(2) << "resolver_component_test: --inject_broken_nameserver_list: "
449 << absl::GetFlag(FLAGS_inject_broken_nameserver_list);
450 std::unique_ptr<grpc_core::testing::FakeUdpAndTcpServer>
451 fake_non_responsive_dns_server;
452 if (absl::GetFlag(FLAGS_inject_broken_nameserver_list) == "True") {
453 fake_non_responsive_dns_server = std::make_unique<
454 grpc_core::testing::FakeUdpAndTcpServer>(
455 grpc_core::testing::FakeUdpAndTcpServer::AcceptMode::
456 kWaitForClientToSendFirstBytes,
457 grpc_core::testing::FakeUdpAndTcpServer::CloseSocketUponCloseFromPeer);
458 g_fake_non_responsive_dns_server_port =
459 fake_non_responsive_dns_server->port();
460 if (grpc_core::IsEventEngineDnsEnabled()) {
461 event_engine_grpc_ares_test_only_inject_config =
462 InjectBrokenNameServerList;
463 } else {
464 grpc_ares_test_only_inject_config = InjectBrokenNameServerList;
465 }
466 whole_uri = absl::StrCat("dns:///", absl::GetFlag(FLAGS_target_name));
467 } else if (absl::GetFlag(FLAGS_inject_broken_nameserver_list) == "False") {
468 LOG(INFO) << "Specifying authority in uris to: "
469 << absl::GetFlag(FLAGS_local_dns_server_address);
470 whole_uri = absl::StrFormat("dns://%s/%s",
471 absl::GetFlag(FLAGS_local_dns_server_address),
472 absl::GetFlag(FLAGS_target_name));
473 } else {
474 grpc_core::Crash("Invalid value for --inject_broken_nameserver_list.");
475 }
476 VLOG(2) << "resolver_component_test: --enable_srv_queries: "
477 << absl::GetFlag(FLAGS_enable_srv_queries);
478 // By default, SRV queries are disabled, so tests that expect no SRV query
479 // should avoid setting any channel arg. Test cases that do rely on the SRV
480 // query must explicitly enable SRV though.
481 if (absl::GetFlag(FLAGS_enable_srv_queries) == "True") {
482 resolver_args = resolver_args.Set(GRPC_ARG_DNS_ENABLE_SRV_QUERIES, true);
483 } else if (absl::GetFlag(FLAGS_enable_srv_queries) != "False") {
484 grpc_core::Crash("Invalid value for --enable_srv_queries.");
485 }
486 VLOG(2) << "resolver_component_test: --enable_txt_queries: "
487 << absl::GetFlag(FLAGS_enable_txt_queries);
488 // By default, TXT queries are disabled, so tests that expect no TXT query
489 // should avoid setting any channel arg. Test cases that do rely on the TXT
490 // query must explicitly enable TXT though.
491 if (absl::GetFlag(FLAGS_enable_txt_queries) == "True") {
492 // Unlike SRV queries, there isn't a channel arg specific to TXT records.
493 // Rather, we use the resolver-agnostic "service config" resolution option,
494 // for which c-ares has its own specific default value, which isn't
495 // necessarily shared by other resolvers.
496 resolver_args =
497 resolver_args.Set(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION, false);
498 } else if (absl::GetFlag(FLAGS_enable_txt_queries) != "False") {
499 grpc_core::Crash("Invalid value for --enable_txt_queries.");
500 }
501 resolver_args = resolver_args.SetObject(GetDefaultEventEngine());
502 // create resolver and resolve
503 grpc_core::OrphanablePtr<grpc_core::Resolver> resolver =
504 grpc_core::CoreConfiguration::Get().resolver_registry().CreateResolver(
505 whole_uri.c_str(), resolver_args, args.pollset_set, args.lock,
506 CreateResultHandler(&args));
507 auto* resolver_ptr = resolver.get();
508 args.lock->Run([resolver_ptr]() { StartResolvingLocked(resolver_ptr); },
509 DEBUG_LOCATION);
510 grpc_core::ExecCtx::Get()->Flush();
511 PollPollsetUntilRequestDone(&args);
512 ArgsFinish(&args);
513 }
514
TEST(ResolverComponentTest,TestResolvesRelevantRecords)515 TEST(ResolverComponentTest, TestResolvesRelevantRecords) {
516 RunResolvesRelevantRecordsTest(CheckingResultHandler::Create,
517 grpc_core::ChannelArgs());
518 }
519
TEST(ResolverComponentTest,TestResolvesRelevantRecordsWithConcurrentFdStress)520 TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) {
521 grpc_core::testing::SocketUseAfterCloseDetector
522 socket_use_after_close_detector;
523 // Run the resolver test
524 RunResolvesRelevantRecordsTest(ResultHandler::Create,
525 grpc_core::ChannelArgs());
526 }
527
TEST(ResolverComponentTest,TestDoesntCrashOrHangWith1MsTimeout)528 TEST(ResolverComponentTest, TestDoesntCrashOrHangWith1MsTimeout) {
529 // Queries in this test could either complete successfully or time out
530 // and show cancellation. This test doesn't care - we just care that the
531 // query completes and doesn't crash, get stuck, leak, etc.
532 RunResolvesRelevantRecordsTest(
533 ResultHandler::Create,
534 grpc_core::ChannelArgs().Set(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS, 1));
535 }
536
537 } // namespace
538
main(int argc,char ** argv)539 int main(int argc, char** argv) {
540 ::testing::InitGoogleTest(&argc, argv);
541 // Need before TestEnvironment construct for --grpc_experiments flag at
542 // least.
543 grpc::testing::InitTest(&argc, &argv, true);
544 grpc::testing::TestEnvironment env(&argc, argv);
545 if (absl::GetFlag(FLAGS_target_name).empty()) {
546 grpc_core::Crash("Missing target_name param.");
547 }
548 grpc_init();
549 auto result = RUN_ALL_TESTS();
550 grpc_shutdown();
551 return result;
552 }
553