1 // Copyright Leandro Lucarella 2008 - 2010.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file COPYING or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
9 * This file should be included from others, and the next symbols are expected
12 * Preprocessor constants:
13 * - One of TEST_[socket type]
14 * - TEST_NS should be set to the namespace the socket family that will be used
15 * - TEST_PROTOCOL should be set to the socket's protocol to be tested
16 * - TEST_HAVE_PAIR should be defined if the socket family have a "pair()"
18 * - TEST_CHECK_ADDR should be defined if name() should return the same
19 * sockaddr used when bind()ing.
22 * - test_address1 and test_address2 should be valid sockaddrs.
25 * - void clean_test_address(TEST_NS::sock& socket, const TEST_NS::sockaddr&)
26 * should be a function. It will be called before binding a socket to do any
27 * cleanup task for a particular address to be used. Can be a macro.
28 * - std::ostream& operator << (std::ostream& os, const TEST_NS::sockaddr&)
35 #define TEST_PF_UNIX 1
37 #define TEST_PF_UNIX 0
41 #define TEST_PF_INET 1
43 #define TEST_PF_INET 0
47 #define TEST_PF_TIPC 1
49 #define TEST_PF_TIPC 0
72 #define TEST_SEQPACKET 1
74 #define TEST_SEQPACKET 0
84 #define TEST_TYPE ::posixx::socket::DGRAM
87 #define TEST_TYPE ::posixx::socket::RDM
90 #define TEST_TYPE ::posixx::socket::STREAM
93 #define TEST_TYPE ::posixx::socket::SEQPACKET
96 #define TEST_TYPE ::posixx::socket::RAW
100 #if TEST_PF_UNIX // unix sockets are the only that provides pairs
102 BOOST_AUTO_TEST_CASE( pair_test )
104 TEST_NS::pair_type p = TEST_NS::pair(TEST_TYPE, TEST_PROTOCOL);
105 BOOST_CHECK_GE( p.first->fd(), 0 );
106 BOOST_CHECK_GE( p.second->fd(), 0 );
111 #endif // TEST_PF_UNIX
113 BOOST_AUTO_TEST_CASE( constructor_test )
115 TEST_NS::socket s(TEST_TYPE, TEST_PROTOCOL);
116 BOOST_CHECK_GE( s.fd(), 0 );
119 BOOST_AUTO_TEST_CASE( close_test )
121 TEST_NS::socket s(TEST_TYPE, TEST_PROTOCOL);
123 BOOST_CHECK_EQUAL( s.fd(), -1 );
126 BOOST_AUTO_TEST_CASE( options_test )
128 using ::posixx::socket::opt::REUSEADDR;
129 TEST_NS::socket s(TEST_TYPE, TEST_PROTOCOL);
130 s.opt< REUSEADDR >(true);
131 BOOST_CHECK_GE( s.opt< REUSEADDR >(), true );
134 BOOST_AUTO_TEST_CASE( bind_test )
136 TEST_NS::socket s(TEST_TYPE, TEST_PROTOCOL);
137 clean_test_address(s, test_address1);
138 s.bind(test_address1);
140 #if !TEST_PF_TIPC // TIPC returns a Port ID (and we use Port names)
141 BOOST_CHECK_EQUAL( s.name(), test_address1 );
146 #if TEST_SEQPACKET || TEST_STREAM
148 // TODO: test different flavors of send/recv.
150 BOOST_AUTO_TEST_CASE( listen_test )
152 TEST_NS::socket s(TEST_TYPE, TEST_PROTOCOL);
153 clean_test_address(s, test_address1);
154 s.bind(test_address1);
159 void set_blocking(int fd, bool blocking)
161 int flags = fcntl(fd, F_GETFL, 0);
164 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
166 fcntl(fd, F_SETFL, flags | O_NONBLOCK);
169 #if !TEST_PF_TIPC // TIPC can't connect a non-blocking socket
170 BOOST_AUTO_TEST_CASE( connect_accept_test )
172 TEST_NS::socket ss(TEST_TYPE, TEST_PROTOCOL);
173 clean_test_address(ss, test_address1);
174 ss.bind(test_address1);
176 TEST_NS::socket sc(TEST_TYPE, TEST_PROTOCOL);
177 set_blocking(sc, false);
179 sc.connect(test_address1);
180 } catch (const posixx::error& e) {
181 BOOST_REQUIRE_EQUAL( e.no, EINPROGRESS );
183 set_blocking(sc, true);
184 TEST_NS::socket* sa = ss.accept();
185 BOOST_CHECK_EQUAL( sc.peer_name(), test_address1 );
186 BOOST_CHECK_EQUAL( sc.peer_name(), sa->name() );
187 #if !TEST_PF_UNIX // Unix sockets has garbage in this addresses
188 BOOST_CHECK_EQUAL( sc.name(), sa->peer_name() );
189 #endif // TEST_PF_UNIX
192 #endif // !TEST_PF_TIPC
194 #endif // TEST_SEQPACKET || TEST_STREAM
197 #if TEST_DGRAM || TEST_RDM || TEST_RAW
199 BOOST_AUTO_TEST_CASE( dgram_sendto_recvfrom_test )
202 TEST_NS::socket s1(TEST_TYPE, TEST_PROTOCOL);
203 clean_test_address(s1, test_address1);
204 s1.bind(test_address1);
206 TEST_NS::socket s2(TEST_TYPE, TEST_PROTOCOL);
207 clean_test_address(s2, test_address2);
208 s2.bind(test_address2);
210 char buffer[] = "hello world!";
211 BOOST_CHECK_EQUAL( s1.send(buffer, sizeof(buffer), test_address2),
213 memset(buffer, 0, sizeof(buffer));
215 TEST_NS::sockaddr addr;
216 BOOST_CHECK_EQUAL( s2.recv(buffer, sizeof(buffer), addr),
218 BOOST_CHECK_EQUAL( buffer, "hello world!" );
219 #if !TEST_PF_TIPC // TIPC returns a Port ID (and we use Port names)
220 BOOST_CHECK_EQUAL( addr, test_address1 );
230 BOOST_AUTO_TEST_CASE( dgram_sendto_recvfrom_struct_test )
233 TEST_NS::socket s1(TEST_TYPE, TEST_PROTOCOL);
234 clean_test_address(s1, test_address1);
235 s1.bind(test_address1);
237 TEST_NS::socket s2(TEST_TYPE, TEST_PROTOCOL);
238 clean_test_address(s2, test_address2);
239 s2.bind(test_address2);
242 memset(&d, 0, sizeof(data));
243 strcpy(d.msg, "hello world!");
244 d.number = -32495813;
245 s1.send_struct(d, test_address2);
246 memset(&d, 0, sizeof(data));
248 TEST_NS::sockaddr addr;
249 s2.recv_struct(d, addr);
250 BOOST_CHECK_EQUAL( d.msg, "hello world!" );
251 BOOST_CHECK_EQUAL( d.number, -32495813 );
254 #endif // TEST_DGRAM || TEST_RDM || TEST_RAW