Prepare libt2n 0.7 release
[libt2n] / test / cmdgroup.cpp
... / ...
CommitLineData
1/*
2Copyright (C) 2004 by Intra2net AG
3
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*/
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#define BOOST_TEST_DYN_LINK
34#include <boost/test/unit_test.hpp>
35
36#include <boost/archive/binary_oarchive.hpp>
37#include <boost/archive/binary_iarchive.hpp>
38#include <boost/archive/xml_oarchive.hpp>
39#include <boost/archive/xml_iarchive.hpp>
40#include <boost/serialization/serialization.hpp>
41#include <boost/serialization/export.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
49#include "test_fixtures.hxx"
50
51using namespace std;
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
176
177BOOST_FIXTURE_TEST_SUITE(test_cmdgroup, KillChildOnShutdownFixture)
178
179BOOST_AUTO_TEST_CASE(GroupOk)
180{
181 switch(child_pid=fork())
182 {
183 case -1:
184 {
185 BOOST_FAIL("fork error");
186 break;
187 }
188 case 0:
189 // child
190 {
191 try
192 {
193 socket_server ss("./socket");
194 group_command_server<cmd_group_a> cs(ss);
195
196 // max 10 sec
197 for (int i=0; i < 10; i++)
198 cs.handle(1000000);
199 } catch(...)
200 {
201 std::cerr << "exception in child. ignoring\n";
202 }
203
204 // don't call atexit and stuff
205 _exit(0);
206 }
207
208 default:
209 // parent
210 {
211 // wait till server is up
212 sleep(1);
213 socket_client_connection sc("./socket");
214 command_client cc(&sc);
215
216 result_container rc;
217 cc.send_command(new testfunc4a_cmd("hello"),rc);
218
219 string ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
220
221 BOOST_CHECK_EQUAL(string("hello, testfunc() was here"),ret);
222 }
223 }
224}
225
226BOOST_AUTO_TEST_CASE(WrongGroup)
227{
228 switch(child_pid=fork())
229 {
230 case -1:
231 {
232 BOOST_FAIL("fork error");
233 break;
234 }
235 case 0:
236 // child
237 {
238 try
239 {
240 socket_server ss("./socket");
241 group_command_server<cmd_group_b> cs(ss);
242
243 // max 10 sec
244 for (int i=0; i < 10; i++)
245 cs.handle(1000000);
246 } catch(...)
247 {
248 std::cerr << "exception in child. ignoring\n";
249 }
250
251 // don't call atexit and stuff
252 _exit(0);
253 }
254
255 default:
256 // parent
257 {
258 // wait till server is up
259 sleep(1);
260 socket_client_connection sc("./socket");
261 command_client cc(&sc);
262
263 result_container rc;
264 cc.send_command(new testfunc4a_cmd("hello"),rc);
265
266 string ret;
267
268 try
269 {
270 ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
271 }
272 catch(t2n_command_error &e)
273 { ret=e.what(); }
274
275 string expected_what="illegal command of type ";
276
277 BOOST_CHECK_EQUAL(expected_what,ret.substr(0,expected_what.size()));
278 }
279 }
280}
281
282BOOST_AUTO_TEST_SUITE_END()