resolver_component_test.cc
Go to the documentation of this file.
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 
20 
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <string.h>
24 
25 #include <string>
26 #include <thread>
27 #include <vector>
28 
29 #include <gmock/gmock.h>
30 
31 #include "absl/flags/flag.h"
32 #include "absl/memory/memory.h"
33 #include "absl/strings/str_cat.h"
34 #include "absl/strings/str_format.h"
35 
36 #include <grpc/grpc.h>
38 #include <grpc/support/alloc.h>
39 #include <grpc/support/log.h>
40 #include <grpc/support/sync.h>
41 #include <grpc/support/time.h>
42 
62 #include "test/core/util/port.h"
66 
67 // TODO(unknown): pull in different headers when enabling this
68 // test on windows. Also set BAD_SOCKET_RETURN_VAL
69 // to INVALID_SOCKET on windows.
70 #ifdef GPR_WINDOWS
74 #define BAD_SOCKET_RETURN_VAL INVALID_SOCKET
75 #else
77 #define BAD_SOCKET_RETURN_VAL (-1)
78 #endif
79 
80 using std::vector;
82 
83 ABSL_FLAG(std::string, target_name, "", "Target name to resolve.");
84 ABSL_FLAG(std::string, do_ordered_address_comparison, "",
85  "Whether or not to compare resolved addresses to expected "
86  "addresses using an ordered comparison. This is useful for "
87  "testing certain behaviors that involve sorting of resolved "
88  "addresses. Note it would be better if this argument was a "
89  "bool flag, but it's a string for ease of invocation from "
90  "the generated python test runner.");
91 ABSL_FLAG(std::string, expected_addrs, "",
92  "List of expected backend or balancer addresses in the form "
93  "'<ip0:port0>,<is_balancer0>;<ip1:port1>,<is_balancer1>;...'. "
94  "'is_balancer' should be bool, i.e. true or false.");
95 ABSL_FLAG(std::string, expected_chosen_service_config, "",
96  "Expected service config json string that gets chosen (no "
97  "whitespace). Empty for none.");
98 ABSL_FLAG(std::string, expected_service_config_error, "",
99  "Expected service config error. Empty for none.");
100 ABSL_FLAG(std::string, local_dns_server_address, "",
101  "Optional. This address is placed as the uri authority if present.");
102 // TODO(Capstan): Is this worth making `bool` now with Abseil flags?
103 ABSL_FLAG(
104  std::string, enable_srv_queries, "",
105  "Whether or not to enable SRV queries for the ares resolver instance."
106  "It would be better if this arg could be bool, but the way that we "
107  "generate "
108  "the python script runner doesn't allow us to pass a gflags bool to this "
109  "binary.");
110 // TODO(Capstan): Is this worth making `bool` now with Abseil flags?
111 ABSL_FLAG(
112  std::string, enable_txt_queries, "",
113  "Whether or not to enable TXT queries for the ares resolver instance."
114  "It would be better if this arg could be bool, but the way that we "
115  "generate "
116  "the python script runner doesn't allow us to pass a gflags bool to this "
117  "binary.");
118 // TODO(Capstan): Is this worth making `bool` now with Abseil flags?
119 ABSL_FLAG(
120  std::string, inject_broken_nameserver_list, "",
121  "Whether or not to configure c-ares to use a broken nameserver list, in "
122  "which "
123  "the first nameserver in the list is non-responsive, but the second one "
124  "works, i.e "
125  "serves the expected DNS records; using for testing such a real scenario."
126  "It would be better if this arg could be bool, but the way that we "
127  "generate "
128  "the python script runner doesn't allow us to pass a gflags bool to this "
129  "binary.");
130 ABSL_FLAG(std::string, expected_lb_policy, "",
131  "Expected lb policy name that appears in resolver result channel "
132  "arg. Empty for none.");
133 
134 namespace {
135 
136 class GrpcLBAddress final {
137  public:
138  GrpcLBAddress(std::string address, bool is_balancer)
139  : is_balancer(is_balancer), address(std::move(address)) {}
140 
141  bool operator==(const GrpcLBAddress& other) const {
142  return this->is_balancer == other.is_balancer &&
143  this->address == other.address;
144  }
145 
146  bool operator!=(const GrpcLBAddress& other) const {
147  return !(*this == other);
148  }
149 
150  bool is_balancer;
151  std::string address;
152 };
153 
154 vector<GrpcLBAddress> ParseExpectedAddrs(std::string expected_addrs) {
155  std::vector<GrpcLBAddress> out;
156  while (!expected_addrs.empty()) {
157  // get the next <ip>,<port> (v4 or v6)
158  size_t next_comma = expected_addrs.find(',');
159  if (next_comma == std::string::npos) {
161  "Missing ','. Expected_addrs arg should be a semicolon-separated "
162  "list of <ip-port>,<bool> pairs. Left-to-be-parsed arg is |%s|",
163  expected_addrs.c_str());
164  abort();
165  }
166  std::string next_addr = expected_addrs.substr(0, next_comma);
167  expected_addrs = expected_addrs.substr(next_comma + 1, std::string::npos);
168  // get the next is_balancer 'bool' associated with this address
169  size_t next_semicolon = expected_addrs.find(';');
170  bool is_balancer = false;
171  gpr_parse_bool_value(expected_addrs.substr(0, next_semicolon).c_str(),
172  &is_balancer);
173  out.emplace_back(GrpcLBAddress(next_addr, is_balancer));
174  if (next_semicolon == std::string::npos) {
175  break;
176  }
177  expected_addrs =
178  expected_addrs.substr(next_semicolon + 1, std::string::npos);
179  }
180  if (out.empty()) {
182  "expected_addrs arg should be a semicolon-separated list of "
183  "<ip-port>,<bool> pairs");
184  abort();
185  }
186  return out;
187 }
188 
189 gpr_timespec TestDeadline(void) {
191 }
192 
193 struct ArgsStruct {
194  gpr_event ev;
195  gpr_atm done_atm;
196  gpr_mu* mu;
197  grpc_pollset* pollset;
198  grpc_pollset_set* pollset_set;
199  std::shared_ptr<grpc_core::WorkSerializer> lock;
200  grpc_channel_args* channel_args;
201  vector<GrpcLBAddress> expected_addrs;
202  std::string expected_service_config_string;
203  std::string expected_service_config_error;
204  std::string expected_lb_policy;
205 };
206 
207 void ArgsInit(ArgsStruct* args) {
208  gpr_event_init(&args->ev);
209  args->pollset = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
210  grpc_pollset_init(args->pollset, &args->mu);
211  args->pollset_set = grpc_pollset_set_create();
212  grpc_pollset_set_add_pollset(args->pollset_set, args->pollset);
213  args->lock = std::make_shared<grpc_core::WorkSerializer>();
214  gpr_atm_rel_store(&args->done_atm, 0);
215  args->channel_args = nullptr;
216 }
217 
218 void DoNothing(void* /*arg*/, grpc_error_handle /*error*/) {}
219 
220 void ArgsFinish(ArgsStruct* args) {
221  GPR_ASSERT(gpr_event_wait(&args->ev, TestDeadline()));
222  grpc_pollset_set_del_pollset(args->pollset_set, args->pollset);
223  grpc_pollset_set_destroy(args->pollset_set);
224  grpc_closure DoNothing_cb;
225  GRPC_CLOSURE_INIT(&DoNothing_cb, DoNothing, nullptr,
226  grpc_schedule_on_exec_ctx);
227  grpc_pollset_shutdown(args->pollset, &DoNothing_cb);
228  // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
229  grpc_channel_args_destroy(args->channel_args);
231  grpc_pollset_destroy(args->pollset);
232  gpr_free(args->pollset);
233 }
234 
235 gpr_timespec NSecondDeadline(int seconds) {
238 }
239 
240 void PollPollsetUntilRequestDone(ArgsStruct* args) {
241  // Use a 20-second timeout to give room for the tests that involve
242  // a non-responsive name server (c-ares uses a ~5 second query timeout
243  // for that server before succeeding with the healthy one).
244  gpr_timespec deadline = NSecondDeadline(20);
245  while (true) {
246  bool done = gpr_atm_acq_load(&args->done_atm) != 0;
247  if (done) {
248  break;
249  }
250  gpr_timespec time_left =
252  gpr_log(GPR_DEBUG, "done=%d, time_left=%" PRId64 ".%09d", done,
253  time_left.tv_sec, time_left.tv_nsec);
254  GPR_ASSERT(gpr_time_cmp(time_left, gpr_time_0(GPR_TIMESPAN)) >= 0);
255  grpc_pollset_worker* worker = nullptr;
257  gpr_mu_lock(args->mu);
259  "pollset_work",
261  args->pollset, &worker,
262  grpc_core::Timestamp::FromTimespecRoundUp(NSecondDeadline(1))));
263  gpr_mu_unlock(args->mu);
264  }
265  gpr_event_set(&args->ev, reinterpret_cast<void*>(1));
266 }
267 
268 void CheckServiceConfigResultLocked(const char* service_config_json,
269  absl::Status service_config_error,
270  ArgsStruct* args) {
271  if (!args->expected_service_config_string.empty()) {
272  ASSERT_NE(service_config_json, nullptr);
273  EXPECT_EQ(service_config_json, args->expected_service_config_string);
274  }
275  if (args->expected_service_config_error.empty()) {
276  EXPECT_TRUE(service_config_error.ok());
277  } else {
278  EXPECT_THAT(service_config_error.ToString(),
279  testing::HasSubstr(args->expected_service_config_error));
280  }
281 }
282 
283 void CheckLBPolicyResultLocked(const grpc_channel_args* channel_args,
284  ArgsStruct* args) {
285  const grpc_arg* lb_policy_arg =
287  if (!args->expected_lb_policy.empty()) {
288  GPR_ASSERT(lb_policy_arg != nullptr);
289  GPR_ASSERT(lb_policy_arg->type == GRPC_ARG_STRING);
290  EXPECT_EQ(lb_policy_arg->value.string, args->expected_lb_policy);
291  } else {
292  GPR_ASSERT(lb_policy_arg == nullptr);
293  }
294 }
295 
296 #ifdef GPR_WINDOWS
297 void OpenAndCloseSocketsStressLoop(int phony_port, gpr_event* done_ev) {
299  memset(&addr, 0, sizeof(addr));
300  addr.sin6_family = AF_INET6;
301  addr.sin6_port = htons(phony_port);
302  ((char*)&addr.sin6_addr)[15] = 1;
303  for (;;) {
304  if (gpr_event_get(done_ev)) {
305  return;
306  }
307  std::vector<int> sockets;
308  for (size_t i = 0; i < 50; i++) {
309  SOCKET s = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, nullptr, 0,
310  WSA_FLAG_OVERLAPPED);
312  << "Failed to create TCP ipv6 socket";
313  gpr_log(GPR_DEBUG, "Opened socket: %d", s);
314  char val = 1;
315  ASSERT_TRUE(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) !=
316  SOCKET_ERROR)
317  << "Failed to set socketopt reuseaddr. WSA error: " +
318  std::to_string(WSAGetLastError());
319  ASSERT_TRUE(grpc_tcp_set_non_block(s) == GRPC_ERROR_NONE)
320  << "Failed to set socket non-blocking";
321  ASSERT_TRUE(bind(s, (const sockaddr*)&addr, sizeof(addr)) != SOCKET_ERROR)
322  << "Failed to bind socket " + std::to_string(s) +
323  " to [::1]:" + std::to_string(phony_port) +
324  ". WSA error: " + std::to_string(WSAGetLastError());
325  ASSERT_TRUE(listen(s, 1) != SOCKET_ERROR)
326  << "Failed to listen on socket " + std::to_string(s) +
327  ". WSA error: " + std::to_string(WSAGetLastError());
328  sockets.push_back(s);
329  }
330  // Do a non-blocking accept followed by a close on all of those sockets.
331  // Do this in a separate loop to try to induce a time window to hit races.
332  for (size_t i = 0; i < sockets.size(); i++) {
333  gpr_log(GPR_DEBUG, "non-blocking accept then close on %d", sockets[i]);
334  ASSERT_TRUE(accept(sockets[i], nullptr, nullptr) == INVALID_SOCKET)
335  << "Accept on phony socket unexpectedly accepted actual connection.";
336  ASSERT_TRUE(WSAGetLastError() == WSAEWOULDBLOCK)
337  << "OpenAndCloseSocketsStressLoop accept on socket " +
339  " failed in "
340  "an unexpected way. "
341  "WSA error: " +
342  std::to_string(WSAGetLastError()) +
343  ". Socket use-after-close bugs are likely.";
344  ASSERT_TRUE(closesocket(sockets[i]) != SOCKET_ERROR)
345  << "Failed to close socket: " + std::to_string(sockets[i]) +
346  ". WSA error: " + std::to_string(WSAGetLastError());
347  }
348  }
349  return;
350 }
351 #else
352 void OpenAndCloseSocketsStressLoop(int phony_port, gpr_event* done_ev) {
353  // The goal of this loop is to catch socket
354  // "use after close" bugs within the c-ares resolver by acting
355  // like some separate thread doing I/O.
356  // It's goal is to try to hit race conditions whereby:
357  // 1) The c-ares resolver closes a socket.
358  // 2) This loop opens a socket with (coincidentally) the same handle.
359  // 3) the c-ares resolver mistakenly uses that same socket without
360  // realizing that its closed.
361  // 4) This loop performs an operation on that socket that should
362  // succeed but instead fails because of what the c-ares
363  // resolver did in the meantime.
365  memset(&addr, 0, sizeof(addr));
366  addr.sin6_family = AF_INET6;
367  addr.sin6_port = htons(phony_port);
368  (reinterpret_cast<char*>(&addr.sin6_addr))[15] = 1;
369  for (;;) {
370  if (gpr_event_get(done_ev)) {
371  return;
372  }
373  std::vector<int> sockets;
374  // First open a bunch of sockets, bind and listen
375  // '50' is an arbitrary number that, experimentally,
376  // has a good chance of catching bugs.
377  for (size_t i = 0; i < 50; i++) {
378  int s = socket(AF_INET6, SOCK_STREAM, 0);
379  int val = 1;
380  ASSERT_TRUE(setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)) ==
381  0)
382  << "Failed to set socketopt reuseport";
383  ASSERT_TRUE(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) ==
384  0)
385  << "Failed to set socket reuseaddr";
386  ASSERT_TRUE(fcntl(s, F_SETFL, O_NONBLOCK) == 0)
387  << "Failed to set socket non-blocking";
389  << "Failed to create TCP ipv6 socket";
390  gpr_log(GPR_DEBUG, "Opened fd: %d", s);
391  ASSERT_TRUE(bind(s, (const sockaddr*)&addr, sizeof(addr)) == 0)
392  << "Failed to bind socket " + std::to_string(s) +
393  " to [::1]:" + std::to_string(phony_port) +
394  ". errno: " + std::to_string(errno);
395  ASSERT_TRUE(listen(s, 1) == 0) << "Failed to listen on socket " +
396  std::to_string(s) +
397  ". errno: " + std::to_string(errno);
398  sockets.push_back(s);
399  }
400  // Do a non-blocking accept followed by a close on all of those sockets.
401  // Do this in a separate loop to try to induce a time window to hit races.
402  for (size_t i = 0; i < sockets.size(); i++) {
403  gpr_log(GPR_DEBUG, "non-blocking accept then close on %d", sockets[i]);
404  if (accept(sockets[i], nullptr, nullptr)) {
405  // If e.g. a "shutdown" was called on this fd from another thread,
406  // then this accept call should fail with an unexpected error.
407  ASSERT_TRUE(errno == EAGAIN || errno == EWOULDBLOCK)
408  << "OpenAndCloseSocketsStressLoop accept on socket " +
410  " failed in "
411  "an unexpected way. "
412  "errno: " +
413  std::to_string(errno) +
414  ". Socket use-after-close bugs are likely.";
415  }
416  ASSERT_TRUE(close(sockets[i]) == 0)
417  << "Failed to close socket: " + std::to_string(sockets[i]) +
418  ". errno: " + std::to_string(errno);
419  }
420  }
421 }
422 #endif
423 
425  public:
426  static std::unique_ptr<grpc_core::Resolver::ResultHandler> Create(
427  ArgsStruct* args) {
428  return std::unique_ptr<grpc_core::Resolver::ResultHandler>(
429  new ResultHandler(args));
430  }
431 
432  explicit ResultHandler(ArgsStruct* args) : args_(args) {}
433 
434  void ReportResult(grpc_core::Resolver::Result result) override {
435  CheckResult(result);
436  gpr_atm_rel_store(&args_->done_atm, 1);
437  gpr_mu_lock(args_->mu);
438  GRPC_LOG_IF_ERROR("pollset_kick",
439  grpc_pollset_kick(args_->pollset, nullptr));
440  gpr_mu_unlock(args_->mu);
441  }
442 
443  virtual void CheckResult(const grpc_core::Resolver::Result& /*result*/) {}
444 
445  protected:
446  ArgsStruct* args_struct() const { return args_; }
447 
448  private:
449  ArgsStruct* args_;
450 };
451 
452 class CheckingResultHandler : public ResultHandler {
453  public:
454  static std::unique_ptr<grpc_core::Resolver::ResultHandler> Create(
455  ArgsStruct* args) {
456  return std::unique_ptr<grpc_core::Resolver::ResultHandler>(
457  new CheckingResultHandler(args));
458  }
459 
460  explicit CheckingResultHandler(ArgsStruct* args) : ResultHandler(args) {}
461 
462  void CheckResult(const grpc_core::Resolver::Result& result) override {
463  ASSERT_TRUE(result.addresses.ok()) << result.addresses.status().ToString();
464  ArgsStruct* args = args_struct();
465  std::vector<GrpcLBAddress> found_lb_addrs;
466  AddActualAddresses(*result.addresses, /*is_balancer=*/false,
467  &found_lb_addrs);
468  const grpc_core::ServerAddressList* balancer_addresses =
470  if (balancer_addresses != nullptr) {
471  AddActualAddresses(*balancer_addresses, /*is_balancer=*/true,
472  &found_lb_addrs);
473  }
475  "found %" PRIdPTR " backend addresses and %" PRIdPTR
476  " balancer addresses",
477  result.addresses->size(),
478  balancer_addresses == nullptr ? 0L : balancer_addresses->size());
479  if (args->expected_addrs.size() != found_lb_addrs.size()) {
481  "found lb addrs size is: %" PRIdPTR
482  ". expected addrs size is %" PRIdPTR,
483  found_lb_addrs.size(), args->expected_addrs.size());
484  abort();
485  }
486  if (absl::GetFlag(FLAGS_do_ordered_address_comparison) == "True") {
487  EXPECT_EQ(args->expected_addrs, found_lb_addrs);
488  } else if (absl::GetFlag(FLAGS_do_ordered_address_comparison) == "False") {
489  EXPECT_THAT(args->expected_addrs,
490  UnorderedElementsAreArray(found_lb_addrs));
491  } else {
493  "Invalid for setting for --do_ordered_address_comparison. "
494  "Have %s, want True or False",
495  absl::GetFlag(FLAGS_do_ordered_address_comparison).c_str());
496  GPR_ASSERT(0);
497  }
498  if (!result.service_config.ok()) {
499  CheckServiceConfigResultLocked(nullptr, result.service_config.status(),
500  args);
501  } else if (*result.service_config == nullptr) {
502  CheckServiceConfigResultLocked(nullptr, absl::OkStatus(), args);
503  } else {
504  CheckServiceConfigResultLocked(
505  std::string((*result.service_config)->json_string()).c_str(),
506  absl::OkStatus(), args);
507  }
508  if (args->expected_service_config_string.empty()) {
509  CheckLBPolicyResultLocked(result.args, args);
510  }
511  }
512 
513  private:
514  static void AddActualAddresses(const grpc_core::ServerAddressList& addresses,
515  bool is_balancer,
516  std::vector<GrpcLBAddress>* out) {
517  for (size_t i = 0; i < addresses.size(); i++) {
518  const grpc_core::ServerAddress& addr = addresses[i];
519  std::string str =
520  grpc_sockaddr_to_string(&addr.address(), true /* normalize */)
521  .value();
522  gpr_log(GPR_INFO, "%s", str.c_str());
523  out->emplace_back(GrpcLBAddress(std::move(str), is_balancer));
524  }
525  }
526 };
527 
528 int g_fake_non_responsive_dns_server_port = -1;
529 
530 /* This function will configure any ares_channel created by the c-ares based
531  * resolver. This is useful to effectively mock /etc/resolv.conf settings
532  * (and equivalent on Windows), which unit tests don't have write permissions.
533  */
534 void InjectBrokenNameServerList(ares_channel channel) {
535  struct ares_addr_port_node dns_server_addrs[2];
536  memset(dns_server_addrs, 0, sizeof(dns_server_addrs));
537  std::string unused_host;
538  std::string local_dns_server_port;
540  absl::GetFlag(FLAGS_local_dns_server_address).c_str(), &unused_host,
541  &local_dns_server_port));
543  "Injecting broken nameserver list. Bad server address:|[::1]:%d|. "
544  "Good server address:%s",
545  g_fake_non_responsive_dns_server_port,
546  absl::GetFlag(FLAGS_local_dns_server_address).c_str());
547  // Put the non-responsive DNS server at the front of c-ares's nameserver list.
548  dns_server_addrs[0].family = AF_INET6;
549  (reinterpret_cast<char*>(&dns_server_addrs[0].addr.addr6))[15] = 0x1;
550  dns_server_addrs[0].tcp_port = g_fake_non_responsive_dns_server_port;
551  dns_server_addrs[0].udp_port = g_fake_non_responsive_dns_server_port;
552  dns_server_addrs[0].next = &dns_server_addrs[1];
553  // Put the actual healthy DNS server after the first one. The expectation is
554  // that the resolver will timeout the query to the non-responsive DNS server
555  // and will skip over to this healthy DNS server, without causing any DNS
556  // resolution errors.
557  dns_server_addrs[1].family = AF_INET;
558  (reinterpret_cast<char*>(&dns_server_addrs[1].addr.addr4))[0] = 0x7f;
559  (reinterpret_cast<char*>(&dns_server_addrs[1].addr.addr4))[3] = 0x1;
560  dns_server_addrs[1].tcp_port = atoi(local_dns_server_port.c_str());
561  dns_server_addrs[1].udp_port = atoi(local_dns_server_port.c_str());
562  dns_server_addrs[1].next = nullptr;
563  GPR_ASSERT(ares_set_servers_ports(channel, dns_server_addrs) == ARES_SUCCESS);
564 }
565 
566 void StartResolvingLocked(grpc_core::Resolver* r) { r->StartLocked(); }
567 
568 void RunResolvesRelevantRecordsTest(
569  std::unique_ptr<grpc_core::Resolver::ResultHandler> (*CreateResultHandler)(
570  ArgsStruct* args)) {
572  ArgsStruct args;
573  ArgsInit(&args);
574  args.expected_addrs = ParseExpectedAddrs(absl::GetFlag(FLAGS_expected_addrs));
575  args.expected_service_config_string =
576  absl::GetFlag(FLAGS_expected_chosen_service_config);
577  args.expected_service_config_error =
578  absl::GetFlag(FLAGS_expected_service_config_error);
579  args.expected_lb_policy = absl::GetFlag(FLAGS_expected_lb_policy);
580  // maybe build the address with an authority
581  std::string whole_uri;
583  "resolver_component_test: --inject_broken_nameserver_list: %s",
584  absl::GetFlag(FLAGS_inject_broken_nameserver_list).c_str());
585  std::unique_ptr<grpc_core::testing::FakeUdpAndTcpServer>
586  fake_non_responsive_dns_server;
587  if (absl::GetFlag(FLAGS_inject_broken_nameserver_list) == "True") {
588  fake_non_responsive_dns_server = absl::make_unique<
593  g_fake_non_responsive_dns_server_port =
594  fake_non_responsive_dns_server->port();
595  grpc_ares_test_only_inject_config = InjectBrokenNameServerList;
596  whole_uri = absl::StrCat("dns:///", absl::GetFlag(FLAGS_target_name));
597  } else if (absl::GetFlag(FLAGS_inject_broken_nameserver_list) == "False") {
598  gpr_log(GPR_INFO, "Specifying authority in uris to: %s",
599  absl::GetFlag(FLAGS_local_dns_server_address).c_str());
600  whole_uri = absl::StrFormat("dns://%s/%s",
601  absl::GetFlag(FLAGS_local_dns_server_address),
602  absl::GetFlag(FLAGS_target_name));
603  } else {
604  gpr_log(GPR_DEBUG, "Invalid value for --inject_broken_nameserver_list.");
605  abort();
606  }
607  gpr_log(GPR_DEBUG, "resolver_component_test: --enable_srv_queries: %s",
608  absl::GetFlag(FLAGS_enable_srv_queries).c_str());
609  grpc_channel_args* resolver_args = nullptr;
610  // By default, SRV queries are disabled, so tests that expect no SRV query
611  // should avoid setting any channel arg. Test cases that do rely on the SRV
612  // query must explicitly enable SRV though.
613  if (absl::GetFlag(FLAGS_enable_srv_queries) == "True") {
614  grpc_arg srv_queries_arg = grpc_channel_arg_integer_create(
615  const_cast<char*>(GRPC_ARG_DNS_ENABLE_SRV_QUERIES), true);
616  resolver_args =
617  grpc_channel_args_copy_and_add(nullptr, &srv_queries_arg, 1);
618  } else if (absl::GetFlag(FLAGS_enable_srv_queries) != "False") {
619  gpr_log(GPR_DEBUG, "Invalid value for --enable_srv_queries.");
620  abort();
621  }
622  gpr_log(GPR_DEBUG, "resolver_component_test: --enable_txt_queries: %s",
623  absl::GetFlag(FLAGS_enable_txt_queries).c_str());
624  // By default, TXT queries are disabled, so tests that expect no TXT query
625  // should avoid setting any channel arg. Test cases that do rely on the TXT
626  // query must explicitly enable TXT though.
627  if (absl::GetFlag(FLAGS_enable_txt_queries) == "True") {
628  // Unlike SRV queries, there isn't a channel arg specific to TXT records.
629  // Rather, we use the resolver-agnostic "service config" resolution option,
630  // for which c-ares has its own specific default value, which isn't
631  // necessarily shared by other resolvers.
632  grpc_arg txt_queries_arg = grpc_channel_arg_integer_create(
633  const_cast<char*>(GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION), false);
634  grpc_channel_args* tmp_args =
635  grpc_channel_args_copy_and_add(resolver_args, &txt_queries_arg, 1);
636  grpc_channel_args_destroy(resolver_args);
637  resolver_args = tmp_args;
638  } else if (absl::GetFlag(FLAGS_enable_txt_queries) != "False") {
639  gpr_log(GPR_DEBUG, "Invalid value for --enable_txt_queries.");
640  abort();
641  }
642  // create resolver and resolve
645  whole_uri.c_str(), resolver_args, args.pollset_set, args.lock,
646  CreateResultHandler(&args));
647  grpc_channel_args_destroy(resolver_args);
648  auto* resolver_ptr = resolver.get();
649  args.lock->Run([resolver_ptr]() { StartResolvingLocked(resolver_ptr); },
652  PollPollsetUntilRequestDone(&args);
653  ArgsFinish(&args);
654 }
655 
656 TEST(ResolverComponentTest, TestResolvesRelevantRecords) {
657  RunResolvesRelevantRecordsTest(CheckingResultHandler::Create);
658 }
659 
660 TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) {
661  // Start up background stress thread
662  int phony_port = grpc_pick_unused_port_or_die();
663  gpr_event done_ev;
664  gpr_event_init(&done_ev);
665  std::thread socket_stress_thread(OpenAndCloseSocketsStressLoop, phony_port,
666  &done_ev);
667  // Run the resolver test
668  RunResolvesRelevantRecordsTest(ResultHandler::Create);
669  // Shutdown and join stress thread
670  gpr_event_set(&done_ev, reinterpret_cast<void*>(1));
671  socket_stress_thread.join();
672 }
673 
674 } // namespace
675 
676 int main(int argc, char** argv) {
677  grpc_init();
678  grpc::testing::TestEnvironment env(&argc, argv);
679  ::testing::InitGoogleTest(&argc, argv);
680  grpc::testing::InitTest(&argc, &argv, true);
681  if (absl::GetFlag(FLAGS_target_name).empty()) {
682  gpr_log(GPR_ERROR, "Missing target_name param.");
683  abort();
684  }
685  auto result = RUN_ALL_TESTS();
686  grpc_shutdown();
687  return result;
688 }
grpc_pollset_worker
struct grpc_pollset_worker grpc_pollset_worker
Definition: pollset.h:39
GRPC_CLOSURE_INIT
#define GRPC_CLOSURE_INIT(closure, cb, cb_arg, scheduler)
Definition: closure.h:115
grpc_arg
Definition: grpc_types.h:103
GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION
#define GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION
Definition: grpc_types.h:306
gpr_timespec::tv_nsec
int32_t tv_nsec
Definition: gpr_types.h:52
xds_interop_client.str
str
Definition: xds_interop_client.py:487
GPR_TIMESPAN
@ GPR_TIMESPAN
Definition: gpr_types.h:45
grpc::testing::InitTest
void InitTest(int *argc, char ***argv, bool remove_flags)
Definition: test_config_cc.cc:28
absl::time_internal::cctz::seconds
std::chrono::duration< std::int_fast64_t > seconds
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h:40
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
gpr_timespec::tv_sec
int64_t tv_sec
Definition: gpr_types.h:51
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
grpc_pollset_size
size_t grpc_pollset_size(void)
Definition: pollset.cc:56
ASSERT_NE
#define ASSERT_NE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2060
iomgr.h
gpr_mu_unlock
GPRAPI void gpr_mu_unlock(gpr_mu *mu)
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
orphanable.h
GRPC_ERROR_NONE
#define GRPC_ERROR_NONE
Definition: error.h:234
grpc_timeout_seconds_to_deadline
gpr_timespec grpc_timeout_seconds_to_deadline(int64_t time_s)
Definition: test/core/util/test_config.cc:81
log.h
port.h
core_configuration.h
grpc_event_engine::experimental::slice_detail::operator==
bool operator==(const BaseSlice &a, const BaseSlice &b)
Definition: include/grpc/event_engine/slice.h:117
sockaddr_utils.h
ABSL_FLAG
ABSL_FLAG(std::string, target_name, "", "Target name to resolve.")
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
gpr_event_get
GPRAPI void * gpr_event_get(gpr_event *ev)
Definition: sync.cc:69
generate.env
env
Definition: generate.py:37
absl::Status::ToString
std::string ToString(StatusToStringMode mode=StatusToStringMode::kDefault) const
Definition: third_party/abseil-cpp/absl/status/status.h:821
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
grpc_arg::value
union grpc_arg::grpc_arg_value value
memset
return memset(p, 0, total)
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
GRPC_ARG_STRING
@ GRPC_ARG_STRING
Definition: grpc_types.h:80
EXPECT_THAT
#define EXPECT_THAT(value, matcher)
gpr_time_0
GPRAPI gpr_timespec gpr_time_0(gpr_clock_type type)
Definition: src/core/lib/gpr/time.cc:47
ares_addr_port_node
Definition: ares.h:704
grpc_pollset_set
struct grpc_pollset_set grpc_pollset_set
Definition: iomgr_fwd.h:23
string.h
grpc_pollset_set_create
grpc_pollset_set * grpc_pollset_set_create()
Definition: pollset_set.cc:29
gpr_event_set
GPRAPI void gpr_event_set(gpr_event *ev, void *value)
Definition: sync.cc:59
gpr_free
GPRAPI void gpr_free(void *ptr)
Definition: alloc.cc:51
resolve_address.h
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
args_struct
struct args_struct args_struct
client_channel.h
grpc_core::ServerAddress
Definition: server_address.h:49
absl::OkStatus
Status OkStatus()
Definition: third_party/abseil-cpp/absl/status/status.h:882
ResultHandler
Definition: dns_resolver_cooldown_test.cc:202
grpc_core::SplitHostPort
bool SplitHostPort(absl::string_view name, absl::string_view *host, absl::string_view *port)
Definition: host_port.cc:88
socket_windows.h
grpc_pollset_work
grpc_error_handle grpc_pollset_work(grpc_pollset *pollset, grpc_pollset_worker **worker, grpc_core::Timestamp deadline)
Definition: pollset.cc:45
absl::FormatConversionChar::s
@ s
GRPC_LOG_IF_ERROR
#define GRPC_LOG_IF_ERROR(what, error)
Definition: error.h:398
time.h
absl::make_unique
memory_internal::MakeUniqueResult< T >::scalar make_unique(Args &&... args)
Definition: third_party/abseil-cpp/absl/memory/memory.h:168
args_
grpc_channel_args * args_
Definition: grpclb.cc:513
grpc_sockaddr_to_string
absl::StatusOr< std::string > grpc_sockaddr_to_string(const grpc_resolved_address *resolved_addr, bool normalize)
Definition: sockaddr_utils.cc:194
grpc_channel_args
Definition: grpc_types.h:132
grpc_core::testing::FakeUdpAndTcpServer::port
int port()
Definition: fake_udp_and_tcp_server.h:94
grpc_core::testing::FakeUdpAndTcpServer::AcceptMode::kWaitForClientToSendFirstBytes
@ kWaitForClientToSendFirstBytes
grpc_pollset_init
void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu)
Definition: pollset.cc:33
gpr_parse_bool_value
bool gpr_parse_bool_value(const char *value, bool *dst)
Definition: string.cc:325
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
gpr_zalloc
GPRAPI void * gpr_zalloc(size_t size)
Definition: alloc.cc:40
grpc_types.h
main
int main(int argc, char **argv)
Definition: resolver_component_test.cc:676
socket_utils.h
DEBUG_LOCATION
#define DEBUG_LOCATION
Definition: debug_location.h:41
parse_address.h
subprocess.h
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
grpc_arg::grpc_arg_value::string
char * string
Definition: grpc_types.h:107
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
sockaddr_in6
Definition: ares_ipv6.h:25
grpc_core::FindGrpclbBalancerAddressesInChannelArgs
const ServerAddressList * FindGrpclbBalancerAddressesInChannelArgs(const grpc_channel_args &args)
Definition: grpclb_balancer_addresses.cc:74
gpr_time_cmp
GPRAPI int gpr_time_cmp(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:30
grpc_pollset_set_del_pollset
void grpc_pollset_set_del_pollset(grpc_pollset_set *pollset_set, grpc_pollset *pollset)
Definition: pollset_set.cc:42
grpc_core::CoreConfiguration::Get
static const CoreConfiguration & Get()
Definition: core_configuration.h:82
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
TEST
#define TEST(name, init_size,...)
Definition: arena_test.cc:75
grpc_core::ExecCtx::Flush
bool Flush()
Definition: exec_ctx.cc:69
mu
Mutex mu
Definition: server_config_selector_filter.cc:74
grpc_core::Resolver
Definition: resolver/resolver.h:53
gpr_time_sub
GPRAPI gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:168
grpc_ares_wrapper.h
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
worker
Definition: worker.py:1
work_serializer.h
grpc_core::Resolver::Result
Results returned by the resolver.
Definition: resolver/resolver.h:56
grpc_core::testing::FakeUdpAndTcpServer
Definition: fake_udp_and_tcp_server.h:72
grpc.h
GRPC_ARG_LB_POLICY_NAME
#define GRPC_ARG_LB_POLICY_NAME
Definition: grpc_types.h:309
grpc_pollset_set_destroy
void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set)
Definition: pollset_set.cc:33
gpr_atm_acq_load
#define gpr_atm_acq_load(p)
Definition: impl/codegen/atm_gcc_atomic.h:52
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
grpc_channel_args_destroy
void grpc_channel_args_destroy(grpc_channel_args *a)
Definition: channel_args.cc:360
operator!=
bool operator!=(const Bytes &a, const Bytes &b)
Definition: boringssl-with-bazel/src/crypto/test/test_util.h:58
server_address.h
gpr_atm_rel_store
#define gpr_atm_rel_store(p, value)
Definition: impl/codegen/atm_gcc_atomic.h:54
close
#define close
Definition: test-fs.c:48
gpr_mu_lock
GPRAPI void gpr_mu_lock(gpr_mu *mu)
gpr_event_init
GPRAPI void gpr_event_init(gpr_event *ev)
Definition: sync.cc:54
absl::GetFlag
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag< T > &flag)
Definition: abseil-cpp/absl/flags/flag.h:98
host_port.h
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
GPR_ERROR
#define GPR_ERROR
Definition: include/grpc/impl/codegen/log.h:57
grpc_pick_unused_port_or_die
int grpc_pick_unused_port_or_die(void)
grpc_core::Resolver::ResultHandler
Definition: resolver/resolver.h:84
grpc_pollset_kick
grpc_error_handle grpc_pollset_kick(grpc_pollset *pollset, grpc_pollset_worker *specific_worker)
Definition: pollset.cc:51
grpc_core::ServerAddressList
std::vector< ServerAddress > ServerAddressList
Definition: server_address.h:120
fake_udp_and_tcp_server.h
gpr_now
GPRAPI gpr_timespec gpr_now(gpr_clock_type clock)
grpc_core::ExecCtx
Definition: exec_ctx.h:97
ARES_SUCCESS
#define ARES_SUCCESS
Definition: ares.h:98
gpr_event_wait
GPRAPI void * gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline)
Definition: sync.cc:73
resolver_registry.h
executor.h
grpclb_balancer_addresses.h
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
resolver.h
GRPC_ARG_DNS_ENABLE_SRV_QUERIES
#define GRPC_ARG_DNS_ENABLE_SRV_QUERIES
Definition: grpc_types.h:433
BAD_SOCKET_RETURN_VAL
#define BAD_SOCKET_RETURN_VAL
Definition: resolver_component_test.cc:77
grpc_core::ResolverRegistry::CreateResolver
OrphanablePtr< Resolver > CreateResolver(absl::string_view target, const grpc_channel_args *args, grpc_pollset_set *pollset_set, std::shared_ptr< WorkSerializer > work_serializer, std::unique_ptr< Resolver::ResultHandler > result_handler) const
Definition: resolver_registry.cc:73
tcp_windows.h
test_config.h
gpr_atm
intptr_t gpr_atm
Definition: impl/codegen/atm_gcc_atomic.h:32
ares_channeldata
Definition: ares_private.h:266
gpr_event
Definition: impl/codegen/sync_generic.h:31
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
ares_set_servers_ports
CARES_EXTERN int ares_set_servers_ports(ares_channel channel, struct ares_addr_port_node *servers)
Definition: ares_options.c:195
grpc_channel_arg_integer_create
grpc_arg grpc_channel_arg_integer_create(char *name, int value)
Definition: channel_args.cc:484
gpr_time_add
GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b)
Definition: src/core/lib/gpr/time.cc:135
gpr_mu
pthread_mutex_t gpr_mu
Definition: impl/codegen/sync_posix.h:47
exec_ctx
grpc_core::ExecCtx exec_ctx
Definition: end2end_binder_transport_test.cc:75
http2_test_server.listen
def listen(endpoint, test_case)
Definition: http2_test_server.py:87
absl::Status
Definition: third_party/abseil-cpp/absl/status/status.h:424
grpc_pollset_shutdown
void grpc_pollset_shutdown(grpc_pollset *pollset, grpc_closure *closure)
Definition: pollset.cc:37
alloc.h
grpc_core::OrphanablePtr
std::unique_ptr< T, Deleter > OrphanablePtr
Definition: orphanable.h:64
L
lua_State * L
Definition: upb/upb/bindings/lua/main.c:35
fix_build_deps.r
r
Definition: fix_build_deps.py:491
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
sockaddr_windows.h
grpc_core::CoreConfiguration::resolver_registry
const ResolverRegistry & resolver_registry() const
Definition: core_configuration.h:157
absl::Status::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: third_party/abseil-cpp/absl/status/status.h:802
test_config.h
sockets
static uv_udp_t sockets[2500]
Definition: test-watcher-cross-stop.c:34
channel_args.h
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
grpc_core::testing::FakeUdpAndTcpServer::CloseSocketUponCloseFromPeer
static ProcessReadResult CloseSocketUponCloseFromPeer(int bytes_received_size, int read_error, int s)
Definition: fake_udp_and_tcp_server.cc:179
GPR_DEBUG
#define GPR_DEBUG
Definition: include/grpc/impl/codegen/log.h:55
test_server.socket
socket
Definition: test_server.py:65
closesocket
static int closesocket(int sock)
Definition: bio_test.cc:46
testing::UnorderedElementsAreArray
internal::UnorderedElementsAreArrayMatcher< typename ::std::iterator_traits< Iter >::value_type > UnorderedElementsAreArray(Iter first, Iter last)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8507
absl::StatusOr::value
const T & value() const &ABSL_ATTRIBUTE_LIFETIME_BOUND
Definition: abseil-cpp/absl/status/statusor.h:687
gpr_timespec
Definition: gpr_types.h:50
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
grpc_error
Definition: error_internal.h:42
sockaddr_posix.h
grpc_core::Timestamp::FromTimespecRoundUp
static Timestamp FromTimespecRoundUp(gpr_timespec t)
Definition: src/core/lib/gprpp/time.cc:136
GPR_CLOCK_REALTIME
@ GPR_CLOCK_REALTIME
Definition: gpr_types.h:39
grpc_arg::type
grpc_arg_type type
Definition: grpc_types.h:104
grpc_pollset
Definition: bm_cq_multiple_threads.cc:37
grpc_pollset_destroy
void grpc_pollset_destroy(grpc_pollset *pollset)
Definition: pollset.cc:41
to_string
static bool to_string(zval *from)
Definition: protobuf/php/ext/google/protobuf/convert.c:333
sync.h
grpc_closure
Definition: closure.h:56
grpc_pollset_set_add_pollset
void grpc_pollset_set_add_pollset(grpc_pollset_set *pollset_set, grpc_pollset *pollset)
Definition: pollset_set.cc:37
grpc_channel_args_find
const grpc_arg * grpc_channel_args_find(const grpc_channel_args *args, const char *name)
Definition: channel_args.cc:393
testing::HasSubstr
PolymorphicMatcher< internal::HasSubstrMatcher< internal::string > > HasSubstr(const internal::string &substring)
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:8803
grpc_shutdown
GRPCAPI void grpc_shutdown(void)
Definition: init.cc:209
grpc_ares_test_only_inject_config
void(* grpc_ares_test_only_inject_config)(ares_channel channel)
addr
struct sockaddr_in addr
Definition: libuv/docs/code/tcp-echo-server/main.c:10
thread
static uv_thread_t thread
Definition: test-async-null-cb.c:29
errno.h
grpc_core::ExecCtx::Get
static ExecCtx * Get()
Definition: exec_ctx.h:205
grpc_channel_args_copy_and_add
grpc_channel_args * grpc_channel_args_copy_and_add(const grpc_channel_args *src, const grpc_arg *to_add, size_t num_to_add)
Definition: channel_args.cc:224
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
DoNothing
static void DoNothing(void *, grpc_error_handle)
Definition: bm_call_create.cc:334
gpr_time_from_seconds
GPRAPI gpr_timespec gpr_time_from_seconds(int64_t s, gpr_clock_type clock_type)
Definition: src/core/lib/gpr/time.cc:123
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:10