Update to newer boost autoconf macros
[libt2n] / test / reentrant.cpp
CommitLineData
19facd85
TJ
1/*
2Copyright (C) 2004 by Intra2net AG
3b2543e7 3
19facd85
TJ
4The software in this package is distributed under the GNU General
5Public License version 2 (with a special exception described below).
6
7A copy of GNU General Public License (GPL) is included in this distribution,
8in the file COPYING.GPL.
9
10As a special exception, if other files instantiate templates or use macros
11or inline functions from this file, or you compile this file and link it
12with other works to produce a work based on this file, this file
13does not by itself cause the resulting work to be covered
14by the GNU General Public License.
15
16However the source code for this file must still be made available
17in accordance with section (3) of the GNU General Public License.
18
19This exception does not invalidate any other reasons why a work based
20on this file might be covered by the GNU General Public License.
21*/
3b2543e7
GE
22#include <sys/types.h>
23#include <unistd.h>
24#include <errno.h>
25#include <signal.h>
26#include <stdio.h>
27
28#include <iostream>
29#include <string>
30#include <sstream>
31#include <stdexcept>
32
33#include <cppunit/extensions/TestFactoryRegistry.h>
34#include <cppunit/ui/text/TestRunner.h>
35#include <cppunit/extensions/HelperMacros.h>
36
37#include <boost/archive/binary_oarchive.hpp>
38#include <boost/archive/binary_iarchive.hpp>
39#include <boost/archive/xml_oarchive.hpp>
40#include <boost/archive/xml_iarchive.hpp>
41#include <boost/serialization/serialization.hpp>
42
43#include <container.hxx>
44#include <socket_client.hxx>
45#include <socket_server.hxx>
46#include <command_client.hxx>
47#include <command_server.hxx>
48
49using namespace std;
50using namespace CppUnit;
51using namespace libt2n;
52
276fd052 53namespace reentrant
3b2543e7
GE
54{
55
d55e0d0f 56command_server *global_server = NULL;
3b2543e7 57
696c95c2
TJ
58int fork_count = 3;
59int requests_per_child = 100;
60int all_requests = (2 << (fork_count-1)) * requests_per_child;
61
62int seen_client_requests = 0;
63
3b2543e7
GE
64string testfunc(const string& str)
65{
66 string ret;
67 ret=str+", testfunc() was here";
68
69 // call handle, eventually reentrant
d55e0d0f 70 if (global_server)
56f3994d 71 global_server->handle(10000);
3b2543e7 72
696c95c2
TJ
73 ++seen_client_requests;
74
3b2543e7
GE
75 return ret;
76}
77
78class testfunc_res : public libt2n::result
79{
80 private:
81 string res;
82
83 friend class boost::serialization::access;
84 template<class Archive>
85 void serialize(Archive & ar, const unsigned int version)
86 {
87 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
88 ar & BOOST_SERIALIZATION_NVP(res);
89 }
90
91 public:
92 testfunc_res()
696c95c2
TJ
93 {
94 }
3b2543e7
GE
95
96 testfunc_res(const string& str)
97 {
98 res=str;
99 }
100
101 string get_data()
102 {
103 return res;
104 }
105};
106
107
108class testfunc_cmd : public libt2n::command
109{
110 private:
111 string param;
112
113 friend class boost::serialization::access;
114 template<class Archive>
115 void serialize(Archive & ar, const unsigned int version)
116 {
117 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
118 ar & BOOST_SERIALIZATION_NVP(param);
119 }
120
121 public:
122 testfunc_cmd()
696c95c2
TJ
123 {
124 }
3b2543e7
GE
125
126 testfunc_cmd(const string& str)
127 {
128 param=str;
129 }
130
131 libt2n::result* operator()()
132 {
133 return new testfunc_res(testfunc(param));
134 }
135};
136
137}
138
696c95c2 139
3b2543e7
GE
140#include <boost/serialization/export.hpp>
141
276fd052
TJ
142BOOST_CLASS_EXPORT(reentrant::testfunc_cmd)
143BOOST_CLASS_EXPORT(reentrant::testfunc_res)
144
145using namespace reentrant;
3b2543e7
GE
146
147class test_reentrant : public TestFixture
148{
149 CPPUNIT_TEST_SUITE(test_reentrant);
150
151 CPPUNIT_TEST(ReentrantServer);
152
153 CPPUNIT_TEST_SUITE_END();
154
3b2543e7
GE
155 public:
156
157 void setUp()
158 { }
159
160 void tearDown()
161 { }
162
163 void ReentrantServer()
164 {
56f3994d 165 switch(fork())
3b2543e7
GE
166 {
167 case -1:
168 {
169 CPPUNIT_FAIL("fork error");
170 break;
171 }
172 case 0:
173 // child
174 {
175 // wait till server is up
696c95c2 176 sleep(2);
3b2543e7 177
696c95c2
TJ
178 // hammer the server
179 for (int i = 0; i < fork_count; i++)
180 fork();
3b2543e7 181
56f3994d 182 try
3b2543e7 183 {
696c95c2 184 for (int i=0; i < requests_per_child; i++)
56f3994d
TJ
185 {
186 socket_client_connection sc("./socket");
696c95c2 187 // sc.set_logging(&cerr,debug);
56f3994d
TJ
188 command_client cc(&sc);
189
190 result_container rc;
191 cc.send_command(new testfunc_cmd("hello"),rc);
192
193 testfunc_res *res = dynamic_cast<testfunc_res*>(rc.get_result());
194 if (res)
195 {
196 string ret = res->get_data();
197 if (ret != "hello, testfunc() was here")
696c95c2 198 std::cout << "ERROR reentrant server testfunc_res failed, res: \"" << ret << "\"\n";
56f3994d
TJ
199 }
200 else
201 {
696c95c2 202 std::cout << "ERROR result from reentrant server empty (" << rc.get_result() << ")\n";
56f3994d
TJ
203 }
204 }
205 } catch (exception &e)
206 {
207 cerr << "caught exception: " << e.what() << endl;
441d41fe
TJ
208 } catch(...)
209 {
210 std::cerr << "exception in child. ignoring\n";
3b2543e7
GE
211 }
212
213 // don't call atexit and stuff
214 _exit(0);
215 }
216
217 default:
218 // parent
219 {
56f3994d
TJ
220 // don't kill us on broken pipe
221 signal(SIGPIPE, SIG_IGN);
222
3b2543e7
GE
223 socket_server ss("./socket");
224 command_server cs(ss);
225
226 global_server=&cs;
227
696c95c2
TJ
228 // Wait until all requests have successed
229 int safety_check = 0;
230 while (seen_client_requests < all_requests)
231 {
232 ++safety_check;
233 if (safety_check > 10) {
234 std::cerr << "reached safety check, aborting.\n";
235 break;
236 }
56f3994d 237
696c95c2
TJ
238 long long maxtime=1000000;
239 while(maxtime > 0)
240 cs.handle(maxtime,&maxtime);
241 }
56f3994d 242
d55e0d0f 243 global_server = NULL;
3b2543e7
GE
244 }
245
246 // we are still alive, everything is ok
696c95c2 247 CPPUNIT_ASSERT_EQUAL(all_requests, seen_client_requests);
3b2543e7
GE
248 }
249 }
250
251};
252
253
254CPPUNIT_TEST_SUITE_REGISTRATION(test_reentrant);