4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Stefan Bund <g0dil@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief TCPSocketHandle unit tests */
26 //#include "TCPSocketHandle.test.hh"
27 //#include "TCPSocketHandle.test.ih"
30 #include <sys/types.h>
31 #include <sys/ioctl.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
37 #include "TCPSocketHandle.hh"
38 #include "net.test.hh"
40 #include <senf/Utils/auto_unit_test.hh>
41 #include <boost/test/test_tools.hpp>
44 ///////////////////////////////cc.p////////////////////////////////////////
46 ///////////////////////////////////////////////////////////////////////////
52 int serv = socket(PF_INET,SOCK_STREAM,0);
53 if (serv<0) fail("server_v4","socket()");
55 if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
56 fail("server_v4","setsockopt()");
57 struct sockaddr_in sin;
58 ::memset(&sin,0,sizeof(sin));
59 sin.sin_family = AF_INET;
60 sin.sin_port = htons(port(0));
61 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
62 if (bind(serv,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v4","bind()");
63 if (listen(serv,1)<0) fail("server_v4","listen()");
64 int sock = accept(serv,0,0);
65 if (sock < 0) fail("server_v4","accept()");
69 int n = read(sock,buffer,1024);
70 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
75 if (shutdown(sock, SHUT_RDWR) < 0) fail("server_v4","shutdown()");
76 if (close(sock) < 0) fail("server_v4","close()");
77 if (close(serv) < 0) fail("server_v4","close()");
82 int serv = socket(PF_INET6,SOCK_STREAM,0);
83 if (serv<0) fail("server_v6","socket()");
85 if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
86 fail("server_v6","setsockopt()");
87 struct sockaddr_in6 sin;
88 ::memset(&sin,0,sizeof(sin));
89 sin.sin6_family = AF_INET6;
90 sin.sin6_port = htons(port(0));
91 sin.sin6_addr = in6addr_loopback;
92 if (bind(serv,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v6","bind()");
93 if (listen(serv,1)<0) fail("server_v6","listen()");
94 int sock = accept(serv,0,0);
95 if (sock < 0) fail("server_v6","accept()");
99 int n = read(sock,buffer,1024);
100 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
102 write(sock,buffer,n);
105 if (shutdown(sock, SHUT_RDWR) < 0) fail("server_v6","shutdown()");
106 if (close(sock) < 0) fail("server_v6","close()");
107 if (close(serv) < 0) fail("server_v6","close()");
112 BOOST_AUTO_UNIT_TEST(tcpv4ClientSocketHandle)
115 senf::TCPv4ClientSocketHandle sock;
117 BOOST_CHECK_THROW( sock.connect(senf::INet4SocketAddress(localhost4str(0))),
118 senf::SystemException );
124 senf::TCPv4ClientSocketHandle sock;
125 SENF_CHECK_NO_THROW( sock.bind(senf::INet4SocketAddress(localhost4str(1))) );
126 SENF_CHECK_NO_THROW( sock.connect(senf::INet4SocketAddress(localhost4str(0))) );
127 BOOST_CHECK( sock.peer() == senf::INet4SocketAddress(localhost4str(0)) );
128 BOOST_CHECK( sock.local() == senf::INet4SocketAddress(localhost4str(1)) );
129 BOOST_CHECK( sock.blocking() );
130 SENF_CHECK_NO_THROW( sock.protocol().rcvbuf(2048) );
131 BOOST_CHECK_EQUAL( sock.protocol().rcvbuf(), 2048u );
132 SENF_CHECK_NO_THROW( sock.protocol().sndbuf(2048) );
133 BOOST_CHECK_EQUAL( sock.protocol().sndbuf(), 2048u );
134 SENF_CHECK_NO_THROW( sock.write(std::string("TEST-WRITE")) );
135 BOOST_CHECK_EQUAL( sock.read(), std::string("TEST-WRITE") );
136 BOOST_CHECK( !sock.eof() );
137 sock.write(std::string("QUIT"));
141 BOOST_CHECK_EQUAL( sock.read(), "" );
142 BOOST_CHECK( sock.eof() );
143 BOOST_CHECK( !sock );
154 senf::TCPv4ClientSocketHandle sock;
156 // Since this is a TCP socket, most of the calls will fail or
157 // are at least not sensible ...
158 // I'll have to move those to a UDPSocket test ... they should
159 // realy only be in the UDP Protocol implementation
160 // SENF_CHECK_NO_THROW( sock.protocol().mcTTL() );
161 // BOOST_CHECK_THROW( sock.protocol().mcTTL(1), senf::SystemException );
162 // SENF_CHECK_NO_THROW( sock.protocol().mcLoop() );
163 // SENF_CHECK_NO_THROW( sock.protocol().mcLoop(false) );
164 // SENF_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0") );
165 // SENF_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0","127.0.0.1:0") );
166 // SENF_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0","127.0.0.1:0") );
167 // SENF_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0") );
168 // BOOST_CHECK_THROW( sock.protocol().mcIface("lo"), senf::SystemException );
170 // The following setsockopts are hard to REALLY test ...
171 SENF_CHECK_NO_THROW( sock.protocol().nodelay(true) );
172 BOOST_CHECK( sock.protocol().nodelay() );
173 BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u );
174 BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u );
176 SENF_CHECK_NO_THROW( sock.protocol().reuseaddr(true) );
177 BOOST_CHECK( sock.protocol().reuseaddr() );
178 SENF_CHECK_NO_THROW( sock.protocol().linger(true,0) );
179 BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) );
183 BOOST_AUTO_UNIT_TEST(tcpv6ClientSocketHandle)
186 senf::TCPv6ClientSocketHandle sock;
188 BOOST_CHECK_THROW( sock.connect(senf::INet6SocketAddress(localhost6str(0))),
189 senf::SystemException );
195 senf::TCPv6ClientSocketHandle sock;
196 SENF_CHECK_NO_THROW( sock.bind(senf::INet6SocketAddress(localhost6str(1))) );
197 SENF_CHECK_NO_THROW( sock.connect(senf::INet6SocketAddress(localhost6str(0))) );
198 BOOST_CHECK( sock.peer() == senf::INet6SocketAddress(localhost6str(0)) );
199 BOOST_CHECK( sock.local() == senf::INet6SocketAddress(localhost6str(1)) );
200 BOOST_CHECK( sock.blocking() );
201 SENF_CHECK_NO_THROW( sock.protocol().rcvbuf(2048) );
202 BOOST_CHECK_EQUAL( sock.protocol().rcvbuf(), 2048u );
203 SENF_CHECK_NO_THROW( sock.protocol().sndbuf(2048) );
204 BOOST_CHECK_EQUAL( sock.protocol().sndbuf(), 2048u );
205 SENF_CHECK_NO_THROW( sock.write(std::string("TEST-WRITE")) );
206 BOOST_CHECK_EQUAL( sock.read(), std::string("TEST-WRITE") );
207 // this fails with ENOFILE ... why ????
208 // SENF_CHECK_NO_THROW( sock.protocol().timestamp() );
209 BOOST_CHECK( !sock.eof() );
210 sock.write(std::string("QUIT"));
214 BOOST_CHECK_EQUAL( sock.read(), "" );
215 BOOST_CHECK( sock.eof() );
216 BOOST_CHECK( !sock );
227 senf::TCPv6ClientSocketHandle sock;
229 // The following setsockopts are hard to REALLY test ...
230 SENF_CHECK_NO_THROW( sock.protocol().nodelay(true) );
231 BOOST_CHECK( sock.protocol().nodelay() );
232 BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u );
233 BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u );
235 SENF_CHECK_NO_THROW( sock.protocol().reuseaddr(true) );
236 BOOST_CHECK( sock.protocol().reuseaddr() );
237 SENF_CHECK_NO_THROW( sock.protocol().linger(true,0) );
238 BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) );
242 ///////////////////////////////////////////////////////////////////////////
248 int sock = socket(PF_INET,SOCK_STREAM,0);
249 if (sock<0) fail("client_v4","socket()");
250 struct sockaddr_in sin;
251 ::memset(&sin,0,sizeof(sin));
252 sin.sin_family = AF_INET;
253 sin.sin_port = htons(port(2));
254 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
255 if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
256 fail("client_v4","connect()");
260 int n = read(sock,buffer,1024);
261 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
263 write(sock,buffer,n);
266 if (shutdown(sock, SHUT_RDWR) < 0) fail("client_v4","shutdown()");
267 if (close(sock) < 0) fail("client_v4","close()");
272 int sock = socket(PF_INET6,SOCK_STREAM,0);
273 if (sock<0) fail("client_v6","socket()");
274 struct sockaddr_in6 sin;
275 ::memset(&sin,0,sizeof(sin));
276 sin.sin6_family = AF_INET6;
277 sin.sin6_port = htons(port(3));
278 sin.sin6_addr = in6addr_loopback;
279 if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
280 fail("client_v6","connect()");
284 int n = read(sock,buffer,1024);
285 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
287 write(sock,buffer,n);
290 if (shutdown(sock, SHUT_RDWR) < 0) fail("client_v6","shutdown()");
291 if (close(sock) < 0) fail("client_v6","close()");
296 BOOST_AUTO_UNIT_TEST(tcpv4ServerSocketHandle)
300 BOOST_CHECKPOINT("Opening server socket");
301 senf::TCPv4ServerSocketHandle server (senf::INet4SocketAddress(localhost4str(2)));
302 BOOST_CHECKPOINT("Starting client");
305 BOOST_CHECKPOINT("Accepting connection");
306 senf::TCPv4ClientSocketHandle client = server.accept();
307 SENF_CHECK_NO_THROW(client.write(std::string("QUIT")));
309 BOOST_CHECKPOINT("Stopping client");
322 BOOST_AUTO_UNIT_TEST(tcpv6ServerSocketHandle)
326 BOOST_CHECKPOINT("Opening server socket");
327 senf::TCPv6ServerSocketHandle server (senf::INet6SocketAddress(localhost6str(3)));
328 BOOST_CHECKPOINT("Starting client");
331 BOOST_CHECKPOINT("Accepting connection");
332 senf::TCPv6ClientSocketHandle client = server.accept();
333 SENF_CHECK_NO_THROW(client.write(std::string("QUIT")));
335 BOOST_CHECKPOINT("Stopping client");
348 ///////////////////////////////cc.e////////////////////////////////////////
355 // c-file-style: "senf"
356 // indent-tabs-mode: nil
357 // ispell-local-dictionary: "american"
358 // compile-command: "scons -u test"
359 // comment-column: 40