X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=blobdiff_plain;f=test%2Freconnect.cpp;fp=test%2Freconnect.cpp;h=09c5f5f084c1051221d1ca43ea9c180e070f7970;hp=0000000000000000000000000000000000000000;hb=af84dfb53a739a0c8c343d9172f1847fa908906d;hpb=a64066eb0e456c92c4c06959616443e531d4b39d diff --git a/test/reconnect.cpp b/test/reconnect.cpp new file mode 100644 index 0000000..09c5f5f --- /dev/null +++ b/test/reconnect.cpp @@ -0,0 +1,549 @@ +/*************************************************************************** + * Copyright (C) 2004 by Intra2net AG * + * info@intra2net.com * + * * + ***************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +using namespace std; +using namespace libt2n; +using namespace CppUnit; + +// this is an evil hack to get access to real_write, don't ever do this in an app!!! +class real_write_connection: public socket_server_connection +{ + public: + void real_write(const std::string& data) + { socket_write(data); } +}; + +class test_reconnect : public TestFixture +{ + CPPUNIT_TEST_SUITE(test_reconnect); + + CPPUNIT_TEST(simple_reconnect); + CPPUNIT_TEST(reconnect_with_close); + CPPUNIT_TEST(reconnect_buffer_complete); + CPPUNIT_TEST(reconnect_buffer_several_complete); + CPPUNIT_TEST(reconnect_buffer_no_incomplete1); + CPPUNIT_TEST(reconnect_buffer_no_incomplete2); + + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp() + { } + + void tearDown() + { } + + void send_raw_socket(string hello_string, socket_server* ss, int conn_id) + { + socket_server_connection *ssc=dynamic_cast(ss->get_connection(conn_id)); + + // this is an evil hack to get access to real_write, don't ever do this in an app!!! + real_write_connection *rwc=(real_write_connection*)ssc; + rwc->real_write(hello_string); + } + + void simple_reconnect() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + time_t t0 = time(NULL); + + // max 10 sec + while (time(NULL) < t0 + 10 ) + { + ss.fill_buffer(1000000); + + string data; + unsigned int cid; + + if(ss.get_packet(data,cid)) + { + server_connection* con=ss.get_connection(cid); + + if (data=="QUIT") + break; + + if (data=="x") + con->write(string().insert(0,100,'X')); + else + con->write(string().insert(0,100,'Y')); + } + } + + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + sc.write("abc"); + + string data; + + while (!sc.get_packet(data)) + sc.fill_buffer(1000000); + + sc.reconnect(); + + sc.write("x"); + + while (!sc.get_packet(data)) + sc.fill_buffer(1000000); + + CPPUNIT_ASSERT_EQUAL(string().insert(0,100,'X'),data); + } + } + } + + void reconnect_with_close() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + time_t t0 = time(NULL); + + // max 10 sec + while (time(NULL) < t0 + 10 ) + { + ss.fill_buffer(1000000); + + string data; + unsigned int cid; + + if(ss.get_packet(data,cid)) + { + server_connection* con=ss.get_connection(cid); + + if (data=="QUIT") + break; + + if (data=="x") + con->write(string().insert(0,100,'X')); + else + con->write(string().insert(0,100,'Y')); + } + } + + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + sc.write("abc"); + + string data; + + while (!sc.get_packet(data)) + sc.fill_buffer(1000000); + + sc.close(); + + // empty buffer + sc.get_packet(data); + + sc.reconnect(); + + sc.write("x"); + + while (!sc.get_packet(data)) + sc.fill_buffer(1000000); + + CPPUNIT_ASSERT_EQUAL(string().insert(0,100,'X'),data); + } + } + } + + void reconnect_buffer_complete() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + time_t t0 = time(NULL); + + // max 10 sec + while (time(NULL) < t0 + 10 ) + { + ss.fill_buffer(1000000); + + string data; + unsigned int cid; + + if(ss.get_packet(data,cid)) + { + server_connection* con=ss.get_connection(cid); + + if (data=="QUIT") + break; + + if (data=="x") + con->write(string().insert(0,100,'X')); + } + } + + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + sc.write("x"); + + string data; + + while (!sc.packet_available()) + sc.fill_buffer(1000000); + + sc.reconnect(); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("packet not there",true,sc.get_packet(data)); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("data incorrect",string().insert(0,100,'X'),data); + } + } + } + + void reconnect_buffer_several_complete() + { + pid_t pid; + + const int packets=3; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + time_t t0 = time(NULL); + + // max 10 sec + while (time(NULL) < t0 + 10 ) + { + ss.fill_buffer(1000000); + + string data; + unsigned int cid; + + if(ss.get_packet(data,cid)) + { + server_connection* con=ss.get_connection(cid); + + if (data=="QUIT") + break; + + if (data=="x") + { + for (int i=0; iwrite(string().insert(0,100,'X')); + } + } + } + + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + sc.write("x"); + + // retrieve packets for 3 seconds + time_t t0 = time(NULL); + + // max 3 sec + while (time(NULL) < t0 + 3 ) + sc.fill_buffer(1000000); + + // we now should have packets complete packets in the buffer + + sc.reconnect(); + + // are these packets still there? + + for (int i=0; i < packets; i++) + { + string data; + + ostringstream os; + os << "packet " << i << " not there"; + + CPPUNIT_ASSERT_EQUAL_MESSAGE(os.str(),true,sc.get_packet(data)); + + os.str(""); + os << "packet " << i << " incorrect"; + + CPPUNIT_ASSERT_EQUAL_MESSAGE(os.str(),string().insert(0,100,'X'),data); + } + } + } + } + + void reconnect_buffer_no_incomplete1() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + time_t t0 = time(NULL); + + // max 10 sec + while (time(NULL) < t0 + 10 ) + { + ss.fill_buffer(1000000); + + string data; + unsigned int cid; + + if(ss.get_packet(data,cid)) + { + server_connection* con=ss.get_connection(cid); + + if (data=="QUIT") + break; + + if (data=="x") + { + con->write(string().insert(0,100,'X')); + send_raw_socket("aaaab",&ss,cid); + } + } + } + + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + sc.write("x"); + + // retrieve packets for 3 seconds + time_t t0 = time(NULL); + + // max 3 sec + while (time(NULL) < t0 + 3 ) + sc.fill_buffer(1000000); + + // we now should have one complete packet and some stuff in the buffer + + string data; + sc.get_packet(data); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("no incomplete packet",true,(sc.peek_packet(data))>0); + + sc.reconnect(); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("incomplete packet not removed",0,(int)sc.peek_packet(data)); + } + } + } + + void reconnect_buffer_no_incomplete2() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + time_t t0 = time(NULL); + + // max 10 sec + while (time(NULL) < t0 + 10 ) + { + ss.fill_buffer(1000000); + + string data; + unsigned int cid; + + if(ss.get_packet(data,cid)) + { + server_connection* con=ss.get_connection(cid); + + if (data=="QUIT") + break; + + if (data=="x") + { + con->write(string().insert(0,100,'X')); + + string blob=string().insert(0,100,'Y'); + + // one byte will be missing... + int size=blob.size()+1; + char sizetransfer[sizeof(int)+1]; + memcpy(sizetransfer,(void*)&size,sizeof(int)); + sizetransfer[sizeof(int)+1]=0; + + string packet=string(sizetransfer)+blob; + + send_raw_socket(packet,&ss,cid); + } + } + } + + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + sc.write("x"); + + // retrieve packets for 3 seconds + time_t t0 = time(NULL); + + // max 3 sec + while (time(NULL) < t0 + 3 ) + sc.fill_buffer(1000000); + + // we now should have one complete packet and some stuff in the buffer + + sc.reconnect(); + + string data; + + CPPUNIT_ASSERT_EQUAL_MESSAGE("packet not there",true,sc.get_packet(data)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("data incorrect",string().insert(0,100,'X'),data); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("incomplete packet not removed",0,(int)sc.peek_packet(data)); + } + } + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(test_reconnect);