pkgconfig_DATA = libt2n.pc
EXRA_DIST = COPYING COPYING.LIB
+
+if AUTOCHECK
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+ $(MAKE) $(AM_MAKEFLAGS) check
+endif
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)
</general>
<kdevautoproject>
<general>
- <activetarget>src/libt2n.la</activetarget>
+ <activetarget>test/server</activetarget>
<useconfiguration>debug</useconfiguration>
</general>
<run>
<mainprogram>src/libt2n</mainprogram>
<terminal>true</terminal>
<directoryradio>executable</directoryradio>
+ <runarguments>
+ <client></client>
+ <server></server>
+ <test></test>
+ </runarguments>
</run>
<configurations>
<optimized>
virtual void real_write(const std::string& data)=0;
public:
- ~connection()
+ virtual ~connection()
{ close(); }
bool is_closed()
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(); }
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();
};
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;
buffer.assign(socket_buffer,nbytes);
// more data waiting -> recurse
- if (data_waiting())
+ if (data_waiting(0))
fill_buffer(buffer);
if (nbytes > 0)
std::map<unsigned int, server_connection*>::iterator ie=connections.end();
for(std::map<unsigned int, server_connection*>::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)
{ 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();
};
-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
+++ /dev/null
-/***************************************************************************
- * 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 <iostream>
-
-#include <socket_client.hxx>
-
-using namespace std;
-using namespace libt2n;
-
-int main()
-{
- socket_client_connection sc("./socket");
-
- sc.write("hallo");
-
- return 0;
-}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2004 by Intra2net AG *
+ * info@intra2net.com *
+ * *
+ ***************************************************************************/
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <stdexcept>
+
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <socket_client.hxx>
+#include <socket_server.hxx>
+
+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);
+++ /dev/null
-/***************************************************************************
- * 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 <socket_server.hxx>
-
-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;
-}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2004 by Intra2net AG *
+ * info@intra2net.com *
+ * *
+ ***************************************************************************/
+
+#include <iostream>
+#include <iomanip>
+#include <string>
+
+#include <time.h>
+#include <sys/timeb.h>
+
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/TestListener.h>
+#include <cppunit/TestFailure.h>
+#include <cppunit/TestResult.h>
+#include <cppunit/CompilerOutputter.h>
+
+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<float>(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);
+}