libt2n: (gerd) add example for wrapper
[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
41command_server *global_server;
42
43string testfunc(const string& str)
44{
45 string ret;
46 ret=str+", testfunc() was here";
47
48 // call handle, eventually reentrant
49 global_server->handle(1000);
50
51 return ret;
52}
53
54class testfunc_res : public libt2n::result
55{
56 private:
57 string res;
58
59 friend class boost::serialization::access;
60 template<class Archive>
61 void serialize(Archive & ar, const unsigned int version)
62 {
63 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::result);
64 ar & BOOST_SERIALIZATION_NVP(res);
65 }
66
67 public:
68 testfunc_res()
69 { }
70
71 testfunc_res(const string& str)
72 {
73 res=str;
74 }
75
76 string get_data()
77 {
78 return res;
79 }
80};
81
82
83class testfunc_cmd : public libt2n::command
84{
85 private:
86 string param;
87
88 friend class boost::serialization::access;
89 template<class Archive>
90 void serialize(Archive & ar, const unsigned int version)
91 {
92 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(libt2n::command);
93 ar & BOOST_SERIALIZATION_NVP(param);
94 }
95
96 public:
97 testfunc_cmd()
98 { }
99
100 testfunc_cmd(const string& str)
101 {
102 param=str;
103 }
104
105 libt2n::result* operator()()
106 {
107 return new testfunc_res(testfunc(param));
108 }
109};
110
111}
112
113#include <boost/serialization/export.hpp>
114
115BOOST_CLASS_EXPORT(testfunc_cmd)
116BOOST_CLASS_EXPORT(testfunc_res)
117
118class test_reentrant : public TestFixture
119{
120 CPPUNIT_TEST_SUITE(test_reentrant);
121
122 CPPUNIT_TEST(ReentrantServer);
123
124 CPPUNIT_TEST_SUITE_END();
125
126 pid_t child_pid;
127
128 public:
129
130 void setUp()
131 { }
132
133 void tearDown()
134 { }
135
136 void ReentrantServer()
137 {
138 switch(child_pid=fork())
139 {
140 case -1:
141 {
142 CPPUNIT_FAIL("fork error");
143 break;
144 }
145 case 0:
146 // child
147 {
148 // wait till server is up
149 sleep(1);
150
151 // we want 8 identical childs hammering the server
152 fork();
153 fork();
154 fork();
155
156 for (int i=0; i < 100; i++)
157 {
158 socket_client_connection sc("./socket");
159 command_client cc(&sc);
160
161 result_container rc;
162 cc.send_command(new testfunc_cmd("hello"),rc);
163
164 string ret=dynamic_cast<testfunc_res*>(rc.get_result())->get_data();
165
166 CPPUNIT_ASSERT_EQUAL(string("hello, testfunc() was here"),ret);
167 }
168
169 // don't call atexit and stuff
170 _exit(0);
171 }
172
173 default:
174 // parent
175 {
176 socket_server ss("./socket");
177 command_server cs(ss);
178
179 global_server=&cs;
180
181 // max 10 sec
182 long long maxtime=5000000;
183 while(maxtime > 0)
184 cs.handle(maxtime,&maxtime);
185 }
186
187 // we are still alive, everything is ok
188 CPPUNIT_ASSERT_EQUAL(1,1);
189 }
190 }
191
192};
193
194
195CPPUNIT_TEST_SUITE_REGISTRATION(test_reentrant);