libt2n: (reinhard) 1 Million is not enough! (+ doc fix)
[libt2n] / test / callback.cpp
CommitLineData
6cda58a6
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#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
91730468
GE
36 CPPUNIT_TEST(ServerNewConnCallback);
37 CPPUNIT_TEST(ServerConnClosedCallback);
38 CPPUNIT_TEST(ServerConnDeletedCallback);
39 CPPUNIT_TEST(ServerCallbackOrder);
40 CPPUNIT_TEST(ClientConnClosedCallback);
41 CPPUNIT_TEST(ClientConnDeletedCallback);
6cda58a6
GE
42
43 CPPUNIT_TEST_SUITE_END();
44
45 std::vector<bool> callback_done;
46
b5922184
GE
47 pid_t child_pid;
48
6cda58a6
GE
49 public:
50
51 void setUp()
52 {
53 callback_done.resize(__events_end);
54 }
55
56 void tearDown()
57 {
58 callback_done.clear();
b5922184
GE
59
60 // make sure the server-child is dead before the next test runs
61 kill(child_pid,SIGKILL);
62 sleep(1);
6cda58a6
GE
63 }
64
65 void callback_func(callback_event_type ev, int conn_id)
66 {
67 // we don't care for the conn_id, we just mark the callback as done
68 if (callback_done[ev])
69 throw runtime_error("callback already done for this event");
70
71 callback_done[ev]=true;
72 }
73
91730468 74 void ServerNewConnCallback()
6cda58a6 75 {
b5922184 76 switch(child_pid=fork())
6cda58a6
GE
77 {
78 case -1:
79 {
80 CPPUNIT_FAIL("fork error");
81 break;
82 }
83 case 0:
84 // child
85 {
86 string data;
87 // wait till server is up
88 sleep(1);
89
90 {
91 socket_client_connection sc("./socket");
92
93 sc.write("ABC");
94
95 // wait half a sec
96 sc.fill_buffer(500000);
97 sc.get_packet(data);
98
99 // close the connection
100 }
101
102 // don't call atexit and stuff
103 _exit(0);
104 }
105
106 default:
107 // parent
108 {
109 socket_server ss("./socket");
110
111 ss.add_callback(new_connection,bind(&test_callback::callback_func, boost::ref(*this), new_connection, _1));
112
113 // max 3 sec
114 for (int i=0; i < 3; i++)
115 {
116 ss.fill_buffer(1000000);
117
118 string data;
119 unsigned int cid;
120 if(ss.get_packet(data,cid))
121 {
122 server_connection* con=ss.get_connection(cid);
123 con->write("XYZ");
124 }
125 }
126 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[new_connection]));
127 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
128 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
129 }
130 }
131 }
132
91730468 133 void ServerConnClosedCallback()
6cda58a6 134 {
b5922184 135 switch(child_pid=fork())
6cda58a6
GE
136 {
137 case -1:
138 {
139 CPPUNIT_FAIL("fork error");
140 break;
141 }
142 case 0:
143 // child
144 {
145 string data;
146 // wait till server is up
147 sleep(1);
148
149 {
150 socket_client_connection sc("./socket");
151
152 sc.write("ABC");
153
154 // wait half a sec
155 sc.fill_buffer(500000);
156 sc.get_packet(data);
157
158 // close the connection
159 }
160
161 // don't call atexit and stuff
162 _exit(0);
163 }
164
165 default:
166 // parent
167 {
168 socket_server ss("./socket");
169
170 ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1));
171
172 // max 3 sec
173 for (int i=0; i < 3; i++)
174 {
175 ss.fill_buffer(1000000);
176
177 string data;
178 unsigned int cid;
179 if(ss.get_packet(data,cid))
180 {
181 server_connection* con=ss.get_connection(cid);
182 con->write("XYZ");
183 }
184 }
185 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
186 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
187 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
188 }
189 }
190 }
191
91730468 192 void ServerConnDeletedCallback()
6cda58a6 193 {
b5922184 194 switch(child_pid=fork())
6cda58a6
GE
195 {
196 case -1:
197 {
198 CPPUNIT_FAIL("fork error");
199 break;
200 }
201 case 0:
202 // child
203 {
204 string data;
205 // wait till server is up
206 sleep(1);
207
208 {
209 socket_client_connection sc("./socket");
210
211 sc.write("ABC");
212
213 // wait half a sec
214 sc.fill_buffer(500000);
215 sc.get_packet(data);
216
217 // close the connection
218 }
219
220 // don't call atexit and stuff
221 _exit(0);
222 }
223
224 default:
225 // parent
226 {
227 socket_server ss("./socket");
228
229 ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1));
230
231 // max 3 sec
232 for (int i=0; i < 3; i++)
233 {
234 ss.fill_buffer(1000000);
235
236 string data;
237 unsigned int cid;
238 if(ss.get_packet(data,cid))
239 {
240 server_connection* con=ss.get_connection(cid);
241 con->write("XYZ");
242 }
243 ss.cleanup();
244 }
245 ss.cleanup();
246
247 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
248 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
249 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
250 }
251 }
252 }
253
91730468 254 void ServerCallbackOrder()
6cda58a6 255 {
b5922184 256 switch(child_pid=fork())
6cda58a6
GE
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
af84dfb5 298 for (int i=0; i < 5; i++)
6cda58a6
GE
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
af84dfb5
GE
315 CPPUNIT_ASSERT_EQUAL_MESSAGE("closed done",true,static_cast<bool>(callback_done[connection_closed]));
316 CPPUNIT_ASSERT_EQUAL_MESSAGE("not deleted yet",false,static_cast<bool>(callback_done[connection_deleted]));
6cda58a6
GE
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
af84dfb5
GE
329 CPPUNIT_ASSERT_EQUAL_MESSAGE("closed done (2)",true,static_cast<bool>(callback_done[connection_closed]));
330 CPPUNIT_ASSERT_EQUAL_MESSAGE("deleted done",true,static_cast<bool>(callback_done[connection_deleted]));
6cda58a6
GE
331 }
332 }
333 }
334
91730468
GE
335 void ClientConnClosedCallback()
336 {
b5922184 337 switch(child_pid=fork())
91730468
GE
338 {
339 case -1:
340 {
341 CPPUNIT_FAIL("fork error");
342 break;
343 }
344 case 0:
345 // child
346 {
347 socket_server ss("./socket");
348
349 // max 3 sec
350 for (int i=0; i < 3; i++)
351 {
352 ss.fill_buffer(1000000);
353
354 string data;
355 unsigned int cid;
356 if(ss.get_packet(data,cid))
357 break;
358 }
359 // don't call atexit and stuff
360 _exit(0);
361 }
362
363 default:
364 // parent
365 {
366 string data;
367 // wait till server is up
368 sleep(1);
369
370 socket_client_connection sc("./socket");
371
372 sc.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, 0));
373
374 sc.write("ABC");
375
376 // wait half a sec
377 sc.fill_buffer(500000);
378 sc.get_packet(data);
379
380 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
381 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
382 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
383 }
384 }
385 }
386
387 void ClientConnDeletedCallback()
388 {
b5922184 389 switch(child_pid=fork())
91730468
GE
390 {
391 case -1:
392 {
393 CPPUNIT_FAIL("fork error");
394 break;
395 }
396 case 0:
397 // child
398 {
399 socket_server ss("./socket");
400
401 // max 3 sec
402 for (int i=0; i < 3; i++)
403 {
404 ss.fill_buffer(1000000);
405
406 string data;
407 unsigned int cid;
408 if(ss.get_packet(data,cid))
409 break;
410 }
411 // don't call atexit and stuff
412 _exit(0);
413 }
414
415 default:
416 // parent
417 {
418 string data;
419 // wait till server is up
420 sleep(1);
421
422 {
423 socket_client_connection sc("./socket");
424
425 sc.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, 0));
426
427 sc.write("ABC");
428
429 // wait half a sec
430 sc.fill_buffer(500000);
431 sc.get_packet(data);
432 }
433
434 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
435 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
436 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
437 }
438 }
439 }
6cda58a6
GE
440};
441
442CPPUNIT_TEST_SUITE_REGISTRATION(test_callback);