libt2n: (tomj) disable recently added unit test: it won't work as is
[libt2n] / test / callback.cpp
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
28 using namespace std;
29 using namespace libt2n;
30 using namespace CppUnit;
31
32 class test_callback : public TestFixture
33 {
34     CPPUNIT_TEST_SUITE(test_callback);
35
36     CPPUNIT_TEST(ServerNewConnCallback);
37     CPPUNIT_TEST(ServerConnClosedCallback);
38     CPPUNIT_TEST(ServerConnDeletedCallback);
39     CPPUNIT_TEST(ServerCallbackOrder);
40     CPPUNIT_TEST(ClientConnClosedCallback);
41     CPPUNIT_TEST(ClientConnDeletedCallback);
42
43     CPPUNIT_TEST_SUITE_END();
44
45     std::vector<bool> callback_done;
46
47     pid_t child_pid;
48
49     public:
50
51     void setUp()
52     {
53         callback_done.resize(__events_end);
54     }
55
56     void tearDown()
57     {
58         callback_done.clear();
59
60         // make sure the server-child is dead before the next test runs
61         kill(child_pid,SIGKILL);
62         sleep(1);
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
74     void ServerNewConnCallback()
75     {
76         switch(child_pid=fork())
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
133     void ServerConnClosedCallback()
134     {
135         switch(child_pid=fork())
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
192     void ServerConnDeletedCallback()
193     {
194         switch(child_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
254     void ServerCallbackOrder()
255     {
256         switch(child_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 < 5; 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_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]));
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_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]));
331             }
332         }
333     }
334
335     void ClientConnClosedCallback()
336     {
337         switch(child_pid=fork())
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     {
389         switch(child_pid=fork())
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     }
440 };
441
442 CPPUNIT_TEST_SUITE_REGISTRATION(test_callback);