From: Gerd v. Egidy Date: Sat, 28 Oct 2006 23:32:17 +0000 (+0000) Subject: libt2n: (gerd) small fixes, hello unit tests X-Git-Tag: v0.2~134 X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=commitdiff_plain;h=04d86ba4ad4f14ab08f38804e772ec46a8ac92b0 libt2n: (gerd) small fixes, hello unit tests --- diff --git a/src/command_client.cpp b/src/command_client.cpp index c0e863c..41c74de 100644 --- a/src/command_client.cpp +++ b/src/command_client.cpp @@ -52,7 +52,7 @@ void command_client::read_hello() { // TODO: fix timeout string resultpacket; - while(!c.get_packet(resultpacket)) + while(!c.get_packet(resultpacket) && !c.is_closed()) c.fill_buffer(); istringstream hello(resultpacket); diff --git a/src/server.cpp b/src/server.cpp index 6bc1cba..331bfc3 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -18,12 +18,12 @@ ***************************************************************************/ #include +#include #include #include "server.hxx" #include "log.hxx" -#include "t2n_exception.hxx" namespace libt2n { @@ -96,7 +96,7 @@ void server_connection::reset_timeout() void server_connection::add_callback(callback_event_type event, const boost::function& func) { if (event == new_connection) - throw t2n_parameter_error("new_connection callback not allowed for server_connections"); + throw std::logic_error("new_connection callback not allowed for server_connections"); callbacks[event].push_back(func); } diff --git a/src/t2n_exception.cpp b/src/t2n_exception.cpp index 0b90f87..1aae5c4 100644 --- a/src/t2n_exception.cpp +++ b/src/t2n_exception.cpp @@ -33,7 +33,6 @@ BOOST_CLASS_EXPORT(libt2n::t2n_server_error) BOOST_CLASS_EXPORT(libt2n::t2n_transfer_error) BOOST_CLASS_EXPORT(libt2n::t2n_version_mismatch) BOOST_CLASS_EXPORT(libt2n::t2n_command_error) -BOOST_CLASS_EXPORT(libt2n::t2n_parameter_error) BOOST_CLASS_EXPORT(libt2n::t2n_serialization_error) BOOST_CLASS_EXPORT(libt2n::t2n_runtime_error) @@ -84,12 +83,6 @@ void t2n_command_error::serialize(Archive & ar, const unsigned int version) } template -void t2n_parameter_error::serialize(Archive & ar, const unsigned int version) -{ - ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(t2n_exception); -} - -template void t2n_serialization_error::serialize(Archive & ar, const unsigned int version) { ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(t2n_exception); diff --git a/src/t2n_exception.hxx b/src/t2n_exception.hxx index a494c86..4ce11aa 100644 --- a/src/t2n_exception.hxx +++ b/src/t2n_exception.hxx @@ -206,29 +206,6 @@ class t2n_command_error : public t2n_exception { throw *this; } }; -/// illegal libt2n option set -class t2n_parameter_error : public t2n_exception -{ - private: - friend class boost::serialization::access; - template - void serialize(Archive & ar, const unsigned int version); - - public: - t2n_parameter_error(const std::string& _message) - : t2n_exception(_message) - { } - - t2n_parameter_error() - { } - - t2n_exception* clone() const - { return new t2n_parameter_error(*this); } - - void do_throw() - { throw *this; } -}; - /// error serializing or deserializing a libt2n command packet class t2n_serialization_error : public t2n_exception { diff --git a/test/Makefile.am b/test/Makefile.am index 6b3755c..85b34b2 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,6 +4,6 @@ check_PROGRAMS = test test_LDADD = $(top_builddir)/src/libt2n.la @BOOST_SERIALIZATION_LIB@ \ @BOOST_LDFLAGS@ @CPPUNIT_LIBS@ -test_SOURCES = test.cpp comm.cpp simplecmd.cpp callback.cpp +test_SOURCES = test.cpp comm.cpp simplecmd.cpp callback.cpp hello.cpp TESTS = test diff --git a/test/hello.cpp b/test/hello.cpp new file mode 100644 index 0000000..a0cc532 --- /dev/null +++ b/test/hello.cpp @@ -0,0 +1,412 @@ +/*************************************************************************** + * Copyright (C) 2004 by Intra2net AG * + * info@intra2net.com * + * * + ***************************************************************************/ + +#include +#include +#include +#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_hello : public TestFixture +{ + CPPUNIT_TEST_SUITE(test_hello); + + CPPUNIT_TEST(HelloOk); + CPPUNIT_TEST(BadTag); + CPPUNIT_TEST(BadVersion); + CPPUNIT_TEST(SeparatorMissing); + CPPUNIT_TEST(WrongByteOrder); + CPPUNIT_TEST(OtherServer); + + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp() + { } + + void tearDown() + { } + + void send_hello(string hello_string, socket_server* ss, int conn_id) + { + server_connection *sc=ss->get_connection(conn_id); + sc->write(hello_string); + } + + 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 HelloOk() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + ostringstream hello; + hello << "T2Nv" << PROTOCOL_VERSION << ';'; + int byteordercheck=1; + hello.write((char*)&byteordercheck,sizeof(byteordercheck)); + hello << ';'; + + ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1)); + + // max 10 sec + for (int i=0; i < 10; i++) + ss.fill_buffer(1000000); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + string data; + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + command_client cc(sc); + } + } + } + + void BadTag() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + ostringstream hello; + hello << "XYZ 123"; + + ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1)); + + // max 10 sec + for (int i=0; i < 10; i++) + ss.fill_buffer(1000000); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + string data; + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + string errormsg; + + try + { + command_client cc(sc); + } + catch(t2n_version_mismatch &e) + { errormsg=e.what(); } + catch(...) + { throw; } + + CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg); + } + } + } + + void BadVersion() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + ostringstream hello; + // lets hope we don't ever get near such a version number... + hello << "T2Nv" << 4982271 << ';'; + int byteordercheck=1; + hello.write((char*)&byteordercheck,sizeof(byteordercheck)); + hello << ';'; + + ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1)); + + // max 10 sec + for (int i=0; i < 10; i++) + ss.fill_buffer(1000000); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + string data; + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + string errormsg; + + try + { + command_client cc(sc); + } + catch(t2n_version_mismatch &e) + { errormsg=e.what(); } + catch(...) + { throw; } + + CPPUNIT_ASSERT_EQUAL(string("not compatible with the server protocol version"),errormsg); + } + } + } + + void SeparatorMissing() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + ostringstream hello; + hello << "T2Nv" << PROTOCOL_VERSION; + int byteordercheck=1; + hello.write((char*)&byteordercheck,sizeof(byteordercheck)); + hello << ';'; + + ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1)); + + // max 10 sec + for (int i=0; i < 10; i++) + ss.fill_buffer(1000000); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + string data; + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + string errormsg; + + try + { + command_client cc(sc); + } + catch(t2n_version_mismatch &e) + { errormsg=e.what(); } + catch(...) + { throw; } + + CPPUNIT_ASSERT_EQUAL(string("illegal hello received (1. ;)"),errormsg); + } + } + } + + void WrongByteOrder() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + ostringstream hello; + hello << "T2Nv" << PROTOCOL_VERSION << ';'; + int byteordercheck=1; + int dst; + char* si=(char*)&byteordercheck; + char* di=(char*)&dst; + + di[0]=si[3]; + di[1]=si[2]; + di[2]=si[1]; + di[3]=si[0]; + + hello.write((char*)&dst,sizeof(dst)); + hello << ';'; + + ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1)); + + // max 10 sec + for (int i=0; i < 10; i++) + ss.fill_buffer(1000000); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + string data; + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + string errormsg; + + try + { + command_client cc(sc); + } + catch(t2n_version_mismatch &e) + { errormsg=e.what(); } + catch(...) + { throw; } + + CPPUNIT_ASSERT_EQUAL(string("host byte order not matching"),errormsg); + } + } + } + + void OtherServer() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + + ostringstream hello; + // hmm, we got the wrong socket + hello << "* OK intradev.net.lan Cyrus IMAP4 v2.2.13 server ready"; + + ss.add_callback(new_connection,bind(&test_hello::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1)); + + // max 3 sec + for (int i=0; i < 3; i++) + ss.fill_buffer(1000000); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + string data; + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + string errormsg; + + try + { + command_client cc(sc); + } + catch(t2n_version_mismatch &e) + { errormsg=e.what(); } + catch(...) + { throw; } + + CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg); + } + } + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(test_hello);