libt2n: (tomj) added exception handling to every child after fork(). This is needed...
[libt2n] / test / simplecmd.cpp
CommitLineData
d184c648
GE
1/***************************************************************************
2 * Copyright (C) 2004 by Intra2net AG *
3 * info@intra2net.com *
4 * *
5 ***************************************************************************/
6
7#include <sys/types.h>
8#include <unistd.h>
9#include <errno.h>
10#include <signal.h>
11#include <stdio.h>
12
13#include <iostream>
14#include <string>
15#include <sstream>
16#include <stdexcept>
17
18#include <cppunit/extensions/TestFactoryRegistry.h>
19#include <cppunit/ui/text/TestRunner.h>
20#include <cppunit/extensions/HelperMacros.h>
21
a7170401
GE
22#include <boost/archive/binary_oarchive.hpp>
23#include <boost/archive/binary_iarchive.hpp>
d535333f
GE
24#include <boost/archive/xml_oarchive.hpp>
25#include <boost/archive/xml_iarchive.hpp>
a7170401
GE
26#include <boost/serialization/serialization.hpp>
27
d184c648
GE
28#include <container.hxx>
29#include <socket_client.hxx>
30#include <socket_server.hxx>
31#include <command_client.hxx>
32#include <command_server.hxx>
33
d184c648 34using namespace std;
d184c648
GE
35using namespace CppUnit;
36
37string testfunc(const string& str)
38{
58b327c6 39 string ret;
e453407d
GE
40 if (str=="throw")
41 throw libt2n::t2n_runtime_error("throw me around");
58b327c6
GE
42 if (str=="big")
43 ret.insert(0,100*1024,'x');
44 else
45 ret=str+", testfunc() was here";
d184c648
GE
46 return ret;
47}
48
d535333f 49class testfunc_res : public libt2n::result
d184c648
GE
50{
51 private:
52 string res;
53
54 friend class boost::serialization::access;
55 template<class Archive>
56 void serialize(Archive & ar, const unsigned int version)
57 {
d535333f 58 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
d184c648
GE
59 ar & BOOST_SERIALIZATION_NVP(res);
60 }
61
62 public:
63 testfunc_res()
64 { }
65
66 testfunc_res(const string& str)
67 {
68 res=str;
69 }
70
71 string get_data()
72 {
73 return res;
74 }
75};
76
a7170401 77
d184c648
GE
78class testfunc_cmd : public libt2n::command
79{
80 private:
81 string param;
82
83 friend class boost::serialization::access;
84 template<class Archive>
85 void serialize(Archive & ar, const unsigned int version)
86 {
d184c648
GE
87 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
88 ar & BOOST_SERIALIZATION_NVP(param);
89 }
90
91 public:
92 testfunc_cmd()
93 { }
94
95 testfunc_cmd(const string& str)
96 {
97 param=str;
98 }
99
d535333f 100 libt2n::result* operator()()
d184c648
GE
101 {
102 return new testfunc_res(testfunc(param));
103 }
104};
105
a7170401 106#include <boost/serialization/export.hpp>
d184c648
GE
107
108BOOST_CLASS_EXPORT(testfunc_cmd)
109BOOST_CLASS_EXPORT(testfunc_res)
110
d535333f
GE
111using namespace libt2n;
112
d184c648
GE
113class test_simplecmd : public TestFixture
114{
115 CPPUNIT_TEST_SUITE(test_simplecmd);
116
117 CPPUNIT_TEST(SimpleCmd);
e453407d 118 CPPUNIT_TEST(SimpleException);
58b327c6
GE
119 CPPUNIT_TEST(BigReturn);
120 CPPUNIT_TEST(BigParameter);
d184c648
GE
121
122 CPPUNIT_TEST_SUITE_END();
123
b5922184
GE
124 pid_t child_pid;
125
d184c648
GE
126 public:
127
128 void setUp()
b5922184 129 { }
d184c648
GE
130
131 void tearDown()
b5922184
GE
132 {
133 // make sure the server-child is dead before the next test runs
134 kill(child_pid,SIGKILL);
135 sleep(1);
136 }
d184c648
GE
137
138 void SimpleCmd()
139 {
b5922184 140 switch(child_pid=fork())
d184c648
GE
141 {
142 case -1:
143 {
144 CPPUNIT_FAIL("fork error");
145 break;
146 }
147 case 0:
148 // child
149 {
441d41fe
TJ
150 try
151 {
152 socket_server ss("./socket");
153 command_server cs(ss);
d184c648 154
441d41fe
TJ
155 // max 10 sec
156 for (int i=0; i < 10; i++)
157 cs.handle(1000000);
158 } catch(...)
159 {
160 std::cerr << "exception in child. ignoring\n";
161 }
d184c648
GE
162
163 // don't call atexit and stuff
164 _exit(0);
165 }
166
167 default:
168 // parent
169 {
170 // wait till server is up
171 sleep(1);
172 socket_client_connection sc("./socket");
a7170401 173 sc.set_logging(&cerr,debug);
fb3345ad 174 command_client cc(&sc);
d184c648
GE
175
176 result_container rc;
177 cc.send_command(new testfunc_cmd("hello"),rc);
178
179 string ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
180
181 CPPUNIT_ASSERT_EQUAL(string("hello, testfunc() was here"),ret);
182 }
183 }
184 }
185
e453407d
GE
186 void SimpleException()
187 {
b5922184 188 switch(child_pid=fork())
e453407d
GE
189 {
190 case -1:
191 {
192 CPPUNIT_FAIL("fork error");
193 break;
194 }
195 case 0:
196 // child
197 {
441d41fe
TJ
198 try
199 {
200 socket_server ss("./socket");
201 command_server cs(ss);
e453407d 202
441d41fe
TJ
203 // max 10 sec
204 for (int i=0; i < 10; i++)
205 cs.handle(1000000);
206 } catch(...)
207 {
208 std::cerr << "exception in child. ignoring\n";
209 }
e453407d
GE
210
211 // don't call atexit and stuff
212 _exit(0);
213 }
214
215 default:
216 // parent
217 {
218 // wait till server is up
219 sleep(1);
220 socket_client_connection sc("./socket");
221 sc.set_logging(&cerr,debug);
fb3345ad 222 command_client cc(&sc);
e453407d
GE
223
224 result_container rc;
225 cc.send_command(new testfunc_cmd("throw"),rc);
226
227 string ret;
228
229 try
230 {
231 ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
232 }
233 catch(t2n_runtime_error &e)
234 { ret=e.what(); }
235 catch(...)
236 { throw; }
237
238 CPPUNIT_ASSERT_EQUAL(string("throw me around"),ret);
239 }
240 }
241 }
d184c648 242
58b327c6
GE
243 void BigReturn()
244 {
b5922184 245 switch(child_pid=fork())
58b327c6
GE
246 {
247 case -1:
248 {
249 CPPUNIT_FAIL("fork error");
250 break;
251 }
252 case 0:
253 // child
254 {
441d41fe
TJ
255 try
256 {
257 socket_server ss("./socket");
258 command_server cs(ss);
58b327c6 259
441d41fe
TJ
260 // max 10 sec
261 for (int i=0; i < 10; i++)
262 cs.handle(1000000);
263 } catch(...)
264 {
265 std::cerr << "exception in child. ignoring\n";
266 }
58b327c6
GE
267
268 // don't call atexit and stuff
269 _exit(0);
270 }
271
272 default:
273 // parent
274 {
275 // wait till server is up
276 sleep(1);
277 socket_client_connection sc("./socket");
fb3345ad 278 command_client cc(&sc);
58b327c6
GE
279
280 result_container rc;
281 cc.send_command(new testfunc_cmd("big"),rc);
282
283 string ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
284
285 CPPUNIT_ASSERT_EQUAL(string().insert(0,100*1024,'x'),ret);
286 }
287 }
288 }
289
290 void BigParameter()
291 {
b5922184 292 switch(child_pid=fork())
58b327c6
GE
293 {
294 case -1:
295 {
296 CPPUNIT_FAIL("fork error");
297 break;
298 }
299 case 0:
300 // child
301 {
441d41fe
TJ
302 try
303 {
304 socket_server ss("./socket");
305 command_server cs(ss);
58b327c6 306
441d41fe
TJ
307 // max 60 sec - we need atleast 28 handle calls to transfer the buffer
308 for (int i=0; i < 60; i++) {
309 cs.handle(1000000);
310 }
311 } catch(...)
312 {
313 std::cerr << "exception in child. ignoring\n";
56f3994d 314 }
58b327c6
GE
315
316 // don't call atexit and stuff
317 _exit(0);
318 }
319
320 default:
321 // parent
322 {
323 // wait till server is up
324 sleep(1);
325 socket_client_connection sc("./socket");
fb3345ad 326 command_client cc(&sc);
58b327c6
GE
327
328 result_container rc;
329 cc.send_command(new testfunc_cmd(string().insert(0,100*1024,'y')),rc);
330
331 string ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
332
333 CPPUNIT_ASSERT_EQUAL(string().insert(0,100*1024,'y')+", testfunc() was here",ret);
334 }
335 }
336 }
337
d184c648
GE
338};
339
340CPPUNIT_TEST_SUITE_REGISTRATION(test_simplecmd);