Upgrade to 1.17.1
[platform/upstream/c-ares.git] / test / ares-test-mock.cc
1 #include "ares-test.h"
2 #include "dns-proto.h"
3
4 #include <sstream>
5 #include <vector>
6
7 using testing::InvokeWithoutArgs;
8 using testing::DoAll;
9
10 namespace ares {
11 namespace test {
12
13 TEST_P(MockChannelTest, Basic) {
14   std::vector<byte> reply = {
15     0x00, 0x00,  // qid
16     0x84, // response + query + AA + not-TC + not-RD
17     0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
18     0x00, 0x01,  // 1 question
19     0x00, 0x01,  // 1 answer RRs
20     0x00, 0x00,  // 0 authority RRs
21     0x00, 0x00,  // 0 additional RRs
22     // Question
23     0x03, 'w', 'w', 'w',
24     0x06, 'g', 'o', 'o', 'g', 'l', 'e',
25     0x03, 'c', 'o', 'm',
26     0x00,
27     0x00, 0x01,  // type A
28     0x00, 0x01,  // class IN
29     // Answer
30     0x03, 'w', 'w', 'w',
31     0x06, 'g', 'o', 'o', 'g', 'l', 'e',
32     0x03, 'c', 'o', 'm',
33     0x00,
34     0x00, 0x01,  // type A
35     0x00, 0x01,  // class IN
36     0x00, 0x00, 0x01, 0x00,  // TTL
37     0x00, 0x04,  // rdata length
38     0x01, 0x02, 0x03, 0x04
39   };
40
41   ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
42     .WillByDefault(SetReplyData(&server_, reply));
43
44   HostResult result;
45   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
46   Process();
47   EXPECT_TRUE(result.done_);
48   std::stringstream ss;
49   ss << result.host_;
50   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
51 }
52
53 // UDP only so mock server doesn't get confused by concatenated requests
54 TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
55   DNSPacket rsp1;
56   rsp1.set_response().set_aa()
57     .add_question(new DNSQuestion("www.google.com", ns_t_a))
58     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
59   ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
60     .WillByDefault(SetReply(&server_, &rsp1));
61   DNSPacket rsp2;
62   rsp2.set_response().set_aa()
63     .add_question(new DNSQuestion("www.example.com", ns_t_a))
64     .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4}));
65   ON_CALL(server_, OnRequest("www.example.com", ns_t_a))
66     .WillByDefault(SetReply(&server_, &rsp2));
67
68   HostResult result1;
69   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
70   HostResult result2;
71   ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
72   HostResult result3;
73   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
74   Process();
75   EXPECT_TRUE(result1.done_);
76   EXPECT_TRUE(result2.done_);
77   EXPECT_TRUE(result3.done_);
78   std::stringstream ss1;
79   ss1 << result1.host_;
80   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
81   std::stringstream ss2;
82   ss2 << result2.host_;
83   EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
84   std::stringstream ss3;
85   ss3 << result3.host_;
86   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
87 }
88
89 // UDP to TCP specific test
90 TEST_P(MockUDPChannelTest, TruncationRetry) {
91   DNSPacket rsptruncated;
92   rsptruncated.set_response().set_aa().set_tc()
93     .add_question(new DNSQuestion("www.google.com", ns_t_a));
94   DNSPacket rspok;
95   rspok.set_response()
96     .add_question(new DNSQuestion("www.google.com", ns_t_a))
97     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
98   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
99     .WillOnce(SetReply(&server_, &rsptruncated))
100     .WillOnce(SetReply(&server_, &rspok));
101   HostResult result;
102   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
103   Process();
104   EXPECT_TRUE(result.done_);
105   std::stringstream ss;
106   ss << result.host_;
107   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
108 }
109
110 static int sock_cb_count = 0;
111 static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
112   int rc = *(int*)data;
113   if (verbose) std::cerr << "SocketConnectCallback(" << fd << ") invoked" << std::endl;
114   sock_cb_count++;
115   return rc;
116 }
117
118 TEST_P(MockChannelTest, SockCallback) {
119   DNSPacket rsp;
120   rsp.set_response().set_aa()
121     .add_question(new DNSQuestion("www.google.com", ns_t_a))
122     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
123   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
124     .WillOnce(SetReply(&server_, &rsp));
125
126   // Get notified of new sockets
127   int rc = ARES_SUCCESS;
128   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
129
130   HostResult result;
131   sock_cb_count = 0;
132   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
133   Process();
134   EXPECT_EQ(1, sock_cb_count);
135   EXPECT_TRUE(result.done_);
136   std::stringstream ss;
137   ss << result.host_;
138   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
139 }
140
141 TEST_P(MockChannelTest, SockFailCallback) {
142   // Notification of new sockets gives an error.
143   int rc = -1;
144   ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
145
146   HostResult result;
147   sock_cb_count = 0;
148   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
149   Process();
150   EXPECT_LT(1, sock_cb_count);
151   EXPECT_TRUE(result.done_);
152   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
153 }
154
155 static int sock_config_cb_count = 0;
156 static int SocketConfigureCallback(ares_socket_t fd, int type, void *data) {
157   int rc = *(int*)data;
158   if (verbose) std::cerr << "SocketConfigureCallback(" << fd << ") invoked" << std::endl;
159   sock_config_cb_count++;
160   return rc;
161 }
162
163 TEST_P(MockChannelTest, SockConfigureCallback) {
164   DNSPacket rsp;
165   rsp.set_response().set_aa()
166     .add_question(new DNSQuestion("www.google.com", ns_t_a))
167     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
168   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
169     .WillOnce(SetReply(&server_, &rsp));
170
171   // Get notified of new sockets
172   int rc = ARES_SUCCESS;
173   ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
174
175   HostResult result;
176   sock_config_cb_count = 0;
177   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
178   Process();
179   EXPECT_EQ(1, sock_config_cb_count);
180   EXPECT_TRUE(result.done_);
181   std::stringstream ss;
182   ss << result.host_;
183   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
184 }
185
186 TEST_P(MockChannelTest, SockConfigureFailCallback) {
187   // Notification of new sockets gives an error.
188   int rc = -1;
189   ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
190
191   HostResult result;
192   sock_config_cb_count = 0;
193   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
194   Process();
195   EXPECT_LT(1, sock_config_cb_count);
196   EXPECT_TRUE(result.done_);
197   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
198 }
199
200 // TCP only to prevent retries
201 TEST_P(MockTCPChannelTest, MalformedResponse) {
202   std::vector<byte> one = {0x01};
203   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
204     .WillOnce(SetReplyData(&server_, one));
205
206   HostResult result;
207   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
208   Process();
209   EXPECT_TRUE(result.done_);
210   EXPECT_EQ(ARES_ETIMEOUT, result.status_);
211 }
212
213 TEST_P(MockTCPChannelTest, FormErrResponse) {
214   DNSPacket rsp;
215   rsp.set_response().set_aa()
216     .add_question(new DNSQuestion("www.google.com", ns_t_a));
217   rsp.set_rcode(ns_r_formerr);
218   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
219     .WillOnce(SetReply(&server_, &rsp));
220   HostResult result;
221   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
222   Process();
223   EXPECT_TRUE(result.done_);
224   EXPECT_EQ(ARES_EFORMERR, result.status_);
225 }
226
227 TEST_P(MockTCPChannelTest, ServFailResponse) {
228   DNSPacket rsp;
229   rsp.set_response().set_aa()
230     .add_question(new DNSQuestion("www.google.com", ns_t_a));
231   rsp.set_rcode(ns_r_servfail);
232   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
233     .WillOnce(SetReply(&server_, &rsp));
234   HostResult result;
235   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
236   Process();
237   EXPECT_TRUE(result.done_);
238   // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
239   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
240 }
241
242 TEST_P(MockTCPChannelTest, NotImplResponse) {
243   DNSPacket rsp;
244   rsp.set_response().set_aa()
245     .add_question(new DNSQuestion("www.google.com", ns_t_a));
246   rsp.set_rcode(ns_r_notimpl);
247   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
248     .WillOnce(SetReply(&server_, &rsp));
249   HostResult result;
250   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
251   Process();
252   EXPECT_TRUE(result.done_);
253   // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed
254   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
255 }
256
257 TEST_P(MockTCPChannelTest, RefusedResponse) {
258   DNSPacket rsp;
259   rsp.set_response().set_aa()
260     .add_question(new DNSQuestion("www.google.com", ns_t_a));
261   rsp.set_rcode(ns_r_refused);
262   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
263     .WillOnce(SetReply(&server_, &rsp));
264   HostResult result;
265   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
266   Process();
267   EXPECT_TRUE(result.done_);
268   // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
269   EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
270 }
271
272 TEST_P(MockTCPChannelTest, YXDomainResponse) {
273   DNSPacket rsp;
274   rsp.set_response().set_aa()
275     .add_question(new DNSQuestion("www.google.com", ns_t_a));
276   rsp.set_rcode(ns_r_yxdomain);
277   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
278     .WillOnce(SetReply(&server_, &rsp));
279   HostResult result;
280   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
281   Process();
282   EXPECT_TRUE(result.done_);
283   EXPECT_EQ(ARES_ENODATA, result.status_);
284 }
285
286 class MockExtraOptsTest
287     : public MockChannelOptsTest,
288       public ::testing::WithParamInterface< std::pair<int, bool> > {
289  public:
290   MockExtraOptsTest()
291     : MockChannelOptsTest(1, GetParam().first, GetParam().second,
292                           FillOptions(&opts_),
293                           ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {}
294   static struct ares_options* FillOptions(struct ares_options * opts) {
295     memset(opts, 0, sizeof(struct ares_options));
296     // Set a few options that affect socket communications
297     opts->socket_send_buffer_size = 514;
298     opts->socket_receive_buffer_size = 514;
299     return opts;
300   }
301  private:
302   struct ares_options opts_;
303 };
304
305 TEST_P(MockExtraOptsTest, SimpleQuery) {
306   ares_set_local_ip4(channel_, 0x7F000001);
307   byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
309   ares_set_local_ip6(channel_, addr6);
310   ares_set_local_dev(channel_, "dummy");
311
312   DNSPacket rsp;
313   rsp.set_response().set_aa()
314     .add_question(new DNSQuestion("www.google.com", ns_t_a))
315     .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5}));
316   ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
317     .WillByDefault(SetReply(&server_, &rsp));
318
319   HostResult result;
320   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
321   Process();
322   EXPECT_TRUE(result.done_);
323   std::stringstream ss;
324   ss << result.host_;
325   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
326 }
327
328 class MockFlagsChannelOptsTest
329     : public MockChannelOptsTest,
330       public ::testing::WithParamInterface< std::pair<int, bool> > {
331  public:
332   MockFlagsChannelOptsTest(int flags)
333     : MockChannelOptsTest(1, GetParam().first, GetParam().second,
334                           FillOptions(&opts_, flags), ARES_OPT_FLAGS) {}
335   static struct ares_options* FillOptions(struct ares_options * opts, int flags) {
336     memset(opts, 0, sizeof(struct ares_options));
337     opts->flags = flags;
338     return opts;
339   }
340  private:
341   struct ares_options opts_;
342 };
343
344 class MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
345  public:
346   MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
347 };
348
349 TEST_P(MockNoCheckRespChannelTest, ServFailResponse) {
350   DNSPacket rsp;
351   rsp.set_response().set_aa()
352     .add_question(new DNSQuestion("www.google.com", ns_t_a));
353   rsp.set_rcode(ns_r_servfail);
354   ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
355     .WillByDefault(SetReply(&server_, &rsp));
356   HostResult result;
357   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
358   Process();
359   EXPECT_TRUE(result.done_);
360   EXPECT_EQ(ARES_ESERVFAIL, result.status_);
361 }
362
363 TEST_P(MockNoCheckRespChannelTest, NotImplResponse) {
364   DNSPacket rsp;
365   rsp.set_response().set_aa()
366     .add_question(new DNSQuestion("www.google.com", ns_t_a));
367   rsp.set_rcode(ns_r_notimpl);
368   ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
369     .WillByDefault(SetReply(&server_, &rsp));
370   HostResult result;
371   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
372   Process();
373   EXPECT_TRUE(result.done_);
374   EXPECT_EQ(ARES_ENOTIMP, result.status_);
375 }
376
377 TEST_P(MockNoCheckRespChannelTest, RefusedResponse) {
378   DNSPacket rsp;
379   rsp.set_response().set_aa()
380     .add_question(new DNSQuestion("www.google.com", ns_t_a));
381   rsp.set_rcode(ns_r_refused);
382   ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
383     .WillByDefault(SetReply(&server_, &rsp));
384   HostResult result;
385   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
386   Process();
387   EXPECT_TRUE(result.done_);
388   EXPECT_EQ(ARES_EREFUSED, result.status_);
389 }
390
391 class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
392  public:
393   MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
394 };
395
396 TEST_P(MockEDNSChannelTest, RetryWithoutEDNS) {
397   DNSPacket rspfail;
398   rspfail.set_response().set_aa().set_rcode(ns_r_formerr)
399     .add_question(new DNSQuestion("www.google.com", ns_t_a));
400   DNSPacket rspok;
401   rspok.set_response()
402     .add_question(new DNSQuestion("www.google.com", ns_t_a))
403     .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4}));
404   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
405     .WillOnce(SetReply(&server_, &rspfail))
406     .WillOnce(SetReply(&server_, &rspok));
407   HostResult result;
408   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
409   Process();
410   EXPECT_TRUE(result.done_);
411   std::stringstream ss;
412   ss << result.host_;
413   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
414 }
415
416 TEST_P(MockChannelTest, SearchDomains) {
417   DNSPacket nofirst;
418   nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
419     .add_question(new DNSQuestion("www.first.com", ns_t_a));
420   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
421     .WillByDefault(SetReply(&server_, &nofirst));
422   DNSPacket nosecond;
423   nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
424     .add_question(new DNSQuestion("www.second.org", ns_t_a));
425   ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
426     .WillByDefault(SetReply(&server_, &nosecond));
427   DNSPacket yesthird;
428   yesthird.set_response().set_aa()
429     .add_question(new DNSQuestion("www.third.gov", ns_t_a))
430     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
431   ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
432     .WillByDefault(SetReply(&server_, &yesthird));
433
434   HostResult result;
435   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
436   Process();
437   EXPECT_TRUE(result.done_);
438   std::stringstream ss;
439   ss << result.host_;
440   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
441 }
442
443 // Relies on retries so is UDP-only
444 TEST_P(MockUDPChannelTest, SearchDomainsWithResentReply) {
445   DNSPacket nofirst;
446   nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
447     .add_question(new DNSQuestion("www.first.com", ns_t_a));
448   EXPECT_CALL(server_, OnRequest("www.first.com", ns_t_a))
449     .WillOnce(SetReply(&server_, &nofirst));
450   DNSPacket nosecond;
451   nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
452     .add_question(new DNSQuestion("www.second.org", ns_t_a));
453   EXPECT_CALL(server_, OnRequest("www.second.org", ns_t_a))
454     .WillOnce(SetReply(&server_, &nosecond));
455   DNSPacket yesthird;
456   yesthird.set_response().set_aa()
457     .add_question(new DNSQuestion("www.third.gov", ns_t_a))
458     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
459   // Before sending the real answer, resend an earlier reply
460   EXPECT_CALL(server_, OnRequest("www.third.gov", ns_t_a))
461     .WillOnce(DoAll(SetReply(&server_, &nofirst),
462                     SetReplyQID(&server_, 123)))
463     .WillOnce(DoAll(SetReply(&server_, &yesthird),
464                     SetReplyQID(&server_, -1)));
465
466   HostResult result;
467   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
468   Process();
469   EXPECT_TRUE(result.done_);
470   std::stringstream ss;
471   ss << result.host_;
472   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
473 }
474
475 TEST_P(MockChannelTest, SearchDomainsBare) {
476   DNSPacket nofirst;
477   nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
478     .add_question(new DNSQuestion("www.first.com", ns_t_a));
479   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
480     .WillByDefault(SetReply(&server_, &nofirst));
481   DNSPacket nosecond;
482   nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
483     .add_question(new DNSQuestion("www.second.org", ns_t_a));
484   ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
485     .WillByDefault(SetReply(&server_, &nosecond));
486   DNSPacket nothird;
487   nothird.set_response().set_aa().set_rcode(ns_r_nxdomain)
488     .add_question(new DNSQuestion("www.third.gov", ns_t_a));
489   ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
490     .WillByDefault(SetReply(&server_, &nothird));
491   DNSPacket yesbare;
492   yesbare.set_response().set_aa()
493     .add_question(new DNSQuestion("www", ns_t_a))
494     .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
495   ON_CALL(server_, OnRequest("www", ns_t_a))
496     .WillByDefault(SetReply(&server_, &yesbare));
497
498   HostResult result;
499   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
500   Process();
501   EXPECT_TRUE(result.done_);
502   std::stringstream ss;
503   ss << result.host_;
504   EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
505 }
506
507 TEST_P(MockChannelTest, SearchNoDataThenSuccess) {
508   // First two search domains recognize the name but have no A records.
509   DNSPacket nofirst;
510   nofirst.set_response().set_aa()
511     .add_question(new DNSQuestion("www.first.com", ns_t_a));
512   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
513     .WillByDefault(SetReply(&server_, &nofirst));
514   DNSPacket nosecond;
515   nosecond.set_response().set_aa()
516     .add_question(new DNSQuestion("www.second.org", ns_t_a));
517   ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
518     .WillByDefault(SetReply(&server_, &nosecond));
519   DNSPacket yesthird;
520   yesthird.set_response().set_aa()
521     .add_question(new DNSQuestion("www.third.gov", ns_t_a))
522     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
523   ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
524     .WillByDefault(SetReply(&server_, &yesthird));
525
526   HostResult result;
527   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
528   Process();
529   EXPECT_TRUE(result.done_);
530   std::stringstream ss;
531   ss << result.host_;
532   EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
533 }
534
535 TEST_P(MockChannelTest, SearchNoDataThenNoDataBare) {
536   // First two search domains recognize the name but have no A records.
537   DNSPacket nofirst;
538   nofirst.set_response().set_aa()
539     .add_question(new DNSQuestion("www.first.com", ns_t_a));
540   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
541     .WillByDefault(SetReply(&server_, &nofirst));
542   DNSPacket nosecond;
543   nosecond.set_response().set_aa()
544     .add_question(new DNSQuestion("www.second.org", ns_t_a));
545   ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
546     .WillByDefault(SetReply(&server_, &nosecond));
547   DNSPacket nothird;
548   nothird.set_response().set_aa()
549     .add_question(new DNSQuestion("www.third.gov", ns_t_a));
550   ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
551     .WillByDefault(SetReply(&server_, &nothird));
552   DNSPacket nobare;
553   nobare.set_response().set_aa()
554     .add_question(new DNSQuestion("www", ns_t_a));
555   ON_CALL(server_, OnRequest("www", ns_t_a))
556     .WillByDefault(SetReply(&server_, &nobare));
557
558   HostResult result;
559   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
560   Process();
561   EXPECT_TRUE(result.done_);
562   EXPECT_EQ(ARES_ENODATA, result.status_);
563 }
564
565 TEST_P(MockChannelTest, SearchNoDataThenFail) {
566   // First two search domains recognize the name but have no A records.
567   DNSPacket nofirst;
568   nofirst.set_response().set_aa()
569     .add_question(new DNSQuestion("www.first.com", ns_t_a));
570   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
571     .WillByDefault(SetReply(&server_, &nofirst));
572   DNSPacket nosecond;
573   nosecond.set_response().set_aa()
574     .add_question(new DNSQuestion("www.second.org", ns_t_a));
575   ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
576     .WillByDefault(SetReply(&server_, &nosecond));
577   DNSPacket nothird;
578   nothird.set_response().set_aa()
579     .add_question(new DNSQuestion("www.third.gov", ns_t_a));
580   ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
581     .WillByDefault(SetReply(&server_, &nothird));
582   DNSPacket nobare;
583   nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
584     .add_question(new DNSQuestion("www", ns_t_a));
585   ON_CALL(server_, OnRequest("www", ns_t_a))
586     .WillByDefault(SetReply(&server_, &nobare));
587
588   HostResult result;
589   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
590   Process();
591   EXPECT_TRUE(result.done_);
592   EXPECT_EQ(ARES_ENODATA, result.status_);
593 }
594
595 TEST_P(MockChannelTest, SearchAllocFailure) {
596   SearchResult result;
597   SetAllocFail(1);
598   ares_search(channel_, "fully.qualified.", ns_c_in, ns_t_a, SearchCallback, &result);
599   /* Already done */
600   EXPECT_TRUE(result.done_);
601   EXPECT_EQ(ARES_ENOMEM, result.status_);
602 }
603
604 TEST_P(MockChannelTest, SearchHighNdots) {
605   DNSPacket nobare;
606   nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
607     .add_question(new DNSQuestion("a.b.c.w.w.w", ns_t_a));
608   ON_CALL(server_, OnRequest("a.b.c.w.w.w", ns_t_a))
609     .WillByDefault(SetReply(&server_, &nobare));
610   DNSPacket yesfirst;
611   yesfirst.set_response().set_aa()
612     .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", ns_t_a))
613     .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
614   ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", ns_t_a))
615     .WillByDefault(SetReply(&server_, &yesfirst));
616
617   SearchResult result;
618   ares_search(channel_, "a.b.c.w.w.w", ns_c_in, ns_t_a, SearchCallback, &result);
619   Process();
620   EXPECT_TRUE(result.done_);
621   EXPECT_EQ(ARES_SUCCESS, result.status_);
622   std::stringstream ss;
623   ss << PacketToString(result.data_);
624   EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
625             "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
626             ss.str());
627 }
628
629 TEST_P(MockChannelTest, UnspecifiedFamilyV6) {
630   DNSPacket rsp6;
631   rsp6.set_response().set_aa()
632     .add_question(new DNSQuestion("example.com", ns_t_aaaa))
633     .add_answer(new DNSAaaaRR("example.com", 100,
634                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
636   ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
637     .WillByDefault(SetReply(&server_, &rsp6));
638
639   HostResult result;
640   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
641   Process();
642   EXPECT_TRUE(result.done_);
643   std::stringstream ss;
644   ss << result.host_;
645   // Default to IPv6 when both are available.
646   EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
647 }
648
649 TEST_P(MockChannelTest, UnspecifiedFamilyV4) {
650   DNSPacket rsp6;
651   rsp6.set_response().set_aa()
652     .add_question(new DNSQuestion("example.com", ns_t_aaaa));
653   ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
654     .WillByDefault(SetReply(&server_, &rsp6));
655   DNSPacket rsp4;
656   rsp4.set_response().set_aa()
657     .add_question(new DNSQuestion("example.com", ns_t_a))
658     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
659   ON_CALL(server_, OnRequest("example.com", ns_t_a))
660     .WillByDefault(SetReply(&server_, &rsp4));
661
662   HostResult result;
663   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
664   Process();
665   EXPECT_TRUE(result.done_);
666   std::stringstream ss;
667   ss << result.host_;
668   EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
669 }
670
671 TEST_P(MockChannelTest, UnspecifiedFamilyNoData) {
672   DNSPacket rsp6;
673   rsp6.set_response().set_aa()
674     .add_question(new DNSQuestion("example.com", ns_t_aaaa))
675     .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
676   ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
677     .WillByDefault(SetReply(&server_, &rsp6));
678   DNSPacket rsp4;
679   rsp4.set_response().set_aa()
680     .add_question(new DNSQuestion("example.com", ns_t_a));
681   ON_CALL(server_, OnRequest("example.com", ns_t_a))
682     .WillByDefault(SetReply(&server_, &rsp4));
683
684   HostResult result;
685   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
686   Process();
687   EXPECT_TRUE(result.done_);
688   std::stringstream ss;
689   ss << result.host_;
690   EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
691 }
692
693 TEST_P(MockChannelTest, UnspecifiedFamilyCname6A4) {
694   DNSPacket rsp6;
695   rsp6.set_response().set_aa()
696     .add_question(new DNSQuestion("example.com", ns_t_aaaa))
697     .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
698   ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
699     .WillByDefault(SetReply(&server_, &rsp6));
700   DNSPacket rsp4;
701   rsp4.set_response().set_aa()
702     .add_question(new DNSQuestion("example.com", ns_t_a))
703     .add_answer(new DNSARR("example.com", 100, {1, 2, 3, 4}));
704   ON_CALL(server_, OnRequest("example.com", ns_t_a))
705     .WillByDefault(SetReply(&server_, &rsp4));
706
707   HostResult result;
708   ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
709   Process();
710   EXPECT_TRUE(result.done_);
711   std::stringstream ss;
712   ss << result.host_;
713   EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
714 }
715
716 TEST_P(MockChannelTest, ExplicitIP) {
717   HostResult result;
718   ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
719   EXPECT_TRUE(result.done_);  // Immediate return
720   EXPECT_EQ(ARES_SUCCESS, result.status_);
721   std::stringstream ss;
722   ss << result.host_;
723   EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
724 }
725
726 TEST_P(MockChannelTest, ExplicitIPAllocFail) {
727   HostResult result;
728   SetAllocSizeFail(strlen("1.2.3.4") + 1);
729   ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
730   EXPECT_TRUE(result.done_);  // Immediate return
731   EXPECT_EQ(ARES_ENOMEM, result.status_);
732 }
733
734 TEST_P(MockChannelTest, SortListV4) {
735   DNSPacket rsp;
736   rsp.set_response().set_aa()
737     .add_question(new DNSQuestion("example.com", ns_t_a))
738     .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
739     .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
740     .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
741   ON_CALL(server_, OnRequest("example.com", ns_t_a))
742     .WillByDefault(SetReply(&server_, &rsp));
743
744   {
745     EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
746     HostResult result;
747     ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
748     Process();
749     EXPECT_TRUE(result.done_);
750     std::stringstream ss;
751     ss << result.host_;
752     EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
753   }
754   {
755     EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
756     HostResult result;
757     ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
758     Process();
759     EXPECT_TRUE(result.done_);
760     std::stringstream ss;
761     ss << result.host_;
762     EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
763   }
764   struct ares_options options;
765   memset(&options, 0, sizeof(options));
766   int optmask = 0;
767   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
768   EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
769   ares_destroy_options(&options);
770 }
771
772 TEST_P(MockChannelTest, SortListV6) {
773   DNSPacket rsp;
774   rsp.set_response().set_aa()
775     .add_question(new DNSQuestion("example.com", ns_t_aaaa))
776     .add_answer(new DNSAaaaRR("example.com", 100,
777                               {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
779     .add_answer(new DNSAaaaRR("example.com", 100,
780                               {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781                                0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03}));
782   ON_CALL(server_, OnRequest("example.com", ns_t_aaaa))
783     .WillByDefault(SetReply(&server_, &rsp));
784
785   {
786     ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
787     HostResult result;
788     ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
789     Process();
790     EXPECT_TRUE(result.done_);
791     std::stringstream ss;
792     ss << result.host_;
793     EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
794               "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
795   }
796   {
797     ares_set_sortlist(channel_, "2121::/8");
798     HostResult result;
799     ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
800     Process();
801     EXPECT_TRUE(result.done_);
802     std::stringstream ss;
803     ss << result.host_;
804     EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
805               "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
806   }
807 }
808
809 // Relies on retries so is UDP-only
810 TEST_P(MockUDPChannelTest, SearchDomainsAllocFail) {
811   DNSPacket nofirst;
812   nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
813     .add_question(new DNSQuestion("www.first.com", ns_t_a));
814   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
815     .WillByDefault(SetReply(&server_, &nofirst));
816   DNSPacket nosecond;
817   nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain)
818     .add_question(new DNSQuestion("www.second.org", ns_t_a));
819   ON_CALL(server_, OnRequest("www.second.org", ns_t_a))
820     .WillByDefault(SetReply(&server_, &nosecond));
821   DNSPacket yesthird;
822   yesthird.set_response().set_aa()
823     .add_question(new DNSQuestion("www.third.gov", ns_t_a))
824     .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5}));
825   ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
826     .WillByDefault(SetReply(&server_, &yesthird));
827
828   // Fail a variety of different memory allocations, and confirm
829   // that the operation either fails with ENOMEM or succeeds
830   // with the expected result.
831   const int kCount = 34;
832   HostResult results[kCount];
833   for (int ii = 1; ii <= kCount; ii++) {
834     HostResult* result = &(results[ii - 1]);
835     ClearFails();
836     SetAllocFail(ii);
837     ares_gethostbyname(channel_, "www", AF_INET, HostCallback, result);
838     Process();
839     EXPECT_TRUE(result->done_);
840     if (result->status_ == ARES_SUCCESS) {
841       std::stringstream ss;
842       ss << result->host_;
843       EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str()) << " failed alloc #" << ii;
844       if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
845     }
846   }
847
848   // Explicitly destroy the channel now, so that the HostResult objects
849   // are still valid (in case any pending work refers to them).
850   ares_destroy(channel_);
851   channel_ = nullptr;
852 }
853
854 // Relies on retries so is UDP-only
855 TEST_P(MockUDPChannelTest, Resend) {
856   std::vector<byte> nothing;
857   DNSPacket reply;
858   reply.set_response().set_aa()
859     .add_question(new DNSQuestion("www.google.com", ns_t_a))
860     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
861
862   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
863     .WillOnce(SetReplyData(&server_, nothing))
864     .WillOnce(SetReplyData(&server_, nothing))
865     .WillOnce(SetReply(&server_, &reply));
866
867   HostResult result;
868   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
869   Process();
870   EXPECT_TRUE(result.done_);
871   EXPECT_EQ(2, result.timeouts_);
872   std::stringstream ss;
873   ss << result.host_;
874   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
875 }
876
877 TEST_P(MockChannelTest, CancelImmediate) {
878   HostResult result;
879   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
880   ares_cancel(channel_);
881   EXPECT_TRUE(result.done_);
882   EXPECT_EQ(ARES_ECANCELLED, result.status_);
883   EXPECT_EQ(0, result.timeouts_);
884 }
885
886 TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) {
887   HostResult result;
888   struct in_addr addr;
889   addr.s_addr = htonl(0x08080808);
890   
891   ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
892   ares_cancel(channel_);
893   EXPECT_TRUE(result.done_);
894   EXPECT_EQ(ARES_ECANCELLED, result.status_);
895   EXPECT_EQ(0, result.timeouts_);
896 }
897
898 // Relies on retries so is UDP-only
899 TEST_P(MockUDPChannelTest, CancelLater) {
900   std::vector<byte> nothing;
901
902   // On second request, cancel the channel.
903   EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
904     .WillOnce(SetReplyData(&server_, nothing))
905     .WillOnce(CancelChannel(&server_, channel_));
906
907   HostResult result;
908   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
909   Process();
910   EXPECT_TRUE(result.done_);
911   EXPECT_EQ(ARES_ECANCELLED, result.status_);
912   EXPECT_EQ(0, result.timeouts_);
913 }
914
915 TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
916   HostResult result;
917   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
918
919   ares_destroy(channel_);
920   channel_ = nullptr;
921
922   EXPECT_TRUE(result.done_);  // Synchronous
923   EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
924   EXPECT_EQ(0, result.timeouts_);
925 }
926
927 TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
928   HostResult result;
929   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
930
931   ares_destroy(channel_);
932   channel_ = nullptr;
933
934   EXPECT_TRUE(result.done_);  // Synchronous
935   EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
936   EXPECT_EQ(0, result.timeouts_);
937 }
938
939 TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
940   DNSPacket response;
941   response.set_response().set_aa()
942     .add_question(new DNSQuestion("cname.first.com", ns_t_a))
943     .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com"));
944   ON_CALL(server_, OnRequest("cname.first.com", ns_t_a))
945     .WillByDefault(SetReply(&server_, &response));
946
947   HostResult result;
948   ares_gethostbyname(channel_, "cname.first.com", AF_INET, HostCallback, &result);
949   Process();
950   EXPECT_TRUE(result.done_);
951   EXPECT_EQ(ARES_ENODATA, result.status_);
952 }
953
954 TEST_P(MockChannelTest, GetHostByAddrDestroy) {
955   unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
956   HostResult result;
957   ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
958
959   ares_destroy(channel_);
960   channel_ = nullptr;
961
962   EXPECT_TRUE(result.done_);  // Synchronous
963   EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
964   EXPECT_EQ(0, result.timeouts_);
965 }
966
967 #ifndef WIN32
968 TEST_P(MockChannelTest, HostAlias) {
969   DNSPacket reply;
970   reply.set_response().set_aa()
971     .add_question(new DNSQuestion("www.google.com", ns_t_a))
972     .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
973   ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
974     .WillByDefault(SetReply(&server_, &reply));
975
976   TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
977   EnvValue with_env("HOSTALIASES", aliases.filename());
978
979   HostResult result;
980   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
981   Process();
982   EXPECT_TRUE(result.done_);
983   std::stringstream ss;
984   ss << result.host_;
985   EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
986 }
987
988 TEST_P(MockChannelTest, HostAliasMissing) {
989   DNSPacket yesfirst;
990   yesfirst.set_response().set_aa()
991     .add_question(new DNSQuestion("www.first.com", ns_t_a))
992     .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
993   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
994     .WillByDefault(SetReply(&server_, &yesfirst));
995
996   TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
997   EnvValue with_env("HOSTALIASES", aliases.filename());
998   HostResult result;
999   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1000   Process();
1001   EXPECT_TRUE(result.done_);
1002   std::stringstream ss;
1003   ss << result.host_;
1004   EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1005 }
1006
1007 TEST_P(MockChannelTest, HostAliasMissingFile) {
1008   DNSPacket yesfirst;
1009   yesfirst.set_response().set_aa()
1010     .add_question(new DNSQuestion("www.first.com", ns_t_a))
1011     .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
1012   ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
1013     .WillByDefault(SetReply(&server_, &yesfirst));
1014
1015   EnvValue with_env("HOSTALIASES", "bogus.mcfile");
1016   HostResult result;
1017   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1018   Process();
1019   EXPECT_TRUE(result.done_);
1020   std::stringstream ss;
1021   ss << result.host_;
1022   EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1023 }
1024
1025 TEST_P(MockChannelTest, HostAliasUnreadable) {
1026   TempFile aliases("www www.google.com\n");
1027   chmod(aliases.filename(), 0);
1028   EnvValue with_env("HOSTALIASES", aliases.filename());
1029
1030   HostResult result;
1031   ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
1032   EXPECT_TRUE(result.done_);
1033   EXPECT_EQ(ARES_EFILE, result.status_);
1034   chmod(aliases.filename(), 0777);
1035 }
1036 #endif
1037
1038 class MockMultiServerChannelTest
1039   : public MockChannelOptsTest,
1040     public ::testing::WithParamInterface< std::pair<int, bool> > {
1041  public:
1042   MockMultiServerChannelTest(bool rotate)
1043     : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
1044   void CheckExample() {
1045     HostResult result;
1046     ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
1047     Process();
1048     EXPECT_TRUE(result.done_);
1049     std::stringstream ss;
1050     ss << result.host_;
1051     EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
1052   }
1053 };
1054
1055 class RotateMultiMockTest : public MockMultiServerChannelTest {
1056  public:
1057   RotateMultiMockTest() : MockMultiServerChannelTest(true) {}
1058 };
1059
1060 class NoRotateMultiMockTest : public MockMultiServerChannelTest {
1061  public:
1062   NoRotateMultiMockTest() : MockMultiServerChannelTest(false) {}
1063 };
1064
1065
1066 TEST_P(RotateMultiMockTest, ThirdServer) {
1067   struct ares_options opts = {0};
1068   int optmask = 0;
1069   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
1070   EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE));
1071   ares_destroy_options(&opts);
1072
1073   DNSPacket servfailrsp;
1074   servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
1075     .add_question(new DNSQuestion("www.example.com", ns_t_a));
1076   DNSPacket notimplrsp;
1077   notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
1078     .add_question(new DNSQuestion("www.example.com", ns_t_a));
1079   DNSPacket okrsp;
1080   okrsp.set_response().set_aa()
1081     .add_question(new DNSQuestion("www.example.com", ns_t_a))
1082     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
1083
1084   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1085     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1086   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1087     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1088   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1089     .WillOnce(SetReply(servers_[2].get(), &okrsp));
1090   CheckExample();
1091
1092   // Second time around, starts from server [1].
1093   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1094     .WillOnce(SetReply(servers_[1].get(), &servfailrsp));
1095   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1096     .WillOnce(SetReply(servers_[2].get(), &notimplrsp));
1097   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1098     .WillOnce(SetReply(servers_[0].get(), &okrsp));
1099   CheckExample();
1100
1101   // Third time around, starts from server [2].
1102   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1103     .WillOnce(SetReply(servers_[2].get(), &servfailrsp));
1104   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1105     .WillOnce(SetReply(servers_[0].get(), &notimplrsp));
1106   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1107     .WillOnce(SetReply(servers_[1].get(), &okrsp));
1108   CheckExample();
1109 }
1110
1111 TEST_P(NoRotateMultiMockTest, ThirdServer) {
1112   struct ares_options opts = {0};
1113   int optmask = 0;
1114   EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask));
1115   EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
1116   ares_destroy_options(&opts);
1117
1118   DNSPacket servfailrsp;
1119   servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail)
1120     .add_question(new DNSQuestion("www.example.com", ns_t_a));
1121   DNSPacket notimplrsp;
1122   notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl)
1123     .add_question(new DNSQuestion("www.example.com", ns_t_a));
1124   DNSPacket okrsp;
1125   okrsp.set_response().set_aa()
1126     .add_question(new DNSQuestion("www.example.com", ns_t_a))
1127     .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5}));
1128
1129   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1130     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1131   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1132     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1133   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1134     .WillOnce(SetReply(servers_[2].get(), &okrsp));
1135   CheckExample();
1136
1137   // Second time around, still starts from server [0].
1138   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1139     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1140   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1141     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1142   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1143     .WillOnce(SetReply(servers_[2].get(), &okrsp));
1144   CheckExample();
1145
1146   // Third time around, still starts from server [0].
1147   EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a))
1148     .WillOnce(SetReply(servers_[0].get(), &servfailrsp));
1149   EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
1150     .WillOnce(SetReply(servers_[1].get(), &notimplrsp));
1151   EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
1152     .WillOnce(SetReply(servers_[2].get(), &okrsp));
1153   CheckExample();
1154 }
1155
1156 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes));
1157
1158 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families));
1159
1160 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families));
1161
1162 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes));
1163
1164 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes));
1165
1166 INSTANTIATE_TEST_CASE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes));
1167
1168 INSTANTIATE_TEST_CASE_P(TransportModes, RotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
1169
1170 INSTANTIATE_TEST_CASE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
1171
1172 }  // namespace test
1173 }  // namespace ares