install makefile snippet and .pc file template
[libt2n] / test / cmdgroup.cpp
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
35 using namespace std;
36 using namespace CppUnit;
37 using namespace libt2n;
38
39 string 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
48 class 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
76 class 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
87 class 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
98 class 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
126 class 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
155 BOOST_CLASS_EXPORT(testfunc4_res)
156 BOOST_CLASS_EXPORT(cmd_group_a)
157 BOOST_CLASS_EXPORT(cmd_group_b)
158 BOOST_CLASS_EXPORT(testfunc4a_cmd)
159 BOOST_CLASS_EXPORT(testfunc4b_cmd)
160
161 class 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
170     public:
171
172     void setUp()
173     { }
174
175     void tearDown()
176     { }
177
178     void GroupOk()
179     {
180         pid_t pid;
181
182         switch(pid=fork())
183         {
184             case -1:
185             {
186                 CPPUNIT_FAIL("fork error");
187                 break;
188             }
189             case 0:
190             // child
191             {
192                 socket_server ss("./socket");
193                 group_command_server<cmd_group_a> cs(ss);
194
195                 // max 10 sec
196                 for (int i=0; i < 10; i++)
197                     cs.handle(1000000);
198
199                 // don't call atexit and stuff
200                 _exit(0);
201             }
202
203             default:
204             // parent
205             {
206                 // wait till server is up
207                 sleep(1);
208                 socket_client_connection sc("./socket");
209                 command_client cc(sc);
210
211                 result_container rc;
212                 cc.send_command(new testfunc4a_cmd("hello"),rc);
213
214                 string ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
215
216                 CPPUNIT_ASSERT_EQUAL(string("hello, testfunc() was here"),ret);
217             }
218         }
219     }
220
221     void WrongGroup()
222     {
223         pid_t pid;
224
225         switch(pid=fork())
226         {
227             case -1:
228             {
229                 CPPUNIT_FAIL("fork error");
230                 break;
231             }
232             case 0:
233             // child
234             {
235                 socket_server ss("./socket");
236                 group_command_server<cmd_group_b> cs(ss);
237
238                 // max 10 sec
239                 for (int i=0; i < 10; i++)
240                     cs.handle(1000000);
241
242                 // don't call atexit and stuff
243                 _exit(0);
244             }
245
246             default:
247             // parent
248             {
249                 // wait till server is up
250                 sleep(1);
251                 socket_client_connection sc("./socket");
252                 command_client cc(sc);
253
254                 result_container rc;
255                 cc.send_command(new testfunc4a_cmd("hello"),rc);
256
257                 string ret;
258
259                 try
260                 {
261                     ret=dynamic_cast<testfunc4_res*>(rc.get_result())->get_data();
262                 }
263                 catch(t2n_command_error &e)
264                     { ret=e.what(); }
265                 catch(...)
266                     { throw; }
267
268                 string expected_what="illegal command of type ";
269
270                 CPPUNIT_ASSERT_EQUAL(expected_what,ret.substr(0,expected_what.size()));
271             }
272         }
273     }
274
275 };
276
277 CPPUNIT_TEST_SUITE_REGISTRATION(test_cmdgroup);