• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2015 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 "src/core/lib/iomgr/resolve_address.h"
20 
21 #include <address_sorting/address_sorting.h>
22 #include <gmock/gmock.h>
23 #include <grpc/grpc.h>
24 #include <grpc/support/alloc.h>
25 #include <grpc/support/sync.h>
26 #include <grpc/support/time.h>
27 #include <gtest/gtest.h>
28 #include <string.h>
29 
30 #include "absl/functional/bind_front.h"
31 #include "absl/log/check.h"
32 #include "absl/log/log.h"
33 #include "absl/strings/match.h"
34 #include "src/core/config/config_vars.h"
35 #include "src/core/lib/iomgr/executor.h"
36 #include "src/core/lib/iomgr/iomgr.h"
37 #include "src/core/lib/iomgr/pollset.h"
38 #include "src/core/resolver/dns/c_ares/grpc_ares_wrapper.h"
39 #include "src/core/util/crash.h"
40 #include "src/core/util/string.h"
41 #include "src/core/util/sync.h"
42 #include "src/core/util/time.h"
43 #include "test/core/test_util/cmdline.h"
44 #include "test/core/test_util/fake_udp_and_tcp_server.h"
45 #include "test/core/test_util/test_config.h"
46 #include "test/cpp/util/test_config.h"
47 
48 namespace {
49 
NSecDeadline(int seconds)50 grpc_core::Timestamp NSecDeadline(int seconds) {
51   return grpc_core::Timestamp::FromTimespecRoundUp(
52       grpc_timeout_seconds_to_deadline(seconds));
53 }
54 
55 const char* g_resolver_type = "";
56 
57 class ResolveAddressTest : public ::testing::Test {
58  public:
ResolveAddressTest()59   ResolveAddressTest() {
60     grpc_init();
61     grpc_core::ExecCtx exec_ctx;
62     pollset_ = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
63     grpc_pollset_init(pollset_, &mu_);
64     pollset_set_ = grpc_pollset_set_create();
65     grpc_pollset_set_add_pollset(pollset_set_, pollset_);
66     default_inject_config_ = grpc_ares_test_only_inject_config;
67   }
68 
~ResolveAddressTest()69   ~ResolveAddressTest() override {
70     {
71       grpc_core::ExecCtx exec_ctx;
72       grpc_pollset_set_del_pollset(pollset_set_, pollset_);
73       grpc_pollset_set_destroy(pollset_set_);
74       grpc_closure do_nothing_cb;
75       GRPC_CLOSURE_INIT(&do_nothing_cb, DoNothing, nullptr,
76                         grpc_schedule_on_exec_ctx);
77       gpr_mu_lock(mu_);
78       grpc_pollset_shutdown(pollset_, &do_nothing_cb);
79       gpr_mu_unlock(mu_);
80       // exec_ctx needs to be flushed before calling grpc_pollset_destroy()
81       grpc_core::ExecCtx::Get()->Flush();
82       grpc_pollset_destroy(pollset_);
83       gpr_free(pollset_);
84       // reset this since it might have been altered
85       grpc_ares_test_only_inject_config = default_inject_config_;
86     }
87     grpc_shutdown();
88   }
89 
PollPollsetUntilRequestDone()90   void PollPollsetUntilRequestDone() {
91     // Try to give enough time for c-ares to run through its retries
92     // a few times if needed.
93     grpc_core::Timestamp deadline = NSecDeadline(90);
94     while (true) {
95       grpc_core::ExecCtx exec_ctx;
96       {
97         grpc_core::MutexLockForGprMu lock(mu_);
98         if (done_) {
99           break;
100         }
101         grpc_core::Duration time_left = deadline - grpc_core::Timestamp::Now();
102         VLOG(2) << "done=" << done_ << ", time_left=" << time_left.millis();
103         ASSERT_GE(time_left, grpc_core::Duration::Zero());
104         grpc_pollset_worker* worker = nullptr;
105         GRPC_LOG_IF_ERROR("pollset_work", grpc_pollset_work(pollset_, &worker,
106                                                             NSecDeadline(1)));
107       }
108     }
109   }
110 
MustSucceed(absl::StatusOr<std::vector<grpc_resolved_address>> result)111   void MustSucceed(absl::StatusOr<std::vector<grpc_resolved_address>> result) {
112     EXPECT_EQ(result.status(), absl::OkStatus());
113     EXPECT_FALSE(result->empty());
114     Finish();
115   }
116 
MustFail(absl::StatusOr<std::vector<grpc_resolved_address>> result)117   void MustFail(absl::StatusOr<std::vector<grpc_resolved_address>> result) {
118     EXPECT_NE(result.status(), absl::OkStatus());
119     Finish();
120   }
121 
MustFailExpectCancelledErrorMessage(absl::StatusOr<std::vector<grpc_resolved_address>> result)122   void MustFailExpectCancelledErrorMessage(
123       absl::StatusOr<std::vector<grpc_resolved_address>> result) {
124     EXPECT_NE(result.status(), absl::OkStatus());
125     EXPECT_THAT(result.status().ToString(),
126                 testing::HasSubstr("DNS query cancelled"));
127     Finish();
128   }
129 
DontCare(absl::StatusOr<std::vector<grpc_resolved_address>>)130   void DontCare(
131       absl::StatusOr<std::vector<grpc_resolved_address>> /* result */) {
132     Finish();
133   }
134 
135   // This test assumes the environment has an ipv6 loopback
MustSucceedWithIPv6First(absl::StatusOr<std::vector<grpc_resolved_address>> result)136   void MustSucceedWithIPv6First(
137       absl::StatusOr<std::vector<grpc_resolved_address>> result) {
138     EXPECT_EQ(result.status(), absl::OkStatus());
139     EXPECT_TRUE(!result->empty() &&
140                 reinterpret_cast<const struct sockaddr*>((*result)[0].addr)
141                         ->sa_family == AF_INET6);
142     Finish();
143   }
144 
MustSucceedWithIPv4First(absl::StatusOr<std::vector<grpc_resolved_address>> result)145   void MustSucceedWithIPv4First(
146       absl::StatusOr<std::vector<grpc_resolved_address>> result) {
147     EXPECT_EQ(result.status(), absl::OkStatus());
148     EXPECT_TRUE(!result->empty() &&
149                 reinterpret_cast<const struct sockaddr*>((*result)[0].addr)
150                         ->sa_family == AF_INET);
151     Finish();
152   }
153 
MustNotBeCalled(absl::StatusOr<std::vector<grpc_resolved_address>>)154   void MustNotBeCalled(
155       absl::StatusOr<std::vector<grpc_resolved_address>> /*result*/) {
156     FAIL() << "This should never be called";
157   }
158 
Finish()159   void Finish() {
160     grpc_core::MutexLockForGprMu lock(mu_);
161     done_ = true;
162     GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(pollset_, nullptr));
163   }
164 
pollset_set() const165   grpc_pollset_set* pollset_set() const { return pollset_set_; }
166 
167  private:
DoNothing(void *,grpc_error_handle)168   static void DoNothing(void* /*arg*/, grpc_error_handle /*error*/) {}
169 
170   gpr_mu* mu_;
171   bool done_ = false;      // guarded by mu
172   grpc_pollset* pollset_;  // guarded by mu
173   grpc_pollset_set* pollset_set_;
174   // the default value of grpc_ares_test_only_inject_config, which might
175   // be modified during a test
176   void (*default_inject_config_)(ares_channel* channel) = nullptr;
177 };
178 
179 }  // namespace
180 
TEST_F(ResolveAddressTest,Localhost)181 TEST_F(ResolveAddressTest, Localhost) {
182   grpc_core::ExecCtx exec_ctx;
183   grpc_core::GetDNSResolver()->LookupHostname(
184       absl::bind_front(&ResolveAddressTest::MustSucceed, this), "localhost:1",
185       "", grpc_core::kDefaultDNSRequestTimeout, pollset_set(), "");
186   grpc_core::ExecCtx::Get()->Flush();
187   PollPollsetUntilRequestDone();
188 }
189 
TEST_F(ResolveAddressTest,DefaultPort)190 TEST_F(ResolveAddressTest, DefaultPort) {
191   grpc_core::ExecCtx exec_ctx;
192   grpc_core::GetDNSResolver()->LookupHostname(
193       absl::bind_front(&ResolveAddressTest::MustSucceed, this), "localhost",
194       "1", grpc_core::kDefaultDNSRequestTimeout, pollset_set(), "");
195   grpc_core::ExecCtx::Get()->Flush();
196   PollPollsetUntilRequestDone();
197 }
198 
TEST_F(ResolveAddressTest,LocalhostResultHasIPv6First)199 TEST_F(ResolveAddressTest, LocalhostResultHasIPv6First) {
200   if (std::string(g_resolver_type) != "ares") {
201     GTEST_SKIP() << "this test is only valid with the c-ares resolver";
202   }
203   grpc_core::ExecCtx exec_ctx;
204   grpc_core::GetDNSResolver()->LookupHostname(
205       absl::bind_front(&ResolveAddressTest::MustSucceedWithIPv6First, this),
206       "localhost:1", "", grpc_core::kDefaultDNSRequestTimeout, pollset_set(),
207       "");
208   grpc_core::ExecCtx::Get()->Flush();
209   PollPollsetUntilRequestDone();
210 }
211 
212 namespace {
213 
IPv6DisabledGetSourceAddr(address_sorting_source_addr_factory *,const address_sorting_address * dest_addr,address_sorting_address * source_addr)214 bool IPv6DisabledGetSourceAddr(address_sorting_source_addr_factory* /*factory*/,
215                                const address_sorting_address* dest_addr,
216                                address_sorting_address* source_addr) {
217   // Mock lack of IPv6. For IPv4, set the source addr to be the same
218   // as the destination; tests won't actually connect on the result anyways.
219   if (address_sorting_abstract_get_family(dest_addr) ==
220       ADDRESS_SORTING_AF_INET6) {
221     return false;
222   }
223   memcpy(source_addr->addr, &dest_addr->addr, dest_addr->len);
224   source_addr->len = dest_addr->len;
225   return true;
226 }
227 
DeleteSourceAddrFactory(address_sorting_source_addr_factory * factory)228 void DeleteSourceAddrFactory(address_sorting_source_addr_factory* factory) {
229   delete factory;
230 }
231 
232 const address_sorting_source_addr_factory_vtable
233     kMockIpv6DisabledSourceAddrFactoryVtable = {
234         IPv6DisabledGetSourceAddr,
235         DeleteSourceAddrFactory,
236 };
237 
238 }  // namespace
239 
TEST_F(ResolveAddressTest,LocalhostResultHasIPv4FirstWhenIPv6IsntAvailable)240 TEST_F(ResolveAddressTest, LocalhostResultHasIPv4FirstWhenIPv6IsntAvailable) {
241   if (std::string(g_resolver_type) != "ares") {
242     GTEST_SKIP() << "this test is only valid with the c-ares resolver";
243   }
244   // Mock the kernel source address selection. Note that source addr factory
245   // is reset to its default value during grpc initialization for each test.
246   address_sorting_source_addr_factory* mock =
247       new address_sorting_source_addr_factory();
248   mock->vtable = &kMockIpv6DisabledSourceAddrFactoryVtable;
249   address_sorting_override_source_addr_factory_for_testing(mock);
250   // run the test
251   grpc_core::ExecCtx exec_ctx;
252   grpc_core::GetDNSResolver()->LookupHostname(
253       absl::bind_front(&ResolveAddressTest::MustSucceedWithIPv4First, this),
254       "localhost:1", "", grpc_core::kDefaultDNSRequestTimeout, pollset_set(),
255       "");
256   grpc_core::ExecCtx::Get()->Flush();
257   PollPollsetUntilRequestDone();
258 }
259 
TEST_F(ResolveAddressTest,NonNumericDefaultPort)260 TEST_F(ResolveAddressTest, NonNumericDefaultPort) {
261   grpc_core::ExecCtx exec_ctx;
262   grpc_core::GetDNSResolver()->LookupHostname(
263       absl::bind_front(&ResolveAddressTest::MustSucceed, this), "localhost",
264       "http", grpc_core::kDefaultDNSRequestTimeout, pollset_set(), "");
265   grpc_core::ExecCtx::Get()->Flush();
266   PollPollsetUntilRequestDone();
267 }
268 
TEST_F(ResolveAddressTest,MissingDefaultPort)269 TEST_F(ResolveAddressTest, MissingDefaultPort) {
270   grpc_core::ExecCtx exec_ctx;
271   grpc_core::GetDNSResolver()->LookupHostname(
272       absl::bind_front(&ResolveAddressTest::MustFail, this), "localhost", "",
273       grpc_core::kDefaultDNSRequestTimeout, pollset_set(), "");
274   grpc_core::ExecCtx::Get()->Flush();
275   PollPollsetUntilRequestDone();
276 }
277 
TEST_F(ResolveAddressTest,IPv6WithPort)278 TEST_F(ResolveAddressTest, IPv6WithPort) {
279   grpc_core::ExecCtx exec_ctx;
280   grpc_core::GetDNSResolver()->LookupHostname(
281       absl::bind_front(&ResolveAddressTest::MustSucceed, this),
282       "[2001:db8::1]:1", "", grpc_core::kDefaultDNSRequestTimeout,
283       pollset_set(), "");
284   grpc_core::ExecCtx::Get()->Flush();
285   PollPollsetUntilRequestDone();
286 }
287 
TestIPv6WithoutPort(ResolveAddressTest * test,const char * target)288 void TestIPv6WithoutPort(ResolveAddressTest* test, const char* target) {
289   grpc_core::ExecCtx exec_ctx;
290   grpc_core::GetDNSResolver()->LookupHostname(
291       absl::bind_front(&ResolveAddressTest::MustSucceed, test), target, "80",
292       grpc_core::kDefaultDNSRequestTimeout, test->pollset_set(), "");
293   grpc_core::ExecCtx::Get()->Flush();
294   test->PollPollsetUntilRequestDone();
295 }
296 
TEST_F(ResolveAddressTest,IPv6WithoutPortNoBrackets)297 TEST_F(ResolveAddressTest, IPv6WithoutPortNoBrackets) {
298   TestIPv6WithoutPort(this, "2001:db8::1");
299 }
300 
TEST_F(ResolveAddressTest,IPv6WithoutPortWithBrackets)301 TEST_F(ResolveAddressTest, IPv6WithoutPortWithBrackets) {
302   TestIPv6WithoutPort(this, "[2001:db8::1]");
303 }
304 
TEST_F(ResolveAddressTest,IPv6WithoutPortV4MappedV6)305 TEST_F(ResolveAddressTest, IPv6WithoutPortV4MappedV6) {
306   TestIPv6WithoutPort(this, "2001:db8::1.2.3.4");
307 }
308 
TestInvalidIPAddress(ResolveAddressTest * test,const char * target)309 void TestInvalidIPAddress(ResolveAddressTest* test, const char* target) {
310   grpc_core::ExecCtx exec_ctx;
311   grpc_core::GetDNSResolver()->LookupHostname(
312       absl::bind_front(&ResolveAddressTest::MustFail, test), target, "",
313       grpc_core::kDefaultDNSRequestTimeout, test->pollset_set(), "");
314   grpc_core::ExecCtx::Get()->Flush();
315   test->PollPollsetUntilRequestDone();
316 }
317 
TEST_F(ResolveAddressTest,InvalidIPv4Addresses)318 TEST_F(ResolveAddressTest, InvalidIPv4Addresses) {
319   TestInvalidIPAddress(this, "293.283.1238.3:1");
320 }
321 
TEST_F(ResolveAddressTest,InvalidIPv6Addresses)322 TEST_F(ResolveAddressTest, InvalidIPv6Addresses) {
323   TestInvalidIPAddress(this, "[2001:db8::11111]:1");
324 }
325 
TestUnparsableHostPort(ResolveAddressTest * test,const char * target)326 void TestUnparsableHostPort(ResolveAddressTest* test, const char* target) {
327   grpc_core::ExecCtx exec_ctx;
328   grpc_core::GetDNSResolver()->LookupHostname(
329       absl::bind_front(&ResolveAddressTest::MustFail, test), target, "1",
330       grpc_core::kDefaultDNSRequestTimeout, test->pollset_set(), "");
331   grpc_core::ExecCtx::Get()->Flush();
332   test->PollPollsetUntilRequestDone();
333 }
334 
TEST_F(ResolveAddressTest,UnparsableHostPortsOnlyBracket)335 TEST_F(ResolveAddressTest, UnparsableHostPortsOnlyBracket) {
336   TestUnparsableHostPort(this, "[");
337 }
338 
TEST_F(ResolveAddressTest,UnparsableHostPortsMissingRightBracket)339 TEST_F(ResolveAddressTest, UnparsableHostPortsMissingRightBracket) {
340   TestUnparsableHostPort(this, "[::1");
341 }
342 
TEST_F(ResolveAddressTest,UnparsableHostPortsBadPort)343 TEST_F(ResolveAddressTest, UnparsableHostPortsBadPort) {
344   TestUnparsableHostPort(this, "[::1]bad");
345 }
346 
TEST_F(ResolveAddressTest,UnparsableHostPortsBadIPv6)347 TEST_F(ResolveAddressTest, UnparsableHostPortsBadIPv6) {
348   TestUnparsableHostPort(this, "[1.2.3.4]");
349 }
350 
TEST_F(ResolveAddressTest,UnparsableHostPortsBadLocalhost)351 TEST_F(ResolveAddressTest, UnparsableHostPortsBadLocalhost) {
352   TestUnparsableHostPort(this, "[localhost]");
353 }
354 
TEST_F(ResolveAddressTest,UnparsableHostPortsBadLocalhostWithPort)355 TEST_F(ResolveAddressTest, UnparsableHostPortsBadLocalhostWithPort) {
356   TestUnparsableHostPort(this, "[localhost]:1");
357 }
358 
359 // Kick off a simple DNS resolution and then immediately cancel. This
360 // test doesn't care what the result is, just that we don't crash etc.
TEST_F(ResolveAddressTest,ImmediateCancel)361 TEST_F(ResolveAddressTest, ImmediateCancel) {
362   grpc_core::ExecCtx exec_ctx;
363   auto resolver = grpc_core::GetDNSResolver();
364   auto request_handle = resolver->LookupHostname(
365       absl::bind_front(&ResolveAddressTest::DontCare, this), "localhost:1", "1",
366       grpc_core::kDefaultDNSRequestTimeout, pollset_set(), "");
367   if (resolver->Cancel(request_handle)) {
368     Finish();
369   }
370   grpc_core::ExecCtx::Get()->Flush();
371   PollPollsetUntilRequestDone();
372 }
373 
374 // Attempt to cancel a request after it has completed.
TEST_F(ResolveAddressTest,CancelDoesNotSucceed)375 TEST_F(ResolveAddressTest, CancelDoesNotSucceed) {
376   grpc_core::ExecCtx exec_ctx;
377   auto resolver = grpc_core::GetDNSResolver();
378   auto request_handle = resolver->LookupHostname(
379       absl::bind_front(&ResolveAddressTest::MustSucceed, this), "localhost:1",
380       "1", grpc_core::kDefaultDNSRequestTimeout, pollset_set(), "");
381   grpc_core::ExecCtx::Get()->Flush();
382   PollPollsetUntilRequestDone();
383   ASSERT_FALSE(resolver->Cancel(request_handle));
384 }
385 
386 namespace {
387 
388 int g_fake_non_responsive_dns_server_port;
389 
InjectNonResponsiveDNSServer(ares_channel * channel)390 void InjectNonResponsiveDNSServer(ares_channel* channel) {
391   VLOG(2) << "Injecting broken nameserver list. Bad server address:|[::1]:"
392           << g_fake_non_responsive_dns_server_port << "|.";
393   // Configure a non-responsive DNS server at the front of c-ares's nameserver
394   // list.
395   struct ares_addr_port_node dns_server_addrs[1];
396   memset(dns_server_addrs, 0, sizeof(dns_server_addrs));
397   dns_server_addrs[0].family = AF_INET6;
398   (reinterpret_cast<char*>(&dns_server_addrs[0].addr.addr6))[15] = 0x1;
399   dns_server_addrs[0].tcp_port = g_fake_non_responsive_dns_server_port;
400   dns_server_addrs[0].udp_port = g_fake_non_responsive_dns_server_port;
401   dns_server_addrs[0].next = nullptr;
402   ASSERT_EQ(ares_set_servers_ports(*channel, dns_server_addrs), ARES_SUCCESS);
403 }
404 
405 }  // namespace
406 
TEST_F(ResolveAddressTest,CancelWithNonResponsiveDNSServer)407 TEST_F(ResolveAddressTest, CancelWithNonResponsiveDNSServer) {
408   if (std::string(g_resolver_type) != "ares") {
409     GTEST_SKIP() << "the native resolver doesn't support cancellation, so we "
410                     "can only test this with c-ares";
411   }
412   // Inject an unresponsive DNS server into the resolver's DNS server config
413   grpc_core::testing::FakeUdpAndTcpServer fake_dns_server(
414       grpc_core::testing::FakeUdpAndTcpServer::AcceptMode::
415           kWaitForClientToSendFirstBytes,
416       grpc_core::testing::FakeUdpAndTcpServer::CloseSocketUponCloseFromPeer);
417   g_fake_non_responsive_dns_server_port = fake_dns_server.port();
418   grpc_ares_test_only_inject_config = InjectNonResponsiveDNSServer;
419   // Run the test
420   grpc_core::ExecCtx exec_ctx;
421   auto resolver = grpc_core::GetDNSResolver();
422   auto request_handle = resolver->LookupHostname(
423       absl::bind_front(&ResolveAddressTest::MustNotBeCalled, this),
424       "foo.bar.com:1", "1", grpc_core::kDefaultDNSRequestTimeout, pollset_set(),
425       "");
426   grpc_core::ExecCtx::Get()->Flush();  // initiate DNS requests
427   ASSERT_TRUE(resolver->Cancel(request_handle));
428   Finish();
429   // let cancellation work finish to ensure the callback is not called
430   grpc_core::ExecCtx::Get()->Flush();
431   PollPollsetUntilRequestDone();
432 }
433 
434 // RAII class for pollset and pollset_set creation
435 class PollsetSetWrapper {
436  public:
Create()437   static std::unique_ptr<PollsetSetWrapper> Create() {
438     return absl::WrapUnique<PollsetSetWrapper>(new PollsetSetWrapper());
439   }
440 
~PollsetSetWrapper()441   ~PollsetSetWrapper() {
442     grpc_pollset_set_del_pollset(pss_, ps_);
443     grpc_pollset_set_destroy(pss_);
444     grpc_pollset_shutdown(ps_, nullptr);
445     grpc_core::ExecCtx::Get()->Flush();
446     grpc_pollset_destroy(ps_);
447     gpr_free(ps_);
448     VLOG(2) << "PollsetSetWrapper:" << this << " deleted";
449   }
450 
pollset_set()451   grpc_pollset_set* pollset_set() { return pss_; }
452 
453  private:
PollsetSetWrapper()454   PollsetSetWrapper() {
455     ps_ = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
456     grpc_pollset_init(ps_, &mu_);
457     pss_ = grpc_pollset_set_create();
458     grpc_pollset_set_add_pollset(pss_, ps_);
459     VLOG(2) << "PollsetSetWrapper:" << this << " created";
460   }
461 
462   gpr_mu* mu_;
463   grpc_pollset* ps_;
464   grpc_pollset_set* pss_;
465 };
466 
TEST_F(ResolveAddressTest,DeleteInterestedPartiesAfterCancellation)467 TEST_F(ResolveAddressTest, DeleteInterestedPartiesAfterCancellation) {
468   // Regression test for race around interested_party deletion after
469   // cancellation.
470   if (absl::string_view(g_resolver_type) != "ares") {
471     GTEST_SKIP() << "the native resolver doesn't support cancellation, so we "
472                     "can only test this with c-ares";
473   }
474   // Inject an unresponsive DNS server into the resolver's DNS server config
475   grpc_core::testing::FakeUdpAndTcpServer fake_dns_server(
476       grpc_core::testing::FakeUdpAndTcpServer::AcceptMode::
477           kWaitForClientToSendFirstBytes,
478       grpc_core::testing::FakeUdpAndTcpServer::CloseSocketUponCloseFromPeer);
479   g_fake_non_responsive_dns_server_port = fake_dns_server.port();
480   grpc_ares_test_only_inject_config = InjectNonResponsiveDNSServer;
481   {
482     grpc_core::ExecCtx exec_ctx;
483     // Create a pollset_set, destroyed immediately after cancellation
484     std::unique_ptr<PollsetSetWrapper> pss = PollsetSetWrapper::Create();
485     // Run the test
486     auto resolver = grpc_core::GetDNSResolver();
487     auto request_handle = resolver->LookupHostname(
488         absl::bind_front(&ResolveAddressTest::MustNotBeCalled, this),
489         "foo.bar.com:1", "1", grpc_core::kDefaultDNSRequestTimeout,
490         pss->pollset_set(), "");
491     grpc_core::ExecCtx::Get()->Flush();  // initiate DNS requests
492     ASSERT_TRUE(resolver->Cancel(request_handle));
493   }
494   {
495     // let cancellation work finish to ensure the callback is not called
496     grpc_core::ExecCtx ctx;
497     Finish();
498   }
499   PollPollsetUntilRequestDone();
500 }
501 
TEST_F(ResolveAddressTest,NativeResolverCannotLookupSRVRecords)502 TEST_F(ResolveAddressTest, NativeResolverCannotLookupSRVRecords) {
503   if (absl::string_view(g_resolver_type) == "ares") {
504     GTEST_SKIP() << "this test is only for native resolvers";
505   }
506   grpc_core::ExecCtx exec_ctx;
507   grpc_core::GetDNSResolver()->LookupSRV(
508       [this](absl::StatusOr<std::vector<grpc_resolved_address>> error) {
509         grpc_core::ExecCtx exec_ctx;
510         EXPECT_EQ(error.status().code(), absl::StatusCode::kUnimplemented);
511         Finish();
512       },
513       "localhost", grpc_core::kDefaultDNSRequestTimeout, pollset_set(),
514       /*name_server=*/"");
515   grpc_core::ExecCtx::Get()->Flush();
516   PollPollsetUntilRequestDone();
517 }
518 
TEST_F(ResolveAddressTest,NativeResolverCannotLookupTXTRecords)519 TEST_F(ResolveAddressTest, NativeResolverCannotLookupTXTRecords) {
520   if (absl::string_view(g_resolver_type) == "ares") {
521     GTEST_SKIP() << "this test is only for native resolvers";
522   }
523   grpc_core::ExecCtx exec_ctx;
524   grpc_core::GetDNSResolver()->LookupTXT(
525       [this](absl::StatusOr<std::string> error) {
526         grpc_core::ExecCtx exec_ctx;
527         EXPECT_EQ(error.status().code(), absl::StatusCode::kUnimplemented);
528         Finish();
529       },
530       "localhost", grpc_core::kDefaultDNSRequestTimeout, pollset_set(),
531       /*name_server=*/"");
532   grpc_core::ExecCtx::Get()->Flush();
533   PollPollsetUntilRequestDone();
534 }
535 
main(int argc,char ** argv)536 int main(int argc, char** argv) {
537   // Configure the DNS resolver (c-ares vs. native) based on the
538   // name of the binary. TODO(apolcyn): is there a way to pass command
539   // line flags to a gtest that it works in all of our test environments?
540   if (absl::StrContains(std::string(argv[0]), "using_native_resolver")) {
541     g_resolver_type = "native";
542   } else if (absl::StrContains(std::string(argv[0]), "using_ares_resolver")) {
543     g_resolver_type = "ares";
544   } else {
545     CHECK(0);
546   }
547   grpc_core::ConfigVars::Overrides overrides;
548   overrides.dns_resolver = g_resolver_type;
549   grpc_core::ConfigVars::SetOverrides(overrides);
550   ::testing::InitGoogleTest(&argc, argv);
551   grpc::testing::TestEnvironment env(&argc, argv);
552   const auto result = RUN_ALL_TESTS();
553   return result;
554 }
555