libt2n: (reinhard) more compile fixes.
[libt2n] / test / reconnect.cpp
CommitLineData
af84dfb5
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>
4c3662a0 12#include <time.h>
af84dfb5
GE
13
14#include <iostream>
15#include <string>
16#include <sstream>
17#include <stdexcept>
18
19#include <cppunit/extensions/TestFactoryRegistry.h>
20#include <cppunit/ui/text/TestRunner.h>
21#include <cppunit/extensions/HelperMacros.h>
22
23#include <socket_client.hxx>
24#include <socket_server.hxx>
25
26#ifdef HAVE_CONFIG_H
27#include <config.h>
28#endif
29
30using namespace std;
31using namespace libt2n;
32using namespace CppUnit;
33
34// this is an evil hack to get access to real_write, don't ever do this in an app!!!
35class real_write_connection: public socket_server_connection
36{
37 public:
38 void real_write(const std::string& data)
39 { socket_write(data); }
40};
41
42class test_reconnect : public TestFixture
43{
44 CPPUNIT_TEST_SUITE(test_reconnect);
45
46 CPPUNIT_TEST(simple_reconnect);
47 CPPUNIT_TEST(reconnect_with_close);
48 CPPUNIT_TEST(reconnect_buffer_complete);
49 CPPUNIT_TEST(reconnect_buffer_several_complete);
50 CPPUNIT_TEST(reconnect_buffer_no_incomplete1);
51 CPPUNIT_TEST(reconnect_buffer_no_incomplete2);
52
53 CPPUNIT_TEST_SUITE_END();
54
55 public:
56
57 void setUp()
58 { }
59
60 void tearDown()
61 { }
62
63 void send_raw_socket(string hello_string, socket_server* ss, int conn_id)
64 {
65 socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id));
66
67 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
68 real_write_connection *rwc=(real_write_connection*)ssc;
69 rwc->real_write(hello_string);
70 }
71
72 void simple_reconnect()
73 {
74 pid_t pid;
75
76 switch(pid=fork())
77 {
78 case -1:
79 {
80 CPPUNIT_FAIL("fork error");
81 break;
82 }
83 case 0:
84 // child
85 {
86 socket_server ss("./socket");
87
88 time_t t0 = time(NULL);
89
90 // max 10 sec
91 while (time(NULL) < t0 + 10 )
92 {
93 ss.fill_buffer(1000000);
94
95 string data;
96 unsigned int cid;
97
98 if(ss.get_packet(data,cid))
99 {
100 server_connection* con=ss.get_connection(cid);
101
102 if (data=="QUIT")
103 break;
104
105 if (data=="x")
106 con->write(string().insert(0,100,'X'));
107 else
108 con->write(string().insert(0,100,'Y'));
109 }
110 }
111
112 // don't call atexit and stuff
113 _exit(0);
114 }
115
116 default:
117 // parent
118 {
119 // don't kill us on broken pipe
120 signal(SIGPIPE, SIG_IGN);
121
122 // wait till server is up
123 sleep(1);
124 socket_client_connection sc("./socket");
125
126 sc.write("abc");
127
128 string data;
129
130 while (!sc.get_packet(data))
131 sc.fill_buffer(1000000);
132
133 sc.reconnect();
134
135 sc.write("x");
136
137 while (!sc.get_packet(data))
138 sc.fill_buffer(1000000);
139
140 CPPUNIT_ASSERT_EQUAL(string().insert(0,100,'X'),data);
141 }
142 }
143 }
144
145 void reconnect_with_close()
146 {
147 pid_t pid;
148
149 switch(pid=fork())
150 {
151 case -1:
152 {
153 CPPUNIT_FAIL("fork error");
154 break;
155 }
156 case 0:
157 // child
158 {
159 socket_server ss("./socket");
160
161 time_t t0 = time(NULL);
162
163 // max 10 sec
164 while (time(NULL) < t0 + 10 )
165 {
166 ss.fill_buffer(1000000);
167
168 string data;
169 unsigned int cid;
170
171 if(ss.get_packet(data,cid))
172 {
173 server_connection* con=ss.get_connection(cid);
174
175 if (data=="QUIT")
176 break;
177
178 if (data=="x")
179 con->write(string().insert(0,100,'X'));
180 else
181 con->write(string().insert(0,100,'Y'));
182 }
183 }
184
185 // don't call atexit and stuff
186 _exit(0);
187 }
188
189 default:
190 // parent
191 {
192 // don't kill us on broken pipe
193 signal(SIGPIPE, SIG_IGN);
194
195 // wait till server is up
196 sleep(1);
197 socket_client_connection sc("./socket");
198
199 sc.write("abc");
200
201 string data;
202
203 while (!sc.get_packet(data))
204 sc.fill_buffer(1000000);
205
206 sc.close();
207
208 // empty buffer
209 sc.get_packet(data);
210
211 sc.reconnect();
212
213 sc.write("x");
214
215 while (!sc.get_packet(data))
216 sc.fill_buffer(1000000);
217
218 CPPUNIT_ASSERT_EQUAL(string().insert(0,100,'X'),data);
219 }
220 }
221 }
222
223 void reconnect_buffer_complete()
224 {
225 pid_t pid;
226
227 switch(pid=fork())
228 {
229 case -1:
230 {
231 CPPUNIT_FAIL("fork error");
232 break;
233 }
234 case 0:
235 // child
236 {
237 socket_server ss("./socket");
238
239 time_t t0 = time(NULL);
240
241 // max 10 sec
242 while (time(NULL) < t0 + 10 )
243 {
244 ss.fill_buffer(1000000);
245
246 string data;
247 unsigned int cid;
248
249 if(ss.get_packet(data,cid))
250 {
251 server_connection* con=ss.get_connection(cid);
252
253 if (data=="QUIT")
254 break;
255
256 if (data=="x")
257 con->write(string().insert(0,100,'X'));
258 }
259 }
260
261 // don't call atexit and stuff
262 _exit(0);
263 }
264
265 default:
266 // parent
267 {
268 // don't kill us on broken pipe
269 signal(SIGPIPE, SIG_IGN);
270
271 // wait till server is up
272 sleep(1);
273 socket_client_connection sc("./socket");
274
275 sc.write("x");
276
277 string data;
278
279 while (!sc.packet_available())
280 sc.fill_buffer(1000000);
281
282 sc.reconnect();
283
284 CPPUNIT_ASSERT_EQUAL_MESSAGE("packet not there",true,sc.get_packet(data));
285
286 CPPUNIT_ASSERT_EQUAL_MESSAGE("data incorrect",string().insert(0,100,'X'),data);
287 }
288 }
289 }
290
291 void reconnect_buffer_several_complete()
292 {
293 pid_t pid;
294
295 const int packets=3;
296
297 switch(pid=fork())
298 {
299 case -1:
300 {
301 CPPUNIT_FAIL("fork error");
302 break;
303 }
304 case 0:
305 // child
306 {
307 socket_server ss("./socket");
308
309 time_t t0 = time(NULL);
310
311 // max 10 sec
312 while (time(NULL) < t0 + 10 )
313 {
314 ss.fill_buffer(1000000);
315
316 string data;
317 unsigned int cid;
318
319 if(ss.get_packet(data,cid))
320 {
321 server_connection* con=ss.get_connection(cid);
322
323 if (data=="QUIT")
324 break;
325
326 if (data=="x")
327 {
328 for (int i=0; i<packets; i++)
329 con->write(string().insert(0,100,'X'));
330 }
331 }
332 }
333
334 // don't call atexit and stuff
335 _exit(0);
336 }
337
338 default:
339 // parent
340 {
341 // don't kill us on broken pipe
342 signal(SIGPIPE, SIG_IGN);
343
344 // wait till server is up
345 sleep(1);
346 socket_client_connection sc("./socket");
347
348 sc.write("x");
349
350 // retrieve packets for 3 seconds
351 time_t t0 = time(NULL);
352
353 // max 3 sec
354 while (time(NULL) < t0 + 3 )
355 sc.fill_buffer(1000000);
356
357 // we now should have packets complete packets in the buffer
358
359 sc.reconnect();
360
361 // are these packets still there?
362
363 for (int i=0; i < packets; i++)
364 {
365 string data;
366
367 ostringstream os;
368 os << "packet " << i << " not there";
369
370 CPPUNIT_ASSERT_EQUAL_MESSAGE(os.str(),true,sc.get_packet(data));
371
372 os.str("");
373 os << "packet " << i << " incorrect";
374
375 CPPUNIT_ASSERT_EQUAL_MESSAGE(os.str(),string().insert(0,100,'X'),data);
376 }
377 }
378 }
379 }
380
381 void reconnect_buffer_no_incomplete1()
382 {
383 pid_t pid;
384
385 switch(pid=fork())
386 {
387 case -1:
388 {
389 CPPUNIT_FAIL("fork error");
390 break;
391 }
392 case 0:
393 // child
394 {
395 socket_server ss("./socket");
396
397 time_t t0 = time(NULL);
398
399 // max 10 sec
400 while (time(NULL) < t0 + 10 )
401 {
402 ss.fill_buffer(1000000);
403
404 string data;
405 unsigned int cid;
406
407 if(ss.get_packet(data,cid))
408 {
409 server_connection* con=ss.get_connection(cid);
410
411 if (data=="QUIT")
412 break;
413
414 if (data=="x")
415 {
416 con->write(string().insert(0,100,'X'));
417 send_raw_socket("aaaab",&ss,cid);
418 }
419 }
420 }
421
422 // don't call atexit and stuff
423 _exit(0);
424 }
425
426 default:
427 // parent
428 {
429 // don't kill us on broken pipe
430 signal(SIGPIPE, SIG_IGN);
431
432 // wait till server is up
433 sleep(1);
434 socket_client_connection sc("./socket");
435
436 sc.write("x");
437
438 // retrieve packets for 3 seconds
439 time_t t0 = time(NULL);
440
441 // max 3 sec
442 while (time(NULL) < t0 + 3 )
443 sc.fill_buffer(1000000);
444
445 // we now should have one complete packet and some stuff in the buffer
446
447 string data;
448 sc.get_packet(data);
449
450 CPPUNIT_ASSERT_EQUAL_MESSAGE("no incomplete packet",true,(sc.peek_packet(data))>0);
451
452 sc.reconnect();
453
454 CPPUNIT_ASSERT_EQUAL_MESSAGE("incomplete packet not removed",0,(int)sc.peek_packet(data));
455 }
456 }
457 }
458
459 void reconnect_buffer_no_incomplete2()
460 {
461 pid_t pid;
462
463 switch(pid=fork())
464 {
465 case -1:
466 {
467 CPPUNIT_FAIL("fork error");
468 break;
469 }
470 case 0:
471 // child
472 {
473 socket_server ss("./socket");
474
475 time_t t0 = time(NULL);
476
477 // max 10 sec
478 while (time(NULL) < t0 + 10 )
479 {
480 ss.fill_buffer(1000000);
481
482 string data;
483 unsigned int cid;
484
485 if(ss.get_packet(data,cid))
486 {
487 server_connection* con=ss.get_connection(cid);
488
489 if (data=="QUIT")
490 break;
491
492 if (data=="x")
493 {
494 con->write(string().insert(0,100,'X'));
495
496 string blob=string().insert(0,100,'Y');
497
498 // one byte will be missing...
499 int size=blob.size()+1;
500 char sizetransfer[sizeof(int)+1];
501 memcpy(sizetransfer,(void*)&size,sizeof(int));
502 sizetransfer[sizeof(int)+1]=0;
503
504 string packet=string(sizetransfer)+blob;
505
506 send_raw_socket(packet,&ss,cid);
507 }
508 }
509 }
510
511 // don't call atexit and stuff
512 _exit(0);
513 }
514
515 default:
516 // parent
517 {
518 // don't kill us on broken pipe
519 signal(SIGPIPE, SIG_IGN);
520
521 // wait till server is up
522 sleep(1);
523 socket_client_connection sc("./socket");
524
525 sc.write("x");
526
527 // retrieve packets for 3 seconds
528 time_t t0 = time(NULL);
529
530 // max 3 sec
531 while (time(NULL) < t0 + 3 )
532 sc.fill_buffer(1000000);
533
534 // we now should have one complete packet and some stuff in the buffer
535
536 sc.reconnect();
537
538 string data;
539
540 CPPUNIT_ASSERT_EQUAL_MESSAGE("packet not there",true,sc.get_packet(data));
541 CPPUNIT_ASSERT_EQUAL_MESSAGE("data incorrect",string().insert(0,100,'X'),data);
542
543 CPPUNIT_ASSERT_EQUAL_MESSAGE("incomplete packet not removed",0,(int)sc.peek_packet(data));
544 }
545 }
546 }
547
548};
549
550CPPUNIT_TEST_SUITE_REGISTRATION(test_reconnect);