Increase version
[libt2n] / test / callback.cpp
... / ...
CommitLineData
1/*
2Copyright (C) 2004 by Intra2net AG
3
4The software in this package is distributed under the GNU General
5Public License version 2 (with a special exception described below).
6
7A copy of GNU General Public License (GPL) is included in this distribution,
8in the file COPYING.GPL.
9
10As a special exception, if other files instantiate templates or use macros
11or inline functions from this file, or you compile this file and link it
12with other works to produce a work based on this file, this file
13does not by itself cause the resulting work to be covered
14by the GNU General Public License.
15
16However the source code for this file must still be made available
17in accordance with section (3) of the GNU General Public License.
18
19This exception does not invalidate any other reasons why a work based
20on this file might be covered by the GNU General Public License.
21*/
22#include <sys/types.h>
23#include <unistd.h>
24#include <errno.h>
25#include <signal.h>
26#include <stdio.h>
27
28#include <iostream>
29#include <string>
30#include <sstream>
31#include <stdexcept>
32#include <vector>
33
34#include <boost/bind.hpp>
35
36#define BOOST_TEST_DYN_LINK
37#include <boost/test/unit_test.hpp>
38
39#include <socket_client.hxx>
40#include <socket_server.hxx>
41
42#include "test_fixtures.hxx"
43
44using namespace std;
45using namespace libt2n;
46
47class test_callbackFixture : public KillChildOnShutdownFixture
48{
49protected:
50 std::vector<bool> callback_done;
51
52 void callback_func(callback_event_type ev, int conn_id)
53 {
54 // we don't care for the conn_id, we just mark the callback as done
55 if (callback_done[ev])
56 throw runtime_error("callback already done for this event");
57
58 callback_done[ev]=true;
59 }
60
61public:
62 test_callbackFixture()
63 {
64 callback_done.resize(__events_end);
65 }
66
67 ~test_callbackFixture()
68 {
69 callback_done.clear();
70 }
71};
72
73BOOST_FIXTURE_TEST_SUITE(test_callback, test_callbackFixture)
74
75BOOST_AUTO_TEST_CASE(ServerNewConnCallback)
76{
77 switch(child_pid=fork())
78 {
79 case -1:
80 {
81 BOOST_FAIL("fork error");
82 break;
83 }
84 case 0:
85 // child
86 {
87 try
88 {
89 string data;
90 // wait till server is up
91 sleep(1);
92
93 {
94 socket_client_connection sc("./socket");
95
96 sc.write("ABC");
97
98 // wait half a sec
99 sc.fill_buffer(500000);
100 sc.get_packet(data);
101
102 // close the connection
103 }
104 } catch(...)
105 {
106 std::cerr << "exception in child. ignoring\n";
107 }
108
109 // don't call atexit and stuff
110 _exit(0);
111 }
112
113 default:
114 // parent
115 {
116 socket_server ss("./socket");
117
118 ss.add_callback(new_connection,bind(&test_callback::ServerNewConnCallback::callback_func, boost::ref(*this), new_connection, _1));
119
120 // max 3 sec
121 for (int i=0; i < 3; i++)
122 {
123 ss.fill_buffer(1000000);
124
125 string data;
126 unsigned int cid;
127 if(ss.get_packet(data,cid))
128 {
129 server_connection* con=ss.get_connection(cid);
130 con->write("XYZ");
131 }
132 }
133 BOOST_CHECK_EQUAL(true,static_cast<bool>(callback_done[new_connection]));
134 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
135 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
136 }
137 }
138}
139
140BOOST_AUTO_TEST_CASE(ServerConnClosedCallback)
141{
142 switch(child_pid=fork())
143 {
144 case -1:
145 {
146 BOOST_FAIL("fork error");
147 break;
148 }
149 case 0:
150 // child
151 {
152 try
153 {
154 string data;
155 // wait till server is up
156 sleep(1);
157
158 {
159 socket_client_connection sc("./socket");
160
161 sc.write("ABC");
162
163 // wait half a sec
164 sc.fill_buffer(500000);
165 sc.get_packet(data);
166
167 // close the connection
168 }
169 } catch(...)
170 {
171 std::cerr << "exception in child. ignoring\n";
172 }
173
174 // don't call atexit and stuff
175 _exit(0);
176 }
177
178 default:
179 // parent
180 {
181 socket_server ss("./socket");
182
183 ss.add_callback(connection_closed,bind(&test_callback::ServerConnClosedCallback::callback_func, boost::ref(*this), connection_closed, _1));
184
185 // max 3 sec
186 for (int i=0; i < 3; i++)
187 {
188 ss.fill_buffer(1000000);
189
190 string data;
191 unsigned int cid;
192 if(ss.get_packet(data,cid))
193 {
194 server_connection* con=ss.get_connection(cid);
195 con->write("XYZ");
196 }
197 }
198 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
199 BOOST_CHECK_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
200 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
201 }
202 }
203}
204
205BOOST_AUTO_TEST_CASE(ServerConnDeletedCallback)
206{
207 switch(child_pid=fork())
208 {
209 case -1:
210 {
211 BOOST_FAIL("fork error");
212 break;
213 }
214 case 0:
215 // child
216 {
217 try
218 {
219 string data;
220 // wait till server is up
221 sleep(1);
222
223 {
224 socket_client_connection sc("./socket");
225
226 sc.write("ABC");
227
228 // wait half a sec
229 sc.fill_buffer(500000);
230 sc.get_packet(data);
231
232 // close the connection
233 }
234 } catch(...)
235 {
236 std::cerr << "exception in child. ignoring\n";
237 }
238
239 // don't call atexit and stuff
240 _exit(0);
241 }
242
243 default:
244 // parent
245 {
246 socket_server ss("./socket");
247
248 ss.add_callback(connection_deleted,bind(&test_callback::ServerConnDeletedCallback::callback_func, boost::ref(*this), connection_deleted, _1));
249
250 // max 3 sec
251 for (int i=0; i < 3; i++)
252 {
253 ss.fill_buffer(1000000);
254
255 string data;
256 unsigned int cid;
257 if(ss.get_packet(data,cid))
258 {
259 server_connection* con=ss.get_connection(cid);
260 con->write("XYZ");
261 }
262 ss.cleanup();
263 }
264 ss.cleanup();
265
266 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
267 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
268 BOOST_CHECK_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
269 }
270 }
271}
272
273BOOST_AUTO_TEST_CASE(ServerCallbackOrder)
274{
275 switch(child_pid=fork())
276 {
277 case -1:
278 {
279 BOOST_FAIL("fork error");
280 break;
281 }
282 case 0:
283 // child
284 {
285 try
286 {
287 string data;
288 // wait till server is up
289 sleep(1);
290
291 {
292 socket_client_connection sc("./socket");
293
294 sc.write("1");
295
296 // wait half a sec
297 sc.fill_buffer(500000);
298 sc.get_packet(data);
299
300 sc.write("2");
301
302 // close the connection
303 }
304 } catch(...)
305 {
306 std::cerr << "exception in child. ignoring\n";
307 }
308
309 // don't call atexit and stuff
310 _exit(0);
311 }
312
313 default:
314 // parent
315 {
316 socket_server ss("./socket");
317
318 ss.add_callback(connection_closed,bind(&test_callback::ServerCallbackOrder::callback_func, boost::ref(*this), connection_closed, _1));
319 ss.add_callback(connection_deleted,bind(&test_callback::ServerCallbackOrder::callback_func, boost::ref(*this), connection_deleted, _1));
320
321 bool got_1=false;
322
323 for (int i=0; i < 5; i++)
324 {
325 ss.fill_buffer(500000);
326
327 string data;
328 unsigned int cid;
329 if(!got_1 && ss.get_packet(data,cid))
330 {
331 server_connection* con=ss.get_connection(cid);
332 con->write("XYZ");
333 got_1=true;
334 // don't call get_packet anymore
335 }
336 ss.cleanup();
337 }
338 ss.cleanup();
339
340 BOOST_CHECK_MESSAGE(static_cast<bool>(callback_done[connection_closed]) == true, "closed done");
341 BOOST_CHECK_MESSAGE(static_cast<bool>(callback_done[connection_deleted]) == false, "not deleted yet");
342
343 for (int i=0; i < 4; i++)
344 {
345 ss.fill_buffer(500000);
346
347 string data;
348 unsigned int cid;
349 ss.get_packet(data,cid);
350 ss.cleanup();
351 }
352 ss.cleanup();
353
354 BOOST_CHECK_MESSAGE(static_cast<bool>(callback_done[connection_closed]) == true, "closed done (2)");
355 BOOST_CHECK_MESSAGE(static_cast<bool>(callback_done[connection_deleted]) == true, "not deleted yet(2)");
356 }
357 }
358}
359
360BOOST_AUTO_TEST_CASE(ClientConnClosedCallback)
361{
362 switch(child_pid=fork())
363 {
364 case -1:
365 {
366 BOOST_FAIL("fork error");
367 break;
368 }
369 case 0:
370 // child
371 {
372 try
373 {
374 socket_server ss("./socket");
375
376 // max 3 sec
377 for (int i=0; i < 3; i++)
378 {
379 ss.fill_buffer(1000000);
380
381 string data;
382 unsigned int cid;
383 if(ss.get_packet(data,cid))
384 break;
385 }
386 } catch(...)
387 {
388 std::cerr << "exception in child. ignoring\n";
389 }
390
391 // don't call atexit and stuff
392 _exit(0);
393 }
394
395 default:
396 // parent
397 {
398 string data;
399 // wait till server is up
400 sleep(1);
401
402 socket_client_connection sc("./socket");
403
404 sc.add_callback(connection_closed,bind(&test_callback::ClientConnClosedCallback::callback_func, boost::ref(*this), connection_closed, 0));
405
406 sc.write("ABC");
407
408 // wait half a sec
409 sc.fill_buffer(500000);
410 sc.get_packet(data);
411
412 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
413 BOOST_CHECK_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
414 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
415 }
416 }
417}
418
419BOOST_AUTO_TEST_CASE(ClientConnDeletedCallback)
420{
421 switch(child_pid=fork())
422 {
423 case -1:
424 {
425 BOOST_FAIL("fork error");
426 break;
427 }
428 case 0:
429 // child
430 {
431 try
432 {
433 socket_server ss("./socket");
434
435 // max 3 sec
436 for (int i=0; i < 3; i++)
437 {
438 ss.fill_buffer(1000000);
439
440 string data;
441 unsigned int cid;
442 if(ss.get_packet(data,cid))
443 break;
444 }
445 } catch(...)
446 {
447 std::cerr << "exception in child. ignoring\n";
448 }
449
450 // don't call atexit and stuff
451 _exit(0);
452 }
453
454 default:
455 // parent
456 {
457 string data;
458 // wait till server is up
459 sleep(1);
460
461 {
462 socket_client_connection sc("./socket");
463
464 sc.add_callback(connection_deleted,bind(&test_callback::ClientConnDeletedCallback::callback_func, boost::ref(*this), connection_deleted, 0));
465
466 sc.write("ABC");
467
468 // wait half a sec
469 sc.fill_buffer(500000);
470 sc.get_packet(data);
471 }
472
473 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
474 BOOST_CHECK_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
475 BOOST_CHECK_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
476 }
477 }
478}
479
480BOOST_AUTO_TEST_SUITE_END()