libt2n: (tomj) added exception handling to every child after fork(). This is needed...
[libt2n] / test / cmdgroup.cpp
CommitLineData
539b09c0
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
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#include <boost/serialization/export.hpp>
28
29#include <container.hxx>
30#include <socket_client.hxx>
31#include <socket_server.hxx>
32#include <command_client.hxx>
33#include <command_server.hxx>
34
35using namespace std;
36using namespace CppUnit;
37using namespace libt2n;
38
39string testfunc4(const string& str)
40{
41 if (str=="throw")
42 throw libt2n::t2n_runtime_error("throw me around");
43 string ret(str);
44 ret+=", testfunc() was here";
45 return ret;
46}
47
48class testfunc4_res : public libt2n::result
49{
50 private:
51 string res;
52
53 friend class boost::serialization::access;
54 template<class Archive>
55 void serialize(Archive & ar, const unsigned int version)
56 {
57 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
58 ar & BOOST_SERIALIZATION_NVP(res);
59 }
60
61 public:
62 testfunc4_res()
63 { }
64
65 testfunc4_res(const string& str)
66 {
67 res=str;
68 }
69
70 string get_data()
71 {
72 return res;
73 }
74};
75
76class cmd_group_a : public command
77{
78 private:
79 friend class boost::serialization::access;
80 template<class Archive>
81 void serialize(Archive & ar, const unsigned int version)
82 {
83 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
84 }
85};
86
87class cmd_group_b : public command
88{
89 private:
90 friend class boost::serialization::access;
91 template<class Archive>
92 void serialize(Archive & ar, const unsigned int version)
93 {
94 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
95 }
96};
97
98class testfunc4a_cmd : public cmd_group_a
99{
100 private:
101 string param;
102
103 friend class boost::serialization::access;
104 template<class Archive>
105 void serialize(Archive & ar, const unsigned int version)
106 {
107 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(cmd_group_a);
108 ar & BOOST_SERIALIZATION_NVP(param);
109 }
110
111 public:
112 testfunc4a_cmd()
113 { }
114
115 testfunc4a_cmd(const string& str)
116 {
117 param=str;
118 }
119
120 libt2n::result* operator()()
121 {
122 return new testfunc4_res(testfunc4(param));
123 }
124};
125
126class testfunc4b_cmd : public cmd_group_b
127{
128 private:
129 string param;
130
131 friend class boost::serialization::access;
132 template<class Archive>
133 void serialize(Archive & ar, const unsigned int version)
134 {
135 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(cmd_group_b);
136 ar & BOOST_SERIALIZATION_NVP(param);
137 }
138
139 public:
140 testfunc4b_cmd()
141 { }
142
143 testfunc4b_cmd(const string& str)
144 {
145 param=str;
146 }
147
148 libt2n::result* operator()()
149 {
150 return new testfunc4_res(testfunc4(param));
151 }
152};
153
154
155BOOST_CLASS_EXPORT(testfunc4_res)
156BOOST_CLASS_EXPORT(cmd_group_a)
157BOOST_CLASS_EXPORT(cmd_group_b)
158BOOST_CLASS_EXPORT(testfunc4a_cmd)
159BOOST_CLASS_EXPORT(testfunc4b_cmd)
160
161class test_cmdgroup : public TestFixture
162{
163 CPPUNIT_TEST_SUITE(test_cmdgroup);
164
165 CPPUNIT_TEST(GroupOk);
166 CPPUNIT_TEST(WrongGroup);
167
168 CPPUNIT_TEST_SUITE_END();
169
b5922184
GE
170 pid_t child_pid;
171
539b09c0
GE
172 public:
173
174 void setUp()
175 { }
176
177 void tearDown()
b5922184
GE
178 {
179 // make sure the server-child is dead before the next test runs
180 kill(child_pid,SIGKILL);
181 sleep(1);
182 }
539b09c0
GE
183
184 void GroupOk()
185 {
b5922184 186 switch(child_pid=fork())
539b09c0
GE
187 {
188 case -1:
189 {
190 CPPUNIT_FAIL("fork error");
191 break;
192 }
193 case 0:
194 // child
195 {
441d41fe
TJ
196 try
197 {
198 socket_server ss("./socket");
199 group_command_server<cmd_group_a> cs(ss);
539b09c0 200
441d41fe
TJ
201 // max 10 sec
202 for (int i=0; i < 10; i++)
203 cs.handle(1000000);
204 } catch(...)
205 {
206 std::cerr << "exception in child. ignoring\n";
207 }
539b09c0
GE
208
209 // don't call atexit and stuff
210 _exit(0);
211 }
212
213 default:
214 // parent
215 {
216 // wait till server is up
217 sleep(1);
218 socket_client_connection sc("./socket");
fb3345ad 219 command_client cc(&sc);
539b09c0
GE
220
221 result_container rc;
222 cc.send_command(new testfunc4a_cmd("hello"),rc);
223
224 string ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
225
226 CPPUNIT_ASSERT_EQUAL(string("hello, testfunc() was here"),ret);
227 }
228 }
229 }
230
231 void WrongGroup()
232 {
b5922184 233 switch(child_pid=fork())
539b09c0
GE
234 {
235 case -1:
236 {
237 CPPUNIT_FAIL("fork error");
238 break;
239 }
240 case 0:
241 // child
242 {
441d41fe
TJ
243 try
244 {
245 socket_server ss("./socket");
246 group_command_server<cmd_group_b> cs(ss);
539b09c0 247
441d41fe
TJ
248 // max 10 sec
249 for (int i=0; i < 10; i++)
250 cs.handle(1000000);
251 } catch(...)
252 {
253 std::cerr << "exception in child. ignoring\n";
254 }
539b09c0
GE
255
256 // don't call atexit and stuff
257 _exit(0);
258 }
259
260 default:
261 // parent
262 {
263 // wait till server is up
264 sleep(1);
265 socket_client_connection sc("./socket");
fb3345ad 266 command_client cc(&sc);
539b09c0
GE
267
268 result_container rc;
269 cc.send_command(new testfunc4a_cmd("hello"),rc);
270
271 string ret;
272
273 try
274 {
275 ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
276 }
277 catch(t2n_command_error &e)
278 { ret=e.what(); }
279 catch(...)
280 { throw; }
281
282 string expected_what="illegal command of type ";
283
284 CPPUNIT_ASSERT_EQUAL(expected_what,ret.substr(0,expected_what.size()));
285 }
286 }
287 }
288
289};
290
291CPPUNIT_TEST_SUITE_REGISTRATION(test_cmdgroup);