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  memcpy(addr, getsockname_addr, len);
725  }
726  EXPECT_TRUE(NULL != addrlen);
727  if (NULL != addrlen) {
728  *addrlen = getsockname_len;
729  }
730 
731  errno = getsockname_errno;
732  return getsockname_ret;
733 }
734 
736  fake_getsockname = test_getsockname;
737 
738  struct sockaddr_in inet_addr;
739  inet_addr.sin_family = AF_INET;
740  inet_addr.sin_port = htons(123);
741 
742  struct sockaddr_in6 inet6_addr;
743  inet6_addr.sin6_family = AF_INET6;
744  inet6_addr.sin6_port = htons(4224);
745 
746  getsockname_sockfd = 14;
747 
748  getsockname_errno = 0;
749  getsockname_ret = 0;
750 
751  getsockname_calls = 0;
752  getsockname_addr = &inet_addr;
753  getsockname_len = sizeof(struct sockaddr_in);
754  EXPECT_EQ(123, XmlRpcSocket::get_port(14));
755  EXPECT_EQ(0, XmlRpcSocket::getError());
756  EXPECT_EQ(1, getsockname_calls);
757 
758  getsockname_calls = 0;
759  getsockname_addr = &inet6_addr;
760  getsockname_len = sizeof(struct sockaddr_in6);
761  EXPECT_EQ(4224, XmlRpcSocket::get_port(14));
762  EXPECT_EQ(0, XmlRpcSocket::getError());
763  EXPECT_EQ(1, getsockname_calls);
764 
765  getsockname_ret = -1;
766  FOR_ERRNO(i, errnos, EBADF, EFAULT, EINVAL, ENOBUFS, ENOTSOCK) {
767  getsockname_errno = errnos[i];
768 
769  // Errors, no data written to buffer.
770  getsockname_calls = 0;
771  getsockname_addr = NULL;
772  getsockname_len = 0;
773  EXPECT_EQ(0, XmlRpcSocket::get_port(14));
774  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
775  EXPECT_EQ(1, getsockname_calls);
776 
777  // Same errors, but this time put valid data and expect that it is ignored.
778  getsockname_calls = 0;
779  getsockname_addr = &inet_addr;
780  getsockname_len = sizeof(struct sockaddr_in);
781  EXPECT_EQ(0, XmlRpcSocket::get_port(14));
782  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
783  EXPECT_EQ(1, getsockname_calls);
784  }
785 }
786 
787 int listen_ret = 0;
788 int listen_errno = 0;
791 int test_listen(int sockfd, int backlog) {
792  EXPECT_EQ(listen_sockfd, sockfd);
793  EXPECT_EQ(listen_backlog, backlog);
794 
795  errno = listen_errno;
796  return listen_ret;
797 }
798 
800  fake_listen = test_listen;
801 
802  listen_sockfd = 13;
803  listen_backlog = 10;
804 
805  listen_ret = 0;
806  listen_errno = 0;
807  EXPECT_TRUE(XmlRpcSocket::listen(13, 10));
808  EXPECT_EQ(0, XmlRpcSocket::getError());
809 
810  FOR_ERRNO(i, errnos, EADDRINUSE, EBADF, ENOTSOCK, EOPNOTSUPP) {
811  listen_ret = -1;
812  listen_errno = errnos[i];
813  EXPECT_FALSE(XmlRpcSocket::listen(13, 10));
814  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
815  }
816 }
817 
818 int accept_ret = 0;
819 int accept_errno = 0;
821 void* accept_addr = 0;
822 socklen_t accept_addrlen = 0;
823 int test_accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen) {
824  accept_calls++;
825  EXPECT_EQ(accept_sockfd, sockfd);
826 
827  if (accept_addr) {
828  EXPECT_TRUE(NULL != addr);
829  EXPECT_TRUE(NULL != addrlen);
830  if (NULL != addr && NULL != addrlen) {
831  socklen_t len = std::min(accept_addrlen, *addrlen);
832  memcpy(addr, accept_addr, len);
833  *addrlen = accept_addrlen;
834  }
835  } else {
836  EXPECT_EQ(NULL, addr);
837  EXPECT_EQ(NULL, addrlen);
838  }
839 
840  errno = accept_errno;
841  return accept_ret;
842 }
843 
845  fake_accept = test_accept;
846 
847  // Set up address. XmlRpcSocket::accept expects this, even if it isn't used.
848  struct sockaddr_in addr;
849  addr.sin_family = AF_INET;
850  addr.sin_port = htons(45);
851  addr.sin_addr.s_addr = 0xDEADBEEF;
852 
853  accept_addr = &addr;
854  accept_addrlen = sizeof(struct sockaddr);
855 
856  accept_sockfd = 15;
857 
858  accept_calls = 0;
859  accept_ret = 16;
860  accept_errno = 0;
861  EXPECT_EQ(16, XmlRpcSocket::accept(15));
862  EXPECT_EQ(0, XmlRpcSocket::getError());
863  EXPECT_EQ(1, accept_calls);
864 
865  FOR_ERRNO(i,
866  errnos,
867  EAGAIN,
868  EWOULDBLOCK,
869  EBADF,
870  ECONNABORTED,
871  EFAULT,
872  EINTR, // TODO(austin): Should this retry immediately?
873  EINVAL,
874  EMFILE,
875  ENFILE,
876  ENOBUFS,
877  ENOMEM,
878  ENOTSOCK,
879  EOPNOTSUPP,
880  EPROTO,
881  EPERM) {
882  accept_calls = 0;
883  accept_ret = -1;
884  accept_errno = errnos[i];
885  EXPECT_EQ(-1, XmlRpcSocket::accept(15));
886  EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
887  EXPECT_EQ(1, accept_calls);
888  }
889 }
890 
891 // To test connect() we need mocks for getaddrinfo(), freeaddrinfo(), connect()
892 // and XmlRpc logging hooks to validate that the correct error messages are
893 // logged.
894 
897 const char* getaddrinfo_node = 0;
898 const char* getaddrinfo_service = 0;
899 struct addrinfo getaddrinfo_hints = {.ai_flags = 0,
900  .ai_family = 0,
901  .ai_socktype = 0,
902  .ai_protocol = 0,
903  .ai_addrlen = 0,
904  .ai_addr = 0,
905  .ai_canonname = 0,
906  .ai_next = 0};
907 struct addrinfo* getaddrinfo_res = 0;
908 int test_getaddrinfo(const char* node,
909  const char* service,
910  const struct addrinfo* hints,
911  struct addrinfo** res) {
912  getaddrinfo_calls++;
913 
914  EXPECT_STREQ(getaddrinfo_node, node);
915  EXPECT_STREQ(getaddrinfo_service, service);
916 
917  EXPECT_TRUE(NULL != hints);
918  if (NULL != hints) {
919  EXPECT_TRUE(memcmp(hints, &getaddrinfo_hints, sizeof(struct addrinfo)) ==
920  0);
921  }
922 
923  EXPECT_TRUE(NULL != res);
924  if (NULL != res) {
925  *res = getaddrinfo_res;
926  }
927 
928  errno = getaddrinfo_errno;
929  return getaddrinfo_ret;
930 }
931 
932 struct addrinfo* freeaddrinfo_res = 0;
933 void test_freeaddrinfo(struct addrinfo* res) {
934  // The man page does not indicate any errors that freeaddrinfo may encounter.
936 
937  EXPECT_EQ(freeaddrinfo_res, res);
938 
939  return;
940 }
941 
942 void EXPECT_SOCKADDR_EQ(const sockaddr* addr1, const sockaddr* addr2) {
943  EXPECT_EQ((NULL == addr1), (NULL == addr2));
944  if (NULL != addr1 && NULL != addr2) {
945  EXPECT_EQ(addr1->sa_family, addr2->sa_family);
946  if (addr1->sa_family == addr2->sa_family) {
947  switch (addr1->sa_family) {
948  case AF_INET: {
949  const sockaddr_in* addr1_in = (const sockaddr_in*)addr1;
950  const sockaddr_in* addr2_in = (const sockaddr_in*)addr2;
951  EXPECT_EQ(addr1_in->sin_port, addr2_in->sin_port);
952  EXPECT_EQ(addr1_in->sin_addr.s_addr, addr2_in->sin_addr.s_addr);
953  } break;
954  case AF_INET6: {
955  const sockaddr_in6* addr1_in6 = (const sockaddr_in6*)addr1;
956  const sockaddr_in6* addr2_in6 = (const sockaddr_in6*)addr2;
957  EXPECT_EQ(addr1_in6->sin6_port, addr2_in6->sin6_port);
958  EXPECT_EQ(addr1_in6->sin6_flowinfo, addr2_in6->sin6_flowinfo);
959  EXPECT_EQ(addr1_in6->sin6_scope_id, addr2_in6->sin6_scope_id);
960  EXPECT_TRUE(
961  IN6_ARE_ADDR_EQUAL(&addr1_in6->sin6_addr, &addr2_in6->sin6_addr));
962  for (int i = 0; i < 16; i++) {
963  EXPECT_EQ(addr1_in6->sin6_addr.s6_addr[i],
964  addr2_in6->sin6_addr.s6_addr[i])
965  << "IPv6 address mismstach at byte " << i;
966  }
967  } break;
968  default:
969  ADD_FAILURE() << "Unrecognized address type; cannot compare";
970  }
971  }
972  }
973 }
974 
975 int connect_ret = 0;
978 const struct sockaddr* connect_addr = 0;
979 socklen_t connect_addrlen = 0;
980 int test_connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen) {
981  connect_calls++;
982 
983  EXPECT_EQ(connect_sockfd, sockfd);
984 
985  EXPECT_TRUE(NULL != addr);
986  EXPECT_EQ(connect_addrlen, addrlen);
988 
989  errno = connect_errno;
990  return connect_ret;
991 }
992 
996 public:
997  virtual void log(int level, const char* msg) {
998  last_level = level;
999  last_msg = msg;
1000  std::cout << "LOG(" << level << "):" << msg;
1001  }
1002 
1003  virtual void error(const char* msg) {
1004  last_error = msg;
1005  std::cout << "ERROR: " << msg;
1006  }
1007 
1009  std::string last_msg;
1010  std::string last_error;
1011 
1012  void EXPECT_LOG(int level, const std::string& msg) {
1013  EXPECT_EQ(level, last_level);
1014  EXPECT_EQ(msg, last_msg);
1015  }
1016 
1017  void EXPECT_ERROR(const std::string& msg) {
1018  EXPECT_EQ(msg, last_error);
1019  }
1020 
1021 protected:
1022  void SetUp() {
1024 
1025  // Install mock functions.
1026  fake_getaddrinfo = test_getaddrinfo;
1028  fake_connect = test_connect;
1029 
1032 
1033  // Set up address data structures for testing use.
1034  addr_ip4_22.sin_family = AF_INET;
1035  addr_ip4_22.sin_port = htons(22);
1036  addr_ip4_22.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1037 
1038  addr_ip4_404.sin_family = AF_INET;
1039  addr_ip4_404.sin_port = htons(404);
1040  addr_ip4_404.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1041 
1042  addr_ip6_44.sin6_family = AF_INET6;
1043  addr_ip6_44.sin6_port = htons(44);
1044  addr_ip6_44.sin6_flowinfo = 0;
1045  addr_ip6_44.sin6_addr = in6addr_loopback;
1046  addr_ip6_44.sin6_scope_id = 0;
1047 
1048  addr_ip6_404.sin6_family = AF_INET6;
1049  addr_ip6_404.sin6_port = htons(404);
1050  addr_ip6_404.sin6_flowinfo = 0;
1051  addr_ip6_404.sin6_addr = in6addr_loopback;
1052  addr_ip6_404.sin6_scope_id = 0;
1053 
1054  info_ip4.ai_flags = 0;
1055  info_ip4.ai_family = AF_INET;
1056  info_ip4.ai_socktype = SOCK_STREAM;
1057  info_ip4.ai_protocol = 0;
1058  info_ip4.ai_addrlen = sizeof(struct sockaddr_in);
1059  info_ip4.ai_addr = (struct sockaddr*)&addr_ip4_22;
1060  info_ip4.ai_canonname = 0;
1061  info_ip4.ai_next = 0;
1062 
1063  info_ip6.ai_flags = 0;
1064  info_ip6.ai_family = AF_INET6;
1065  info_ip6.ai_socktype = SOCK_STREAM;
1066  info_ip6.ai_protocol = 0;
1067  info_ip6.ai_addrlen = sizeof(struct sockaddr_in6);
1068  info_ip6.ai_addr = (struct sockaddr*)&addr_ip6_44;
1069  info_ip6.ai_canonname = 0;
1070  info_ip6.ai_next = 0;
1071 
1072  info_canon.ai_flags = 0;
1073  info_canon.ai_family = 0;
1074  info_canon.ai_socktype = 0;
1075  info_canon.ai_protocol = 0;
1076  info_canon.ai_addrlen = 0;
1077  info_canon.ai_addr = 0;
1078  info_canon.ai_canonname = 0;
1079  info_canon.ai_next = 0;
1080 
1081  // Set up expected hints.
1082  getaddrinfo_hints.ai_family = AF_UNSPEC;
1083  // TODO(austin): hints should probably specify SOCK_STREAM
1084  // getaddrinfo_hints.ai_socktype = SOCK_STREAM;
1085 
1086  getaddrinfo_node = "nowhere.com";
1087  getaddrinfo_service = 0;
1088 
1089  connect_sockfd = 19;
1090  }
1091 
1092  void TestConnect() {
1093  // Always free the same getaddrinfo that we started with.
1095 
1096  // Clear last log message.
1097  last_level = 0;
1098  last_msg = "";
1099  last_error = "";
1100 
1101  // Actually start running tests.
1102  getaddrinfo_calls = 0;
1103  freeaddrinfo_calls = 0;
1104  connect_calls = 0;
1105  EXPECT_TRUE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1106  EXPECT_EQ(1, getaddrinfo_calls);
1107  EXPECT_EQ(1, freeaddrinfo_calls);
1108  EXPECT_EQ(1, connect_calls);
1109  }
1110 
1112  // Always free the same getaddrinfo that we started with.
1114 
1115  // Clear last log message.
1116  last_level = 0;
1117  last_msg = "";
1118  last_error = "";
1119 
1120  // Actually start running tests.
1121  getaddrinfo_calls = 0;
1122  freeaddrinfo_calls = 0;
1123  connect_calls = 0;
1124  EXPECT_FALSE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1125  EXPECT_EQ(1, getaddrinfo_calls);
1126  EXPECT_EQ(0, freeaddrinfo_calls);
1127  EXPECT_EQ(0, connect_calls);
1128  }
1129 
1131  // Always free the same getaddrinfo that we started with.
1133 
1134  // Clear last log message.
1135  last_level = 0;
1136  last_msg = "";
1137  last_error = "";
1138 
1139  // Actually start running tests.
1140  getaddrinfo_calls = 0;
1141  freeaddrinfo_calls = 0;
1142  connect_calls = 0;
1143  EXPECT_FALSE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1144  EXPECT_EQ(1, getaddrinfo_calls);
1145  EXPECT_EQ(1, freeaddrinfo_calls);
1146  EXPECT_EQ(1, connect_calls);
1147  }
1148 
1149  void TearDown() {
1150  XmlRpcLogHandler::setLogHandler(NULL);
1151  XmlRpcErrorHandler::setErrorHandler(NULL);
1152 
1154  }
1155 
1156  struct sockaddr_in addr_ip4_22;
1157  struct sockaddr_in addr_ip4_404;
1158  struct sockaddr_in6 addr_ip6_44;
1159  struct sockaddr_in6 addr_ip6_404;
1160  struct addrinfo info_ip4;
1161  struct addrinfo info_ip6;
1162  struct addrinfo info_canon;
1163 };
1164 
1165 TEST_F(XmlRpcConnectTest, connect_ipv4) {
1166  // Expected results from getaddrinfo.
1167  getaddrinfo_ret = 0;
1168  getaddrinfo_errno = 0;
1169 
1170  // Expected results from connect.
1171  connect_ret = 0;
1172  connect_errno = 0;
1173  connect_addr = (struct sockaddr*)&addr_ip4_404;
1174  connect_addrlen = sizeof(struct sockaddr_in);
1175 
1176  // Canonical address first, then IPv4, IPv6.
1177  getaddrinfo_res = &info_canon;
1178  info_canon.ai_next = &info_ip4;
1179  info_ip4.ai_next = &info_ip6;
1180  info_ip6.ai_next = 0;
1181  TestConnect();
1182 
1183  // List with IPv6 first.
1184  getaddrinfo_res = &info_canon;
1185  info_canon.ai_next = &info_ip6;
1186  info_ip6.ai_next = &info_ip4;
1187  info_ip4.ai_next = 0;
1188  TestConnect();
1189 
1190  // List without canon address, IPv6 first.
1191  getaddrinfo_res = &info_ip6;
1192  info_ip6.ai_next = &info_ip4;
1193  info_ip4.ai_next = 0;
1194  TestConnect();
1195 
1196  // List without canon address, IPv4 first.
1197  getaddrinfo_res = &info_ip4;
1198  info_ip4.ai_next = &info_ip6;
1199  info_ip6.ai_next = 0;
1200  TestConnect();
1201 }
1202 
1203 TEST_F(XmlRpcConnectTest, connect_ipv6) {
1204  // Basic IPv6 tests.
1205  XmlRpcSocket::s_use_ipv6_ = true;
1206 
1207  // Expected results from getaddrinfo.
1208  getaddrinfo_ret = 0;
1209  getaddrinfo_errno = 0;
1210 
1211  // Expected results from connect.
1212  connect_ret = 0;
1213  connect_errno = 0;
1214  connect_addr = (struct sockaddr*)&addr_ip6_404;
1215  connect_addrlen = sizeof(struct sockaddr_in6);
1216 
1217  // List without canon address, IPv4 first.
1218  getaddrinfo_res = &info_ip4;
1219  info_ip4.ai_next = &info_ip6;
1220  info_ip6.ai_next = 0;
1221  TestConnect();
1222 
1223  // List without canon address, IPv6 first.
1224  getaddrinfo_res = &info_ip6;
1225  info_ip6.ai_next = &info_ip4;
1226  info_ip4.ai_next = 0;
1227  TestConnect();
1228 }
1229 
1230 // Simulate error returns from getaddrinfo. Check that the error is logged
1231 // correctly, that connect is not called, that the result is freed(or not)
1232 // and that connect correctly returns an error.
1233 TEST_F(XmlRpcConnectTest, connect_lookup_fail) {
1234  // Expected results from connect.
1235  connect_ret = 0;
1236  connect_errno = 0;
1237  connect_addr = (struct sockaddr*)&addr_ip4_404;
1238  connect_addrlen = sizeof(struct sockaddr_in);
1239 
1240  // List without canon address, IPv4 first.
1241  getaddrinfo_res = &info_ip4;
1242  info_ip4.ai_next = &info_ip6;
1243  info_ip6.ai_next = 0;
1244 
1245  // Enumerate possible return codes from getaddrinfo and make sure that
1246  // connect() fails and that the correct error message is reported.
1247  FOR_ERRNO(i,
1248  addr_errs,
1249  EAI_ADDRFAMILY,
1250  EAI_AGAIN,
1251  EAI_BADFLAGS,
1252  EAI_FAIL,
1253  EAI_FAMILY,
1254  EAI_MEMORY,
1255  EAI_NODATA,
1256  EAI_NONAME,
1257  EAI_SERVICE,
1258  EAI_SOCKTYPE) {
1259  // Results from getaddrinfo.
1260  getaddrinfo_ret = addr_errs[i];
1261  getaddrinfo_errno = 0;
1262 
1263  TestLookupFail();
1264  EXPECT_ERROR(
1265  std::string("Couldn't find an AF_INET address for [nowhere.com]: ") +
1266  std::string(gai_strerror(addr_errs[i])) + std::string("\n"));
1267  }
1268 
1269  // Enumerate system failures from getaddrinfo and make sure that connect()
1270  // fails and that the correct error from perror is reported.
1271  // TODO(austin): getaddrinfo should retry on EINTR but it doesn't.
1272  getaddrinfo_ret = EAI_SYSTEM;
1273  FOR_ERRNO(i, errnos, ENFILE, EMFILE, EAGAIN, EINTR) {
1274  getaddrinfo_errno = errnos[i];
1275  TestLookupFail();
1276  EXPECT_ERROR(
1277  std::string("Couldn't find an AF_INET address for [nowhere.com]: ") +
1278  std::string(strerror(errnos[i])) + std::string("\n"));
1279  }
1280 
1281  // IPv4 lookup only returns IPv6 results.
1282  getaddrinfo_res = &info_ip6;
1283  info_ip6.ai_next = 0;
1284 
1285  // Results from getaddrinfo.
1286  getaddrinfo_ret = 0;
1287  getaddrinfo_errno = 0;
1288 
1289  // Always free the same getaddrinfo that we started with.
1291 
1292  // Clear last log message.
1293  last_level = 0;
1294  last_msg = "";
1295  last_error = "";
1296 
1297  // Call connect and analyze results. We do this inline here instead of
1298  // using one of the convenience functions because none of the convenience
1299  // functions fit this pattern.
1300  getaddrinfo_calls = 0;
1301  freeaddrinfo_calls = 0;
1302  connect_calls = 0;
1303  EXPECT_FALSE(XmlRpcSocket::connect(19, "nowhere.com", 404));
1304  EXPECT_EQ(1, getaddrinfo_calls);
1305  EXPECT_EQ(1, freeaddrinfo_calls);
1306  EXPECT_EQ(0, connect_calls);
1307  EXPECT_ERROR(
1308  std::string("Couldn't find an AF_INET address for [nowhere.com]") +
1309  std::string("\n"));
1310 }
1311 
1312 // TODO(austin): this probably won't work, isn't supported upstream and isn't
1313 // required by our current use case. Future work.
1314 // Simulate multiple results for a hostname lookup. Simulate failure to
1315 // connect to the first hostname and verify that another attempt is made
1316 // for the second address.
1317 TEST_F(XmlRpcConnectTest, connect_multiple_result) {}
1318 
1319 // Simulate various error results from connect().
1320 TEST_F(XmlRpcConnectTest, connect_failure) {
1321  // Expected results from getaddrinfo.
1322  getaddrinfo_ret = 0;
1323  getaddrinfo_errno = 0;
1324 
1325  // Expected results from connect.
1326  connect_ret = 0;
1327  connect_errno = 0;
1328  connect_addr = (struct sockaddr*)&addr_ip4_404;
1329  connect_addrlen = sizeof(struct sockaddr_in);
1330 
1331  // List without canon address, IPv4 first.
1332  getaddrinfo_res = &info_ip4;
1333  info_ip4.ai_next = &info_ip6;
1334  info_ip6.ai_next = 0;
1335 
1336  // EINPROGRESS indicates that the socket is non-blocking and the connection
1337  // request has started but not finished, so we expect success.
1338  connect_ret = -1;
1339  connect_errno = EINPROGRESS;
1340  TestConnect();
1341  EXPECT_ERROR("");
1342 
1343  // On Windows, EWOULDBLOCK (really WSAEWOULDBLOCK) indicates that the
1344  // socket is non-blocking and could not be completed immediately (success)
1345  // but on Linux it it synonymous with EAGAIN which indicates that there are
1346  // no more available local ports.
1347  //
1348  // NOTE(austin): if this comparison fails, create separate tests for EAGAIN
1349  // and EWOULDBLOCK.
1350  EXPECT_EQ(EWOULDBLOCK, EAGAIN);
1351  connect_ret = -1;
1352  connect_errno = EWOULDBLOCK;
1353 #if defined(_WINDOWS)
1354  TestConnect();
1355  EXPECT_ERROR("");
1356 #else
1357  TestConnectFail();
1358  EXPECT_ERROR(std::string("::connect error = ") +
1359  std::string(strerror(EWOULDBLOCK)) + std::string("\n"));
1360 #endif
1361 
1362  // All other errors that connect may return should be reported as an error.
1363  // TODO(austin): Connect should immediately retry on EINTR but it doesn't.
1364  FOR_ERRNO(i,
1365  errnos,
1366  EACCES,
1367  EPERM,
1368  EADDRINUSE,
1369  EAFNOSUPPORT,
1370  EALREADY,
1371  EBADF,
1372  ECONNREFUSED,
1373  EFAULT,
1374  EINTR,
1375  EISCONN,
1376  ENETUNREACH,
1377  ENOTSOCK,
1378  ETIMEDOUT) {
1379  connect_ret = -1;
1380  connect_errno = errnos[i];
1381  TestConnectFail();
1382  EXPECT_ERROR(std::string("::connect error = ") +
1383  std::string(strerror(errnos[i])) + std::string("\n"));
1384  }
1385 }
1386 
1387 int main(int argc, char **argv)
1388 {
1389  ::testing::InitGoogleTest(&argc, argv);
1390  return RUN_ALL_TESTS();
1391 }
int listen_ret
int socket_calls
Definition: mock_socket.cpp:76
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:58
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)
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:49
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:61
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:38
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:29


xmlrpcpp
Author(s): Chris Morley, Konstantin Pilipchuk, Morgan Quigley, Austin Hendrix
autogenerated on Sun Feb 3 2019 03:29:51