1 /***************************************************************************
2 * Copyright (C) 2004 by Intra2net AG *
5 ***************************************************************************/
19 #include <cppunit/extensions/TestFactoryRegistry.h>
20 #include <cppunit/ui/text/TestRunner.h>
21 #include <cppunit/extensions/HelperMacros.h>
23 #include <socket_client.hxx>
24 #include <socket_server.hxx>
31 using namespace libt2n;
32 using namespace CppUnit;
34 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
35 class real_write_connection: public socket_server_connection
38 void real_write(const std::string& data)
39 { socket_write(data); }
42 class test_reconnect : public TestFixture
44 CPPUNIT_TEST_SUITE(test_reconnect);
46 CPPUNIT_TEST(simple_reconnect);
47 CPPUNIT_TEST(reconnect_with_close);
48 CPPUNIT_TEST(reconnect_buffer_complete);
49 CPPUNIT_TEST(reconnect_buffer_several_complete);
50 CPPUNIT_TEST(reconnect_buffer_no_incomplete1);
51 CPPUNIT_TEST(reconnect_buffer_no_incomplete2);
53 CPPUNIT_TEST_SUITE_END();
64 // make sure the server-child is dead before the next test runs
65 kill(child_pid,SIGKILL);
69 void send_raw_socket(string hello_string, socket_server* ss, int conn_id)
71 socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id));
73 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
74 real_write_connection *rwc=(real_write_connection*)ssc;
75 rwc->real_write(hello_string);
78 void simple_reconnect()
80 switch(child_pid=fork())
84 CPPUNIT_FAIL("fork error");
92 socket_server ss("./socket");
94 time_t t0 = time(NULL);
97 while (time(NULL) < t0 + 10 )
99 ss.fill_buffer(1000000);
104 if(ss.get_packet(data,cid))
106 server_connection* con=ss.get_connection(cid);
112 con->write(string().insert(0,100,'X'));
114 con->write(string().insert(0,100,'Y'));
119 std::cerr << "exception in child. ignoring\n";
122 // don't call atexit and stuff
129 // don't kill us on broken pipe
130 signal(SIGPIPE, SIG_IGN);
132 // wait till server is up
134 socket_client_connection sc("./socket");
140 while (!sc.get_packet(data))
141 sc.fill_buffer(1000000);
147 while (!sc.get_packet(data))
148 sc.fill_buffer(1000000);
150 CPPUNIT_ASSERT_EQUAL(string().insert(0,100,'X'),data);
155 void reconnect_with_close()
157 switch(child_pid=fork())
161 CPPUNIT_FAIL("fork error");
169 socket_server ss("./socket");
171 time_t t0 = time(NULL);
174 while (time(NULL) < t0 + 10 )
176 ss.fill_buffer(1000000);
181 if(ss.get_packet(data,cid))
183 server_connection* con=ss.get_connection(cid);
189 con->write(string().insert(0,100,'X'));
191 con->write(string().insert(0,100,'Y'));
196 std::cerr << "exception in child. ignoring\n";
199 // don't call atexit and stuff
206 // don't kill us on broken pipe
207 signal(SIGPIPE, SIG_IGN);
209 // wait till server is up
211 socket_client_connection sc("./socket");
217 while (!sc.get_packet(data))
218 sc.fill_buffer(1000000);
229 while (!sc.get_packet(data))
230 sc.fill_buffer(1000000);
232 CPPUNIT_ASSERT_EQUAL(string().insert(0,100,'X'),data);
237 void reconnect_buffer_complete()
239 switch(child_pid=fork())
243 CPPUNIT_FAIL("fork error");
251 socket_server ss("./socket");
253 time_t t0 = time(NULL);
256 while (time(NULL) < t0 + 10 )
258 ss.fill_buffer(1000000);
263 if(ss.get_packet(data,cid))
265 server_connection* con=ss.get_connection(cid);
271 con->write(string().insert(0,100,'X'));
276 std::cerr << "exception in child. ignoring\n";
279 // don't call atexit and stuff
286 // don't kill us on broken pipe
287 signal(SIGPIPE, SIG_IGN);
289 // wait till server is up
291 socket_client_connection sc("./socket");
297 while (!sc.packet_available())
298 sc.fill_buffer(1000000);
302 CPPUNIT_ASSERT_EQUAL_MESSAGE("packet not there",true,sc.get_packet(data));
304 CPPUNIT_ASSERT_EQUAL_MESSAGE("data incorrect",string().insert(0,100,'X'),data);
309 void reconnect_buffer_several_complete()
313 switch(child_pid=fork())
317 CPPUNIT_FAIL("fork error");
325 socket_server ss("./socket");
327 time_t t0 = time(NULL);
330 while (time(NULL) < t0 + 10 )
332 ss.fill_buffer(1000000);
337 if(ss.get_packet(data,cid))
339 server_connection* con=ss.get_connection(cid);
346 for (int i=0; i<packets; i++)
347 con->write(string().insert(0,100,'X'));
353 std::cerr << "exception in child. ignoring\n";
356 // don't call atexit and stuff
363 // don't kill us on broken pipe
364 signal(SIGPIPE, SIG_IGN);
366 // wait till server is up
368 socket_client_connection sc("./socket");
372 // retrieve packets for 3 seconds
373 time_t t0 = time(NULL);
376 while (time(NULL) < t0 + 3 )
377 sc.fill_buffer(1000000);
379 // we now should have packets complete packets in the buffer
383 // are these packets still there?
385 for (int i=0; i < packets; i++)
390 os << "packet " << i << " not there";
392 CPPUNIT_ASSERT_EQUAL_MESSAGE(os.str(),true,sc.get_packet(data));
395 os << "packet " << i << " incorrect";
397 CPPUNIT_ASSERT_EQUAL_MESSAGE(os.str(),string().insert(0,100,'X'),data);
403 void reconnect_buffer_no_incomplete1()
405 switch(child_pid=fork())
409 CPPUNIT_FAIL("fork error");
417 socket_server ss("./socket");
419 time_t t0 = time(NULL);
422 while (time(NULL) < t0 + 10 )
424 ss.fill_buffer(1000000);
429 if(ss.get_packet(data,cid))
431 server_connection* con=ss.get_connection(cid);
438 con->write(string().insert(0,100,'X'));
439 send_raw_socket("aaaab",&ss,cid);
445 std::cerr << "exception in child. ignoring\n";
448 // don't call atexit and stuff
455 // don't kill us on broken pipe
456 signal(SIGPIPE, SIG_IGN);
458 // wait till server is up
460 socket_client_connection sc("./socket");
464 // retrieve packets for 3 seconds
465 time_t t0 = time(NULL);
468 while (time(NULL) < t0 + 3 )
469 sc.fill_buffer(1000000);
471 // we now should have one complete packet and some stuff in the buffer
476 CPPUNIT_ASSERT_EQUAL_MESSAGE("no incomplete packet",true,(sc.peek_packet(data))>0);
480 CPPUNIT_ASSERT_EQUAL_MESSAGE("incomplete packet not removed",0,(int)sc.peek_packet(data));
485 void reconnect_buffer_no_incomplete2()
487 switch(child_pid=fork())
491 CPPUNIT_FAIL("fork error");
499 socket_server ss("./socket");
501 time_t t0 = time(NULL);
504 while (time(NULL) < t0 + 10 )
506 ss.fill_buffer(1000000);
511 if(ss.get_packet(data,cid))
513 server_connection* con=ss.get_connection(cid);
520 con->write(string().insert(0,100,'X'));
522 string blob=string().insert(0,100,'Y');
524 // one byte will be missing...
525 int size=blob.size()+1;
526 char sizetransfer[sizeof(int)+1];
527 memcpy(sizetransfer,(void*)&size,sizeof(int));
528 sizetransfer[sizeof(int)+1]=0;
530 string packet=string(sizetransfer)+blob;
532 send_raw_socket(packet,&ss,cid);
538 std::cerr << "exception in child. ignoring\n";
541 // don't call atexit and stuff
548 // don't kill us on broken pipe
549 signal(SIGPIPE, SIG_IGN);
551 // wait till server is up
553 socket_client_connection sc("./socket");
557 // retrieve packets for 3 seconds
558 time_t t0 = time(NULL);
561 while (time(NULL) < t0 + 3 )
562 sc.fill_buffer(1000000);
564 // we now should have one complete packet and some stuff in the buffer
570 CPPUNIT_ASSERT_EQUAL_MESSAGE("packet not there",true,sc.get_packet(data));
571 CPPUNIT_ASSERT_EQUAL_MESSAGE("data incorrect",string().insert(0,100,'X'),data);
573 CPPUNIT_ASSERT_EQUAL_MESSAGE("incomplete packet not removed",0,(int)sc.peek_packet(data));
580 CPPUNIT_TEST_SUITE_REGISTRATION(test_reconnect);