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);
727 EXPECT_TRUE(NULL != addrlen);
728 if (NULL != addrlen) {
739 struct sockaddr_in inet_addr;
740 inet_addr.sin_family = AF_INET;
741 inet_addr.sin_port = htons(123);
743 struct sockaddr_in6 inet6_addr;
744 inet6_addr.sin6_family = AF_INET6;
745 inet6_addr.sin6_port = htons(4224);
752 getsockname_calls = 0;
755 EXPECT_EQ(123, XmlRpcSocket::get_port(14));
756 EXPECT_EQ(0, XmlRpcSocket::getError());
757 EXPECT_EQ(1, getsockname_calls);
759 getsockname_calls = 0;
762 EXPECT_EQ(4224, XmlRpcSocket::get_port(14));
763 EXPECT_EQ(0, XmlRpcSocket::getError());
764 EXPECT_EQ(1, getsockname_calls);
767 FOR_ERRNO(i, errnos, EBADF, EFAULT, EINVAL, ENOBUFS, ENOTSOCK) {
771 getsockname_calls = 0;
774 EXPECT_EQ(0, XmlRpcSocket::get_port(14));
775 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
776 EXPECT_EQ(1, getsockname_calls);
779 getsockname_calls = 0;
782 EXPECT_EQ(0, XmlRpcSocket::get_port(14));
783 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
784 EXPECT_EQ(1, getsockname_calls);
808 EXPECT_TRUE(XmlRpcSocket::listen(13, 10));
809 EXPECT_EQ(0, XmlRpcSocket::getError());
811 FOR_ERRNO(i, errnos, EADDRINUSE, EBADF, ENOTSOCK, EOPNOTSUPP) {
814 EXPECT_FALSE(XmlRpcSocket::listen(13, 10));
815 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
824 int test_accept(
int sockfd,
struct sockaddr* addr, socklen_t* addrlen) {
829 EXPECT_TRUE(NULL != addr);
830 EXPECT_TRUE(NULL != addrlen);
831 if (NULL != addr && NULL != addrlen) {
837 EXPECT_EQ(NULL, addr);
838 EXPECT_EQ(NULL, addrlen);
849 struct sockaddr_in addr;
850 addr.sin_family = AF_INET;
851 addr.sin_port = htons(45);
852 addr.sin_addr.s_addr = 0xDEADBEEF;
862 EXPECT_EQ(16, XmlRpcSocket::accept(15));
863 EXPECT_EQ(0, XmlRpcSocket::getError());
886 EXPECT_EQ(-1, XmlRpcSocket::accept(15));
887 EXPECT_EQ(errnos[i], XmlRpcSocket::getError());
911 const struct addrinfo* hints,
912 struct addrinfo** res) {
918 EXPECT_TRUE(NULL != hints);
924 EXPECT_TRUE(NULL != res);
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) {
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);
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);
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;
970 ADD_FAILURE() <<
"Unrecognized address type; cannot compare";
981 int test_connect(
int sockfd,
const struct sockaddr* addr, socklen_t addrlen) {
986 EXPECT_TRUE(NULL != addr);
998 virtual void log(
int level,
const char* msg) {
1001 std::cout <<
"LOG(" << level <<
"):" << msg;
1006 std::cout <<
"ERROR: " << msg;
1014 EXPECT_EQ(level, last_level);
1015 EXPECT_EQ(msg, last_msg);
1019 EXPECT_EQ(msg, last_error);
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);
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);
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;
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;
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;
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;
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;
1103 getaddrinfo_calls = 0;
1106 EXPECT_TRUE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1107 EXPECT_EQ(1, getaddrinfo_calls);
1122 getaddrinfo_calls = 0;
1125 EXPECT_FALSE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1126 EXPECT_EQ(1, getaddrinfo_calls);
1141 getaddrinfo_calls = 0;
1144 EXPECT_FALSE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1145 EXPECT_EQ(1, getaddrinfo_calls);
1151 XmlRpcLogHandler::setLogHandler(NULL);
1152 XmlRpcErrorHandler::setErrorHandler(NULL);
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;
1179 info_canon.ai_next = &info_ip4;
1180 info_ip4.ai_next = &info_ip6;
1181 info_ip6.ai_next = 0;
1186 info_canon.ai_next = &info_ip6;
1187 info_ip6.ai_next = &info_ip4;
1188 info_ip4.ai_next = 0;
1193 info_ip6.ai_next = &info_ip4;
1194 info_ip4.ai_next = 0;
1199 info_ip4.ai_next = &info_ip6;
1200 info_ip6.ai_next = 0;
1206 XmlRpcSocket::s_use_ipv6_ =
true;
1220 info_ip4.ai_next = &info_ip6;
1221 info_ip6.ai_next = 0;
1226 info_ip6.ai_next = &info_ip4;
1227 info_ip4.ai_next = 0;
1243 info_ip4.ai_next = &info_ip6;
1244 info_ip6.ai_next = 0;
1266 std::string(
"Couldn't find an AF_INET address for [nowhere.com]: ") +
1267 std::string(gai_strerror(addr_errs[i])) + std::string(
"\n"));
1274 FOR_ERRNO(i, errnos, ENFILE, EMFILE, EAGAIN, EINTR) {
1278 std::string(
"Couldn't find an AF_INET address for [nowhere.com]: ") +
1279 std::string(strerror(errnos[i])) + std::string(
"\n"));
1284 info_ip6.ai_next = 0;
1301 getaddrinfo_calls = 0;
1304 EXPECT_FALSE(XmlRpcSocket::connect(19,
"nowhere.com", 404));
1305 EXPECT_EQ(1, getaddrinfo_calls);
1309 std::string(
"Couldn't find an AF_INET address for [nowhere.com]") +
1334 info_ip4.ai_next = &info_ip6;
1335 info_ip6.ai_next = 0;
1351 EXPECT_EQ(EWOULDBLOCK, EAGAIN);
1354 #if defined(_WINDOWS) 1359 EXPECT_ERROR(std::string(
"::connect error = ") +
1360 std::string(strerror(EWOULDBLOCK)) + std::string(
"\n"));
1383 EXPECT_ERROR(std::string(
"::connect error = ") +
1384 std::string(strerror(errnos[i])) + std::string(
"\n"));
1390 ::testing::InitGoogleTest(&argc, argv);
1391 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)
XMLRPCPP_DECL 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.