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