libt2n: (gerd) make sure no exception is thrown in command_client constructor, fix...
[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 {
196 socket_server ss("./socket");
197 group_command_server<cmd_group_a> cs(ss);
198
199 // max 10 sec
200 for (int i=0; i < 10; i++)
201 cs.handle(1000000);
202
203 // don't call atexit and stuff
204 _exit(0);
205 }
206
207 default:
208 // parent
209 {
210 // wait till server is up
211 sleep(1);
212 socket_client_connection sc("./socket");
fb3345ad 213 command_client cc(&sc);
539b09c0
GE
214
215 result_container rc;
216 cc.send_command(new testfunc4a_cmd("hello"),rc);
217
218 string ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
219
220 CPPUNIT_ASSERT_EQUAL(string("hello, testfunc() was here"),ret);
221 }
222 }
223 }
224
225 void WrongGroup()
226 {
b5922184 227 switch(child_pid=fork())
539b09c0
GE
228 {
229 case -1:
230 {
231 CPPUNIT_FAIL("fork error");
232 break;
233 }
234 case 0:
235 // child
236 {
237 socket_server ss("./socket");
238 group_command_server<cmd_group_b> cs(ss);
239
240 // max 10 sec
241 for (int i=0; i < 10; i++)
242 cs.handle(1000000);
243
244 // don't call atexit and stuff
245 _exit(0);
246 }
247
248 default:
249 // parent
250 {
251 // wait till server is up
252 sleep(1);
253 socket_client_connection sc("./socket");
fb3345ad 254 command_client cc(&sc);
539b09c0
GE
255
256 result_container rc;
257 cc.send_command(new testfunc4a_cmd("hello"),rc);
258
259 string ret;
260
261 try
262 {
263 ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
264 }
265 catch(t2n_command_error &e)
266 { ret=e.what(); }
267 catch(...)
268 { throw; }
269
270 string expected_what="illegal command of type ";
271
272 CPPUNIT_ASSERT_EQUAL(expected_what,ret.substr(0,expected_what.size()));
273 }
274 }
275 }
276
277};
278
279CPPUNIT_TEST_SUITE_REGISTRATION(test_cmdgroup);