test_socket.cpp
Go to the documentation of this file.
1 /*
2  * Unit tests for XmlRpc++
3  *
4  * Copyright (C) 2017, Zoox Inc
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * Author: Austin Hendrix <austin@zoox.com>
21  *
22  */
23 
24 #include "xmlrpcpp/XmlRpcUtil.h"
25 #include "xmlrpcpp/XmlRpcSocket.h"
26 #include "test_system_mocks.h"
27 
28 #include <arpa/inet.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <limits.h>
32 #include <netdb.h>
33 #include <stdarg.h>
34 #include <sys/socket.h>
35 #include <sys/types.h>
36 #include <unistd.h>
37 
38 #include <deque>
39 
40 #include <gtest/gtest.h>
41 
42 #define FOR_ERRNO(itr, var, ...) \
43  int var[] = {__VA_ARGS__}; \
44  for (size_t itr = 0; itr < sizeof(var) / sizeof(int); itr++)
45 
47 
48 class XmlRpcSocketTest : public ::testing::Test {
49 protected:
50  void SetUp() {
51  accept_calls = 0;
52  bind_calls = 0;
53  close_calls = 0;
54  connect_calls = 0;
55  fcntl_calls = 0;
56  listen_calls = 0;
57  read_calls = 0;
58  select_calls = 0;
59  socket_calls = 0;
60  write_calls = 0;
61 
63  XmlRpcSocket::s_use_ipv6_ = false;
64  }
65 
66  void TearDown() {
67  fake_accept = 0;
68  fake_bind = 0;
69  fake_close = 0;
70  fake_connect = 0;
71  fake_fcntl = 0;
72  fake_listen = 0;
73  fake_read = 0;
74  fake_select = 0;
75  fake_socket = 0;
76  fake_write = 0;
77  }
78 };
79 
80 TEST_F(XmlRpcSocketTest, TestMocks) {
81  EXPECT_EQ(0, fake_accept);
82  EXPECT_EQ(0, accept_calls);
83  fake_accept = count_accept;
84  EXPECT_EQ(0, accept(0, 0, 0));
85  EXPECT_EQ(1, accept_calls);
86 
87  EXPECT_EQ(0, fake_bind);
88  EXPECT_EQ(0, bind_calls);
89  fake_bind = count_bind;
90  EXPECT_EQ(0, bind(0, 0, 0));
91  EXPECT_EQ(1, bind_calls);
92 
93  EXPECT_EQ(0, fake_close);
94  EXPECT_EQ(0, close_calls);
95  fake_close = count_close;
96  EXPECT_EQ(0, close(-1));
97  EXPECT_EQ(1, close_calls);
98 
99  EXPECT_EQ(0, fake_connect);
100  EXPECT_EQ(0, connect_calls);
101  fake_connect = count_connect;
102  EXPECT_EQ(0, connect(0, 0, 0));
103  EXPECT_EQ(1, connect_calls);
104 
105  EXPECT_EQ(0, fake_fcntl);
106  EXPECT_EQ(0, fcntl_calls);
108  EXPECT_EQ(0, fcntl(0, 0, 0));
109  EXPECT_EQ(1, fcntl_calls);
110 
111  EXPECT_EQ(0, fake_freeaddrinfo);
112  EXPECT_EQ(0, freeaddrinfo_calls);
114  freeaddrinfo(0);
115  EXPECT_EQ(1, freeaddrinfo_calls);
116 
117  EXPECT_EQ(0, fake_getaddrinfo);
118  EXPECT_EQ(0, getaddrinfo_calls);
119  fake_getaddrinfo = count_getaddrinfo;
120  EXPECT_EQ(0, getaddrinfo(0, 0, 0, 0));
121  EXPECT_EQ(1, getaddrinfo_calls);
122 
123  EXPECT_EQ(0, fake_getsockname);
124  EXPECT_EQ(0, getsockname_calls);
125  fake_getsockname = count_getsockname;
126  EXPECT_EQ(0, getsockname(0, 0, 0));
127  EXPECT_EQ(1, getsockname_calls);
128 
129  EXPECT_EQ(0, fake_listen);
130  EXPECT_EQ(0, listen_calls);
131  fake_listen = count_listen;
132  EXPECT_EQ(0, listen(0, 0));
133  EXPECT_EQ(1, listen_calls);
134 
135  EXPECT_EQ(0, fake_read);
136  EXPECT_EQ(0, read_calls);
137  fake_read = count_read;
138  EXPECT_EQ(0, read(0, 0, 0));
139  EXPECT_EQ(1, read_calls);
140 
141  EXPECT_EQ(0, fake_setsockopt);
142  EXPECT_EQ(0, setsockopt_calls);
143  fake_setsockopt = count_setsockopt;
144  EXPECT_EQ(0, setsockopt(0, 0, 0, 0, 0));
145  EXPECT_EQ(1, setsockopt_calls);
146 
147  EXPECT_EQ(0, fake_select);
148  EXPECT_EQ(0, select_calls);
149  fake_select = count_select;
150  EXPECT_EQ(0, select(0, 0, 0, 0, 0));
151  EXPECT_EQ(1, select_calls);
152 
153  EXPECT_EQ(0, fake_socket);
154  EXPECT_EQ(0, socket_calls);
155  fake_socket = count_socket;
156  EXPECT_EQ(0, socket(0, 0, 0));
157  EXPECT_EQ(1, socket_calls);
158 
159  EXPECT_EQ(0, fake_write);
160  EXPECT_EQ(0, write_calls);
161  fake_write = count_write;
162  EXPECT_EQ(0, write(0, 0, 0));
163  EXPECT_EQ(1, write_calls);
164 }
165 
166 int socket_ret = 0;
167 int socket_errno = 0;
169 int socket_type = 0;
171 int test_socket(int domain, int type, int protocol) {
172  socket_domain = domain;
173  socket_type = type;
174  socket_protocol = protocol;
175 
176  socket_calls++;
177  errno = socket_errno;
178  return socket_ret;
179 }
180 
182  fake_socket = test_socket;
183 
184  errno = 0;
185  EXPECT_EQ(0, errno);
186 
187  socket_ret = 7;
188  socket_errno = 0;
189  socket_calls = 0;
190  EXPECT_EQ(7, XmlRpcSocket::socket());
191  EXPECT_EQ(0, XmlRpcSocket::getError());
192  EXPECT_EQ(1, socket_calls);
193  EXPECT_EQ(AF_INET, socket_domain);
194  EXPECT_EQ(SOCK_STREAM, socket_type);
195  EXPECT_EQ(0, socket_protocol);
196 
197  // Check all of the errno values that the man page says socket can set if
198  // it fails
199  FOR_ERRNO(i,
200  errnos,
201  EACCES,
202  EAFNOSUPPORT,
203  EINVAL,
204  EMFILE,
205  ENFILE,
206  ENOBUFS,
207  ENOMEM,
208  EPROTONOSUPPORT) {
209  socket_ret = -1;
210  socket_errno = errnos[i];
211  socket_calls = 0;
212  EXPECT_EQ(-1, XmlRpcSocket::socket());
213  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
214  EXPECT_EQ(1, socket_calls);
215  EXPECT_EQ(AF_INET, socket_domain);
216  EXPECT_EQ(SOCK_STREAM, socket_type);
217  EXPECT_EQ(0, socket_protocol);
218  }
219 }
220 
221 int close_fd = 0;
222 int close_errno = 0;
223 int close_ret = 0;
224 int test_close(int fd) {
225  EXPECT_EQ(close_fd, fd);
226 
227  close_calls++;
228  errno = close_errno;
229  return close_ret;
230 }
231 
233  // TODO(austin): XmlRpcSocket does not check or return the return value from
234  // close
235  close_fd = 8;
236  close_errno = 0;
237  close_ret = 0;
238  close_calls = 0;
239  fake_close = test_close;
240  XmlRpcSocket::close(8);
241  EXPECT_EQ(0, XmlRpcSocket::getError());
242  EXPECT_EQ(1, close_calls);
243 
244  // TODO(austin): Close should automatically retry on EINTR but does not.
245  FOR_ERRNO(i, errnos, EBADF, EINTR, EIO) {
246  close_errno = errnos[i];
247  close_ret = -1;
248  close_calls = 0;
249  XmlRpcSocket::close(8);
250  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
251  EXPECT_EQ(1, close_calls);
252  }
253 }
254 
255 int fcntl_fd = 0;
256 int fcntl_cmd = 0;
257 unsigned long fcntl_arg = 0;
258 int fcntl_errno = 0;
259 int fcntl_ret = 0;
260 int test_fcntl(int fd, int cmd, unsigned long arg) {
261  EXPECT_EQ(fcntl_fd, fd);
262  EXPECT_EQ(fcntl_cmd, cmd);
263  EXPECT_EQ(fcntl_arg, arg);
264 
265  errno = fcntl_errno;
266  fcntl_calls++;
267  return fcntl_ret;
268 }
269 
270 TEST_F(XmlRpcSocketTest, setNonBlocking) {
272 
273  fcntl_fd = 9;
274  fcntl_cmd = F_SETFL;
275  fcntl_arg = O_NONBLOCK;
276 
277  fcntl_calls = 0;
278  fcntl_errno = 0;
279  fcntl_ret = 0;
280  EXPECT_TRUE(XmlRpcSocket::setNonBlocking(9));
281  EXPECT_EQ(0, XmlRpcSocket::getError());
282  EXPECT_EQ(1, fcntl_calls);
283 
284  // Tests for the errno values that the man page indicates might reasonably be
285  // returned by F_SETFL
286  FOR_ERRNO(i, errnos, EACCES, EAGAIN, EBADF) {
287  fcntl_calls = 0;
288  fcntl_errno = errnos[i];
289  fcntl_ret = -1;
290  EXPECT_FALSE(XmlRpcSocket::setNonBlocking(9));
291  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
292  EXPECT_EQ(1, fcntl_calls);
293  }
294 }
295 
297  expected_read(int fd, const void* buf, size_t sz)
298  : fd(fd), count(4095), buf(buf), sz(sz), ret(sz), _errno(0) {}
299 
300  expected_read(int fd, int _errno)
301  : fd(fd), count(4095), buf(0), sz(0), ret(-1), _errno(_errno) {}
302 
303  int fd;
304  size_t count;
305  const void* buf;
306  size_t sz;
307  ssize_t ret;
308  int _errno;
309 };
310 
311 std::deque<expected_read> expected_reads;
312 
313 ssize_t mock_read(int fd, void* buf, size_t count) {
314  read_calls++;
315 
316  // Check that we have another call in the queue. If not, fail the test and
317  // return 0 (EOF).
318  EXPECT_LE(1u, expected_reads.size());
319  if (expected_reads.size() < 1) {
320  errno = 0;
321  return 0;
322  }
323 
324  // Get the next call off the queue.
325  expected_read r = expected_reads.front();
326  expected_reads.pop_front();
327 
328  // Check file descriptor and count.
329  EXPECT_EQ(r.fd, fd);
330  EXPECT_EQ(r.count, count);
331 
332  // Sanity check on count. Man pages say a count above SSIZE_MAX is undefined,
333  // so check that the count that is passed doesn't trigger undefined behavior.
334  EXPECT_GT(static_cast<size_t>(SSIZE_MAX), count);
335 
336  // Check that the buffer size is less or equal to the requested buffer size.
337  EXPECT_LE(r.sz, count);
338  size_t cnt = std::min(count, r.sz);
339  // If we have a nonzero number of bytes to copy, copy them into the output
340  // buffer.
341  if (cnt > 0) {
342  memcpy(buf, r.buf, cnt);
343  }
344 
345  // Check that the return value is what we expect it to be.
346  if (r.ret >= 0) {
347  EXPECT_EQ(cnt, static_cast<size_t>(r.ret));
348  }
349 
350  // Update errno and return.
351  errno = r._errno;
352  return r.ret;
353 }
354 
356  fake_read = mock_read;
357 
358  const char data[] = "read1 read2 read3 read4 read5 read6 read7 read8";
359  bool eof = false;
360  std::string data_out;
361 
362  // Test: read some incoming data and then return EOF.
363  // This is a nominal case when reading from a blocking descriptor.
364  expected_reads.push_back(expected_read(7, data, 9));
365  expected_reads.push_back(expected_read(7, 0, 0));
366 
367  EXPECT_TRUE(XmlRpcSocket::nbRead(7, data_out, &eof));
368  EXPECT_EQ("read1 rea", data_out);
369  EXPECT_TRUE(eof);
370  EXPECT_EQ(2, read_calls);
371  EXPECT_EQ(0, XmlRpcSocket::getError());
372  EXPECT_EQ(0u, expected_reads.size());
373  expected_reads.clear();
374 }
375 
376 #define TEST_READ(RES, ERR) \
377  TEST_F(XmlRpcSocketTest, nbRead_##ERR) { \
378  fake_read = mock_read; \
379  bool eof = false; \
380  std::string data_out; \
381  \
382  expected_reads.push_back(expected_read(7, ERR)); \
383  \
384  EXPECT_##RES(XmlRpcSocket::nbRead(7, data_out, &eof)); \
385  EXPECT_EQ("", data_out); \
386  EXPECT_FALSE(eof); \
387  EXPECT_EQ(1, read_calls); \
388  EXPECT_EQ(ERR, XmlRpcSocket::getError()); \
389  EXPECT_EQ(0u, expected_reads.size()); \
390  expected_reads.clear(); \
391  }
392 
393 // EAGAIN: fd is ok, read should be expected to return 0 bytes.
394 TEST_READ(TRUE, EAGAIN);
395 
396 // EWOULDBLOCK: same as EAGAIN.
397 TEST_READ(TRUE, EWOULDBLOCK);
398 
399 // EINTR: interrupted by system call. Expected behavior is that the caller
400 // should retry the read again immediately.
401 TEST_F(XmlRpcSocketTest, nbRead_EINTR) {
402  fake_read = mock_read;
403 
404  bool eof = false;
405  std::string data_out;
406 
407  expected_reads.push_back(expected_read(7, EINTR));
408  // TODO(austin): expecting a second read causes the test to fail.
409  // expected_reads.push_back(expected_read(7, 0, 0));
410 
411  EXPECT_TRUE(XmlRpcSocket::nbRead(7, data_out, &eof));
412  EXPECT_EQ("", data_out);
413  EXPECT_FALSE(eof);
414  // TODO(austin): expecting a second read causes the test to fail.
415  // EXPECT_EQ(2, read_calls);
416  EXPECT_EQ(1, read_calls);
417  EXPECT_EQ(EINTR, XmlRpcSocket::getError());
418 }
419 
420 // EBADF: file descriptor is bad; read should fail.
421 TEST_READ(FALSE, EBADF);
422 
423 // EFAULT: buf is bad; read should fail.
424 // TODO(austin): this failure indicates that file descriptor is good, so if
425 // we see this error elsewhere it indicates that we shouldn't close the socket.
426 // Since XmlRpcSocket is handling the buffers, maybe this should be converted
427 // into an assertion failure inside XmlRpcSocket, and this test should
428 // EXPECT_DEATH?
429 TEST_READ(FALSE, EFAULT);
430 
431 // EINVAL: File descriptor is not for reading. read should fail.
432 TEST_READ(FALSE, EINVAL);
433 
434 // EIO: I/O error. read should probably fail.
435 TEST_READ(FALSE, EIO);
436 
437 // EISDIR: File descriptor is a directory. read should fail.
438 TEST_READ(FALSE, EISDIR);
439 
440 // More errors from recv (these should also apply to read on a socket).
441 // EACCES: Permission denied. read should fail.
442 TEST_READ(FALSE, EACCES);
443 
444 // ECONNREFUSED: Connection refused. read should fail.
445 TEST_READ(FALSE, ECONNREFUSED);
446 
447 // ENOMEM: Could not allocate memory. read should fail.
448 TEST_READ(FALSE, ENOMEM);
449 
450 // ENOTCONN: Socket is not connected. read should fail.
451 TEST_READ(FALSE, ENOTCONN);
452 
454  expected_write(int fd, std::string data, size_t count, size_t max_write)
455  : fd(fd),
456  data(data),
457  count(count),
458  max_write(max_write),
459  ret(std::min(count, max_write)),
460  _errno(0) {}
461 
462  expected_write(int fd, size_t count, ssize_t ret, int _errno)
463  : fd(fd), data(""), count(count), max_write(0), ret(ret), _errno(_errno) {}
464 
465  int fd;
466  std::string data;
467  size_t count;
468  size_t max_write;
469  ssize_t ret;
470  int _errno;
471 };
472 
473 std::deque<expected_write> expected_writes;
474 
475 ssize_t mock_write(int fd, const void* buf, size_t count) {
476  write_calls++;
477 
478  // Check that we have another call in the queue. If not, fail the test and
479  // return 0 (EOF).
480  EXPECT_LE(1u, expected_writes.size());
481  if (expected_writes.size() < 1) {
482  // Since the socket is supposed to be non-blocking, return EWOULDBLOCK
483  // if we can't write.
484  errno = EWOULDBLOCK;
485  return -1;
486  }
487 
488  expected_write w = expected_writes.front();
489  expected_writes.pop_front();
490 
491  EXPECT_EQ(w.fd, fd);
492  EXPECT_EQ(w.count, count);
493  size_t sz = std::min(w.max_write, count);
494  if (sz > 0) {
495  std::string data((const char*)buf, sz);
496  EXPECT_EQ(w.data, data);
497  EXPECT_GE(w.ret, 0u);
498  EXPECT_EQ(static_cast<size_t>(w.ret), sz);
499  }
500 
501  errno = w._errno;
502  return w.ret;
503 }
504 
506  fake_write = mock_write;
507  int count = 0;
508  std::string hello = "hello world";
509 
510  // Single write for all the data.
511  expected_writes.push_back(expected_write(10, "hello world", 11, 11));
512  count = 0;
513  write_calls = 0;
514  errno = 0;
515  EXPECT_TRUE(XmlRpcSocket::nbWrite(10, hello, &count));
516  EXPECT_EQ(count, 11);
517  EXPECT_EQ(0, XmlRpcSocket::getError());
518  EXPECT_EQ(0u, expected_writes.size());
519  EXPECT_EQ(1, write_calls);
520 
521  // Write in two parts, both succeed.
522  expected_writes.push_back(expected_write(10, "hello", 11, 5));
523  expected_writes.push_back(expected_write(10, " world", 6, 10));
524  count = 0;
525  write_calls = 0;
526  errno = 0;
527  EXPECT_TRUE(XmlRpcSocket::nbWrite(10, hello, &count));
528  EXPECT_EQ(count, 11);
529  EXPECT_EQ(0, XmlRpcSocket::getError());
530  EXPECT_EQ(0u, expected_writes.size());
531  EXPECT_EQ(2, write_calls);
532 
533  // Partial write.
534  count = 0;
535  write_calls = 0;
536  errno = 0;
537  expected_writes.push_back(expected_write(10, "hello", 11, 5));
538  expected_writes.push_back(expected_write(10, 6, -1, EWOULDBLOCK));
539  EXPECT_TRUE(XmlRpcSocket::nbWrite(10, hello, &count));
540  EXPECT_EQ(count, 5);
541  EXPECT_EQ(EWOULDBLOCK, XmlRpcSocket::getError());
542  EXPECT_EQ(0u, expected_writes.size());
543  EXPECT_EQ(2, write_calls);
544 }
545 
546 #define TEST_WRITE(RES, ERR) \
547  TEST_F(XmlRpcSocketTest, nbWrite_##ERR) { \
548  fake_write = mock_write; \
549  int count = 0; \
550  std::string hello = "hello world"; \
551  errno = 0; \
552  expected_writes.push_back(expected_write(10, 11, -1, ERR)); \
553  EXPECT_##RES(XmlRpcSocket::nbWrite(10, hello, &count)); \
554  EXPECT_EQ(count, 0); \
555  EXPECT_EQ(ERR, XmlRpcSocket::getError()); \
556  EXPECT_EQ(0u, expected_writes.size()); \
557  EXPECT_EQ(1, write_calls); \
558  expected_writes.clear(); \
559  }
560 
561 TEST_WRITE(TRUE, EAGAIN);
562 TEST_WRITE(TRUE, EWOULDBLOCK);
563 TEST_WRITE(TRUE, EINTR); // TODO(austin): this should retry immediately.
564 TEST_WRITE(FALSE, EBADF);
565 TEST_WRITE(FALSE, EDESTADDRREQ);
566 TEST_WRITE(FALSE, EDQUOT);
567 TEST_WRITE(FALSE, EFAULT);
568 TEST_WRITE(FALSE, EFBIG);
569 TEST_WRITE(FALSE, EINVAL);
570 TEST_WRITE(FALSE, EIO);
571 TEST_WRITE(FALSE, ENOSPC);
572 TEST_WRITE(FALSE, EPIPE);
573 TEST_WRITE(FALSE, EACCES);
574 TEST_WRITE(FALSE, ECONNRESET);
575 TEST_WRITE(FALSE, EISCONN);
576 TEST_WRITE(FALSE, ENOBUFS);
577 TEST_WRITE(FALSE, ENOMEM);
578 TEST_WRITE(FALSE, ENOTCONN);
579 
584  int sockfd, int level, int optname, const void* optval, socklen_t optlen) {
585  setsockopt_calls++;
586  setsockopt_sockfd = sockfd;
587 
588  // These arguments are all fixed, so just test for them here.
589  EXPECT_EQ(SOL_SOCKET, level);
590  EXPECT_EQ(SO_REUSEADDR, optname);
591  EXPECT_EQ(sizeof(int), optlen);
592  if (sizeof(int) == optlen) {
593  EXPECT_EQ(1, *(int*)optval);
594  }
595 
596  errno = setsockopt_errno;
597  return setsockopt_ret;
598 }
599 
600 TEST_F(XmlRpcSocketTest, setReuseAddr) {
601  fake_setsockopt = test_setsockopt;
602 
603  errno = 0;
604  setsockopt_sockfd = 0;
605  setsockopt_calls = 0;
606 
607  setsockopt_errno = 0;
608  setsockopt_ret = 0;
609  EXPECT_TRUE(XmlRpcSocket::setReuseAddr(11));
610  EXPECT_EQ(0, XmlRpcSocket::getError());
611  EXPECT_EQ(11, setsockopt_sockfd);
612  EXPECT_EQ(1, setsockopt_calls);
613 
614  FOR_ERRNO(i, errnos, EBADF, EFAULT, EINVAL, ENOPROTOOPT, ENOTSOCK) {
615  errno = 0;
616  setsockopt_sockfd = 0;
617  setsockopt_calls = 0;
618 
619  setsockopt_errno = errnos[i];
620  setsockopt_ret = -1;
621  EXPECT_FALSE(XmlRpcSocket::setReuseAddr(11));
622  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
623  EXPECT_EQ(11, setsockopt_sockfd);
624  EXPECT_EQ(1, setsockopt_calls);
625  }
626 }
627 
628 bool operator==(const in6_addr a, const in6_addr b) {
629  // Delegate to IPv6 address comparison macro.
630  return IN6_ARE_ADDR_EQUAL(&a, &b);
631 }
632 
633 int bind_ret = 0;
634 int bind_errno = 0;
635 int bind_sockfd = 0;
636 int bind_family = 0;
637 int bind_port = 0;
638 int test_bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen) {
639  bind_calls++;
640  EXPECT_EQ(bind_sockfd, sockfd);
641 
642  EXPECT_TRUE(NULL != addr);
643  if (NULL != addr) {
644  EXPECT_EQ(bind_family, addr->sa_family);
645  if (AF_INET == addr->sa_family) {
646  EXPECT_EQ(sizeof(struct sockaddr_in), addrlen);
647  struct sockaddr_in* in_addr = (struct sockaddr_in*)addr;
648  EXPECT_EQ(INADDR_ANY, ntohl(in_addr->sin_addr.s_addr));
649  EXPECT_EQ(bind_port, ntohs(in_addr->sin_port));
650 
651  } else if (AF_INET6 == addr->sa_family) {
652  EXPECT_EQ(sizeof(struct sockaddr_in6), addrlen);
653  struct sockaddr_in6* in6_addr = (struct sockaddr_in6*)addr;
654  EXPECT_EQ(in6addr_any, in6_addr->sin6_addr);
655  EXPECT_EQ(bind_port, ntohs(in6_addr->sin6_port));
656  } else {
657  ADD_FAILURE() << "Unrecognized sockaddr family";
658  }
659  }
660 
661  errno = bind_errno;
662  return bind_ret;
663 }
664 
666  fake_bind = test_bind;
667 
668  // Nominal case: bind returns success.
669  bind_sockfd = 12;
670  bind_family = AF_INET;
671  bind_port = 22;
672 
673  bind_calls = 0;
674  bind_errno = 0;
675  bind_ret = 0;
676  EXPECT_TRUE(XmlRpcSocket::bind(12, 22));
677  EXPECT_EQ(1, bind_calls);
678  EXPECT_EQ(0, XmlRpcSocket::getError());
679 
680  // Errors that the man page indicates can happen for all sockets; this does
681  // not include the errors that are specific to UNIX domain sockets.
682  FOR_ERRNO(i, errnos, EACCES, EADDRINUSE, EBADF, EINVAL, ENOTSOCK) {
683  bind_calls = 0;
684 
685  bind_family = AF_INET;
686  bind_port = 22;
687 
688  bind_errno = errnos[i];
689  bind_ret = -1;
690  EXPECT_FALSE(XmlRpcSocket::bind(12, 22));
691  EXPECT_EQ(1, bind_calls);
692  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
693  }
694 
695  // Basic test for IPv6 functionality.
696  XmlRpcSocket::s_use_ipv6_ = true;
697 
698  bind_calls = 0;
699 
700  bind_family = AF_INET6;
701  bind_port = 22;
702 
703  bind_errno = 0;
704  bind_ret = 0;
705  EXPECT_TRUE(XmlRpcSocket::bind(12, 22));
706  EXPECT_EQ(1, bind_calls);
707  EXPECT_EQ(0, XmlRpcSocket::getError());
708 }
709 
714 socklen_t getsockname_len = 0;
715 int test_getsockname(int sockfd, struct sockaddr* addr, socklen_t* addrlen) {
716  getsockname_calls++;
717 
718  EXPECT_EQ(getsockname_sockfd, sockfd);
719 
720  EXPECT_TRUE(NULL != addr);
721  EXPECT_LE(getsockname_len, *addrlen);
722  if (NULL != addr) {
723  socklen_t len = std::min(*addrlen, getsockname_len);
724  if (len > 0)
725  memcpy(addr, getsockname_addr, len);
726  }
727  EXPECT_TRUE(NULL != addrlen);
728  if (NULL != addrlen) {
729  *addrlen = getsockname_len;
730  }
731 
732  errno = getsockname_errno;
733  return getsockname_ret;
734 }
735 
737  fake_getsockname = test_getsockname;
738 
739  struct sockaddr_in inet_addr;
740  inet_addr.sin_family = AF_INET;
741  inet_addr.sin_port = htons(123);
742 
743  struct sockaddr_in6 inet6_addr;
744  inet6_addr.sin6_family = AF_INET6;
745  inet6_addr.sin6_port = htons(4224);
746 
747  getsockname_sockfd = 14;
748 
749  getsockname_errno = 0;
750  getsockname_ret = 0;
751 
752  getsockname_calls = 0;
753  getsockname_addr = &inet_addr;
754  getsockname_len = sizeof(struct sockaddr_in);
755  EXPECT_EQ(123, XmlRpcSocket::get_port(14));
756  EXPECT_EQ(0, XmlRpcSocket::getError());
757  EXPECT_EQ(1, getsockname_calls);
758 
759  getsockname_calls = 0;
760  getsockname_addr = &inet6_addr;
761  getsockname_len = sizeof(struct sockaddr_in6);
762  EXPECT_EQ(4224, XmlRpcSocket::get_port(14));
763  EXPECT_EQ(0, XmlRpcSocket::getError());
764  EXPECT_EQ(1, getsockname_calls);
765 
766  getsockname_ret = -1;
767  FOR_ERRNO(i, errnos, EBADF, EFAULT, EINVAL, ENOBUFS, ENOTSOCK) {
768  getsockname_errno = errnos[i];
769 
770  // Errors, no data written to buffer.
771  getsockname_calls = 0;
772  getsockname_addr = NULL;
773  getsockname_len = 0;
774  EXPECT_EQ(0, XmlRpcSocket::get_port(14));
775  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
776  EXPECT_EQ(1, getsockname_calls);
777 
778  // Same errors, but this time put valid data and expect that it is ignored.
779  getsockname_calls = 0;
780  getsockname_addr = &inet_addr;
781  getsockname_len = sizeof(struct sockaddr_in);
782  EXPECT_EQ(0, XmlRpcSocket::get_port(14));
783  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
784  EXPECT_EQ(1, getsockname_calls);
785  }
786 }
787 
788 int listen_ret = 0;
789 int listen_errno = 0;
792 int test_listen(int sockfd, int backlog) {
793  EXPECT_EQ(listen_sockfd, sockfd);
794  EXPECT_EQ(listen_backlog, backlog);
795 
796  errno = listen_errno;
797  return listen_ret;
798 }
799 
801  fake_listen = test_listen;
802 
803  listen_sockfd = 13;
804  listen_backlog = 10;
805 
806  listen_ret = 0;
807  listen_errno = 0;
808  EXPECT_TRUE(XmlRpcSocket::listen(13, 10));
809  EXPECT_EQ(0, XmlRpcSocket::getError());
810 
811  FOR_ERRNO(i, errnos, EADDRINUSE, EBADF, ENOTSOCK, EOPNOTSUPP) {
812  listen_ret = -1;
813  listen_errno = errnos[i];
814  EXPECT_FALSE(XmlRpcSocket::listen(13, 10));
815  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
816  }
817 }
818 
819 int accept_ret = 0;
820 int accept_errno = 0;
822 void* accept_addr = 0;
823 socklen_t accept_addrlen = 0;
824 int test_accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen) {
825  accept_calls++;
826  EXPECT_EQ(accept_sockfd, sockfd);
827 
828  if (accept_addr) {
829  EXPECT_TRUE(NULL != addr);
830  EXPECT_TRUE(NULL != addrlen);
831  if (NULL != addr && NULL != addrlen) {
832  socklen_t len = std::min(accept_addrlen, *addrlen);
833  memcpy(addr, accept_addr, len);
834  *addrlen = accept_addrlen;
835  }
836  } else {
837  EXPECT_EQ(NULL, addr);
838  EXPECT_EQ(NULL, addrlen);
839  }
840 
841  errno = accept_errno;
842  return accept_ret;
843 }
844 
846  fake_accept = test_accept;
847 
848  // Set up address. XmlRpcSocket::accept expects this, even if it isn't used.
849  struct sockaddr_in addr;
850  addr.sin_family = AF_INET;
851  addr.sin_port = htons(45);
852  addr.sin_addr.s_addr = 0xDEADBEEF;
853 
854  accept_addr = &addr;
855  accept_addrlen = sizeof(struct sockaddr);
856 
857  accept_sockfd = 15;
858 
859  accept_calls = 0;
860  accept_ret = 16;
861  accept_errno = 0;
862  EXPECT_EQ(16, XmlRpcSocket::accept(15));
863  EXPECT_EQ(0, XmlRpcSocket::getError());
864  EXPECT_EQ(1, accept_calls);
865 
866  FOR_ERRNO(i,
867  errnos,
868  EAGAIN,
869  EWOULDBLOCK,
870  EBADF,
871  ECONNABORTED,
872  EFAULT,
873  EINTR, // TODO(austin): Should this retry immediately?
874  EINVAL,
875  EMFILE,
876  ENFILE,
877  ENOBUFS,
878  ENOMEM,
879  ENOTSOCK,
880  EOPNOTSUPP,
881  EPROTO,
882  EPERM) {
883  accept_calls = 0;
884  accept_ret = -1;
885  accept_errno = errnos[i];
886  EXPECT_EQ(-1, XmlRpcSocket::accept(15));
887  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
888  EXPECT_EQ(1, accept_calls);
889  }
890 }
891 
892 // To test connect() we need mocks for getaddrinfo(), freeaddrinfo(), connect()
893 // and XmlRpc logging hooks to validate that the correct error messages are
894 // logged.
895 
898 const char* getaddrinfo_node = 0;
899 const char* getaddrinfo_service = 0;
900 struct addrinfo getaddrinfo_hints = {.ai_flags = 0,
901  .ai_family = 0,
902  .ai_socktype = 0,
903  .ai_protocol = 0,
904  .ai_addrlen = 0,
905  .ai_addr = 0,
906  .ai_canonname = 0,
907  .ai_next = 0};
908 struct addrinfo* getaddrinfo_res = 0;
909 int test_getaddrinfo(const char* node,
910  const char* service,
911  const struct addrinfo* hints,
912  struct addrinfo** res) {
913  getaddrinfo_calls++;
914 
915  EXPECT_STREQ(getaddrinfo_node, node);
916  EXPECT_STREQ(getaddrinfo_service, service);
917 
918  EXPECT_TRUE(NULL != hints);
919  if (NULL != hints) {
920  EXPECT_TRUE(memcmp(hints, &getaddrinfo_hints, sizeof(struct addrinfo)) ==
921  0);
922  }
923 
924  EXPECT_TRUE(NULL != res);
925  if (NULL != res) {
926  *res = getaddrinfo_res;
927  }
928 
929  errno = getaddrinfo_errno;
930  return getaddrinfo_ret;
931 }
932 
933 struct addrinfo* freeaddrinfo_res = 0;
934 void test_freeaddrinfo(struct addrinfo* res) {
935  // The man page does not indicate any errors that freeaddrinfo may encounter.
937 
938  EXPECT_EQ(freeaddrinfo_res, res);
939 
940  return;
941 }
942 
943 void EXPECT_SOCKADDR_EQ(const sockaddr* addr1, const sockaddr* addr2) {
944  EXPECT_EQ((NULL == addr1), (NULL == addr2));
945  if (NULL != addr1 && NULL != addr2) {
946  EXPECT_EQ(addr1->sa_family, addr2->sa_family);
947  if (addr1->sa_family == addr2->sa_family) {
948  switch (addr1->sa_family) {
949  case AF_INET: {
950  const sockaddr_in* addr1_in = (const sockaddr_in*)addr1;
951  const sockaddr_in* addr2_in = (const sockaddr_in*)addr2;
952  EXPECT_EQ(addr1_in->sin_port, addr2_in->sin_port);
953  EXPECT_EQ(addr1_in->sin_addr.s_addr, addr2_in->sin_addr.s_addr);
954  } break;
955  case AF_INET6: {
956  const sockaddr_in6* addr1_in6 = (const sockaddr_in6*)addr1;
957  const sockaddr_in6* addr2_in6 = (const sockaddr_in6*)addr2;
958  EXPECT_EQ(addr1_in6->sin6_port, addr2_in6->sin6_port);
959  EXPECT_EQ(addr1_in6->sin6_flowinfo, addr2_in6->sin6_flowinfo);
960  EXPECT_EQ(addr1_in6->sin6_scope_id, addr2_in6->sin6_scope_id);
961  EXPECT_TRUE(
962  IN6_ARE_ADDR_EQUAL(&addr1_in6->sin6_addr, &addr2_in6->sin6_addr));
963  for (int i = 0; i < 16; i++) {
964  EXPECT_EQ(addr1_in6->sin6_addr.s6_addr[i],
965  addr2_in6->sin6_addr.s6_addr[i])
966  << "IPv6 address mismstach at byte " << i;
967  }
968  } break;
969  default:
970  ADD_FAILURE() << "Unrecognized address type; cannot compare";
971  }
972  }
973  }
974 }
975 
976 int connect_ret = 0;
979 const struct sockaddr* connect_addr = 0;
980 socklen_t connect_addrlen = 0;
981 int test_connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen) {
982  connect_calls++;
983 
984  EXPECT_EQ(connect_sockfd, sockfd);
985 
986  EXPECT_TRUE(NULL != addr);
987  EXPECT_EQ(connect_addrlen, addrlen);
989 
990  errno = connect_errno;
991  return connect_ret;
992 }
993 
997 public:
998  virtual void log(int level, const char* msg) {
999  last_level = level;
1000  last_msg = msg;
1001  std::cout << "LOG(" << level << "):" << msg;
1002  }
1003 
1004  virtual void error(const char* msg) {
1005  last_error = msg;
1006  std::cout << "ERROR: " << msg;
1007  }
1008 
1010  std::string last_msg;
1011  std::string last_error;
1012 
1013  void EXPECT_LOG(int level, const std::string& msg) {
1014  EXPECT_EQ(level, last_level);
1015  EXPECT_EQ(msg, last_msg);
1016  }
1017 
1018  void EXPECT_ERROR(const std::string& msg) {
1019  EXPECT_EQ(msg, last_error);
1020  }
1021 
1022 protected:
1023  void SetUp() {
1025 
1026  // Install mock functions.
1027  fake_getaddrinfo = test_getaddrinfo;
1029  fake_connect = test_connect;
1030 
1033 
1034  // Set up address data structures for testing use.
1035  addr_ip4_22.sin_family = AF_INET;
1036  addr_ip4_22.sin_port = htons(22);
1037  addr_ip4_22.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1038 
1039  addr_ip4_404.sin_family = AF_INET;
1040  addr_ip4_404.sin_port = htons(404);
1041  addr_ip4_404.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1042 
1043  addr_ip6_44.sin6_family = AF_INET6;
1044  addr_ip6_44.sin6_port = htons(44);
1045  addr_ip6_44.sin6_flowinfo = 0;
1046  addr_ip6_44.sin6_addr = in6addr_loopback;
1047  addr_ip6_44.sin6_scope_id = 0;
1048 
1049  addr_ip6_404.sin6_family = AF_INET6;
1050  addr_ip6_404.sin6_port = htons(404);
1051  addr_ip6_404.sin6_flowinfo = 0;
1052  addr_ip6_404.sin6_addr = in6addr_loopback;
1053  addr_ip6_404.sin6_scope_id = 0;
1054 
1055  info_ip4.ai_flags = 0;
1056  info_ip4.ai_family = AF_INET;
1057  info_ip4.ai_socktype = SOCK_STREAM;
1058  info_ip4.ai_protocol = 0;
1059  info_ip4.ai_addrlen = sizeof(struct sockaddr_in);
1060  info_ip4.ai_addr = (struct sockaddr*)&addr_ip4_22;
1061  info_ip4.ai_canonname = 0;
1062  info_ip4.ai_next = 0;
1063 
1064  info_ip6.ai_flags = 0;
1065  info_ip6.ai_family = AF_INET6;
1066  info_ip6.ai_socktype = SOCK_STREAM;
1067  info_ip6.ai_protocol = 0;
1068  info_ip6.ai_addrlen = sizeof(struct sockaddr_in6);
1069  info_ip6.ai_addr = (struct sockaddr*)&addr_ip6_44;
1070  info_ip6.ai_canonname = 0;
1071  info_ip6.ai_next = 0;
1072 
1073  info_canon.ai_flags = 0;
1074  info_canon.ai_family = 0;
1075  info_canon.ai_socktype = 0;
1076  info_canon.ai_protocol = 0;
1077  info_canon.ai_addrlen = 0;
1078  info_canon.ai_addr = 0;
1079  info_canon.ai_canonname = 0;
1080  info_canon.ai_next = 0;
1081 
1082  // Set up expected hints.
1083  getaddrinfo_hints.ai_family = AF_UNSPEC;
1084  // TODO(austin): hints should probably specify SOCK_STREAM
1085  // getaddrinfo_hints.ai_socktype = SOCK_STREAM;
1086 
1087  getaddrinfo_node = "nowhere.com";
1088  getaddrinfo_service = 0;
1089 
1090  connect_sockfd = 19;
1091  }
1092 
1093  void TestConnect() {
1094  // Always free the same getaddrinfo that we started with.
1096 
1097  // Clear last log message.
1098  last_level = 0;
1099  last_msg = "";
1100  last_error = "";
1101 
1102  // Actually start running tests.
1103  getaddrinfo_calls = 0;
1104  freeaddrinfo_calls = 0;
1105  connect_calls = 0;
1106  EXPECT_TRUE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1107  EXPECT_EQ(1, getaddrinfo_calls);
1108  EXPECT_EQ(1, freeaddrinfo_calls);
1109  EXPECT_EQ(1, connect_calls);
1110  }
1111 
1113  // Always free the same getaddrinfo that we started with.
1115 
1116  // Clear last log message.
1117  last_level = 0;
1118  last_msg = "";
1119  last_error = "";
1120 
1121  // Actually start running tests.
1122  getaddrinfo_calls = 0;
1123  freeaddrinfo_calls = 0;
1124  connect_calls = 0;
1125  EXPECT_FALSE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1126  EXPECT_EQ(1, getaddrinfo_calls);
1127  EXPECT_EQ(0, freeaddrinfo_calls);
1128  EXPECT_EQ(0, connect_calls);
1129  }
1130 
1132  // Always free the same getaddrinfo that we started with.
1134 
1135  // Clear last log message.
1136  last_level = 0;
1137  last_msg = "";
1138  last_error = "";
1139 
1140  // Actually start running tests.
1141  getaddrinfo_calls = 0;
1142  freeaddrinfo_calls = 0;
1143  connect_calls = 0;
1144  EXPECT_FALSE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1145  EXPECT_EQ(1, getaddrinfo_calls);
1146  EXPECT_EQ(1, freeaddrinfo_calls);
1147  EXPECT_EQ(1, connect_calls);
1148  }
1149 
1150  void TearDown() {
1151  XmlRpcLogHandler::setLogHandler(NULL);
1152  XmlRpcErrorHandler::setErrorHandler(NULL);
1153 
1155  }
1156 
1157  struct sockaddr_in addr_ip4_22;
1158  struct sockaddr_in addr_ip4_404;
1159  struct sockaddr_in6 addr_ip6_44;
1160  struct sockaddr_in6 addr_ip6_404;
1161  struct addrinfo info_ip4;
1162  struct addrinfo info_ip6;
1163  struct addrinfo info_canon;
1164 };
1165 
1166 TEST_F(XmlRpcConnectTest, connect_ipv4) {
1167  // Expected results from getaddrinfo.
1168  getaddrinfo_ret = 0;
1169  getaddrinfo_errno = 0;
1170 
1171  // Expected results from connect.
1172  connect_ret = 0;
1173  connect_errno = 0;
1174  connect_addr = (struct sockaddr*)&addr_ip4_404;
1175  connect_addrlen = sizeof(struct sockaddr_in);
1176 
1177  // Canonical address first, then IPv4, IPv6.
1178  getaddrinfo_res = &info_canon;
1179  info_canon.ai_next = &info_ip4;
1180  info_ip4.ai_next = &info_ip6;
1181  info_ip6.ai_next = 0;
1182  TestConnect();
1183 
1184  // List with IPv6 first.
1185  getaddrinfo_res = &info_canon;
1186  info_canon.ai_next = &info_ip6;
1187  info_ip6.ai_next = &info_ip4;
1188  info_ip4.ai_next = 0;
1189  TestConnect();
1190 
1191  // List without canon address, IPv6 first.
1192  getaddrinfo_res = &info_ip6;
1193  info_ip6.ai_next = &info_ip4;
1194  info_ip4.ai_next = 0;
1195  TestConnect();
1196 
1197  // List without canon address, IPv4 first.
1198  getaddrinfo_res = &info_ip4;
1199  info_ip4.ai_next = &info_ip6;
1200  info_ip6.ai_next = 0;
1201  TestConnect();
1202 }
1203 
1204 TEST_F(XmlRpcConnectTest, connect_ipv6) {
1205  // Basic IPv6 tests.
1206  XmlRpcSocket::s_use_ipv6_ = true;
1207 
1208  // Expected results from getaddrinfo.
1209  getaddrinfo_ret = 0;
1210  getaddrinfo_errno = 0;
1211 
1212  // Expected results from connect.
1213  connect_ret = 0;
1214  connect_errno = 0;
1215  connect_addr = (struct sockaddr*)&addr_ip6_404;
1216  connect_addrlen = sizeof(struct sockaddr_in6);
1217 
1218  // List without canon address, IPv4 first.
1219  getaddrinfo_res = &info_ip4;
1220  info_ip4.ai_next = &info_ip6;
1221  info_ip6.ai_next = 0;
1222  TestConnect();
1223 
1224  // List without canon address, IPv6 first.
1225  getaddrinfo_res = &info_ip6;
1226  info_ip6.ai_next = &info_ip4;
1227  info_ip4.ai_next = 0;
1228  TestConnect();
1229 }
1230 
1231 // Simulate error returns from getaddrinfo. Check that the error is logged
1232 // correctly, that connect is not called, that the result is freed(or not)
1233 // and that connect correctly returns an error.
1234 TEST_F(XmlRpcConnectTest, connect_lookup_fail) {
1235  // Expected results from connect.
1236  connect_ret = 0;
1237  connect_errno = 0;
1238  connect_addr = (struct sockaddr*)&addr_ip4_404;
1239  connect_addrlen = sizeof(struct sockaddr_in);
1240 
1241  // List without canon address, IPv4 first.
1242  getaddrinfo_res = &info_ip4;
1243  info_ip4.ai_next = &info_ip6;
1244  info_ip6.ai_next = 0;
1245 
1246  // Enumerate possible return codes from getaddrinfo and make sure that
1247  // connect() fails and that the correct error message is reported.
1248  FOR_ERRNO(i,
1249  addr_errs,
1250  EAI_ADDRFAMILY,
1251  EAI_AGAIN,
1252  EAI_BADFLAGS,
1253  EAI_FAIL,
1254  EAI_FAMILY,
1255  EAI_MEMORY,
1256  EAI_NODATA,
1257  EAI_NONAME,
1258  EAI_SERVICE,
1259  EAI_SOCKTYPE) {
1260  // Results from getaddrinfo.
1261  getaddrinfo_ret = addr_errs[i];
1262  getaddrinfo_errno = 0;
1263 
1264  TestLookupFail();
1265  EXPECT_ERROR(
1266  std::string("Couldn't find an AF_INET address for [nowhere.com]: ") +
1267  std::string(gai_strerror(addr_errs[i])) + std::string("\n"));
1268  }
1269 
1270  // Enumerate system failures from getaddrinfo and make sure that connect()
1271  // fails and that the correct error from perror is reported.
1272  // TODO(austin): getaddrinfo should retry on EINTR but it doesn't.
1273  getaddrinfo_ret = EAI_SYSTEM;
1274  FOR_ERRNO(i, errnos, ENFILE, EMFILE, EAGAIN, EINTR) {
1275  getaddrinfo_errno = errnos[i];
1276  TestLookupFail();
1277  EXPECT_ERROR(
1278  std::string("Couldn't find an AF_INET address for [nowhere.com]: ") +
1279  std::string(strerror(errnos[i])) + std::string("\n"));
1280  }
1281 
1282  // IPv4 lookup only returns IPv6 results.
1283  getaddrinfo_res = &info_ip6;
1284  info_ip6.ai_next = 0;
1285 
1286  // Results from getaddrinfo.
1287  getaddrinfo_ret = 0;
1288  getaddrinfo_errno = 0;
1289 
1290  // Always free the same getaddrinfo that we started with.
1292 
1293  // Clear last log message.
1294  last_level = 0;
1295  last_msg = "";
1296  last_error = "";
1297 
1298  // Call connect and analyze results. We do this inline here instead of
1299  // using one of the convenience functions because none of the convenience
1300  // functions fit this pattern.
1301  getaddrinfo_calls = 0;
1302  freeaddrinfo_calls = 0;
1303  connect_calls = 0;
1304  EXPECT_FALSE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1305  EXPECT_EQ(1, getaddrinfo_calls);
1306  EXPECT_EQ(1, freeaddrinfo_calls);
1307  EXPECT_EQ(0, connect_calls);
1308  EXPECT_ERROR(
1309  std::string("Couldn't find an AF_INET address for [nowhere.com]") +
1310  std::string("\n"));
1311 }
1312 
1313 // TODO(austin): this probably won't work, isn't supported upstream and isn't
1314 // required by our current use case. Future work.
1315 // Simulate multiple results for a hostname lookup. Simulate failure to
1316 // connect to the first hostname and verify that another attempt is made
1317 // for the second address.
1318 TEST_F(XmlRpcConnectTest, connect_multiple_result) {}
1319 
1320 // Simulate various error results from connect().
1321 TEST_F(XmlRpcConnectTest, connect_failure) {
1322  // Expected results from getaddrinfo.
1323  getaddrinfo_ret = 0;
1324  getaddrinfo_errno = 0;
1325 
1326  // Expected results from connect.
1327  connect_ret = 0;
1328  connect_errno = 0;
1329  connect_addr = (struct sockaddr*)&addr_ip4_404;
1330  connect_addrlen = sizeof(struct sockaddr_in);
1331 
1332  // List without canon address, IPv4 first.
1333  getaddrinfo_res = &info_ip4;
1334  info_ip4.ai_next = &info_ip6;
1335  info_ip6.ai_next = 0;
1336 
1337  // EINPROGRESS indicates that the socket is non-blocking and the connection
1338  // request has started but not finished, so we expect success.
1339  connect_ret = -1;
1340  connect_errno = EINPROGRESS;
1341  TestConnect();
1342  EXPECT_ERROR("");
1343 
1344  // On Windows, EWOULDBLOCK (really WSAEWOULDBLOCK) indicates that the
1345  // socket is non-blocking and could not be completed immediately (success)
1346  // but on Linux it it synonymous with EAGAIN which indicates that there are
1347  // no more available local ports.
1348  //
1349  // NOTE(austin): if this comparison fails, create separate tests for EAGAIN
1350  // and EWOULDBLOCK.
1351  EXPECT_EQ(EWOULDBLOCK, EAGAIN);
1352  connect_ret = -1;
1353  connect_errno = EWOULDBLOCK;
1354 #if defined(_WINDOWS)
1355  TestConnect();
1356  EXPECT_ERROR("");
1357 #else
1358  TestConnectFail();
1359  EXPECT_ERROR(std::string("::connect error = ") +
1360  std::string(strerror(EWOULDBLOCK)) + std::string("\n"));
1361 #endif
1362 
1363  // All other errors that connect may return should be reported as an error.
1364  // TODO(austin): Connect should immediately retry on EINTR but it doesn't.
1365  FOR_ERRNO(i,
1366  errnos,
1367  EACCES,
1368  EPERM,
1369  EADDRINUSE,
1370  EAFNOSUPPORT,
1371  EALREADY,
1372  EBADF,
1373  ECONNREFUSED,
1374  EFAULT,
1375  EINTR,
1376  EISCONN,
1377  ENETUNREACH,
1378  ENOTSOCK,
1379  ETIMEDOUT) {
1380  connect_ret = -1;
1381  connect_errno = errnos[i];
1382  TestConnectFail();
1383  EXPECT_ERROR(std::string("::connect error = ") +
1384  std::string(strerror(errnos[i])) + std::string("\n"));
1385  }
1386 }
1387 
1388 int main(int argc, char **argv)
1389 {
1390  ::testing::InitGoogleTest(&argc, argv);
1391  return RUN_ALL_TESTS();
1392 }
int listen_ret
int socket_calls
Definition: mock_socket.cpp:75
int accept_errno
#define FOR_ERRNO(itr, var,...)
Definition: test_socket.cpp:42
int test_listen(int sockfd, int backlog)
expected_read(int fd, int _errno)
int setsockopt_ret
int close_fd
int socket_ret
static void setLogHandler(XmlRpcLogHandler *lh)
Specifies the message handler.
Definition: XmlRpcUtil.h:56
int bind_errno
int close_errno
int accept_ret
int(* fake_fcntl)(int fd, int cmd, unsigned long)=0
struct addrinfo * getaddrinfo_res
int getaddrinfo_ret
int count_fcntl(int fd, int cmd, unsigned long arg)
int listen_backlog
void * getsockname_addr
expected_write(int fd, size_t count, ssize_t ret, int _errno)
int connect_ret
int test_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
const void * buf
int test_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
bool operator==(const in6_addr a, const in6_addr b)
expected_read(int fd, const void *buf, size_t sz)
void EXPECT_LOG(int level, const std::string &msg)
A platform-independent socket API.
Definition: XmlRpcSocket.h:23
int connect_calls
void * accept_addr
int test_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
void EXPECT_SOCKADDR_EQ(const sockaddr *addr1, const sockaddr *addr2)
int socket_errno
int test_fcntl(int fd, int cmd, unsigned long arg)
int fcntl_cmd
std::string last_msg
int test_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
int freeaddrinfo_calls
int socket_protocol
int connect_sockfd
int main(int argc, char **argv)
#define TEST_READ(RES, ERR)
int getsockname_ret
int bind_calls
int test_close(int fd)
int close_ret
void test_freeaddrinfo(struct addrinfo *res)
XMLRPCPP_DECL void setVerbosity(int level)
Sets log message verbosity. This is short for XmlRpcLogHandler::setVerbosity(level) ...
Definition: XmlRpcUtil.cpp:76
unsigned long fcntl_arg
An interface allowing custom handling of informational message reporting.
Definition: XmlRpcUtil.h:47
int bind_family
TEST_F(XmlRpcSocketTest, TestMocks)
Definition: test_socket.cpp:80
#define TEST_WRITE(RES, ERR)
std::deque< int > close_calls
Definition: mock_socket.cpp:60
int getsockname_errno
int bind_ret
int getsockname_sockfd
std::deque< expected_write > expected_writes
int setsockopt_errno
int getaddrinfo_errno
std::string data
const struct sockaddr * connect_addr
std::deque< expected_read > expected_reads
socklen_t accept_addrlen
int accept_calls
int listen_errno
int bind_port
int fcntl_calls
int test_socket(int domain, int type, int protocol)
int socket_domain
static void setErrorHandler(XmlRpcErrorHandler *eh)
Specifies the error handler.
Definition: XmlRpcUtil.h:36
ssize_t mock_read(int fd, void *buf, size_t count)
const char * getaddrinfo_service
void EXPECT_ERROR(const std::string &msg)
ssize_t mock_write(int fd, const void *buf, size_t count)
socklen_t getsockname_len
int fcntl_ret
std::string last_error
socklen_t connect_addrlen
virtual void log(int level, const char *msg)
Output a message. Custom error handlers should define this method.
struct addrinfo getaddrinfo_hints
int listen_calls
int test_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
int fcntl_errno
struct addrinfo * freeaddrinfo_res
int accept_sockfd
int socket_type
int listen_sockfd
expected_write(int fd, std::string data, size_t count, size_t max_write)
int fcntl_fd
int bind_sockfd
int connect_errno
void count_freeaddrinfo(struct addrinfo *res)
const char * getaddrinfo_node
int setsockopt_sockfd
void(* fake_freeaddrinfo)(struct addrinfo *res)=0
int test_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
virtual void error(const char *msg)
Report an error. Custom error handlers should define this method.
An interface allowing custom handling of error message reporting.
Definition: XmlRpcUtil.h:27


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix
autogenerated on Mon Jun 1 2020 03:22:44