28 #include <arpa/inet.h> 34 #include <sys/socket.h> 35 #include <sys/types.h> 40 #include <gtest/gtest.h> 42 #define FOR_ERRNO(itr, var, ...) \ 43 int var[] = {__VA_ARGS__}; \ 44 for (size_t itr = 0; itr < sizeof(var) / sizeof(int); itr++) 63 XmlRpcSocket::s_use_ipv6_ =
false;
81 EXPECT_EQ(0, fake_accept);
83 fake_accept = count_accept;
84 EXPECT_EQ(0, accept(0, 0, 0));
87 EXPECT_EQ(0, fake_bind);
89 fake_bind = count_bind;
90 EXPECT_EQ(0, bind(0, 0, 0));
93 EXPECT_EQ(0, fake_close);
95 fake_close = count_close;
96 EXPECT_EQ(0, close(-1));
99 EXPECT_EQ(0, fake_connect);
101 fake_connect = count_connect;
102 EXPECT_EQ(0, connect(0, 0, 0));
108 EXPECT_EQ(0, fcntl(0, 0, 0));
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);
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);
129 EXPECT_EQ(0, fake_listen);
131 fake_listen = count_listen;
132 EXPECT_EQ(0, listen(0, 0));
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);
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);
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);
153 EXPECT_EQ(0, fake_socket);
155 fake_socket = count_socket;
156 EXPECT_EQ(0, socket(0, 0, 0));
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);
190 EXPECT_EQ(7, XmlRpcSocket::socket());
191 EXPECT_EQ(0, XmlRpcSocket::getError());
212 EXPECT_EQ(-1, XmlRpcSocket::socket());
213 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
240 XmlRpcSocket::close(8);
241 EXPECT_EQ(0, XmlRpcSocket::getError());
245 FOR_ERRNO(i, errnos, EBADF, EINTR, EIO) {
249 XmlRpcSocket::close(8);
250 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
280 EXPECT_TRUE(XmlRpcSocket::setNonBlocking(9));
281 EXPECT_EQ(0, XmlRpcSocket::getError());
286 FOR_ERRNO(i, errnos, EACCES, EAGAIN, EBADF) {
290 EXPECT_FALSE(XmlRpcSocket::setNonBlocking(9));
291 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
298 : fd(fd), count(4095), buf(buf), sz(sz), ret(sz), _errno(0) {}
301 : fd(fd), count(4095), buf(0), sz(0), ret(-1), _errno(_errno) {}
330 EXPECT_EQ(r.
count, count);
334 EXPECT_GT(static_cast<size_t>(SSIZE_MAX), count);
337 EXPECT_LE(r.
sz, count);
338 size_t cnt = std::min(count, r.
sz);
342 memcpy(buf, r.
buf, cnt);
347 EXPECT_EQ(cnt, static_cast<size_t>(r.
ret));
358 const char data[] =
"read1 read2 read3 read4 read5 read6 read7 read8";
360 std::string data_out;
367 EXPECT_TRUE(XmlRpcSocket::nbRead(7, data_out, &eof));
368 EXPECT_EQ(
"read1 rea", data_out);
370 EXPECT_EQ(2, read_calls);
371 EXPECT_EQ(0, XmlRpcSocket::getError());
376 #define TEST_READ(RES, ERR) \ 377 TEST_F(XmlRpcSocketTest, nbRead_##ERR) { \ 378 fake_read = mock_read; \ 380 std::string data_out; \ 382 expected_reads.push_back(expected_read(7, ERR)); \ 384 EXPECT_##RES(XmlRpcSocket::nbRead(7, data_out, &eof)); \ 385 EXPECT_EQ("", data_out); \ 387 EXPECT_EQ(1, read_calls); \ 388 EXPECT_EQ(ERR, XmlRpcSocket::getError()); \ 389 EXPECT_EQ(0u, expected_reads.size()); \ 390 expected_reads.clear(); \ 405 std::string data_out;
411 EXPECT_TRUE(XmlRpcSocket::nbRead(7, data_out, &eof));
412 EXPECT_EQ(
"", data_out);
416 EXPECT_EQ(1, read_calls);
417 EXPECT_EQ(EINTR, XmlRpcSocket::getError());
458 max_write(max_write),
459 ret(
std::min(count, max_write)),
463 : fd(fd), data(
""), count(count), max_write(0), ret(ret), _errno(_errno) {}
492 EXPECT_EQ(w.
count, count);
493 size_t sz = std::min(w.
max_write, count);
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);
508 std::string hello =
"hello world";
515 EXPECT_TRUE(XmlRpcSocket::nbWrite(10, hello, &count));
516 EXPECT_EQ(count, 11);
517 EXPECT_EQ(0, XmlRpcSocket::getError());
519 EXPECT_EQ(1, write_calls);
527 EXPECT_TRUE(XmlRpcSocket::nbWrite(10, hello, &count));
528 EXPECT_EQ(count, 11);
529 EXPECT_EQ(0, XmlRpcSocket::getError());
531 EXPECT_EQ(2, write_calls);
539 EXPECT_TRUE(XmlRpcSocket::nbWrite(10, hello, &count));
541 EXPECT_EQ(EWOULDBLOCK, XmlRpcSocket::getError());
543 EXPECT_EQ(2, write_calls);
546 #define TEST_WRITE(RES, ERR) \ 547 TEST_F(XmlRpcSocketTest, nbWrite_##ERR) { \ 548 fake_write = mock_write; \ 550 std::string hello = "hello world"; \ 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(); \ 584 int sockfd,
int level,
int optname,
const void* optval, socklen_t optlen) {
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);
605 setsockopt_calls = 0;
609 EXPECT_TRUE(XmlRpcSocket::setReuseAddr(11));
610 EXPECT_EQ(0, XmlRpcSocket::getError());
612 EXPECT_EQ(1, setsockopt_calls);
614 FOR_ERRNO(i, errnos, EBADF, EFAULT, EINVAL, ENOPROTOOPT, ENOTSOCK) {
617 setsockopt_calls = 0;
621 EXPECT_FALSE(XmlRpcSocket::setReuseAddr(11));
622 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
624 EXPECT_EQ(1, setsockopt_calls);
630 return IN6_ARE_ADDR_EQUAL(&a, &b);
638 int test_bind(
int sockfd,
const struct sockaddr* addr, socklen_t addrlen) {
642 EXPECT_TRUE(NULL != addr);
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));
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));
657 ADD_FAILURE() <<
"Unrecognized sockaddr family";
676 EXPECT_TRUE(XmlRpcSocket::bind(12, 22));
678 EXPECT_EQ(0, XmlRpcSocket::getError());
682 FOR_ERRNO(i, errnos, EACCES, EADDRINUSE, EBADF, EINVAL, ENOTSOCK) {
690 EXPECT_FALSE(XmlRpcSocket::bind(12, 22));
692 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
696 XmlRpcSocket::s_use_ipv6_ =
true;
705 EXPECT_TRUE(XmlRpcSocket::bind(12, 22));
707 EXPECT_EQ(0, XmlRpcSocket::getError());
720 EXPECT_TRUE(NULL != addr);
726 EXPECT_TRUE(NULL != addrlen);
727 if (NULL != addrlen) {
738 struct sockaddr_in inet_addr;
739 inet_addr.sin_family = AF_INET;
740 inet_addr.sin_port = htons(123);
742 struct sockaddr_in6 inet6_addr;
743 inet6_addr.sin6_family = AF_INET6;
744 inet6_addr.sin6_port = htons(4224);
751 getsockname_calls = 0;
754 EXPECT_EQ(123, XmlRpcSocket::get_port(14));
755 EXPECT_EQ(0, XmlRpcSocket::getError());
756 EXPECT_EQ(1, getsockname_calls);
758 getsockname_calls = 0;
761 EXPECT_EQ(4224, XmlRpcSocket::get_port(14));
762 EXPECT_EQ(0, XmlRpcSocket::getError());
763 EXPECT_EQ(1, getsockname_calls);
766 FOR_ERRNO(i, errnos, EBADF, EFAULT, EINVAL, ENOBUFS, ENOTSOCK) {
770 getsockname_calls = 0;
773 EXPECT_EQ(0, XmlRpcSocket::get_port(14));
774 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
775 EXPECT_EQ(1, getsockname_calls);
778 getsockname_calls = 0;
781 EXPECT_EQ(0, XmlRpcSocket::get_port(14));
782 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
783 EXPECT_EQ(1, getsockname_calls);
807 EXPECT_TRUE(XmlRpcSocket::listen(13, 10));
808 EXPECT_EQ(0, XmlRpcSocket::getError());
810 FOR_ERRNO(i, errnos, EADDRINUSE, EBADF, ENOTSOCK, EOPNOTSUPP) {
813 EXPECT_FALSE(XmlRpcSocket::listen(13, 10));
814 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
823 int test_accept(
int sockfd,
struct sockaddr* addr, socklen_t* addrlen) {
828 EXPECT_TRUE(NULL != addr);
829 EXPECT_TRUE(NULL != addrlen);
830 if (NULL != addr && NULL != addrlen) {
836 EXPECT_EQ(NULL, addr);
837 EXPECT_EQ(NULL, addrlen);
848 struct sockaddr_in addr;
849 addr.sin_family = AF_INET;
850 addr.sin_port = htons(45);
851 addr.sin_addr.s_addr = 0xDEADBEEF;
861 EXPECT_EQ(16, XmlRpcSocket::accept(15));
862 EXPECT_EQ(0, XmlRpcSocket::getError());
885 EXPECT_EQ(-1, XmlRpcSocket::accept(15));
886 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
910 const struct addrinfo* hints,
911 struct addrinfo** res) {
917 EXPECT_TRUE(NULL != hints);
923 EXPECT_TRUE(NULL != res);
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) {
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);
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);
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;
969 ADD_FAILURE() <<
"Unrecognized address type; cannot compare";
980 int test_connect(
int sockfd,
const struct sockaddr* addr, socklen_t addrlen) {
985 EXPECT_TRUE(NULL != addr);
997 virtual void log(
int level,
const char* msg) {
1000 std::cout <<
"LOG(" << level <<
"):" << msg;
1005 std::cout <<
"ERROR: " << msg;
1013 EXPECT_EQ(level, last_level);
1014 EXPECT_EQ(msg, last_msg);
1018 EXPECT_EQ(msg, last_error);
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);
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);
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;
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;
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;
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;
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;
1102 getaddrinfo_calls = 0;
1105 EXPECT_TRUE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1106 EXPECT_EQ(1, getaddrinfo_calls);
1121 getaddrinfo_calls = 0;
1124 EXPECT_FALSE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1125 EXPECT_EQ(1, getaddrinfo_calls);
1140 getaddrinfo_calls = 0;
1143 EXPECT_FALSE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1144 EXPECT_EQ(1, getaddrinfo_calls);
1150 XmlRpcLogHandler::setLogHandler(NULL);
1151 XmlRpcErrorHandler::setErrorHandler(NULL);
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;
1178 info_canon.ai_next = &info_ip4;
1179 info_ip4.ai_next = &info_ip6;
1180 info_ip6.ai_next = 0;
1185 info_canon.ai_next = &info_ip6;
1186 info_ip6.ai_next = &info_ip4;
1187 info_ip4.ai_next = 0;
1192 info_ip6.ai_next = &info_ip4;
1193 info_ip4.ai_next = 0;
1198 info_ip4.ai_next = &info_ip6;
1199 info_ip6.ai_next = 0;
1205 XmlRpcSocket::s_use_ipv6_ =
true;
1219 info_ip4.ai_next = &info_ip6;
1220 info_ip6.ai_next = 0;
1225 info_ip6.ai_next = &info_ip4;
1226 info_ip4.ai_next = 0;
1242 info_ip4.ai_next = &info_ip6;
1243 info_ip6.ai_next = 0;
1265 std::string(
"Couldn't find an AF_INET address for [nowhere.com]: ") +
1266 std::string(gai_strerror(addr_errs[i])) + std::string(
"\n"));
1273 FOR_ERRNO(i, errnos, ENFILE, EMFILE, EAGAIN, EINTR) {
1277 std::string(
"Couldn't find an AF_INET address for [nowhere.com]: ") +
1278 std::string(strerror(errnos[i])) + std::string(
"\n"));
1283 info_ip6.ai_next = 0;
1300 getaddrinfo_calls = 0;
1303 EXPECT_FALSE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1304 EXPECT_EQ(1, getaddrinfo_calls);
1308 std::string(
"Couldn't find an AF_INET address for [nowhere.com]") +
1333 info_ip4.ai_next = &info_ip6;
1334 info_ip6.ai_next = 0;
1350 EXPECT_EQ(EWOULDBLOCK, EAGAIN);
1353 #if defined(_WINDOWS) 1358 EXPECT_ERROR(std::string(
"::connect error = ") +
1359 std::string(strerror(EWOULDBLOCK)) + std::string(
"\n"));
1382 EXPECT_ERROR(std::string(
"::connect error = ") +
1383 std::string(strerror(errnos[i])) + std::string(
"\n"));
1389 ::testing::InitGoogleTest(&argc, argv);
1390 return RUN_ALL_TESTS();
#define FOR_ERRNO(itr, var,...)
int test_listen(int sockfd, int backlog)
expected_read(int fd, int _errno)
static void setLogHandler(XmlRpcLogHandler *lh)
Specifies the message handler.
int(* fake_fcntl)(int fd, int cmd, unsigned long)=0
struct addrinfo * getaddrinfo_res
int count_fcntl(int fd, int cmd, unsigned long arg)
expected_write(int fd, size_t count, ssize_t ret, int _errno)
int test_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
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.
int test_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
void EXPECT_SOCKADDR_EQ(const sockaddr *addr1, const sockaddr *addr2)
int test_fcntl(int fd, int cmd, unsigned long arg)
int test_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
int main(int argc, char **argv)
#define TEST_READ(RES, ERR)
void test_freeaddrinfo(struct addrinfo *res)
void setVerbosity(int level)
Sets log message verbosity. This is short for XmlRpcLogHandler::setVerbosity(level) ...
An interface allowing custom handling of informational message reporting.
TEST_F(XmlRpcSocketTest, TestMocks)
#define TEST_WRITE(RES, ERR)
std::deque< int > close_calls
std::deque< expected_write > expected_writes
const struct sockaddr * connect_addr
std::deque< expected_read > expected_reads
int test_socket(int domain, int type, int protocol)
static void setErrorHandler(XmlRpcErrorHandler *eh)
Specifies the error handler.
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
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 test_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
struct addrinfo * freeaddrinfo_res
expected_write(int fd, std::string data, size_t count, size_t max_write)
void count_freeaddrinfo(struct addrinfo *res)
const char * getaddrinfo_node
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.