Use override/default for RTPortableServer
[ACE_TAO.git] / ACE / tests / SOCK_Send_Recv_Test_IPV6.cpp
blob567077e580746bb8df25af0e85a7842ca52c7278
1 // ===========================================================================
2 /**
3 * @file SOCK_Send_Recv_Test_IPV6.cpp
5 * @brief This is a test of the <ACE_SOCK>'s various send and receive
6 * methods.
8 * The test forks two processes or spawns two threads (depending upon
9 * the platform) and then executes client and server allowing them to
10 * connect and exchange data in ways designed to exercise the send
11 * and recv functions. Right now, it primarily tests the iov-like
12 * send and recv functions, but others should be added to completely
13 * cover the possible scenarios.
15 * @author Steve Huston <shuston@riverace.com>
16 * Brian Buesker <bbuesker@qualcomm.com>
18 // ============================================================================
20 #include "test_config.h"
21 #include "ace/OS_NS_sys_wait.h"
22 #include "ace/OS_NS_unistd.h"
23 #include "ace/Thread.h"
24 #include "ace/Thread_Manager.h"
25 #include "ace/Time_Value.h"
26 #include "ace/SOCK_Connector.h"
27 #include "ace/SOCK_Acceptor.h"
28 #include "ace/SOCK_Stream.h"
30 // Change to non-zero if test fails
31 static int Test_Result = 0;
33 #if !defined (ACE_LACKS_FORK) || defined (ACE_HAS_THREADS)
35 // In test 3, a large amount of data is sent. The purpose is to overflow the
36 // TCP send window, causing the sender to block (it's a send_n). This value
37 // is the amount to send. The assumption is that no implementation has a
38 // receive window larger than 128K bytes. If one is found, this is the place
39 // to change it.
40 // For some odd reason, NT will try to send a single large buffer, but not
41 // multiple smaller ones that add up to the large size.
42 const size_t Test3_Send_Size = 4*1024;
43 const size_t Test3_Loops = 10;
44 const size_t Test3_Total_Size = Test3_Send_Size * Test3_Loops;
47 #if defined (ACE_HAS_IPV6)
49 static void *
50 client (void *arg)
52 ACE_INET_Addr *remote_addr = reinterpret_cast<ACE_INET_Addr *> (arg);
53 ACE_INET_Addr server_addr (remote_addr->get_port_number (),
54 ACE_IPV6_LOCALHOST);
56 ACE_SOCK_Stream cli_stream;
57 ACE_SOCK_Connector con;
58 ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
60 ACE_DEBUG ((LM_DEBUG,
61 ACE_TEXT ("(%P|%t) Connecting to port %d\n"),
62 server_addr.get_port_number()));
64 // Initiate connection with server; don't wait forever
65 if (con.connect (cli_stream,
66 server_addr,
67 &timeout) == -1)
69 ACE_ERROR ((LM_ERROR,
70 ACE_TEXT ("(%P|%t) %p\n"),
71 ACE_TEXT ("connection failed")));
72 Test_Result = 1;
73 return 0;
76 ACE_DEBUG ((LM_DEBUG,
77 ACE_TEXT ("(%P|%t) connected to %C\n"),
78 server_addr.get_host_name ()));
80 //******************* TEST 1 ******************************
82 // Do a iovec sendv - send the 255 byte buffer in 5 chunks. The
83 // server will verify that the correct data is sent, and that there
84 // is no more and no less.
86 u_char buffer[255];
87 size_t i;
88 ssize_t len;
90 // The server will verify that this data pattern gets there intact.
92 for (i = 0; i < sizeof buffer; ++i)
93 buffer[i] = static_cast<u_char> (i);
95 iovec iov[5];
97 iov[0].iov_base = reinterpret_cast<char *> (&buffer[0]);
98 iov[0].iov_len = 50;
100 iov[1].iov_base = reinterpret_cast<char *> (&buffer[50]);
101 iov[1].iov_len = 25;
103 iov[2].iov_base = reinterpret_cast<char *> (&buffer[75]);
104 iov[2].iov_len = 150;
106 iov[3].iov_base = reinterpret_cast<char *> (&buffer[225]);
107 iov[3].iov_len = 29;
109 iov[4].iov_base = reinterpret_cast<char *> (&buffer[254]);
110 iov[4].iov_len = 1;
112 len = cli_stream.sendv (iov, 5);
113 if (len == -1)
115 ACE_ERROR ((LM_ERROR,
116 ACE_TEXT ("(%P|%t) %p\n"),
117 ACE_TEXT ("Test 1, sendv failed")));
118 Test_Result = 1;
120 else
121 ACE_TEST_ASSERT (len == 255);
123 //******************* TEST 2 ******************************
125 // The same data is coming back - receive it using recv (size_t n,
126 // ...) and compare it to the original data.
128 u_char buffer2[255];
129 // Give it a chance to get here
130 ACE_OS::sleep (2);
131 len = cli_stream.recv (4,
132 buffer2,
133 150,
134 &buffer2[150],
135 105);
136 if (len != 255)
138 ACE_ERROR ((LM_ERROR,
139 ACE_TEXT ("(%P|%t) %p; len is %d, but should be 255!\n"),
140 len));
142 ACE_TEST_ASSERT (len == 255);
144 for (i = 0; i < 255; i++)
145 if (buffer2[i] != buffer[i])
147 ACE_ERROR ((LM_ERROR,
148 ACE_TEXT ("(%P|%t) Test 2, rcvd byte %d is %d, not %d\n"),
149 i, buffer2[i], buffer[i]));
150 Test_Result = 1;
153 //******************* TEST 3 ******************************
155 // Do a send_n of a large size. The receive should sleep some to
156 // cause the data reception to be delayed, which will fill up the
157 // TCP window and cause send_n to block at some point. The particular
158 // case this tests only needs to be exercised if the socket is
159 // non-blocking, so set that first.
161 ssize_t sent;
162 char buff[Test3_Send_Size];
163 ACE_TEST_ASSERT (cli_stream.enable (ACE_NONBLOCK) != -1);
164 for (i = 0; i < Test3_Loops; ++i)
166 errno = 0;
167 sent = cli_stream.send_n (buff, sizeof (buff));
168 if (sent != sizeof (buff) && errno != 0)
170 ACE_ERROR ((LM_ERROR,
171 ACE_TEXT ("(%P|%t) Test 3, pass %d, sent %d, %p\n"),
172 i, sent, ACE_TEXT ("error")));
173 Test_Result = 1; // Fail
177 cli_stream.close ();
179 return 0;
182 static void *
183 server (void *arg)
185 ACE_SOCK_Acceptor *peer_acceptor = (ACE_SOCK_Acceptor *) arg;
186 ACE_SOCK_Stream sock_str;
187 ACE_INET_Addr cli_addr;
188 ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
190 // Accept the connection over which the stream tests will run.
191 // Don't lock up if client doesn't connect
192 if (peer_acceptor->accept (sock_str,
193 &cli_addr,
194 &timeout) == -1)
196 ACE_ERROR ((LM_ERROR,
197 ACE_TEXT ("(%P|%t) %p\n"),
198 ACE_TEXT ("accept")));
199 Test_Result = 1;
200 return 0;
203 ACE_DEBUG ((LM_DEBUG,
204 ACE_TEXT ("(%P|%t) client %C connected from %d\n"),
205 cli_addr.get_host_name (),
206 cli_addr.get_port_number ()));
208 //******************* TEST 1 ******************************
210 // Do a iovec recvv - the client should send 255 bytes, which we
211 // will be detected and read into a ACE-allocated buffer. Use a 5
212 // second timeout to give the client a chance to send it all.
214 ACE_OS::sleep (5);
216 iovec iov[3];
217 u_char buffer[255];
218 ssize_t len;
219 int i;
221 iov[0].iov_base = reinterpret_cast<char *> (&buffer[0]);
222 iov[0].iov_len = 75;
224 iov[1].iov_base = reinterpret_cast<char *> (&buffer[75]);
225 iov[1].iov_len = 100;
227 iov[2].iov_base = reinterpret_cast<char *> (&buffer[175]);
228 iov[2].iov_len = 80;
230 len = sock_str.recvv_n (iov, 3);
231 if (len == -1)
233 ACE_ERROR ((LM_ERROR,
234 ACE_TEXT ("(%P|%t) %p\n"),
235 ACE_TEXT ("Test 1, recvv failed")));
236 Test_Result = 1;
239 ACE_TEST_ASSERT (len == 255);
240 for (i = 0; i < 255; i++)
241 if (buffer[i] != i)
243 ACE_ERROR ((LM_ERROR,
244 ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"),
246 buffer[i],
247 i));
248 Test_Result = 1;
251 //******************* TEST 2 ******************************
253 // Send the buffer back, using send (size_t n, ...) in 3 pieces.
255 len = sock_str.send (6,
256 buffer,
258 &buffer[42],
259 189,
260 &buffer[231],
261 24);
262 ACE_TEST_ASSERT (len == 255);
264 //******************* TEST 3 ******************************
266 // The sender is testing send_n to make sure it blocks if the TCP
267 // window fills. So sleep here for a bit to avoid getting the data
268 // yet. Then just read and empty out the received data.
269 ACE_OS::sleep (8);
270 // Keep reading until the peer closes.
271 sock_str.disable (ACE_NONBLOCK);
272 ssize_t got = 1;
273 size_t total_recv = 0;
274 while (got != 0)
276 errno = 0;
277 got = sock_str.recv (buffer, sizeof (buffer));
278 if (got < 0)
279 break;
280 total_recv += got;
283 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) Test 3 received %d bytes\n"),
284 total_recv));
286 if (total_recv == Test3_Total_Size)
288 if (got != 0 || errno != 0)
290 ACE_ERROR ((LM_ERROR,
291 ACE_TEXT ("(%P|%t) Test 3 final recv status %d, expected 0\n"),
292 got));
293 ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"),
294 ACE_TEXT ("expected errno == 0, instead")));
295 Test_Result = 1; // Fail
298 else
300 ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) Test 3 expected %d %p\n"),
301 Test3_Total_Size, ACE_TEXT ("bytes")));
302 Test_Result = 1;
305 sock_str.close();
307 return 0;
310 #endif /*ACE_HAS_IPV6*/
312 #endif /* !ACE_LACKS_FORK || ACE_HAS_THREADS */
314 #if defined (ACE_HAS_IPV6)
315 static void
316 spawn ()
318 // Acceptor
319 ACE_SOCK_Acceptor peer_acceptor;
321 // Create a server address.
322 ACE_INET_Addr server_addr;
324 // Bind listener to any port and then find out what the port was.
325 if (peer_acceptor.open (ACE_Addr::sap_any, 0, AF_INET6) == -1
326 || peer_acceptor.get_local_addr (server_addr) == -1)
327 ACE_ERROR ((LM_ERROR,
328 ACE_TEXT ("(%P|%t) %p\n"),
329 ACE_TEXT ("open")));
330 else
332 ACE_DEBUG ((LM_DEBUG,
333 ACE_TEXT ("(%P|%t) starting server at port %d\n"),
334 server_addr.get_port_number ()));
336 #if !defined (ACE_LACKS_FORK)
337 switch (ACE_OS::fork (ACE_TEXT("child")))
339 case -1:
340 ACE_ERROR ((LM_ERROR,
341 ACE_TEXT ("(%P|%t) %p\n%a"),
342 ACE_TEXT ("fork failed"),
343 1));
344 /* NOTREACHED */
345 case 0:
346 client (&server_addr);
347 ACE_OS::exit (0);
348 /* NOTREACHED */
349 default:
350 server (reinterpret_cast<void *> (&peer_acceptor));
351 ACE_OS::wait ();
353 #elif defined (ACE_HAS_THREADS)
354 if (ACE_Thread_Manager::instance ()->spawn
355 (ACE_THR_FUNC (server),
356 reinterpret_cast<void *> (&peer_acceptor),
357 THR_NEW_LWP | THR_DETACHED) == -1)
358 ACE_ERROR ((LM_ERROR,
359 ACE_TEXT ("(%P|%t) %p\n%a"),
360 ACE_TEXT ("thread create failed"),
361 1));
363 if (ACE_Thread_Manager::instance ()->spawn
364 (ACE_THR_FUNC (client),
365 reinterpret_cast<void *> (&server_addr),
366 THR_NEW_LWP | THR_DETACHED) == -1)
367 ACE_ERROR ((LM_ERROR,
368 ACE_TEXT ("(%P|%t) %p\n%a"),
369 ACE_TEXT ("thread create failed"),
370 1));
372 // Wait for the threads to exit.
373 ACE_Thread_Manager::instance ()->wait ();
374 #else
375 ACE_ERROR ((LM_INFO,
376 ACE_TEXT ("(%P|%t) ")
377 ACE_TEXT ("only one thread may be run ")
378 ACE_TEXT ("in a process on this platform\n")));
379 #endif /* ACE_HAS_THREADS */
381 peer_acceptor.close ();
385 #endif /*ACE_HAS_IPV6*/
388 run_main (int, ACE_TCHAR *[])
390 ACE_START_TEST (ACE_TEXT ("SOCK_Send_Recv_Test_IPV6"));
392 #if defined (ACE_HAS_IPV6)
393 spawn ();
394 #endif /* ACE_HAS_IPV6 */
396 ACE_END_TEST;
397 return Test_Result;