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(); }
374 BOOST_CHECK_EQUAL(string("timeout exceeded"),errormsg);
379 BOOST_AUTO_TEST_CASE(CommandSlowResponse)
381 switch(child_pid=fork())
385 BOOST_FAIL("fork error");
393 socket_server ss("./socket");
396 hello << "T2Nv" << PROTOCOL_VERSION << ';';
397 int byteordercheck=1;
398 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
401 ss.add_callback(new_connection,bind(&test_timeout::CommandSlowResponse::send_hello, boost::ref(*this), hello.str(),&ss, _1));
404 for (int i=0; i < 10; i++)
406 ss.fill_buffer(1000000);
411 if(ss.get_packet(data,cid))
413 // create a valid packet & send
414 string response="abcdefghijklmnopqrstuvwxyz";
415 packet_size_indicator psize=htonl(response.size());
416 std::string send_data(response);
417 send_data.insert(0,(char*)&psize,sizeof(packet_size_indicator));
418 send_slow_raw_socket(send_data,&ss,cid);
423 std::cerr << "exception in child. ignoring\n";
426 // don't call atexit and stuff
435 // wait till server is up
437 socket_client_connection sc("./socket");
439 command_client cc(&sc,1000000,1000000);
446 cc.send_command(new testfunc2_cmd("hello"),rc);
448 catch(t2n_transfer_error &e)
449 { errormsg=e.what(); }
451 BOOST_CHECK_EQUAL(string("timeout exceeded"),errormsg);
456 BOOST_AUTO_TEST_CASE(DisconnectOnWrite)
458 switch(child_pid=fork())
462 BOOST_FAIL("fork error");
470 socket_server ss("./socket");
472 // bail out as soon as we get something
476 std::cerr << "exception in child. ignoring\n";
479 // don't call atexit and stuff
488 // don't kill us on broken pipe
489 signal(SIGPIPE, SIG_IGN);
491 // wait till server is up
493 socket_client_connection sc("./socket");
497 string huge(5000000,'x');
503 catch(t2n_transfer_error &e)
504 { errormsg=e.what(); }
506 BOOST_CHECK_EQUAL(string("write() returned Broken pipe"),errormsg);
511 BOOST_AUTO_TEST_CASE(WriteTwice)
513 switch(child_pid=fork())
517 BOOST_FAIL("fork error");
525 socket_server ss("./socket");
527 // bail out as soon as we get something
532 std::cerr << "exception in child. ignoring\n";
535 // don't call atexit and stuff
544 // don't kill us on broken pipe
545 signal(SIGPIPE, SIG_IGN);
547 // wait till server is up
549 socket_client_connection sc("./socket");
553 sc.write("somedata");
557 // server should disconnect now
560 sc.write("other data(2)");
562 sc.write("other data(3)");
564 catch(t2n_transfer_error &e)
565 { errormsg=e.what(); }
567 BOOST_CHECK_EQUAL(string("write() returned Broken pipe"),errormsg);
572 BOOST_AUTO_TEST_CASE(DisconnectOnRead)
576 switch(child_pid=fork())
580 BOOST_FAIL("fork error");
588 // wait till server is up
591 socket_client_connection sc("./socket");
593 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
594 real_write_client_connection *rwc=(real_write_client_connection*)≻
595 rwc->real_write(string(10000,'x'));
598 std::cerr << "exception in child. ignoring\n";
601 // don't call atexit and stuff
608 // don't kill us on broken pipe
609 signal(SIGPIPE, SIG_IGN);
611 socket_server ss("./socket");
613 time_t t0 = time(NULL);
616 while (time(NULL) < t0 + 5 )
618 ss.fill_buffer(1000000);
624 // are we still alive and able to process data?
630 BOOST_FAIL("fork error");
638 socket_client_connection *sc=new socket_client_connection("./socket");
639 sc->write(string(10000,'x'));
640 // socket is closed regularly
644 std::cerr << "exception in child. ignoring\n";
647 // don't run regular cleanup, otherwise cppunit stuff gets called
659 while (time(NULL) < t0 + 10 )
661 ss.fill_buffer(1000000);
663 if (ss.get_packet(received))
667 BOOST_CHECK_EQUAL(string(10000,'x'),received);
675 BOOST_AUTO_TEST_CASE(BreakAccept)
679 switch(child_pid=fork())
683 BOOST_FAIL("fork error");
691 // wait till server is really up and waiting
694 // connect with very tight timeout and only 1 retry
695 socket_client_connection sc("./socket",50,1);
698 std::cerr << "exception in child. ignoring\n";
701 // don't call atexit and stuff
708 // don't kill us on broken pipe
709 signal(SIGPIPE, SIG_IGN);
711 socket_server ss("./socket");
713 // server is "working" while client wants to connect
716 time_t t0 = time(NULL);
719 while (time(NULL) < t0 + 5 )
721 ss.fill_buffer(1000000);
727 // are we still alive and able to process data?
733 BOOST_FAIL("fork error");
741 socket_client_connection *sc=new socket_client_connection("./socket");
742 sc->write(string(10000,'x'));
744 // socket is closed regularly
747 std::cerr << "exception in child. ignoring\n";
750 // don't run regular cleanup, otherwise cppunit stuff gets called
762 while (time(NULL) < t0 + 10 )
764 ss.fill_buffer(1000000);
766 if (ss.get_packet(received))
770 BOOST_CHECK_EQUAL(string(10000,'x'),received);
778 BOOST_AUTO_TEST_SUITE_END()