Reconstructed release dates in ChangeLog
[libt2n] / test / simplecmd.cpp
... / ...
CommitLineData
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
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>
27
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
34using namespace std;
35using namespace CppUnit;
36
37string testfunc(const string& str)
38{
39 string ret;
40 if (str=="throw")
41 throw libt2n::t2n_runtime_error("throw me around");
42 if (str=="big")
43 ret.insert(0,100*1024,'x');
44 else
45 ret=str+", testfunc() was here";
46 return ret;
47}
48
49class testfunc_res : public libt2n::result
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 {
58 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
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
77
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 {
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
100 libt2n::result* operator()()
101 {
102 return new testfunc_res(testfunc(param));
103 }
104};
105
106#include <boost/serialization/export.hpp>
107
108BOOST_CLASS_EXPORT(testfunc_cmd)
109BOOST_CLASS_EXPORT(testfunc_res)
110
111using namespace libt2n;
112
113class test_simplecmd : public TestFixture
114{
115 CPPUNIT_TEST_SUITE(test_simplecmd);
116
117 CPPUNIT_TEST(SimpleCmd);
118 CPPUNIT_TEST(SimpleException);
119 CPPUNIT_TEST(BigReturn);
120 CPPUNIT_TEST(BigParameter);
121
122 CPPUNIT_TEST_SUITE_END();
123
124 pid_t child_pid;
125
126 public:
127
128 void setUp()
129 { }
130
131 void tearDown()
132 {
133 // make sure the server-child is dead before the next test runs
134 kill(child_pid,SIGKILL);
135 sleep(1);
136 }
137
138 void SimpleCmd()
139 {
140 switch(child_pid=fork())
141 {
142 case -1:
143 {
144 CPPUNIT_FAIL("fork error");
145 break;
146 }
147 case 0:
148 // child
149 {
150 try
151 {
152 socket_server ss("./socket");
153 command_server cs(ss);
154
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 }
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");
173 sc.set_logging(&cerr,debug);
174 command_client cc(&sc);
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
186 void SimpleException()
187 {
188 switch(child_pid=fork())
189 {
190 case -1:
191 {
192 CPPUNIT_FAIL("fork error");
193 break;
194 }
195 case 0:
196 // child
197 {
198 try
199 {
200 socket_server ss("./socket");
201 command_server cs(ss);
202
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 }
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);
222 command_client cc(&sc);
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 }
242
243 void BigReturn()
244 {
245 switch(child_pid=fork())
246 {
247 case -1:
248 {
249 CPPUNIT_FAIL("fork error");
250 break;
251 }
252 case 0:
253 // child
254 {
255 try
256 {
257 socket_server ss("./socket");
258 command_server cs(ss);
259
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 }
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");
278 command_client cc(&sc);
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 {
292 switch(child_pid=fork())
293 {
294 case -1:
295 {
296 CPPUNIT_FAIL("fork error");
297 break;
298 }
299 case 0:
300 // child
301 {
302 try
303 {
304 socket_server ss("./socket");
305 command_server cs(ss);
306
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";
314 }
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");
326 command_client cc(&sc);
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
338};
339
340CPPUNIT_TEST_SUITE_REGISTRATION(test_simplecmd);