libt2n: (tomj) make result_container's has_exception and has_result a bit more robust
[libt2n] / test / reentrant.cpp
CommitLineData
3b2543e7
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
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
34using namespace std;
35using namespace CppUnit;
36using namespace libt2n;
37
38namespace
39{
40
d55e0d0f 41command_server *global_server = NULL;
3b2543e7
GE
42
43string testfunc(const string& str)
44{
45 string ret;
46 ret=str+", testfunc() was here";
47
48 // call handle, eventually reentrant
d55e0d0f 49 if (global_server)
56f3994d 50 global_server->handle(10000);
3b2543e7
GE
51
52 return ret;
53}
54
55class testfunc_res : public libt2n::result
56{
57 private:
58 string res;
59
60 friend class boost::serialization::access;
61 template<class Archive>
62 void serialize(Archive & ar, const unsigned int version)
63 {
64 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
65 ar & BOOST_SERIALIZATION_NVP(res);
66 }
67
68 public:
69 testfunc_res()
70 { }
71
72 testfunc_res(const string& str)
73 {
74 res=str;
75 }
76
77 string get_data()
78 {
79 return res;
80 }
81};
82
83
84class testfunc_cmd : public libt2n::command
85{
86 private:
87 string param;
88
89 friend class boost::serialization::access;
90 template<class Archive>
91 void serialize(Archive & ar, const unsigned int version)
92 {
93 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
94 ar & BOOST_SERIALIZATION_NVP(param);
95 }
96
97 public:
98 testfunc_cmd()
99 { }
100
101 testfunc_cmd(const string& str)
102 {
103 param=str;
104 }
105
106 libt2n::result* operator()()
107 {
108 return new testfunc_res(testfunc(param));
109 }
110};
111
112}
113
114#include <boost/serialization/export.hpp>
115
116BOOST_CLASS_EXPORT(testfunc_cmd)
117BOOST_CLASS_EXPORT(testfunc_res)
118
119class test_reentrant : public TestFixture
120{
121 CPPUNIT_TEST_SUITE(test_reentrant);
122
123 CPPUNIT_TEST(ReentrantServer);
124
125 CPPUNIT_TEST_SUITE_END();
126
3b2543e7
GE
127 public:
128
129 void setUp()
130 { }
131
132 void tearDown()
133 { }
134
135 void ReentrantServer()
136 {
56f3994d 137 switch(fork())
3b2543e7
GE
138 {
139 case -1:
140 {
141 CPPUNIT_FAIL("fork error");
142 break;
143 }
144 case 0:
145 // child
146 {
147 // wait till server is up
d55e0d0f 148 sleep(3);
3b2543e7
GE
149
150 // we want 8 identical childs hammering the server
151 fork();
152 fork();
153 fork();
154
56f3994d 155 try
3b2543e7 156 {
56f3994d
TJ
157 for (int i=0; i < 100; i++)
158 {
159 socket_client_connection sc("./socket");
160 command_client cc(&sc);
161
162 result_container rc;
163 cc.send_command(new testfunc_cmd("hello"),rc);
164
165 testfunc_res *res = dynamic_cast<testfunc_res*>(rc.get_result());
166 if (res)
167 {
168 string ret = res->get_data();
169 if (ret != "hello, testfunc() was here")
170 std::cout << "ERROR reentrant server testfunc_res failed, res: " << ret << "\n";
171 }
172 else
173 {
174 std::cout << "ERROR result from reentrant server empty\n";
175 }
176 }
177 } catch (exception &e)
178 {
179 cerr << "caught exception: " << e.what() << endl;
3b2543e7
GE
180 }
181
182 // don't call atexit and stuff
183 _exit(0);
184 }
185
186 default:
187 // parent
188 {
56f3994d
TJ
189 // don't kill us on broken pipe
190 signal(SIGPIPE, SIG_IGN);
191
3b2543e7
GE
192 socket_server ss("./socket");
193 command_server cs(ss);
194
195 global_server=&cs;
196
197 // max 10 sec
56f3994d 198 long long maxtime=1000000;
3b2543e7
GE
199 while(maxtime > 0)
200 cs.handle(maxtime,&maxtime);
56f3994d
TJ
201
202 // max 10 sec
203 maxtime=1000000;
204 while(maxtime > 0)
205 cs.handle(maxtime,&maxtime);
206
207 // max 10 sec
208 maxtime=1000000;
209 while(maxtime > 0)
210 cs.handle(maxtime,&maxtime);
211
d55e0d0f 212 global_server = NULL;
3b2543e7
GE
213 }
214
215 // we are still alive, everything is ok
216 CPPUNIT_ASSERT_EQUAL(1,1);
217 }
218 }
219
220};
221
222
223CPPUNIT_TEST_SUITE_REGISTRATION(test_reentrant);