license section
[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
47 public:
48
49 void setUp()
50 {
51 callback_done.resize(__events_end);
52 }
53
54 void tearDown()
55 {
56 callback_done.clear();
57 }
58
59 void callback_func(callback_event_type ev, int conn_id)
60 {
61 // we don't care for the conn_id, we just mark the callback as done
62 if (callback_done[ev])
63 throw runtime_error("callback already done for this event");
64
65 callback_done[ev]=true;
66 }
67
91730468 68 void ServerNewConnCallback()
6cda58a6
GE
69 {
70 pid_t pid;
71
72 switch(pid=fork())
73 {
74 case -1:
75 {
76 CPPUNIT_FAIL("fork error");
77 break;
78 }
79 case 0:
80 // child
81 {
82 string data;
83 // wait till server is up
84 sleep(1);
85
86 {
87 socket_client_connection sc("./socket");
88
89 sc.write("ABC");
90
91 // wait half a sec
92 sc.fill_buffer(500000);
93 sc.get_packet(data);
94
95 // close the connection
96 }
97
98 // don't call atexit and stuff
99 _exit(0);
100 }
101
102 default:
103 // parent
104 {
105 socket_server ss("./socket");
106
107 ss.add_callback(new_connection,bind(&test_callback::callback_func, boost::ref(*this), new_connection, _1));
108
109 // max 3 sec
110 for (int i=0; i < 3; i++)
111 {
112 ss.fill_buffer(1000000);
113
114 string data;
115 unsigned int cid;
116 if(ss.get_packet(data,cid))
117 {
118 server_connection* con=ss.get_connection(cid);
119 con->write("XYZ");
120 }
121 }
122 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[new_connection]));
123 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
124 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
125 }
126 }
127 }
128
91730468 129 void ServerConnClosedCallback()
6cda58a6
GE
130 {
131 pid_t pid;
132
133 switch(pid=fork())
134 {
135 case -1:
136 {
137 CPPUNIT_FAIL("fork error");
138 break;
139 }
140 case 0:
141 // child
142 {
143 string data;
144 // wait till server is up
145 sleep(1);
146
147 {
148 socket_client_connection sc("./socket");
149
150 sc.write("ABC");
151
152 // wait half a sec
153 sc.fill_buffer(500000);
154 sc.get_packet(data);
155
156 // close the connection
157 }
158
159 // don't call atexit and stuff
160 _exit(0);
161 }
162
163 default:
164 // parent
165 {
166 socket_server ss("./socket");
167
168 ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1));
169
170 // max 3 sec
171 for (int i=0; i < 3; i++)
172 {
173 ss.fill_buffer(1000000);
174
175 string data;
176 unsigned int cid;
177 if(ss.get_packet(data,cid))
178 {
179 server_connection* con=ss.get_connection(cid);
180 con->write("XYZ");
181 }
182 }
183 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
184 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
185 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
186 }
187 }
188 }
189
91730468 190 void ServerConnDeletedCallback()
6cda58a6
GE
191 {
192 pid_t pid;
193
194 switch(pid=fork())
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
GE
255 {
256 pid_t pid;
257
258 switch(pid=fork())
259 {
260 case -1:
261 {
262 CPPUNIT_FAIL("fork error");
263 break;
264 }
265 case 0:
266 // child
267 {
268 string data;
269 // wait till server is up
270 sleep(1);
271
272 {
273 socket_client_connection sc("./socket");
274
275 sc.write("1");
276
277 // wait half a sec
278 sc.fill_buffer(500000);
279 sc.get_packet(data);
280
281 sc.write("2");
282
283 // close the connection
284 }
285
286 // don't call atexit and stuff
287 _exit(0);
288 }
289
290 default:
291 // parent
292 {
293 socket_server ss("./socket");
294
295 ss.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, _1));
296 ss.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, _1));
297
298 bool got_1=false;
299
300 for (int i=0; i < 4; i++)
301 {
302 ss.fill_buffer(500000);
303
304 string data;
305 unsigned int cid;
306 if(!got_1 && ss.get_packet(data,cid))
307 {
308 server_connection* con=ss.get_connection(cid);
309 con->write("XYZ");
310 got_1=true;
311 // don't call get_packet anymore
312 }
313 ss.cleanup();
314 }
315 ss.cleanup();
316
317 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
318 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
319
320 for (int i=0; i < 4; i++)
321 {
322 ss.fill_buffer(500000);
323
324 string data;
325 unsigned int cid;
326 ss.get_packet(data,cid);
327 ss.cleanup();
328 }
329 ss.cleanup();
330
331 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
332 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
333 }
334 }
335 }
336
91730468
GE
337 void ClientConnClosedCallback()
338 {
339 pid_t pid;
340
341 switch(pid=fork())
342 {
343 case -1:
344 {
345 CPPUNIT_FAIL("fork error");
346 break;
347 }
348 case 0:
349 // child
350 {
351 socket_server ss("./socket");
352
353 // max 3 sec
354 for (int i=0; i < 3; i++)
355 {
356 ss.fill_buffer(1000000);
357
358 string data;
359 unsigned int cid;
360 if(ss.get_packet(data,cid))
361 break;
362 }
363 // don't call atexit and stuff
364 _exit(0);
365 }
366
367 default:
368 // parent
369 {
370 string data;
371 // wait till server is up
372 sleep(1);
373
374 socket_client_connection sc("./socket");
375
376 sc.add_callback(connection_closed,bind(&test_callback::callback_func, boost::ref(*this), connection_closed, 0));
377
378 sc.write("ABC");
379
380 // wait half a sec
381 sc.fill_buffer(500000);
382 sc.get_packet(data);
383
384 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
385 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_closed]));
386 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_deleted]));
387 }
388 }
389 }
390
391 void ClientConnDeletedCallback()
392 {
393 pid_t pid;
394
395 switch(pid=fork())
396 {
397 case -1:
398 {
399 CPPUNIT_FAIL("fork error");
400 break;
401 }
402 case 0:
403 // child
404 {
405 socket_server ss("./socket");
406
407 // max 3 sec
408 for (int i=0; i < 3; i++)
409 {
410 ss.fill_buffer(1000000);
411
412 string data;
413 unsigned int cid;
414 if(ss.get_packet(data,cid))
415 break;
416 }
417 // don't call atexit and stuff
418 _exit(0);
419 }
420
421 default:
422 // parent
423 {
424 string data;
425 // wait till server is up
426 sleep(1);
427
428 {
429 socket_client_connection sc("./socket");
430
431 sc.add_callback(connection_deleted,bind(&test_callback::callback_func, boost::ref(*this), connection_deleted, 0));
432
433 sc.write("ABC");
434
435 // wait half a sec
436 sc.fill_buffer(500000);
437 sc.get_packet(data);
438 }
439
440 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[new_connection]));
441 CPPUNIT_ASSERT_EQUAL(false,static_cast<bool>(callback_done[connection_closed]));
442 CPPUNIT_ASSERT_EQUAL(true,static_cast<bool>(callback_done[connection_deleted]));
443 }
444 }
445 }
6cda58a6
GE
446};
447
448CPPUNIT_TEST_SUITE_REGISTRATION(test_callback);