Prepare libt2n 0.7 release
[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
307b5e74
TJ
33#define BOOST_TEST_DYN_LINK
34#include <boost/test/unit_test.hpp>
539b09c0
GE
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
307b5e74
TJ
49#include "test_fixtures.hxx"
50
539b09c0 51using namespace std;
539b09c0
GE
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
b5922184 176
307b5e74 177BOOST_FIXTURE_TEST_SUITE(test_cmdgroup, KillChildOnShutdownFixture)
539b09c0 178
307b5e74
TJ
179BOOST_AUTO_TEST_CASE(GroupOk)
180{
181 switch(child_pid=fork())
539b09c0 182 {
307b5e74 183 case -1:
539b09c0 184 {
307b5e74
TJ
185 BOOST_FAIL("fork error");
186 break;
187 }
188 case 0:
189 // child
190 {
191 try
539b09c0 192 {
307b5e74
TJ
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(...)
539b09c0 200 {
307b5e74 201 std::cerr << "exception in child. ignoring\n";
539b09c0
GE
202 }
203
307b5e74
TJ
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);
539b09c0 215
307b5e74
TJ
216 result_container rc;
217 cc.send_command(new testfunc4a_cmd("hello"),rc);
539b09c0 218
307b5e74 219 string ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
539b09c0 220
307b5e74 221 BOOST_CHECK_EQUAL(string("hello, testfunc() was here"),ret);
539b09c0
GE
222 }
223 }
307b5e74 224}
539b09c0 225
307b5e74
TJ
226BOOST_AUTO_TEST_CASE(WrongGroup)
227{
228 switch(child_pid=fork())
539b09c0 229 {
307b5e74 230 case -1:
539b09c0 231 {
307b5e74
TJ
232 BOOST_FAIL("fork error");
233 break;
234 }
235 case 0:
236 // child
237 {
238 try
539b09c0 239 {
307b5e74
TJ
240 socket_server ss("./socket");
241 group_command_server<cmd_group_b> cs(ss);
539b09c0 242
307b5e74
TJ
243 // max 10 sec
244 for (int i=0; i < 10; i++)
245 cs.handle(1000000);
246 } catch(...)
539b09c0 247 {
307b5e74
TJ
248 std::cerr << "exception in child. ignoring\n";
249 }
539b09c0 250
307b5e74
TJ
251 // don't call atexit and stuff
252 _exit(0);
253 }
539b09c0 254
307b5e74
TJ
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);
539b09c0 262
307b5e74
TJ
263 result_container rc;
264 cc.send_command(new testfunc4a_cmd("hello"),rc);
539b09c0 265
307b5e74 266 string ret;
539b09c0 267
307b5e74
TJ
268 try
269 {
270 ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
539b09c0 271 }
307b5e74
TJ
272 catch(t2n_command_error &e)
273 { ret=e.what(); }
307b5e74
TJ
274
275 string expected_what="illegal command of type ";
276
277 BOOST_CHECK_EQUAL(expected_what,ret.substr(0,expected_what.size()));
539b09c0
GE
278 }
279 }
307b5e74 280}
539b09c0 281
307b5e74 282BOOST_AUTO_TEST_SUITE_END()