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>
33 #include <boost/bind.hpp>
35 #define BOOST_TEST_DYN_LINK
36 #include <boost/test/unit_test.hpp>
38 #include <boost/archive/binary_oarchive.hpp>
39 #include <boost/archive/binary_iarchive.hpp>
40 #include <boost/archive/xml_oarchive.hpp>
41 #include <boost/archive/xml_iarchive.hpp>
42 #include <boost/serialization/serialization.hpp>
44 #include <container.hxx>
45 #include <socket_client.hxx>
46 #include <socket_server.hxx>
47 #include <command_client.hxx>
48 #include <command_server.hxx>
50 #include "test_fixtures.hxx"
57 using namespace libt2n;
59 string testfunc2(const string& str)
62 throw libt2n::t2n_runtime_error("throw me around");
64 ret+=", testfunc() was here";
68 class testfunc2_res : public libt2n::result
73 friend class boost::serialization::access;
74 template<class Archive>
75 void serialize(Archive & ar, const unsigned int version)
77 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
78 ar & BOOST_SERIALIZATION_NVP(res);
85 testfunc2_res(const string& str)
97 class testfunc2_cmd : public libt2n::command
102 friend class boost::serialization::access;
103 template<class Archive>
104 void serialize(Archive & ar, const unsigned int version)
106 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
107 ar & BOOST_SERIALIZATION_NVP(param);
114 testfunc2_cmd(const string& str)
119 libt2n::result* operator()()
121 return new testfunc2_res(testfunc2(param));
125 #include <boost/serialization/export.hpp>
127 BOOST_CLASS_EXPORT(testfunc2_cmd)
128 BOOST_CLASS_EXPORT(testfunc2_res)
130 class test_timeoutFixture : public KillChildOnShutdownFixture
133 typedef uint32_t packet_size_indicator;
135 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
136 class real_write_client_connection: public socket_client_connection
139 void real_write(const std::string& data)
140 { socket_write(data); }
143 void send_slow_raw_socket(string data, socket_server* ss, unsigned int conn_id)
145 socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id));
147 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
148 real_write_connection *rwc=(real_write_connection*)ssc;
150 // we write one char each 0.2 sec
151 for (int pos=0; pos < data.size(); pos++)
155 rwc->real_write(onebyte);
161 BOOST_FIXTURE_TEST_SUITE(test_timeout, test_timeoutFixture)
163 BOOST_AUTO_TEST_CASE(ConnectTimeout)
165 switch(child_pid=fork())
169 BOOST_FAIL("fork error");
177 socket_server ss("./socket");
180 std::cerr << "exception in child. ignoring\n";
183 // don't call atexit and stuff
192 // wait till server is up
197 socket_client_connection sc("./socket");
199 BOOST_CHECK_MESSAGE(sc.connection::is_closed() == true, "connection not closed");
201 BOOST_CHECK_MESSAGE(sc.get_last_error_msg() == string("no more retries left after connect error"), "wrong errormessage");
206 BOOST_AUTO_TEST_CASE(HelloTimeoutNothing)
208 switch(child_pid=fork())
212 BOOST_FAIL("fork error");
220 socket_server ss("./socket");
223 for (int i=0; i < 10; i++)
224 ss.fill_buffer(1000000);
227 std::cerr << "exception in child. ignoring\n";
230 // don't call atexit and stuff
239 // wait till server is up
241 socket_client_connection sc("./socket");
242 command_client cc(&sc,1000000,1000000);
244 t2n_exception* ep=cc.get_constuctor_exception();
250 BOOST_CHECK_EQUAL(string("timeout exceeded"),errormsg);
255 BOOST_AUTO_TEST_CASE(HelloTimeoutSlowData)
257 switch(child_pid=fork())
261 BOOST_FAIL("fork error");
269 socket_server ss("./socket");
271 // create a valid packet
273 hello << "T2Nv" << PROTOCOL_VERSION << ';';
274 int byteordercheck=1;
275 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
278 packet_size_indicator psize=htonl(hello.str().size());
279 std::string send_data(hello.str());
280 send_data.insert(0,(char*)&psize,sizeof(packet_size_indicator));
282 ss.add_callback(new_connection,bind(&test_timeout::HelloTimeoutSlowData::send_slow_raw_socket, boost::ref(*this), send_data,&ss, _1));
285 for (int i=0; i < 10; i++)
286 ss.fill_buffer(1000000);
289 std::cerr << "exception in child. ignoring\n";
292 // don't call atexit and stuff
301 // wait till server is up
303 socket_client_connection sc("./socket");
304 command_client cc(&sc,1000000,1000000);
306 t2n_exception* ep=cc.get_constuctor_exception();
312 BOOST_CHECK_EQUAL(string("timeout exceeded"),errormsg);
317 BOOST_AUTO_TEST_CASE(CommandTimeout)
319 switch(child_pid=fork())
323 BOOST_FAIL("fork error");
331 socket_server ss("./socket");
334 hello << "T2Nv" << PROTOCOL_VERSION << ';';
335 int byteordercheck=1;
336 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
339 ss.add_callback(new_connection,bind(&test_timeout::CommandTimeout::send_hello, boost::ref(*this), hello.str(),&ss, _1));
342 for (int i=0; i < 10; i++)
343 ss.fill_buffer(1000000);
346 std::cerr << "exception in child. ignoring\n";
349 // don't call atexit and stuff
358 // wait till server is up
360 socket_client_connection sc("./socket");
362 command_client cc(&sc,1000000,1000000);
369 cc.send_command(new testfunc2_cmd("hello"),rc);
371 catch(t2n_transfer_error &e)
372 { errormsg=e.what(); }
376 BOOST_CHECK_EQUAL(string("timeout exceeded"),errormsg);
381 BOOST_AUTO_TEST_CASE(CommandSlowResponse)
383 switch(child_pid=fork())
387 BOOST_FAIL("fork error");
395 socket_server ss("./socket");
398 hello << "T2Nv" << PROTOCOL_VERSION << ';';
399 int byteordercheck=1;
400 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
403 ss.add_callback(new_connection,bind(&test_timeout::CommandSlowResponse::send_hello, boost::ref(*this), hello.str(),&ss, _1));
406 for (int i=0; i < 10; i++)
408 ss.fill_buffer(1000000);
413 if(ss.get_packet(data,cid))
415 // create a valid packet & send
416 string response="abcdefghijklmnopqrstuvwxyz";
417 packet_size_indicator psize=htonl(response.size());
418 std::string send_data(response);
419 send_data.insert(0,(char*)&psize,sizeof(packet_size_indicator));
420 send_slow_raw_socket(send_data,&ss,cid);
425 std::cerr << "exception in child. ignoring\n";
428 // don't call atexit and stuff
437 // wait till server is up
439 socket_client_connection sc("./socket");
441 command_client cc(&sc,1000000,1000000);
448 cc.send_command(new testfunc2_cmd("hello"),rc);
450 catch(t2n_transfer_error &e)
451 { errormsg=e.what(); }
455 BOOST_CHECK_EQUAL(string("timeout exceeded"),errormsg);
460 BOOST_AUTO_TEST_CASE(DisconnectOnWrite)
462 switch(child_pid=fork())
466 BOOST_FAIL("fork error");
474 socket_server ss("./socket");
476 // bail out as soon as we get something
480 std::cerr << "exception in child. ignoring\n";
483 // don't call atexit and stuff
492 // don't kill us on broken pipe
493 signal(SIGPIPE, SIG_IGN);
495 // wait till server is up
497 socket_client_connection sc("./socket");
501 string huge(5000000,'x');
507 catch(t2n_transfer_error &e)
508 { errormsg=e.what(); }
512 BOOST_CHECK_EQUAL(string("write() returned Broken pipe"),errormsg);
517 BOOST_AUTO_TEST_CASE(WriteTwice)
519 switch(child_pid=fork())
523 BOOST_FAIL("fork error");
531 socket_server ss("./socket");
533 // bail out as soon as we get something
538 std::cerr << "exception in child. ignoring\n";
541 // don't call atexit and stuff
550 // don't kill us on broken pipe
551 signal(SIGPIPE, SIG_IGN);
553 // wait till server is up
555 socket_client_connection sc("./socket");
559 sc.write("somedata");
563 // server should disconnect now
566 sc.write("other data(2)");
568 sc.write("other data(3)");
570 catch(t2n_transfer_error &e)
571 { errormsg=e.what(); }
575 BOOST_CHECK_EQUAL(string("write() returned Broken pipe"),errormsg);
580 BOOST_AUTO_TEST_CASE(DisconnectOnRead)
584 switch(child_pid=fork())
588 BOOST_FAIL("fork error");
596 // wait till server is up
599 socket_client_connection sc("./socket");
601 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
602 real_write_client_connection *rwc=(real_write_client_connection*)≻
603 rwc->real_write(string(10000,'x'));
606 std::cerr << "exception in child. ignoring\n";
609 // don't call atexit and stuff
616 // don't kill us on broken pipe
617 signal(SIGPIPE, SIG_IGN);
619 socket_server ss("./socket");
621 time_t t0 = time(NULL);
624 while (time(NULL) < t0 + 5 )
626 ss.fill_buffer(1000000);
632 // are we still alive and able to process data?
638 BOOST_FAIL("fork error");
646 socket_client_connection *sc=new socket_client_connection("./socket");
647 sc->write(string(10000,'x'));
648 // socket is closed regularly
652 std::cerr << "exception in child. ignoring\n";
655 // don't run regular cleanup, otherwise cppunit stuff gets called
667 while (time(NULL) < t0 + 10 )
669 ss.fill_buffer(1000000);
671 if (ss.get_packet(received))
675 BOOST_CHECK_EQUAL(string(10000,'x'),received);
683 BOOST_AUTO_TEST_CASE(BreakAccept)
687 switch(child_pid=fork())
691 BOOST_FAIL("fork error");
699 // wait till server is really up and waiting
702 // connect with very tight timeout and only 1 retry
703 socket_client_connection sc("./socket",50,1);
706 std::cerr << "exception in child. ignoring\n";
709 // don't call atexit and stuff
716 // don't kill us on broken pipe
717 signal(SIGPIPE, SIG_IGN);
719 socket_server ss("./socket");
721 // server is "working" while client wants to connect
724 time_t t0 = time(NULL);
727 while (time(NULL) < t0 + 5 )
729 ss.fill_buffer(1000000);
735 // are we still alive and able to process data?
741 BOOST_FAIL("fork error");
749 socket_client_connection *sc=new socket_client_connection("./socket");
750 sc->write(string(10000,'x'));
752 // socket is closed regularly
755 std::cerr << "exception in child. ignoring\n";
758 // don't run regular cleanup, otherwise cppunit stuff gets called
770 while (time(NULL) < t0 + 10 )
772 ss.fill_buffer(1000000);
774 if (ss.get_packet(received))
778 BOOST_CHECK_EQUAL(string(10000,'x'),received);
786 BOOST_AUTO_TEST_SUITE_END()