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