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