X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=blobdiff_plain;f=test%2Freentrant.cpp;h=204e741a6d3d0ce938a7054c78f99acb3f8a310d;hp=c08df62681782611bb14cadcf4950e6ecffafa20;hb=0f8ddc6cbdbd213e3bb00c41567e514fdeeed79d;hpb=d55e0d0f9f17e1706e9751b7e920479f31370f51 diff --git a/test/reentrant.cpp b/test/reentrant.cpp index c08df62..204e741 100644 --- a/test/reentrant.cpp +++ b/test/reentrant.cpp @@ -1,9 +1,24 @@ -/*************************************************************************** - * Copyright (C) 2004 by Intra2net AG * - * info@intra2net.com * - * * - ***************************************************************************/ +/* +Copyright (C) 2004 by Intra2net AG +The software in this package is distributed under the GNU General +Public License version 2 (with a special exception described below). + +A copy of GNU General Public License (GPL) is included in this distribution, +in the file COPYING.GPL. + +As a special exception, if other files instantiate templates or use macros +or inline functions from this file, or you compile this file and link it +with other works to produce a work based on this file, this file +does not by itself cause the resulting work to be covered +by the GNU General Public License. + +However the source code for this file must still be made available +in accordance with section (3) of the GNU General Public License. + +This exception does not invalidate any other reasons why a work based +on this file might be covered by the GNU General Public License. +*/ #include #include #include @@ -15,9 +30,8 @@ #include #include -#include -#include -#include +#define BOOST_TEST_DYN_LINK +#include #include #include @@ -32,14 +46,19 @@ #include using namespace std; -using namespace CppUnit; using namespace libt2n; -namespace +namespace reentrant { command_server *global_server = NULL; +int fork_count = 3; +int requests_per_child = 100; +int all_requests = (2 << (fork_count-1)) * requests_per_child; + +int seen_client_requests = 0; + string testfunc(const string& str) { string ret; @@ -47,7 +66,9 @@ string testfunc(const string& str) // call handle, eventually reentrant if (global_server) - global_server->handle(1000); + global_server->handle(10000); + + ++seen_client_requests; return ret; } @@ -67,7 +88,8 @@ class testfunc_res : public libt2n::result public: testfunc_res() - { } + { + } testfunc_res(const string& str) { @@ -96,7 +118,8 @@ class testfunc_cmd : public libt2n::command public: testfunc_cmd() - { } + { + } testfunc_cmd(const string& str) { @@ -111,88 +134,102 @@ class testfunc_cmd : public libt2n::command } -#include -BOOST_CLASS_EXPORT(testfunc_cmd) -BOOST_CLASS_EXPORT(testfunc_res) - -class test_reentrant : public TestFixture -{ - CPPUNIT_TEST_SUITE(test_reentrant); - - CPPUNIT_TEST(ReentrantServer); - - CPPUNIT_TEST_SUITE_END(); +#include - pid_t child_pid; +BOOST_CLASS_EXPORT(reentrant::testfunc_cmd) +BOOST_CLASS_EXPORT(reentrant::testfunc_res) - public: +using namespace reentrant; - void setUp() - { } +BOOST_AUTO_TEST_SUITE(test_reentrant) - void tearDown() - { } - - void ReentrantServer() +BOOST_AUTO_TEST_CASE(ReentrantServer) +{ + switch(fork()) { - switch(child_pid=fork()) + case -1: { - case -1: - { - CPPUNIT_FAIL("fork error"); - break; - } - case 0: - // child - { - // wait till server is up - sleep(3); + BOOST_FAIL("fork error"); + break; + } + case 0: + // child + { + // wait till server is up + sleep(2); - // we want 8 identical childs hammering the server - fork(); - fork(); + // hammer the server + for (int i = 0; i < fork_count; i++) fork(); - for (int i=0; i < 100; i++) + try + { + for (int i=0; i < requests_per_child; i++) { socket_client_connection sc("./socket"); + // sc.set_logging(&cerr,debug); command_client cc(&sc); result_container rc; cc.send_command(new testfunc_cmd("hello"),rc); - string ret=dynamic_cast(rc.get_result())->get_data(); - - CPPUNIT_ASSERT_EQUAL(string("hello, testfunc() was here"),ret); + testfunc_res *res = dynamic_cast(rc.get_result()); + if (res) + { + string ret = res->get_data(); + if (ret != "hello, testfunc() was here") + std::cout << "ERROR reentrant server testfunc_res failed, res: \"" << ret << "\"\n"; + } + else + { + std::cout << "ERROR result from reentrant server empty (" << rc.get_result() << ")\n"; + } } - - // don't call atexit and stuff - _exit(0); + } catch (exception &e) + { + cerr << "caught exception: " << e.what() << endl; + } catch(...) + { + std::cerr << "exception in child. ignoring\n"; } - default: - // parent - { - socket_server ss("./socket"); - command_server cs(ss); + // don't call atexit and stuff + _exit(0); + } - global_server=&cs; + default: + // parent + { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + + socket_server ss("./socket"); + command_server cs(ss); + + global_server=&cs; + + // Wait until all requests have successed + int safety_check = 0; + while (seen_client_requests < all_requests) + { + ++safety_check; + if (safety_check > 10) { + std::cerr << "reached safety check, aborting.\n"; + break; + } - // max 10 sec - long long maxtime=5000000; + long long maxtime=1000000; while(maxtime > 0) cs.handle(maxtime,&maxtime); - - global_server = NULL; } - // we are still alive, everything is ok - CPPUNIT_ASSERT_EQUAL(1,1); + global_server = NULL; } - } - -}; + // we are still alive, everything is ok + BOOST_CHECK_EQUAL(all_requests, seen_client_requests); + } +} -CPPUNIT_TEST_SUITE_REGISTRATION(test_reentrant); +BOOST_AUTO_TEST_SUITE_END()