1 /***************************************************************************
2 * Copyright (C) 2004 by Intra2net AG *
5 ***************************************************************************/
18 #include <cppunit/extensions/TestFactoryRegistry.h>
19 #include <cppunit/ui/text/TestRunner.h>
20 #include <cppunit/extensions/HelperMacros.h>
22 #include <boost/archive/binary_oarchive.hpp>
23 #include <boost/archive/binary_iarchive.hpp>
24 #include <boost/archive/xml_oarchive.hpp>
25 #include <boost/archive/xml_iarchive.hpp>
26 #include <boost/serialization/serialization.hpp>
28 #include <container.hxx>
29 #include <socket_client.hxx>
30 #include <socket_server.hxx>
31 #include <command_client.hxx>
32 #include <command_server.hxx>
35 using namespace CppUnit;
36 using namespace libt2n;
41 command_server *global_server = NULL;
44 int requests_per_child = 100;
45 int all_requests = (2 << (fork_count-1)) * requests_per_child;
47 int seen_client_requests = 0;
49 string testfunc(const string& str)
52 ret=str+", testfunc() was here";
54 // call handle, eventually reentrant
56 global_server->handle(10000);
58 ++seen_client_requests;
63 class testfunc_res : public libt2n::result
68 friend class boost::serialization::access;
69 template<class Archive>
70 void serialize(Archive & ar, const unsigned int version)
72 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
73 ar & BOOST_SERIALIZATION_NVP(res);
81 testfunc_res(const string& str)
93 class testfunc_cmd : public libt2n::command
98 friend class boost::serialization::access;
99 template<class Archive>
100 void serialize(Archive & ar, const unsigned int version)
102 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
103 ar & BOOST_SERIALIZATION_NVP(param);
111 testfunc_cmd(const string& str)
116 libt2n::result* operator()()
118 return new testfunc_res(testfunc(param));
125 #include <boost/serialization/export.hpp>
127 BOOST_CLASS_EXPORT(reentrant::testfunc_cmd)
128 BOOST_CLASS_EXPORT(reentrant::testfunc_res)
130 using namespace reentrant;
132 class test_reentrant : public TestFixture
134 CPPUNIT_TEST_SUITE(test_reentrant);
136 CPPUNIT_TEST(ReentrantServer);
138 CPPUNIT_TEST_SUITE_END();
148 void ReentrantServer()
154 CPPUNIT_FAIL("fork error");
160 // wait till server is up
164 for (int i = 0; i < fork_count; i++)
169 for (int i=0; i < requests_per_child; i++)
171 socket_client_connection sc("./socket");
172 // sc.set_logging(&cerr,debug);
173 command_client cc(&sc);
176 cc.send_command(new testfunc_cmd("hello"),rc);
178 testfunc_res *res = dynamic_cast<testfunc_res*>(rc.get_result());
181 string ret = res->get_data();
182 if (ret != "hello, testfunc() was here")
183 std::cout << "ERROR reentrant server testfunc_res failed, res: \"" << ret << "\"\n";
187 std::cout << "ERROR result from reentrant server empty (" << rc.get_result() << ")\n";
190 } catch (exception &e)
192 cerr << "caught exception: " << e.what() << endl;
195 std::cerr << "exception in child. ignoring\n";
198 // don't call atexit and stuff
205 // don't kill us on broken pipe
206 signal(SIGPIPE, SIG_IGN);
208 socket_server ss("./socket");
209 command_server cs(ss);
213 // Wait until all requests have successed
214 int safety_check = 0;
215 while (seen_client_requests < all_requests)
218 if (safety_check > 10) {
219 std::cerr << "reached safety check, aborting.\n";
223 long long maxtime=1000000;
225 cs.handle(maxtime,&maxtime);
228 global_server = NULL;
231 // we are still alive, everything is ok
232 CPPUNIT_ASSERT_EQUAL(all_requests, seen_client_requests);
239 CPPUNIT_TEST_SUITE_REGISTRATION(test_reentrant);