From 07e98688a1a8c3e915ce923f79261a88251a9edd Mon Sep 17 00:00:00 2001 From: Gerd v. Egidy Date: Wed, 11 Oct 2006 14:04:18 +0000 Subject: [PATCH] libt2n: (gerd) fixes & real unit tests --- Makefile.am | 6 ++ configure.in | 3 + libt2n.kdevelop | 7 ++- src/connection.hxx | 4 +- src/socket_client.hxx | 4 +- src/socket_handler.cpp | 6 +- src/socket_server.cpp | 2 +- src/socket_server.hxx | 4 +- test/Makefile.am | 13 ++-- test/client.cpp | 34 ---------- test/comm.cpp | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ test/server.cpp | 41 ------------ test/test.cpp | 84 +++++++++++++++++++++++++ 13 files changed, 275 insertions(+), 92 deletions(-) delete mode 100644 test/client.cpp create mode 100644 test/comm.cpp delete mode 100644 test/server.cpp create mode 100644 test/test.cpp diff --git a/Makefile.am b/Makefile.am index 1154b0a..f9360eb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,3 +9,9 @@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libt2n.pc EXRA_DIST = COPYING COPYING.LIB + +if AUTOCHECK +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + $(MAKE) $(AM_MAKEFLAGS) check +endif diff --git a/configure.in b/configure.in index 72e3e45..b7d9353 100644 --- a/configure.in +++ b/configure.in @@ -11,4 +11,7 @@ dnl check for doxygen AC_PATH_PROG(DOXYGEN, doxygen, $PATH) AM_CONDITIONAL(HAVE_DOXYGEN, test -n $DOXYGEN); +AM_CONDITIONAL(AUTOCHECK, test "$enable_autocheck" = yes) +AM_PATH_CPPUNIT(1.8.0) + AC_OUTPUT(Makefile doc/Doxyfile doc/Makefile src/Makefile libt2n.pc libt2n.spec test/Makefile) diff --git a/libt2n.kdevelop b/libt2n.kdevelop index 0faf98a..7024d3f 100644 --- a/libt2n.kdevelop +++ b/libt2n.kdevelop @@ -14,13 +14,18 @@ - src/libt2n.la + test/server debug src/libt2n true executable + + + + + diff --git a/src/connection.hxx b/src/connection.hxx index 9142c52..94506e2 100644 --- a/src/connection.hxx +++ b/src/connection.hxx @@ -42,7 +42,7 @@ class connection virtual void real_write(const std::string& data)=0; public: - ~connection() + virtual ~connection() { close(); } bool is_closed() @@ -51,7 +51,7 @@ class connection virtual void close() { closed=true; } - virtual void fill_buffer(long long usec_timeout=-1)=0; + virtual bool fill_buffer(long long usec_timeout=-1)=0; bool get_packet(std::string& data); bool packet_available() { return bytes_available(); } diff --git a/src/socket_client.hxx b/src/socket_client.hxx index 198e1a7..a17ec88 100644 --- a/src/socket_client.hxx +++ b/src/socket_client.hxx @@ -45,8 +45,8 @@ class socket_client_connection : public client_connection, public socket_handler socket_client_connection(const std::string& _server, int _port, int _max_retries=max_retries_default); socket_client_connection(const std::string& _path, int _max_retries=max_retries_default); - void fill_buffer(long long usec_timeout=-1) - { socket_handler::fill_buffer(buffer,usec_timeout); } + bool fill_buffer(long long usec_timeout=-1) + { return socket_handler::fill_buffer(buffer,usec_timeout); } void close(); }; diff --git a/src/socket_handler.cpp b/src/socket_handler.cpp index 6f9df07..f2ddcb6 100644 --- a/src/socket_handler.cpp +++ b/src/socket_handler.cpp @@ -149,8 +149,8 @@ bool socket_handler::data_waiting(long long usec_timeout) bool socket_handler::fill_buffer(std::string& buffer, long long usec_timeout) { - // fast path for timeout==-1 - if (usec_timeout==-1 || data_waiting(usec_timeout)) + // fast path for timeout==0 + if (usec_timeout==0 || data_waiting(usec_timeout)) return fill_buffer(buffer); else return false; @@ -192,7 +192,7 @@ bool socket_handler::fill_buffer(std::string& buffer) buffer.assign(socket_buffer,nbytes); // more data waiting -> recurse - if (data_waiting()) + if (data_waiting(0)) fill_buffer(buffer); if (nbytes > 0) diff --git a/src/socket_server.cpp b/src/socket_server.cpp index 372960a..cbaaff6 100644 --- a/src/socket_server.cpp +++ b/src/socket_server.cpp @@ -233,7 +233,7 @@ void socket_server::fill_connection_buffers() std::map::iterator ie=connections.end(); for(std::map::iterator i=connections.begin(); i != ie; i++) if (!i->second->server_connection::is_closed()) - i->second->fill_buffer(); + i->second->fill_buffer(0); } void socket_server::remove_connection_socket(int sock) diff --git a/src/socket_server.hxx b/src/socket_server.hxx index a9c7b3d..5dcf4f3 100644 --- a/src/socket_server.hxx +++ b/src/socket_server.hxx @@ -76,8 +76,8 @@ class socket_server_connection : public socket_handler, public server_connection { socket_write(data); } public: - void fill_buffer(long long usec_timeout=-1) - { socket_handler::fill_buffer(buffer,usec_timeout); } + bool fill_buffer(long long usec_timeout=-1) + { return socket_handler::fill_buffer(buffer,usec_timeout); } void close(); }; diff --git a/test/Makefile.am b/test/Makefile.am index ec58406..a7a5515 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,7 +1,8 @@ -INCLUDES = -I$(top_srcdir)/src +INCLUDES = -I$(top_srcdir)/src @CPPUNIT_CFLAGS@ METASOURCES = AUTO -bin_PROGRAMS = client server -client_SOURCES = client.cpp -client_LDADD = $(top_builddir)/src/libt2n.la -server_LDADD = $(top_builddir)/src/libt2n.la -server_SOURCES = server.cpp +check_PROGRAMS = test + +test_LDADD = $(top_builddir)/src/libt2n.la @CPPUNIT_LIBS@ +test_SOURCES = test.cpp comm.cpp + +TESTS = test diff --git a/test/client.cpp b/test/client.cpp deleted file mode 100644 index 5d71291..0000000 --- a/test/client.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Gerd v. Egidy * - * gve@intra2net.com * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License version * - * 2.1 as published by the Free Software Foundation. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include - -#include - -using namespace std; -using namespace libt2n; - -int main() -{ - socket_client_connection sc("./socket"); - - sc.write("hallo"); - - return 0; -} diff --git a/test/comm.cpp b/test/comm.cpp new file mode 100644 index 0000000..60907b2 --- /dev/null +++ b/test/comm.cpp @@ -0,0 +1,159 @@ +/*************************************************************************** + * Copyright (C) 2004 by Intra2net AG * + * info@intra2net.com * + * * + ***************************************************************************/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +using namespace std; +using namespace libt2n; +using namespace CppUnit; + +class test_comm : public TestFixture +{ + CPPUNIT_TEST_SUITE(test_comm); + + CPPUNIT_TEST(UnixCommToServer); + CPPUNIT_TEST(UnixCommToServerAndBack); + + CPPUNIT_TEST_SUITE_END(); + + public: + + void setUp() + { } + + void tearDown() + { } + + void UnixCommToServer() + { + pid_t pid; + string data; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + sc.write("hello"); + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + socket_server ss("./socket"); + + // max 10 sec + for (int i=0; i < 10; i++) + { + ss.fill_buffer(1000000); + + if(ss.get_packet(data)) + break; + } + } + } + CPPUNIT_ASSERT_EQUAL(string("hello"),data); + } + + void UnixCommToServerAndBack() + { + pid_t pid; + + switch(pid=fork()) + { + case -1: + { + CPPUNIT_FAIL("fork error"); + break; + } + case 0: + // child + { + socket_server ss("./socket"); + ss.set_logging(&cerr,debug); + + // max 10 sec + for (int i=0; i < 10; i++) + { + 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=="ABC") + con->write("DEF"); + else + con->write("xyz"); + } + } + // don't call atexit and stuff + _exit(0); + } + + default: + // parent + { + string data; + + // wait till server is up + sleep(1); + socket_client_connection sc("./socket"); + + sc.write("ABC"); + + sc.fill_buffer(1000000); + sc.get_packet(data); + + CPPUNIT_ASSERT_EQUAL(string("DEF"),data); + + sc.write("HAHA"); + + sc.fill_buffer(1000000); + sc.get_packet(data); + + CPPUNIT_ASSERT_EQUAL(string("xyz"),data); + + sc.write("QUIT"); + } + } + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(test_comm); diff --git a/test/server.cpp b/test/server.cpp deleted file mode 100644 index f5a0349..0000000 --- a/test/server.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2006 by Gerd v. Egidy * - * gve@intra2net.com * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License version * - * 2.1 as published by the Free Software Foundation. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include - -using namespace std; -using namespace libt2n; - -int main() -{ - socket_server ss("./socket"); - - while(true) - { - ss.fill_buffer(1000000); - - unsigned int cid; - string data; - - while(ss.get_packet(data,cid)) - cout << "conn " << cid << ": " << data << endl; - } - - return 0; -} diff --git a/test/test.cpp b/test/test.cpp new file mode 100644 index 0000000..4451c48 --- /dev/null +++ b/test/test.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2004 by Intra2net AG * + * info@intra2net.com * + * * + ***************************************************************************/ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +class VerboseTimingListener : public CppUnit::TestListener +{ + private: + double start_time; + std::string resultstr; + + double get_time(void) + { + struct timeb tb; + ftime(&tb); + return tb.time+(static_cast(tb.millitm)/1000); + } + + public: + + void startTest( CppUnit::Test *test ) + { + resultstr="OK"; + std::cout << test->getName() << ": "; + start_time=get_time(); + } + + void endTest( CppUnit::Test *test ) + { + double timediff=get_time()-start_time; + + // fix clock unpreciseness for small timespans + if (timediff < 0) timediff=0; + + std::cout << resultstr << " (" + << std::fixed << std::setprecision(3) + << timediff << " sec)" << std::endl; + } + + void addFailure(const CppUnit::TestFailure &failure) + { + if(failure.isError()) + resultstr="ERROR"; + else + resultstr="FAIL"; + } +}; + +int main(int argc, char **argv) +{ + CppUnit::TextTestRunner runner; + CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + + // set output format that KDevelop can catch errors + CppUnit::CompilerOutputter *op=CppUnit::CompilerOutputter::defaultOutputter(&runner.result(),std::cout); + op->setLocationFormat("%p:%l: error: "); + runner.setOutputter(op); + + // show every test with timing + VerboseTimingListener listener; + runner.eventManager().addListener(&listener); + + runner.addTest(registry.makeTest()); + + // run all tests in registry (not using the default progress listener) + bool wasSucessful = runner.run("",false,true,false); + + return (wasSucessful ? 0 : 1); +} -- 1.7.1