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