42721ea64a233763fee63063cce4807fe4955fbe
[libt2n] / test / simplecmd.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
28 #include <container.hxx>
29 #include <socket_client.hxx>
30 #include <socket_server.hxx>
31 #include <command_client.hxx>
32 #include <command_server.hxx>
33
34 using namespace std;
35 using namespace CppUnit;
36
37 string testfunc(const string& str)
38 {
39     string ret;
40     if (str=="throw")
41         throw libt2n::t2n_runtime_error("throw me around");
42     if (str=="big")
43         ret.insert(0,100*1024,'x');
44     else
45         ret=str+", testfunc() was here";
46     return ret;
47 }
48
49 class testfunc_res : public libt2n::result
50 {
51     private:
52         string res;
53
54         friend class boost::serialization::access;
55         template<class Archive>
56         void serialize(Archive & ar, const unsigned int version)
57         {
58             ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
59             ar & BOOST_SERIALIZATION_NVP(res);
60         }
61
62     public:
63         testfunc_res()
64             { }
65
66         testfunc_res(const string& str)
67         {
68             res=str;
69         }
70
71         string get_data()
72         {
73             return res;
74         }
75 };
76
77
78 class testfunc_cmd : public libt2n::command
79 {
80     private:
81         string param;
82
83         friend class boost::serialization::access;
84         template<class Archive>
85         void serialize(Archive & ar, const unsigned int version)
86         {
87             ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
88             ar & BOOST_SERIALIZATION_NVP(param);
89         }
90
91     public:
92         testfunc_cmd()
93             { }
94
95         testfunc_cmd(const string& str)
96         {
97             param=str;
98         }
99
100         libt2n::result* operator()()
101         {
102             return new testfunc_res(testfunc(param));
103         }
104 };
105
106 #include <boost/serialization/export.hpp>
107
108 BOOST_CLASS_EXPORT(testfunc_cmd)
109 BOOST_CLASS_EXPORT(testfunc_res)
110
111 using namespace libt2n;
112
113 class test_simplecmd : public TestFixture
114 {
115     CPPUNIT_TEST_SUITE(test_simplecmd);
116
117     CPPUNIT_TEST(SimpleCmd);
118     CPPUNIT_TEST(SimpleException);
119     CPPUNIT_TEST(BigReturn);
120     CPPUNIT_TEST(BigParameter);
121
122     CPPUNIT_TEST_SUITE_END();
123
124     public:
125
126     void setUp()
127     {
128 }
129
130     void tearDown()
131     { }
132
133     void SimpleCmd()
134     {
135         pid_t pid;
136
137         switch(pid=fork())
138         {
139             case -1:
140             {
141                 CPPUNIT_FAIL("fork error");
142                 break;
143             }
144             case 0:
145             // child
146             {
147                 socket_server ss("./socket");
148                 command_server cs(ss);
149
150                 // max 10 sec
151                 for (int i=0; i < 10; i++)
152                     cs.handle(1000000);
153
154                 // don't call atexit and stuff
155                 _exit(0);
156             }
157
158             default:
159             // parent
160             {
161                 // wait till server is up
162                 sleep(1);
163                 socket_client_connection sc("./socket");
164                 sc.set_logging(&cerr,debug);
165                 command_client cc(&sc);
166
167                 result_container rc;
168                 cc.send_command(new testfunc_cmd("hello"),rc);
169
170                 string ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
171
172                 CPPUNIT_ASSERT_EQUAL(string("hello, testfunc() was here"),ret);
173             }
174         }
175         kill(pid,SIGKILL);
176     }
177
178     void SimpleException()
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                 command_server 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                 sc.set_logging(&cerr,debug);
210                 command_client cc(&sc);
211
212                 result_container rc;
213                 cc.send_command(new testfunc_cmd("throw"),rc);
214
215                 string ret;
216
217                 try
218                 {
219                     ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
220                 }
221                 catch(t2n_runtime_error &e)
222                     { ret=e.what(); }
223                 catch(...)
224                     { throw; }
225
226                 CPPUNIT_ASSERT_EQUAL(string("throw me around"),ret);
227
228                 kill(pid,SIGKILL);
229             }
230         }
231     }
232
233     void BigReturn()
234     {
235         pid_t pid;
236
237         switch(pid=fork())
238         {
239             case -1:
240             {
241                 CPPUNIT_FAIL("fork error");
242                 break;
243             }
244             case 0:
245             // child
246             {
247                 socket_server ss("./socket");
248                 command_server cs(ss);
249
250                 // max 10 sec
251                 for (int i=0; i < 10; i++)
252                     cs.handle(1000000);
253
254                 // don't call atexit and stuff
255                 _exit(0);
256             }
257
258             default:
259             // parent
260             {
261                 // wait till server is up
262                 sleep(1);
263                 socket_client_connection sc("./socket");
264                 command_client cc(&sc);
265
266                 result_container rc;
267                 cc.send_command(new testfunc_cmd("big"),rc);
268
269                 string ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
270
271                 CPPUNIT_ASSERT_EQUAL(string().insert(0,100*1024,'x'),ret);
272
273                 kill(pid,SIGKILL);
274             }
275         }
276     }
277
278     void BigParameter()
279     {
280         pid_t pid;
281
282         switch(pid=fork())
283         {
284             case -1:
285             {
286                 CPPUNIT_FAIL("fork error");
287                 break;
288             }
289             case 0:
290             // child
291             {
292                 socket_server ss("./socket");
293                 command_server cs(ss);
294
295                 // max 10 sec
296                 for (int i=0; i < 10; i++)
297                     cs.handle(1000000);
298
299                 // don't call atexit and stuff
300                 _exit(0);
301             }
302
303             default:
304             // parent
305             {
306                 // wait till server is up
307                 sleep(1);
308                 socket_client_connection sc("./socket");
309                 command_client cc(&sc);
310
311                 result_container rc;
312                 cc.send_command(new testfunc_cmd(string().insert(0,100*1024,'y')),rc);
313
314                 string ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
315
316                 CPPUNIT_ASSERT_EQUAL(string().insert(0,100*1024,'y')+", testfunc() was here",ret);
317
318                 kill(pid,SIGKILL);
319             }
320         }
321     }
322
323 };
324
325 CPPUNIT_TEST_SUITE_REGISTRATION(test_simplecmd);