Update to newer boost autoconf macros
[libt2n] / test / callback.cpp
CommitLineData
19facd85
TJ
1/*
2Copyright (C) 2004 by Intra2net AG
6cda58a6 3
19facd85
TJ
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*/
6cda58a6
GE
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#include <cppunit/extensions/TestFactoryRegistry.h>
37#include <cppunit/ui/text/TestRunner.h>
38#include <cppunit/extensions/HelperMacros.h>
39
40#include <socket_client.hxx>
41#include <socket_server.hxx>
42
43using namespace std;
44using namespace libt2n;
45using namespace CppUnit;
46
47class test_callback : public TestFixture
48{
49 CPPUNIT_TEST_SUITE(test_callback);
50
91730468
GE
51 CPPUNIT_TEST(ServerNewConnCallback);
52 CPPUNIT_TEST(ServerConnClosedCallback);
53 CPPUNIT_TEST(ServerConnDeletedCallback);
54 CPPUNIT_TEST(ServerCallbackOrder);
55 CPPUNIT_TEST(ClientConnClosedCallback);
56 CPPUNIT_TEST(ClientConnDeletedCallback);
6cda58a6
GE
57
58 CPPUNIT_TEST_SUITE_END();
59
60 std::vector<bool> callback_done;
61
b5922184
GE
62 pid_t child_pid;
63
6cda58a6
GE
64 public:
65
66 void setUp()
67 {
68 callback_done.resize(__events_end);
69 }
70
71 void tearDown()
72 {
73 callback_done.clear();
b5922184
GE
74
75 // make sure the server-child is dead before the next test runs
76 kill(child_pid,SIGKILL);
77 sleep(1);
6cda58a6
GE
78 }
79
80 void callback_func(callback_event_type ev, int conn_id)
81 {
82 // we don't care for the conn_id, we just mark the callback as done
83 if (callback_done[ev])
84 throw runtime_error("callback already done for this event");
85
86 callback_done[ev]=true;
87 }
88
91730468 89 void ServerNewConnCallback()
6cda58a6 90 {
b5922184 91 switch(child_pid=fork())
6cda58a6
GE
92 {
93 case -1:
94 {
95 CPPUNIT_FAIL("fork error");
96 break;
97 }
98 case 0:
99 // child
100 {
441d41fe 101 try
6cda58a6 102 {
441d41fe
TJ
103 string data;
104 // wait till server is up
105 sleep(1);
6cda58a6 106
441d41fe
TJ
107 {
108 socket_client_connection sc("./socket");
6cda58a6 109
441d41fe 110 sc.write("ABC");
6cda58a6 111
441d41fe
TJ
112 // wait half a sec
113 sc.fill_buffer(500000);
114 sc.get_packet(data);
115
116 // close the connection
117 }
118 } catch(...)
119 {
120 std::cerr << "exception in child. ignoring\n";
6cda58a6
GE
121 }
122
123 // don't call atexit and stuff
124 _exit(0);
125 }
126
127 default:
128 // parent
129 {
130 socket_server ss("./socket");
131
132 ss.add_callback(new_connection,bind(&test_callback::callback_func, boost::ref(*this), new_connection, _1));
133
134 // max 3 sec
135 for (int i=0; i < 3; i++)
136 {
137 ss.fill_buffer(1000000);
138
139 string data;
140 unsigned int cid;
141 if(ss.get_packet(data,cid))
142 {
143 server_connection* con=ss.get_connection(cid);
144 con->write("XYZ");
145 }
146 }
147 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[new_connection]));
148 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
149 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
150 }
151 }
152 }
153
91730468 154 void ServerConnClosedCallback()
6cda58a6 155 {
b5922184 156 switch(child_pid=fork())
6cda58a6
GE
157 {
158 case -1:
159 {
160 CPPUNIT_FAIL("fork error");
161 break;
162 }
163 case 0:
164 // child
165 {
441d41fe 166 try
6cda58a6 167 {
441d41fe
TJ
168 string data;
169 // wait till server is up
170 sleep(1);
6cda58a6 171
441d41fe
TJ
172 {
173 socket_client_connection sc("./socket");
6cda58a6 174
441d41fe
TJ
175 sc.write("ABC");
176
177 // wait half a sec
178 sc.fill_buffer(500000);
179 sc.get_packet(data);
6cda58a6 180
441d41fe
TJ
181 // close the connection
182 }
183 } catch(...)
184 {
185 std::cerr << "exception in child. ignoring\n";
6cda58a6
GE
186 }
187
188 // don't call atexit and stuff
189 _exit(0);
190 }
191
192 default:
193 // parent
194 {
195 socket_server ss("./socket");
196
197 ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1));
198
199 // max 3 sec
200 for (int i=0; i < 3; i++)
201 {
202 ss.fill_buffer(1000000);
203
204 string data;
205 unsigned int cid;
206 if(ss.get_packet(data,cid))
207 {
208 server_connection* con=ss.get_connection(cid);
209 con->write("XYZ");
210 }
211 }
212 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
213 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
214 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
215 }
216 }
217 }
218
91730468 219 void ServerConnDeletedCallback()
6cda58a6 220 {
b5922184 221 switch(child_pid=fork())
6cda58a6
GE
222 {
223 case -1:
224 {
225 CPPUNIT_FAIL("fork error");
226 break;
227 }
228 case 0:
229 // child
230 {
441d41fe 231 try
6cda58a6 232 {
441d41fe
TJ
233 string data;
234 // wait till server is up
235 sleep(1);
6cda58a6 236
441d41fe
TJ
237 {
238 socket_client_connection sc("./socket");
6cda58a6 239
441d41fe 240 sc.write("ABC");
6cda58a6 241
441d41fe
TJ
242 // wait half a sec
243 sc.fill_buffer(500000);
244 sc.get_packet(data);
245
246 // close the connection
247 }
248 } catch(...)
249 {
250 std::cerr << "exception in child. ignoring\n";
6cda58a6
GE
251 }
252
253 // don't call atexit and stuff
254 _exit(0);
255 }
256
257 default:
258 // parent
259 {
260 socket_server ss("./socket");
261
262 ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1));
263
264 // max 3 sec
265 for (int i=0; i < 3; i++)
266 {
267 ss.fill_buffer(1000000);
268
269 string data;
270 unsigned int cid;
271 if(ss.get_packet(data,cid))
272 {
273 server_connection* con=ss.get_connection(cid);
274 con->write("XYZ");
275 }
276 ss.cleanup();
277 }
278 ss.cleanup();
279
280 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
281 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
282 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
283 }
284 }
285 }
286
91730468 287 void ServerCallbackOrder()
6cda58a6 288 {
b5922184 289 switch(child_pid=fork())
6cda58a6
GE
290 {
291 case -1:
292 {
293 CPPUNIT_FAIL("fork error");
294 break;
295 }
296 case 0:
297 // child
298 {
441d41fe 299 try
6cda58a6 300 {
441d41fe
TJ
301 string data;
302 // wait till server is up
303 sleep(1);
6cda58a6 304
441d41fe
TJ
305 {
306 socket_client_connection sc("./socket");
6cda58a6 307
441d41fe
TJ
308 sc.write("1");
309
310 // wait half a sec
311 sc.fill_buffer(500000);
312 sc.get_packet(data);
6cda58a6 313
441d41fe 314 sc.write("2");
6cda58a6 315
441d41fe
TJ
316 // close the connection
317 }
318 } catch(...)
319 {
320 std::cerr << "exception in child. ignoring\n";
6cda58a6
GE
321 }
322
323 // don't call atexit and stuff
324 _exit(0);
325 }
326
327 default:
328 // parent
329 {
330 socket_server ss("./socket");
331
332 ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1));
333 ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1));
334
335 bool got_1=false;
336
af84dfb5 337 for (int i=0; i < 5; i++)
6cda58a6
GE
338 {
339 ss.fill_buffer(500000);
340
341 string data;
342 unsigned int cid;
343 if(!got_1 && ss.get_packet(data,cid))
344 {
345 server_connection* con=ss.get_connection(cid);
346 con->write("XYZ");
347 got_1=true;
348 // don't call get_packet anymore
349 }
350 ss.cleanup();
351 }
352 ss.cleanup();
353
af84dfb5
GE
354 CPPUNIT_ASSERT_EQUAL_MESSAGE("closed done",true,static_cast<bool>(callback_done[connection_closed]));
355 CPPUNIT_ASSERT_EQUAL_MESSAGE("not deleted yet",false,static_cast<bool>(callback_done[connection_deleted]));
6cda58a6
GE
356
357 for (int i=0; i < 4; i++)
358 {
359 ss.fill_buffer(500000);
360
361 string data;
362 unsigned int cid;
363 ss.get_packet(data,cid);
364 ss.cleanup();
365 }
366 ss.cleanup();
367
af84dfb5
GE
368 CPPUNIT_ASSERT_EQUAL_MESSAGE("closed done (2)",true,static_cast<bool>(callback_done[connection_closed]));
369 CPPUNIT_ASSERT_EQUAL_MESSAGE("deleted done",true,static_cast<bool>(callback_done[connection_deleted]));
6cda58a6
GE
370 }
371 }
372 }
373
91730468
GE
374 void ClientConnClosedCallback()
375 {
b5922184 376 switch(child_pid=fork())
91730468
GE
377 {
378 case -1:
379 {
380 CPPUNIT_FAIL("fork error");
381 break;
382 }
383 case 0:
384 // child
385 {
441d41fe 386 try
91730468 387 {
441d41fe 388 socket_server ss("./socket");
91730468 389
441d41fe
TJ
390 // max 3 sec
391 for (int i=0; i < 3; i++)
392 {
393 ss.fill_buffer(1000000);
394
395 string data;
396 unsigned int cid;
397 if(ss.get_packet(data,cid))
398 break;
399 }
400 } catch(...)
401 {
402 std::cerr << "exception in child. ignoring\n";
91730468 403 }
441d41fe 404
91730468
GE
405 // don't call atexit and stuff
406 _exit(0);
407 }
408
409 default:
410 // parent
411 {
412 string data;
413 // wait till server is up
414 sleep(1);
415
416 socket_client_connection sc("./socket");
417
418 sc.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, 0));
419
420 sc.write("ABC");
421
422 // wait half a sec
423 sc.fill_buffer(500000);
424 sc.get_packet(data);
425
426 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
427 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
428 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
429 }
430 }
431 }
432
433 void ClientConnDeletedCallback()
434 {
b5922184 435 switch(child_pid=fork())
91730468
GE
436 {
437 case -1:
438 {
439 CPPUNIT_FAIL("fork error");
440 break;
441 }
442 case 0:
443 // child
444 {
441d41fe 445 try
91730468 446 {
441d41fe 447 socket_server ss("./socket");
91730468 448
441d41fe
TJ
449 // max 3 sec
450 for (int i=0; i < 3; i++)
451 {
452 ss.fill_buffer(1000000);
453
454 string data;
455 unsigned int cid;
456 if(ss.get_packet(data,cid))
457 break;
458 }
459 } catch(...)
460 {
461 std::cerr << "exception in child. ignoring\n";
91730468 462 }
441d41fe 463
91730468
GE
464 // don't call atexit and stuff
465 _exit(0);
466 }
467
468 default:
469 // parent
470 {
471 string data;
472 // wait till server is up
473 sleep(1);
474
475 {
476 socket_client_connection sc("./socket");
477
478 sc.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, 0));
479
480 sc.write("ABC");
481
482 // wait half a sec
483 sc.fill_buffer(500000);
484 sc.get_packet(data);
485 }
486
487 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
488 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
489 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
490 }
491 }
492 }
6cda58a6
GE
493};
494
495CPPUNIT_TEST_SUITE_REGISTRATION(test_callback);