libt2n: (gerd) finish server callbacks
[libt2n] / test / callback.cpp
... / ...
CommitLineData
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#include <vector>
18
19#include <boost/bind.hpp>
20
21#include <cppunit/extensions/TestFactoryRegistry.h>
22#include <cppunit/ui/text/TestRunner.h>
23#include <cppunit/extensions/HelperMacros.h>
24
25#include <socket_client.hxx>
26#include <socket_server.hxx>
27
28using namespace std;
29using namespace libt2n;
30using namespace CppUnit;
31
32class test_callback : public TestFixture
33{
34 CPPUNIT_TEST_SUITE(test_callback);
35
36 CPPUNIT_TEST(NewConnCallback);
37 CPPUNIT_TEST(ConnClosedCallback);
38 CPPUNIT_TEST(ConnDeletedCallback);
39 CPPUNIT_TEST(CallbackOrder);
40
41 CPPUNIT_TEST_SUITE_END();
42
43 std::vector<bool> callback_done;
44
45 public:
46
47 void setUp()
48 {
49 callback_done.resize(__events_end);
50 }
51
52 void tearDown()
53 {
54 callback_done.clear();
55 }
56
57 void callback_func(callback_event_type ev, int conn_id)
58 {
59 // we don't care for the conn_id, we just mark the callback as done
60 if (callback_done[ev])
61 throw runtime_error("callback already done for this event");
62
63 callback_done[ev]=true;
64 }
65
66 void NewConnCallback()
67 {
68 pid_t pid;
69
70 switch(pid=fork())
71 {
72 case -1:
73 {
74 CPPUNIT_FAIL("fork error");
75 break;
76 }
77 case 0:
78 // child
79 {
80 string data;
81 // wait till server is up
82 sleep(1);
83
84 {
85 socket_client_connection sc("./socket");
86
87 sc.write("ABC");
88
89 // wait half a sec
90 sc.fill_buffer(500000);
91 sc.get_packet(data);
92
93 // close the connection
94 }
95
96 // don't call atexit and stuff
97 _exit(0);
98 }
99
100 default:
101 // parent
102 {
103 socket_server ss("./socket");
104
105 ss.add_callback(new_connection,bind(&test_callback::callback_func, boost::ref(*this), new_connection, _1));
106
107 // max 3 sec
108 for (int i=0; i < 3; i++)
109 {
110 ss.fill_buffer(1000000);
111
112 string data;
113 unsigned int cid;
114 if(ss.get_packet(data,cid))
115 {
116 server_connection* con=ss.get_connection(cid);
117 con->write("XYZ");
118 }
119 }
120 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[new_connection]));
121 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
122 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
123 }
124 }
125 }
126
127 void ConnClosedCallback()
128 {
129 pid_t pid;
130
131 switch(pid=fork())
132 {
133 case -1:
134 {
135 CPPUNIT_FAIL("fork error");
136 break;
137 }
138 case 0:
139 // child
140 {
141 string data;
142 // wait till server is up
143 sleep(1);
144
145 {
146 socket_client_connection sc("./socket");
147
148 sc.write("ABC");
149
150 // wait half a sec
151 sc.fill_buffer(500000);
152 sc.get_packet(data);
153
154 // close the connection
155 }
156
157 // don't call atexit and stuff
158 _exit(0);
159 }
160
161 default:
162 // parent
163 {
164 socket_server ss("./socket");
165
166 ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1));
167
168 // max 3 sec
169 for (int i=0; i < 3; i++)
170 {
171 ss.fill_buffer(1000000);
172
173 string data;
174 unsigned int cid;
175 if(ss.get_packet(data,cid))
176 {
177 server_connection* con=ss.get_connection(cid);
178 con->write("XYZ");
179 }
180 }
181 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
182 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
183 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
184 }
185 }
186 }
187
188 void ConnDeletedCallback()
189 {
190 pid_t pid;
191
192 switch(pid=fork())
193 {
194 case -1:
195 {
196 CPPUNIT_FAIL("fork error");
197 break;
198 }
199 case 0:
200 // child
201 {
202 string data;
203 // wait till server is up
204 sleep(1);
205
206 {
207 socket_client_connection sc("./socket");
208
209 sc.write("ABC");
210
211 // wait half a sec
212 sc.fill_buffer(500000);
213 sc.get_packet(data);
214
215 // close the connection
216 }
217
218 // don't call atexit and stuff
219 _exit(0);
220 }
221
222 default:
223 // parent
224 {
225 socket_server ss("./socket");
226
227 ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1));
228
229 // max 3 sec
230 for (int i=0; i < 3; i++)
231 {
232 ss.fill_buffer(1000000);
233
234 string data;
235 unsigned int cid;
236 if(ss.get_packet(data,cid))
237 {
238 server_connection* con=ss.get_connection(cid);
239 con->write("XYZ");
240 }
241 ss.cleanup();
242 }
243 ss.cleanup();
244
245 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
246 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
247 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
248 }
249 }
250 }
251
252 void CallbackOrder()
253 {
254 pid_t pid;
255
256 switch(pid=fork())
257 {
258 case -1:
259 {
260 CPPUNIT_FAIL("fork error");
261 break;
262 }
263 case 0:
264 // child
265 {
266 string data;
267 // wait till server is up
268 sleep(1);
269
270 {
271 socket_client_connection sc("./socket");
272
273 sc.write("1");
274
275 // wait half a sec
276 sc.fill_buffer(500000);
277 sc.get_packet(data);
278
279 sc.write("2");
280
281 // close the connection
282 }
283
284 // don't call atexit and stuff
285 _exit(0);
286 }
287
288 default:
289 // parent
290 {
291 socket_server ss("./socket");
292
293 ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1));
294 ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1));
295
296 bool got_1=false;
297
298 for (int i=0; i < 4; i++)
299 {
300 ss.fill_buffer(500000);
301
302 string data;
303 unsigned int cid;
304 if(!got_1 && ss.get_packet(data,cid))
305 {
306 server_connection* con=ss.get_connection(cid);
307 con->write("XYZ");
308 got_1=true;
309 // don't call get_packet anymore
310 }
311 ss.cleanup();
312 }
313 ss.cleanup();
314
315 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
316 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
317
318 for (int i=0; i < 4; i++)
319 {
320 ss.fill_buffer(500000);
321
322 string data;
323 unsigned int cid;
324 ss.get_packet(data,cid);
325 ss.cleanup();
326 }
327 ss.cleanup();
328
329 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
330 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
331 }
332 }
333 }
334
335};
336
337CPPUNIT_TEST_SUITE_REGISTRATION(test_callback);