2 Copyright (C) 2004 by Intra2net AG
4 The software in this package is distributed under the GNU General
5 Public License version 2 (with a special exception described below).
7 A copy of GNU General Public License (GPL) is included in this distribution,
8 in the file COPYING.GPL.
10 As a special exception, if other files instantiate templates or use macros
11 or inline functions from this file, or you compile this file and link it
12 with other works to produce a work based on this file, this file
13 does not by itself cause the resulting work to be covered
14 by the GNU General Public License.
16 However the source code for this file must still be made available
17 in accordance with section (3) of the GNU General Public License.
19 This exception does not invalidate any other reasons why a work based
20 on this file might be covered by the GNU General Public License.
22 #include <sys/types.h>
34 #define BOOST_TEST_DYN_LINK
35 #include <boost/test/unit_test.hpp>
37 #include <socket_client.hxx>
38 #include <socket_server.hxx>
40 #include "test_fixtures.hxx"
47 using namespace libt2n;
49 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
50 class real_write_connection: public socket_server_connection
53 void real_write(const std::string& data)
54 { socket_write(data); }
57 class test_reconnectFixture : public KillChildOnShutdownFixture
60 void send_raw_socket(string hello_string, socket_server* ss, int conn_id)
62 socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id));
64 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
65 real_write_connection *rwc=(real_write_connection*)ssc;
66 rwc->real_write(hello_string);
70 test_reconnectFixture()
74 ~test_reconnectFixture()
79 BOOST_FIXTURE_TEST_SUITE(test_reconnect, test_reconnectFixture)
81 BOOST_AUTO_TEST_CASE(simple_reconnect)
83 switch(child_pid=fork())
87 BOOST_FAIL("fork error");
95 socket_server ss("./socket");
97 time_t t0 = time(NULL);
100 while (time(NULL) < t0 + 10 )
102 ss.fill_buffer(1000000);
107 if(ss.get_packet(data,cid))
109 server_connection* con=ss.get_connection(cid);
115 con->write(string().insert(0,100,'X'));
117 con->write(string().insert(0,100,'Y'));
122 std::cerr << "exception in child. ignoring\n";
125 // don't call atexit and stuff
132 // don't kill us on broken pipe
133 signal(SIGPIPE, SIG_IGN);
135 // wait till server is up
137 socket_client_connection sc("./socket");
143 while (!sc.get_packet(data))
144 sc.fill_buffer(1000000);
150 while (!sc.get_packet(data))
151 sc.fill_buffer(1000000);
153 BOOST_CHECK_EQUAL(string().insert(0,100,'X'),data);
158 BOOST_AUTO_TEST_CASE(reconnect_with_close)
160 switch(child_pid=fork())
164 BOOST_FAIL("fork error");
172 socket_server ss("./socket");
174 time_t t0 = time(NULL);
177 while (time(NULL) < t0 + 10 )
179 ss.fill_buffer(1000000);
184 if(ss.get_packet(data,cid))
186 server_connection* con=ss.get_connection(cid);
192 con->write(string().insert(0,100,'X'));
194 con->write(string().insert(0,100,'Y'));
199 std::cerr << "exception in child. ignoring\n";
202 // don't call atexit and stuff
209 // don't kill us on broken pipe
210 signal(SIGPIPE, SIG_IGN);
212 // wait till server is up
214 socket_client_connection sc("./socket");
220 while (!sc.get_packet(data))
221 sc.fill_buffer(1000000);
232 while (!sc.get_packet(data))
233 sc.fill_buffer(1000000);
235 BOOST_CHECK_EQUAL(string().insert(0,100,'X'),data);
240 BOOST_AUTO_TEST_CASE(reconnect_buffer_complete)
242 switch(child_pid=fork())
246 BOOST_FAIL("fork error");
254 socket_server ss("./socket");
256 time_t t0 = time(NULL);
259 while (time(NULL) < t0 + 10 )
261 ss.fill_buffer(1000000);
266 if(ss.get_packet(data,cid))
268 server_connection* con=ss.get_connection(cid);
274 con->write(string().insert(0,100,'X'));
279 std::cerr << "exception in child. ignoring\n";
282 // don't call atexit and stuff
289 // don't kill us on broken pipe
290 signal(SIGPIPE, SIG_IGN);
292 // wait till server is up
294 socket_client_connection sc("./socket");
300 while (!sc.packet_available())
301 sc.fill_buffer(1000000);
305 BOOST_CHECK_MESSAGE(sc.get_packet(data) == true, "packet not there");
307 BOOST_CHECK_MESSAGE(data == string().insert(0,100,'X'), "data incorrect");
312 BOOST_AUTO_TEST_CASE(reconnect_buffer_several_complete)
316 switch(child_pid=fork())
320 BOOST_FAIL("fork error");
328 socket_server ss("./socket");
330 time_t t0 = time(NULL);
333 while (time(NULL) < t0 + 10 )
335 ss.fill_buffer(1000000);
340 if(ss.get_packet(data,cid))
342 server_connection* con=ss.get_connection(cid);
349 for (int i=0; i<packets; i++)
350 con->write(string().insert(0,100,'X'));
356 std::cerr << "exception in child. ignoring\n";
359 // don't call atexit and stuff
366 // don't kill us on broken pipe
367 signal(SIGPIPE, SIG_IGN);
369 // wait till server is up
371 socket_client_connection sc("./socket");
375 // retrieve packets for 3 seconds
376 time_t t0 = time(NULL);
379 while (time(NULL) < t0 + 3 )
380 sc.fill_buffer(1000000);
382 // we now should have packets complete packets in the buffer
386 // are these packets still there?
388 for (int i=0; i < packets; i++)
393 os << "packet " << i << " not there";
395 BOOST_CHECK_MESSAGE(sc.get_packet(data) == true, os.str());
398 os << "packet " << i << " incorrect";
400 BOOST_CHECK_MESSAGE(string().insert(0,100,'X') == data, os.str());
406 BOOST_AUTO_TEST_CASE(reconnect_buffer_no_incomplete1)
408 switch(child_pid=fork())
412 BOOST_FAIL("fork error");
420 socket_server ss("./socket");
422 time_t t0 = time(NULL);
425 while (time(NULL) < t0 + 10 )
427 ss.fill_buffer(1000000);
432 if(ss.get_packet(data,cid))
434 server_connection* con=ss.get_connection(cid);
441 con->write(string().insert(0,100,'X'));
442 send_raw_socket("aaaab",&ss,cid);
448 std::cerr << "exception in child. ignoring\n";
451 // don't call atexit and stuff
458 // don't kill us on broken pipe
459 signal(SIGPIPE, SIG_IGN);
461 // wait till server is up
463 socket_client_connection sc("./socket");
467 // retrieve packets for 3 seconds
468 time_t t0 = time(NULL);
471 while (time(NULL) < t0 + 3 )
472 sc.fill_buffer(1000000);
474 // we now should have one complete packet and some stuff in the buffer
479 BOOST_CHECK_MESSAGE((sc.peek_packet(data))>0, "no incomplete packet");
483 BOOST_CHECK_MESSAGE((int)sc.peek_packet(data) == 0, "incomplete packet not removed");
488 BOOST_AUTO_TEST_CASE(reconnect_buffer_no_incomplete2)
490 switch(child_pid=fork())
494 BOOST_FAIL("fork error");
502 socket_server ss("./socket");
504 time_t t0 = time(NULL);
507 while (time(NULL) < t0 + 10 )
509 ss.fill_buffer(1000000);
514 if(ss.get_packet(data,cid))
516 server_connection* con=ss.get_connection(cid);
523 con->write(string().insert(0,100,'X'));
525 string blob=string().insert(0,100,'Y');
527 // one byte will be missing...
528 int size=blob.size()+1;
529 char sizetransfer[sizeof(int)+1];
530 memcpy(sizetransfer,(void*)&size,sizeof(int));
531 sizetransfer[sizeof(int)+1]=0;
533 string packet=string(sizetransfer)+blob;
535 send_raw_socket(packet,&ss,cid);
541 std::cerr << "exception in child. ignoring\n";
544 // don't call atexit and stuff
551 // don't kill us on broken pipe
552 signal(SIGPIPE, SIG_IGN);
554 // wait till server is up
556 socket_client_connection sc("./socket");
560 // retrieve packets for 3 seconds
561 time_t t0 = time(NULL);
564 while (time(NULL) < t0 + 3 )
565 sc.fill_buffer(1000000);
567 // we now should have one complete packet and some stuff in the buffer
573 BOOST_CHECK_MESSAGE(sc.get_packet(data) == true, "packet not there");
574 BOOST_CHECK_MESSAGE(string().insert(0,100,'X') == data, "data incorrect");
576 BOOST_CHECK_MESSAGE((int)sc.peek_packet(data) == 0, "incomplete packet not removed");
581 BOOST_AUTO_TEST_SUITE_END()