X-Git-Url: http://developer.intra2net.com/git/?p=libt2n;a=blobdiff_plain;f=test%2Freentrant.cpp;h=13f62503bad6bb6cce37171d04d1ea94ee8148e5;hp=bb9420a4db0d118d5f0937d09cb6289a7d6a0f37;hb=0995cebb9189b872e8d7e58d8b8122fa00cc9061;hpb=3b2543e7dfd705d6e624560dd5a681898c0f242c diff --git a/test/reentrant.cpp b/test/reentrant.cpp index bb9420a..13f6250 100644 --- a/test/reentrant.cpp +++ b/test/reentrant.cpp @@ -35,10 +35,16 @@ using namespace std; using namespace CppUnit; using namespace libt2n; -namespace +namespace reentrant { -command_server *global_server; +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) { @@ -46,7 +52,10 @@ string testfunc(const string& str) ret=str+", testfunc() was here"; // call handle, eventually reentrant - global_server->handle(1000); + if (global_server) + global_server->handle(10000); + + ++seen_client_requests; return ret; } @@ -66,7 +75,8 @@ class testfunc_res : public libt2n::result public: testfunc_res() - { } + { + } testfunc_res(const string& str) { @@ -95,7 +105,8 @@ class testfunc_cmd : public libt2n::command public: testfunc_cmd() - { } + { + } testfunc_cmd(const string& str) { @@ -110,10 +121,13 @@ class testfunc_cmd : public libt2n::command } + #include -BOOST_CLASS_EXPORT(testfunc_cmd) -BOOST_CLASS_EXPORT(testfunc_res) +BOOST_CLASS_EXPORT(reentrant::testfunc_cmd) +BOOST_CLASS_EXPORT(reentrant::testfunc_res) + +using namespace reentrant; class test_reentrant : public TestFixture { @@ -123,8 +137,6 @@ class test_reentrant : public TestFixture CPPUNIT_TEST_SUITE_END(); - pid_t child_pid; - public: void setUp() @@ -135,7 +147,7 @@ class test_reentrant : public TestFixture void ReentrantServer() { - switch(child_pid=fork()) + switch(fork()) { case -1: { @@ -146,24 +158,41 @@ class test_reentrant : public TestFixture // child { // wait till server is up - sleep(1); + sleep(2); - // we want 8 identical childs hammering the server - fork(); - fork(); - fork(); + // hammer the server + for (int i = 0; i < fork_count; i++) + fork(); - for (int i=0; i < 100; i++) + try { - socket_client_connection sc("./socket"); - 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); + 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); + + 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"; + } + } + } catch (exception &e) + { + cerr << "caught exception: " << e.what() << endl; + } catch(...) + { + std::cerr << "exception in child. ignoring\n"; } // don't call atexit and stuff @@ -173,19 +202,34 @@ class test_reentrant : public TestFixture default: // parent { + // don't kill us on broken pipe + signal(SIGPIPE, SIG_IGN); + socket_server ss("./socket"); command_server cs(ss); global_server=&cs; - // max 10 sec - long long maxtime=5000000; - while(maxtime > 0) - cs.handle(maxtime,&maxtime); + // 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; + } + + 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); + CPPUNIT_ASSERT_EQUAL(all_requests, seen_client_requests); } }