Reconstructed release dates in ChangeLog
[libt2n] / test / reentrant.cpp
index bb9420a..13f6250 100644 (file)
@@ -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/serialization/export.hpp>
 
-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<testfunc_res*>(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<testfunc_res*>(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);
         }
     }