blob: 66570ace550b8803b24b76af9fa39bde19dbde43 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001#include "ares-test.h"
2
3// library initialization is only needed for windows builds
4#ifdef WIN32
5#define EXPECTED_NONINIT ARES_ENOTINITIALIZED
6#else
7#define EXPECTED_NONINIT ARES_SUCCESS
8#endif
9
10namespace ares {
11namespace test {
12
13TEST(LibraryInit, Basic) {
14 EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
15 EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
16 EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
17 ares_library_cleanup();
18 EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
19}
20
21TEST(LibraryInit, UnexpectedCleanup) {
22 EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
23 ares_library_cleanup();
24 EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
25}
26
27TEST(LibraryInit, DISABLED_InvalidParam) {
28 // TODO: police flags argument to ares_library_init()
29 EXPECT_EQ(ARES_EBADQUERY, ares_library_init(ARES_LIB_INIT_ALL << 2));
30 EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
31 ares_library_cleanup();
32}
33
34TEST(LibraryInit, Nested) {
35 EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
36 EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
37 EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
38 EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
39 EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
40 ares_library_cleanup();
41 EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
42 ares_library_cleanup();
43 EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
44}
45
46TEST(LibraryInit, BasicChannelInit) {
47 EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
48 ares_channel channel = nullptr;
49 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
50 EXPECT_NE(nullptr, channel);
51 ares_destroy(channel);
52 ares_library_cleanup();
53}
54
55TEST_F(LibraryTest, OptionsChannelInit) {
56 struct ares_options opts = {0};
57 int optmask = 0;
58 opts.flags = ARES_FLAG_USEVC | ARES_FLAG_PRIMARY;
59 optmask |= ARES_OPT_FLAGS;
60 opts.timeout = 2000;
61 optmask |= ARES_OPT_TIMEOUTMS;
62 opts.tries = 2;
63 optmask |= ARES_OPT_TRIES;
64 opts.ndots = 4;
65 optmask |= ARES_OPT_NDOTS;
66 opts.udp_port = 54;
67 optmask |= ARES_OPT_UDP_PORT;
68 opts.tcp_port = 54;
69 optmask |= ARES_OPT_TCP_PORT;
70 opts.socket_send_buffer_size = 514;
71 optmask |= ARES_OPT_SOCK_SNDBUF;
72 opts.socket_receive_buffer_size = 514;
73 optmask |= ARES_OPT_SOCK_RCVBUF;
74 opts.ednspsz = 1280;
75 optmask |= ARES_OPT_EDNSPSZ;
76 opts.nservers = 2;
77 opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
78 opts.servers[0].s_addr = htonl(0x01020304);
79 opts.servers[1].s_addr = htonl(0x02030405);
80 optmask |= ARES_OPT_SERVERS;
81 opts.ndomains = 2;
82 opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
83 opts.domains[0] = strdup("example.com");
84 opts.domains[1] = strdup("example2.com");
85 optmask |= ARES_OPT_DOMAINS;
86 opts.lookups = strdup("b");
87 optmask |= ARES_OPT_LOOKUPS;
88 optmask |= ARES_OPT_ROTATE;
89
90 ares_channel channel = nullptr;
91 EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
92 EXPECT_NE(nullptr, channel);
93
94 ares_channel channel2 = nullptr;
95 EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel));
96
97 struct ares_options opts2 = {0};
98 int optmask2 = 0;
99 EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel2, &opts2, &optmask2));
100
101 // Note that not all opts-settable fields are saved (e.g.
102 // ednspsz, socket_{send,receive}_buffer_size).
103 EXPECT_EQ(opts.flags, opts2.flags);
104 EXPECT_EQ(opts.timeout, opts2.timeout);
105 EXPECT_EQ(opts.tries, opts2.tries);
106 EXPECT_EQ(opts.ndots, opts2.ndots);
107 EXPECT_EQ(opts.udp_port, opts2.udp_port);
108 EXPECT_EQ(opts.tcp_port, opts2.tcp_port);
109 EXPECT_EQ(1, opts2.nservers); // Truncated by ARES_FLAG_PRIMARY
110 EXPECT_EQ(opts.servers[0].s_addr, opts2.servers[0].s_addr);
111 EXPECT_EQ(opts.ndomains, opts2.ndomains);
112 EXPECT_EQ(std::string(opts.domains[0]), std::string(opts2.domains[0]));
113 EXPECT_EQ(std::string(opts.domains[1]), std::string(opts2.domains[1]));
114 EXPECT_EQ(std::string(opts.lookups), std::string(opts2.lookups));
115
116 ares_destroy_options(&opts);
117 ares_destroy_options(&opts2);
118 ares_destroy(channel);
119 ares_destroy(channel2);
120}
121
122TEST_F(LibraryTest, ChannelAllocFail) {
123 ares_channel channel;
124 for (int ii = 1; ii <= 25; ii++) {
125 ClearFails();
126 SetAllocFail(ii);
127 channel = nullptr;
128 int rc = ares_init(&channel);
129 // The number of allocations depends on local environment, so don't expect ENOMEM.
130 if (rc == ARES_ENOMEM) {
131 EXPECT_EQ(nullptr, channel);
132 } else {
133 ares_destroy(channel);
134 }
135 }
136}
137
138TEST_F(LibraryTest, OptionsChannelAllocFail) {
139 struct ares_options opts = {0};
140 int optmask = 0;
141 opts.flags = ARES_FLAG_USEVC;
142 optmask |= ARES_OPT_FLAGS;
143 opts.timeout = 2;
144 optmask |= ARES_OPT_TIMEOUT;
145 opts.tries = 2;
146 optmask |= ARES_OPT_TRIES;
147 opts.ndots = 4;
148 optmask |= ARES_OPT_NDOTS;
149 opts.udp_port = 54;
150 optmask |= ARES_OPT_UDP_PORT;
151 opts.tcp_port = 54;
152 optmask |= ARES_OPT_TCP_PORT;
153 opts.socket_send_buffer_size = 514;
154 optmask |= ARES_OPT_SOCK_SNDBUF;
155 opts.socket_receive_buffer_size = 514;
156 optmask |= ARES_OPT_SOCK_RCVBUF;
157 opts.ednspsz = 1280;
158 optmask |= ARES_OPT_EDNSPSZ;
159 opts.nservers = 2;
160 opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
161 opts.servers[0].s_addr = htonl(0x01020304);
162 opts.servers[1].s_addr = htonl(0x02030405);
163 optmask |= ARES_OPT_SERVERS;
164 opts.ndomains = 2;
165 opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
166 opts.domains[0] = strdup("example.com");
167 opts.domains[1] = strdup("example2.com");
168 optmask |= ARES_OPT_DOMAINS;
169 opts.lookups = strdup("b");
170 optmask |= ARES_OPT_LOOKUPS;
171 optmask |= ARES_OPT_ROTATE;
172
173 ares_channel channel = nullptr;
174 for (int ii = 1; ii <= 8; ii++) {
175 ClearFails();
176 SetAllocFail(ii);
177 int rc = ares_init_options(&channel, &opts, optmask);
178 if (rc == ARES_ENOMEM) {
179 EXPECT_EQ(nullptr, channel);
180 } else {
181 EXPECT_EQ(ARES_SUCCESS, rc);
182 ares_destroy(channel);
183 channel = nullptr;
184 }
185 }
186 ClearFails();
187
188 EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
189 EXPECT_NE(nullptr, channel);
190
191 // Add some servers and a sortlist for flavour.
192 EXPECT_EQ(ARES_SUCCESS,
193 ares_set_servers_csv(channel, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
194 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel, "1.2.3.4 2.3.4.5"));
195
196 ares_channel channel2 = nullptr;
197 for (int ii = 1; ii <= 18; ii++) {
198 ClearFails();
199 SetAllocFail(ii);
200 EXPECT_EQ(ARES_ENOMEM, ares_dup(&channel2, channel)) << ii;
201 EXPECT_EQ(nullptr, channel2) << ii;
202 }
203
204 struct ares_options opts2;
205 int optmask2 = 0;
206 for (int ii = 1; ii <= 6; ii++) {
207 memset(&opts2, 0, sizeof(opts2));
208 ClearFails();
209 SetAllocFail(ii);
210 EXPECT_EQ(ARES_ENOMEM, ares_save_options(channel, &opts2, &optmask2)) << ii;
211 // May still have allocations even after ARES_ENOMEM return code.
212 ares_destroy_options(&opts2);
213 }
214 ares_destroy_options(&opts);
215 ares_destroy(channel);
216}
217
218TEST_F(LibraryTest, FailChannelInit) {
219 EXPECT_EQ(ARES_SUCCESS,
220 ares_library_init_mem(ARES_LIB_INIT_ALL,
221 &LibraryTest::amalloc,
222 &LibraryTest::afree,
223 &LibraryTest::arealloc));
224 SetAllocFail(1);
225 ares_channel channel = nullptr;
226 EXPECT_EQ(ARES_ENOMEM, ares_init(&channel));
227 EXPECT_EQ(nullptr, channel);
228 ares_library_cleanup();
229}
230
231#ifndef WIN32
232TEST_F(LibraryTest, EnvInit) {
233 ares_channel channel = nullptr;
234 EnvValue v1("LOCALDOMAIN", "this.is.local");
235 EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
236 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
237 ares_destroy(channel);
238}
239
240TEST_F(LibraryTest, EnvInitAllocFail) {
241 ares_channel channel;
242 EnvValue v1("LOCALDOMAIN", "this.is.local");
243 EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
244 for (int ii = 1; ii <= 10; ii++) {
245 ClearFails();
246 SetAllocFail(ii);
247 channel = nullptr;
248 int rc = ares_init(&channel);
249 if (rc == ARES_SUCCESS) {
250 ares_destroy(channel);
251 } else {
252 EXPECT_EQ(ARES_ENOMEM, rc);
253 }
254 }
255}
256#endif
257
258TEST_F(DefaultChannelTest, SetAddresses) {
259 ares_set_local_ip4(channel_, 0x01020304);
260 byte addr6[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
261 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
262 ares_set_local_ip6(channel_, addr6);
263 ares_set_local_dev(channel_, "dummy");
264}
265
266TEST_F(DefaultChannelTest, SetSortlistFailures) {
267 EXPECT_EQ(ARES_ENODATA, ares_set_sortlist(nullptr, "1.2.3.4"));
268 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; lwk"));
269 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; 0x123"));
270}
271
272TEST_F(DefaultChannelTest, SetSortlistVariants) {
273 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4"));
274 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4 ; 2.3.4.5"));
275 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "129.1.1.1"));
276 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "192.1.1.1"));
277 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "224.1.1.1"));
278 EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "225.1.1.1"));
279}
280
281TEST_F(DefaultChannelTest, SetSortlistAllocFail) {
282 for (int ii = 1; ii <= 3; ii++) {
283 ClearFails();
284 SetAllocFail(ii);
285 EXPECT_EQ(ARES_ENOMEM, ares_set_sortlist(channel_, "12.13.0.0/16 1234::5678/40 1.2.3.4")) << ii;
286 }
287}
288
289#ifdef USE_WINSOCK
290TEST(Init, NoLibraryInit) {
291 ares_channel channel = nullptr;
292 EXPECT_EQ(ARES_ENOTINITIALIZED, ares_init(&channel));
293}
294#endif
295
296#ifdef HAVE_CONTAINER
297// These tests rely on the ability of non-root users to create a chroot
298// using Linux namespaces.
299
300
301// The library uses a variety of information sources to initialize a channel,
302// in particular to determine:
303// - search: the search domains to use
304// - servers: the name servers to use
305// - lookup: whether to check files or DNS or both (e.g. "fb")
306// - options: various resolver options
307// - sortlist: the order of preference for IP addresses
308//
309// The first source from the following list is used:
310// - init_by_options(): explicitly specified values in struct ares_options
311// - init_by_environment(): values from the environment:
312// - LOCALDOMAIN -> search (single value)
313// - RES_OPTIONS -> options
314// - init_by_resolv_conf(): values from various config files:
315// - /etc/resolv.conf -> search, lookup, servers, sortlist, options
316// - /etc/nsswitch.conf -> lookup
317// - /etc/host.conf -> lookup
318// - /etc/svc.conf -> lookup
319// - init_by_defaults(): fallback values:
320// - gethostname(3) -> domain
321// - "fb" -> lookup
322
323NameContentList filelist = {
324 {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
325 "sortlist 1.2.3.4/16 2.3.4.5\n"
326 "search first.com second.com\n"},
327 {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
328 {"/etc/nsswitch.conf", "hosts: files\n"}};
329CONTAINED_TEST_F(LibraryTest, ContainerChannelInit,
330 "myhostname", "mydomainname.org", filelist) {
331 ares_channel channel = nullptr;
332 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
333 std::vector<std::string> actual = GetNameServers(channel);
334 std::vector<std::string> expected = {"1.2.3.4"};
335 EXPECT_EQ(expected, actual);
336
337 struct ares_options opts;
338 int optmask = 0;
339 ares_save_options(channel, &opts, &optmask);
340 EXPECT_EQ(2, opts.ndomains);
341 EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
342 EXPECT_EQ(std::string("second.com"), std::string(opts.domains[1]));
343 ares_destroy_options(&opts);
344
345 HostResult result;
346 ares_gethostbyname(channel, "ahostname.com", AF_INET, HostCallback, &result);
347 ProcessWork(channel, NoExtraFDs, nullptr);
348 EXPECT_TRUE(result.done_);
349 std::stringstream ss;
350 ss << result.host_;
351 EXPECT_EQ("{'ahostname.com' aliases=[] addrs=[3.4.5.6]}", ss.str());
352
353 ares_destroy(channel);
354 return HasFailure();
355}
356
357CONTAINED_TEST_F(LibraryTest, ContainerSortlistOptionInit,
358 "myhostname", "mydomainname.org", filelist) {
359 ares_channel channel = nullptr;
360 struct ares_options opts = {0};
361 int optmask = 0;
362 optmask |= ARES_OPT_SORTLIST;
363 opts.nsort = 0;
364 // Explicitly specifying an empty sortlist in the options should override the
365 // environment.
366 EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
367 ares_save_options(channel, &opts, &optmask);
368 EXPECT_EQ(0, opts.nsort);
369 EXPECT_EQ(nullptr, opts.sortlist);
370 EXPECT_EQ(ARES_OPT_SORTLIST, (optmask & ARES_OPT_SORTLIST));
371 ares_destroy_options(&opts);
372
373 ares_destroy(channel);
374 return HasFailure();
375}
376
377NameContentList fullresolv = {
378 {"/etc/resolv.conf", " nameserver 1.2.3.4 \n"
379 "search first.com second.com\n"
380 "lookup bind\n"
381 "options debug ndots:5\n"
382 "sortlist 1.2.3.4/16 2.3.4.5\n"}};
383CONTAINED_TEST_F(LibraryTest, ContainerFullResolvInit,
384 "myhostname", "mydomainname.org", fullresolv) {
385 ares_channel channel = nullptr;
386 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
387
388 struct ares_options opts;
389 int optmask = 0;
390 ares_save_options(channel, &opts, &optmask);
391 EXPECT_EQ(std::string("b"), std::string(opts.lookups));
392 EXPECT_EQ(5, opts.ndots);
393 ares_destroy_options(&opts);
394
395 ares_destroy(channel);
396 return HasFailure();
397}
398
399NameContentList hostconf = {
400 {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
401 "sortlist1.2.3.4\n" // malformed line
402 "search first.com second.com\n"},
403 {"/etc/host.conf", "order bind hosts\n"}};
404CONTAINED_TEST_F(LibraryTest, ContainerHostConfInit,
405 "myhostname", "mydomainname.org", hostconf) {
406 ares_channel channel = nullptr;
407 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
408
409 struct ares_options opts;
410 int optmask = 0;
411 ares_save_options(channel, &opts, &optmask);
412 EXPECT_EQ(std::string("bf"), std::string(opts.lookups));
413 ares_destroy_options(&opts);
414
415 ares_destroy(channel);
416 return HasFailure();
417}
418
419NameContentList svcconf = {
420 {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
421 "search first.com second.com\n"},
422 {"/etc/svc.conf", "hosts= bind\n"}};
423CONTAINED_TEST_F(LibraryTest, ContainerSvcConfInit,
424 "myhostname", "mydomainname.org", svcconf) {
425 ares_channel channel = nullptr;
426 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
427
428 struct ares_options opts;
429 int optmask = 0;
430 ares_save_options(channel, &opts, &optmask);
431 EXPECT_EQ(std::string("b"), std::string(opts.lookups));
432 ares_destroy_options(&opts);
433
434 ares_destroy(channel);
435 return HasFailure();
436}
437
438// Failures when expected config filenames are inaccessible.
439class MakeUnreadable {
440 public:
441 explicit MakeUnreadable(const std::string& filename)
442 : filename_(filename) {
443 chmod(filename_.c_str(), 0000);
444 }
445 ~MakeUnreadable() { chmod(filename_.c_str(), 0644); }
446 private:
447 std::string filename_;
448};
449
450CONTAINED_TEST_F(LibraryTest, ContainerResolvConfNotReadable,
451 "myhostname", "mydomainname.org", filelist) {
452 ares_channel channel = nullptr;
453 MakeUnreadable hide("/etc/resolv.conf");
454 // Unavailable /etc/resolv.conf falls back to defaults
455 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
456 return HasFailure();
457}
458CONTAINED_TEST_F(LibraryTest, ContainerNsswitchConfNotReadable,
459 "myhostname", "mydomainname.org", filelist) {
460 ares_channel channel = nullptr;
461 // Unavailable /etc/nsswitch.conf falls back to defaults.
462 MakeUnreadable hide("/etc/nsswitch.conf");
463 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
464
465 struct ares_options opts;
466 int optmask = 0;
467 ares_save_options(channel, &opts, &optmask);
468 EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
469 ares_destroy_options(&opts);
470
471 ares_destroy(channel);
472 return HasFailure();
473}
474CONTAINED_TEST_F(LibraryTest, ContainerHostConfNotReadable,
475 "myhostname", "mydomainname.org", hostconf) {
476 ares_channel channel = nullptr;
477 // Unavailable /etc/host.conf falls back to defaults.
478 MakeUnreadable hide("/etc/host.conf");
479 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
480 ares_destroy(channel);
481 return HasFailure();
482}
483CONTAINED_TEST_F(LibraryTest, ContainerSvcConfNotReadable,
484 "myhostname", "mydomainname.org", svcconf) {
485 ares_channel channel = nullptr;
486 // Unavailable /etc/svc.conf falls back to defaults.
487 MakeUnreadable hide("/etc/svc.conf");
488 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
489 ares_destroy(channel);
490 return HasFailure();
491}
492
493NameContentList rotateenv = {
494 {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
495 "search first.com second.com\n"
496 "options rotate\n"}};
497CONTAINED_TEST_F(LibraryTest, ContainerRotateInit,
498 "myhostname", "mydomainname.org", rotateenv) {
499 ares_channel channel = nullptr;
500 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
501
502 struct ares_options opts;
503 int optmask = 0;
504 ares_save_options(channel, &opts, &optmask);
505 EXPECT_EQ(ARES_OPT_ROTATE, (optmask & ARES_OPT_ROTATE));
506 ares_destroy_options(&opts);
507
508 ares_destroy(channel);
509 return HasFailure();
510}
511
512CONTAINED_TEST_F(LibraryTest, ContainerRotateOverride,
513 "myhostname", "mydomainname.org", rotateenv) {
514 ares_channel channel = nullptr;
515 struct ares_options opts = {0};
516 int optmask = ARES_OPT_NOROTATE;
517 EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
518
519 optmask = 0;
520 ares_save_options(channel, &opts, &optmask);
521 EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
522 ares_destroy_options(&opts);
523
524 ares_destroy(channel);
525 return HasFailure();
526}
527
528NameContentList multiresolv = {
529 {"/etc/resolv.conf", " nameserver 1::2 ; ;;\n"
530 " domain first.com\n"},
531 {"/etc/nsswitch.conf", "hosts: files\n"}};
532CONTAINED_TEST_F(LibraryTest, ContainerMultiResolvInit,
533 "myhostname", "mydomainname.org", multiresolv) {
534 ares_channel channel = nullptr;
535 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
536 std::vector<std::string> actual = GetNameServers(channel);
537 std::vector<std::string> expected = {"0001:0000:0000:0000:0000:0000:0000:0002"};
538 EXPECT_EQ(expected, actual);
539
540 struct ares_options opts;
541 int optmask = 0;
542 ares_save_options(channel, &opts, &optmask);
543 EXPECT_EQ(1, opts.ndomains);
544 EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
545 ares_destroy_options(&opts);
546
547 ares_destroy(channel);
548 return HasFailure();
549}
550
551NameContentList systemdresolv = {
552 {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
553 "domain first.com\n"},
554 {"/etc/nsswitch.conf", "hosts: junk resolve files\n"}};
555CONTAINED_TEST_F(LibraryTest, ContainerSystemdResolvInit,
556 "myhostname", "mydomainname.org", systemdresolv) {
557 ares_channel channel = nullptr;
558 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
559
560 struct ares_options opts;
561 int optmask = 0;
562 ares_save_options(channel, &opts, &optmask);
563 EXPECT_EQ(std::string("bf"), std::string(opts.lookups));
564 ares_destroy_options(&opts);
565
566 ares_destroy(channel);
567 return HasFailure();
568}
569
570NameContentList empty = {}; // no files
571CONTAINED_TEST_F(LibraryTest, ContainerEmptyInit,
572 "host.domain.org", "domain.org", empty) {
573 ares_channel channel = nullptr;
574 EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
575 std::vector<std::string> actual = GetNameServers(channel);
576 std::vector<std::string> expected = {"127.0.0.1"};
577 EXPECT_EQ(expected, actual);
578
579 struct ares_options opts;
580 int optmask = 0;
581 ares_save_options(channel, &opts, &optmask);
582 EXPECT_EQ(1, opts.ndomains);
583 EXPECT_EQ(std::string("domain.org"), std::string(opts.domains[0]));
584 EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
585 ares_destroy_options(&opts);
586
587
588 ares_destroy(channel);
589 return HasFailure();
590}
591
592#endif
593
594} // namespace test
595} // namespace ares