4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Stefan Bund <g0dil@berlios.de>
29 \brief TCPSocketHandle unit tests */
31 //#include "TCPSocketHandle.test.hh"
32 //#include "TCPSocketHandle.test.ih"
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
42 #include "TCPSocketHandle.hh"
43 #include "net.test.hh"
45 #include <senf/Utils/auto_unit_test.hh>
46 #include <boost/test/test_tools.hpp>
49 //-/////////////////////////////////////////////////////////////////////////////////////////////////
51 using namespace senf::test;
57 int serv = socket(PF_INET,SOCK_STREAM,0);
58 if (serv<0) fail("server_v4","socket()");
60 if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
61 fail("server_v4","setsockopt()");
62 struct sockaddr_in sin;
63 ::memset(&sin,0,sizeof(sin));
64 sin.sin_family = AF_INET;
65 sin.sin_port = htons(port(0));
66 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
67 if (bind(serv,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v4","bind()");
68 if (listen(serv,1)<0) fail("server_v4","listen()");
69 int sock = accept(serv,0,0);
70 if (sock < 0) fail("server_v4","accept()");
74 int n = read(sock,buffer,1024);
75 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
77 senf::IGNORE( write(sock,buffer,n) );
80 if (shutdown(sock, SHUT_RDWR) < 0) fail("server_v4","shutdown()");
81 if (close(sock) < 0) fail("server_v4","close()");
82 if (close(serv) < 0) fail("server_v4","close()");
87 int serv = socket(PF_INET6,SOCK_STREAM,0);
88 if (serv<0) fail("server_v6","socket()");
90 if (setsockopt(serv,SOL_SOCKET,SO_REUSEADDR,&v,sizeof(v))<0)
91 fail("server_v6","setsockopt()");
92 struct sockaddr_in6 sin;
93 ::memset(&sin,0,sizeof(sin));
94 sin.sin6_family = AF_INET6;
95 sin.sin6_port = htons(port(0));
96 sin.sin6_addr = in6addr_loopback;
97 if (bind(serv,(struct sockaddr *)&sin,sizeof(sin))<0) fail("server_v6","bind()");
98 if (listen(serv,1)<0) fail("server_v6","listen()");
99 int sock = accept(serv,0,0);
100 if (sock < 0) fail("server_v6","accept()");
104 int n = read(sock,buffer,1024);
105 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
107 senf::IGNORE( write(sock,buffer,n) );
110 if (shutdown(sock, SHUT_RDWR) < 0) fail("server_v6","shutdown()");
111 if (close(sock) < 0) fail("server_v6","close()");
112 if (close(serv) < 0) fail("server_v6","close()");
117 SENF_AUTO_UNIT_TEST(tcpv4ClientSocketHandle)
120 senf::TCPv4ClientSocketHandle sock;
122 BOOST_CHECK_THROW( sock.connect(senf::INet4SocketAddress(localhost4str(0))),
123 senf::SystemException );
129 senf::TCPv4ClientSocketHandle sock;
130 SENF_CHECK_NO_THROW( sock.bind(senf::INet4SocketAddress(localhost4str(1))) );
131 SENF_CHECK_NO_THROW( sock.connect(senf::INet4SocketAddress(localhost4str(0))) );
132 BOOST_CHECK( sock.peer() == senf::INet4SocketAddress(localhost4str(0)) );
133 BOOST_CHECK( sock.local() == senf::INet4SocketAddress(localhost4str(1)) );
134 BOOST_CHECK( sock.blocking() );
135 SENF_CHECK_NO_THROW( sock.protocol().rcvbuf(2048) );
136 BOOST_CHECK_EQUAL( sock.protocol().rcvbuf(), 2048u );
137 SENF_CHECK_NO_THROW( sock.protocol().sndbuf(2048) );
138 BOOST_CHECK_EQUAL( sock.protocol().sndbuf(), 2048u );
139 SENF_CHECK_NO_THROW( sock.write(std::string("TEST-WRITE")) );
140 BOOST_CHECK_EQUAL( sock.read(), std::string("TEST-WRITE") );
141 BOOST_CHECK( !sock.eof() );
142 sock.write(std::string("QUIT"));
146 BOOST_CHECK_EQUAL( sock.read(), "" );
147 BOOST_CHECK( sock.eof() );
148 BOOST_CHECK( !sock );
159 senf::TCPv4ClientSocketHandle sock;
161 // Since this is a TCP socket, most of the calls will fail or
162 // are at least not sensible ...
163 // I'll have to move those to a UDPSocket test ... they should
164 // realy only be in the UDP Protocol implementation
165 // SENF_CHECK_NO_THROW( sock.protocol().mcTTL() );
166 // BOOST_CHECK_THROW( sock.protocol().mcTTL(1), senf::SystemException );
167 // SENF_CHECK_NO_THROW( sock.protocol().mcLoop() );
168 // SENF_CHECK_NO_THROW( sock.protocol().mcLoop(false) );
169 // SENF_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0") );
170 // SENF_CHECK_NO_THROW( sock.protocol().mcAddMembership("224.0.0.1:0","127.0.0.1:0") );
171 // SENF_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0","127.0.0.1:0") );
172 // SENF_CHECK_NO_THROW( sock.protocol().mcDropMembership("224.0.0.1:0") );
173 // BOOST_CHECK_THROW( sock.protocol().mcIface("lo"), senf::SystemException );
175 // The following setsockopts are hard to REALLY test ...
176 SENF_CHECK_NO_THROW( sock.protocol().nodelay(true) );
177 BOOST_CHECK( sock.protocol().nodelay() );
178 BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u );
179 BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u );
181 SENF_CHECK_NO_THROW( sock.protocol().reuseaddr(true) );
182 BOOST_CHECK( sock.protocol().reuseaddr() );
183 SENF_CHECK_NO_THROW( sock.protocol().linger(true,0) );
184 BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) );
188 SENF_AUTO_UNIT_TEST(tcpv6ClientSocketHandle)
191 senf::TCPv6ClientSocketHandle sock;
193 BOOST_CHECK_THROW( sock.connect(senf::INet6SocketAddress(localhost6str(0))),
194 senf::SystemException );
200 senf::TCPv6ClientSocketHandle sock;
201 SENF_CHECK_NO_THROW( sock.bind(senf::INet6SocketAddress(localhost6str(1))) );
202 SENF_CHECK_NO_THROW( sock.connect(senf::INet6SocketAddress(localhost6str(0))) );
203 BOOST_CHECK( sock.peer() == senf::INet6SocketAddress(localhost6str(0)) );
204 BOOST_CHECK( sock.local() == senf::INet6SocketAddress(localhost6str(1)) );
205 BOOST_CHECK( sock.blocking() );
206 SENF_CHECK_NO_THROW( sock.protocol().rcvbuf(2048) );
207 BOOST_CHECK_EQUAL( sock.protocol().rcvbuf(), 2048u );
208 SENF_CHECK_NO_THROW( sock.protocol().sndbuf(2048) );
209 BOOST_CHECK_EQUAL( sock.protocol().sndbuf(), 2048u );
210 SENF_CHECK_NO_THROW( sock.write(std::string("TEST-WRITE")) );
211 BOOST_CHECK_EQUAL( sock.read(), std::string("TEST-WRITE") );
212 // this fails with ENOFILE ... why ????
213 // SENF_CHECK_NO_THROW( sock.protocol().timestamp() );
214 BOOST_CHECK( !sock.eof() );
215 sock.write(std::string("QUIT"));
219 BOOST_CHECK_EQUAL( sock.read(), "" );
220 BOOST_CHECK( sock.eof() );
221 BOOST_CHECK( !sock );
232 senf::TCPv6ClientSocketHandle sock;
234 // The following setsockopts are hard to REALLY test ...
235 SENF_CHECK_NO_THROW( sock.protocol().nodelay(true) );
236 BOOST_CHECK( sock.protocol().nodelay() );
237 BOOST_CHECK_EQUAL( sock.protocol().siocinq(), 0u );
238 BOOST_CHECK_EQUAL( sock.protocol().siocoutq(), 0u );
240 SENF_CHECK_NO_THROW( sock.protocol().reuseaddr(true) );
241 BOOST_CHECK( sock.protocol().reuseaddr() );
242 SENF_CHECK_NO_THROW( sock.protocol().linger(true,0) );
243 BOOST_CHECK( sock.protocol().linger() == std::make_pair(true, 0u) );
247 //-/////////////////////////////////////////////////////////////////////////////////////////////////
253 int sock = socket(PF_INET,SOCK_STREAM,0);
254 if (sock<0) fail("client_v4","socket()");
255 struct sockaddr_in sin;
256 ::memset(&sin,0,sizeof(sin));
257 sin.sin_family = AF_INET;
258 sin.sin_port = htons(port(2));
259 sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
260 if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
261 fail("client_v4","connect()");
265 int n = read(sock,buffer,1024);
266 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
268 senf::IGNORE( write(sock,buffer,n) );
271 if (shutdown(sock, SHUT_RDWR) < 0) fail("client_v4","shutdown()");
272 if (close(sock) < 0) fail("client_v4","close()");
277 int sock = socket(PF_INET6,SOCK_STREAM,0);
278 if (sock<0) fail("client_v6","socket()");
279 struct sockaddr_in6 sin;
280 ::memset(&sin,0,sizeof(sin));
281 sin.sin6_family = AF_INET6;
282 sin.sin6_port = htons(port(3));
283 sin.sin6_addr = in6addr_loopback;
284 if (connect(sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
285 fail("client_v6","connect()");
289 int n = read(sock,buffer,1024);
290 if (n == 4 && strncmp(buffer,"QUIT",4) == 0)
292 senf::IGNORE( write(sock,buffer,n) );
295 if (shutdown(sock, SHUT_RDWR) < 0) fail("client_v6","shutdown()");
296 if (close(sock) < 0) fail("client_v6","close()");
301 SENF_AUTO_UNIT_TEST(tcpv4ServerSocketHandle)
305 BOOST_CHECKPOINT("Opening server socket");
306 senf::TCPv4ServerSocketHandle server (senf::INet4SocketAddress(localhost4str(2)));
307 BOOST_CHECKPOINT("Starting client");
310 BOOST_CHECKPOINT("Accepting connection");
311 senf::TCPv4ClientSocketHandle client = server.accept();
312 SENF_CHECK_NO_THROW(client.write(std::string("QUIT")));
314 BOOST_CHECKPOINT("Stopping client");
327 SENF_AUTO_UNIT_TEST(tcpv6ServerSocketHandle)
331 BOOST_CHECKPOINT("Opening server socket");
332 senf::TCPv6ServerSocketHandle server (senf::INet6SocketAddress(localhost6str(3)));
333 BOOST_CHECKPOINT("Starting client");
336 BOOST_CHECKPOINT("Accepting connection");
337 senf::TCPv6ClientSocketHandle client = server.accept();
338 SENF_CHECK_NO_THROW(client.write(std::string("QUIT")));
340 BOOST_CHECKPOINT("Stopping client");
353 //-/////////////////////////////////////////////////////////////////////////////////////////////////
360 // c-file-style: "senf"
361 // indent-tabs-mode: nil
362 // ispell-local-dictionary: "american"
363 // compile-command: "scons -u test"
364 // comment-column: 40