Update exception message. Atleast boost 1.44.0 uses this one
[libt2n] / test / hello.cpp
1 /*
2 Copyright (C) 2004 by Intra2net AG
3
4 The software in this package is distributed under the GNU General
5 Public License version 2 (with a special exception described below).
6
7 A copy of GNU General Public License (GPL) is included in this distribution,
8 in the file COPYING.GPL.
9
10 As a special exception, if other files instantiate templates or use macros
11 or inline functions from this file, or you compile this file and link it
12 with other works to produce a work based on this file, this file
13 does not by itself cause the resulting work to be covered
14 by the GNU General Public License.
15
16 However the source code for this file must still be made available
17 in accordance with section (3) of the GNU General Public License.
18
19 This exception does not invalidate any other reasons why a work based
20 on this file might be covered by the GNU General Public License.
21 */
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
33 #include <boost/bind.hpp>
34
35 #define BOOST_TEST_DYN_LINK
36 #include <boost/test/unit_test.hpp>
37
38 #include <t2n_exception.hxx>
39 #include <socket_client.hxx>
40 #include <socket_server.hxx>
41 #include <command_client.hxx>
42
43 #include "test_fixtures.hxx"
44
45 #ifdef HAVE_CONFIG_H
46 #include <config.h>
47 #endif
48
49 using namespace std;
50 using namespace libt2n;
51
52
53 BOOST_FIXTURE_TEST_SUITE(test_hello, KillChildOnShutdownFixture)
54
55 BOOST_AUTO_TEST_CASE(HelloOk)
56 {
57     switch(child_pid=fork())
58     {
59         case -1:
60         {
61             BOOST_FAIL("fork error");
62             break;
63         }
64         case 0:
65         // child
66         {
67             try
68             {
69                 socket_server ss("./socket");
70
71                 ostringstream hello;
72                 hello << "T2Nv" << PROTOCOL_VERSION << ';';
73                 int byteordercheck=1;
74                 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
75                 hello << ';';
76
77                 ss.add_callback(new_connection,bind(&test_hello::HelloOk::send_hello, boost::ref(*this), hello.str(),&ss, _1));
78
79                 // max 10 sec
80                 for (int i=0; i < 10; i++)
81                     ss.fill_buffer(1000000);
82             } catch(...)
83             {
84                 std::cerr << "exception in child. ignoring\n";
85             }
86
87             // don't call atexit and stuff
88             _exit(0);
89         }
90
91         default:
92         // parent
93         {
94             string data;
95
96             // wait till server is up
97             sleep(1);
98             socket_client_connection sc("./socket");
99             command_client cc(&sc);
100
101             // All fine we reached this point
102             BOOST_CHECK(true);
103         }
104     }
105 }
106
107 BOOST_AUTO_TEST_CASE(BadTag)
108 {
109     switch(child_pid=fork())
110     {
111         case -1:
112         {
113             BOOST_FAIL("fork error");
114             break;
115         }
116         case 0:
117         // child
118         {
119             try
120             {
121                 socket_server ss("./socket");
122
123                 ostringstream hello;
124                 hello << "XYZ 123";
125
126                 ss.add_callback(new_connection,bind(&test_hello::BadTag::send_hello, boost::ref(*this), hello.str(),&ss, _1));
127
128                 // max 10 sec
129                 for (int i=0; i < 10; i++)
130                     ss.fill_buffer(1000000);
131             } catch(...)
132             {
133                 std::cerr << "exception in child. ignoring\n";
134             }
135
136             // don't call atexit and stuff
137             _exit(0);
138         }
139
140         default:
141         // parent
142         {
143             string data;
144
145             // wait till server is up
146             sleep(1);
147             socket_client_connection sc("./socket");
148
149             command_client cc(&sc);
150
151             t2n_exception* ep=cc.get_constuctor_exception();
152
153             string errormsg;
154             if (ep)
155                 errormsg=ep->what();
156
157             BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg);
158         }
159     }
160 }
161
162 BOOST_AUTO_TEST_CASE(BadVersion)
163 {
164     switch(child_pid=fork())
165     {
166         case -1:
167         {
168             BOOST_FAIL("fork error");
169             break;
170         }
171         case 0:
172         // child
173         {
174             try
175             {
176                 socket_server ss("./socket");
177
178                 ostringstream hello;
179                 // lets hope we don't ever get near such a version number...
180                 hello << "T2Nv" << 4982271 << ';';
181                 int byteordercheck=1;
182                 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
183                 hello << ';';
184
185                 ss.add_callback(new_connection,bind(&test_hello::BadVersion::send_hello, boost::ref(*this), hello.str(),&ss, _1));
186
187                 // max 10 sec
188                 for (int i=0; i < 10; i++)
189                     ss.fill_buffer(1000000);
190             } catch(...)
191             {
192                 std::cerr << "exception in child. ignoring\n";
193             }
194
195             // don't call atexit and stuff
196             _exit(0);
197         }
198
199         default:
200         // parent
201         {
202             string data;
203
204             // wait till server is up
205             sleep(1);
206             socket_client_connection sc("./socket");
207
208             command_client cc(&sc);
209
210             t2n_exception* ep=cc.get_constuctor_exception();
211
212             string errormsg;
213             if (ep)
214                 errormsg=ep->what();
215
216             BOOST_CHECK_EQUAL(string("not compatible with the server protocol version"),errormsg);
217         }
218     }
219 }
220
221 BOOST_AUTO_TEST_CASE(SeparatorMissing)
222 {
223     switch(child_pid=fork())
224     {
225         case -1:
226         {
227             BOOST_FAIL("fork error");
228             break;
229         }
230         case 0:
231         // child
232         {
233             try
234             {
235                 socket_server ss("./socket");
236
237                 ostringstream hello;
238                 hello << "T2Nv" << PROTOCOL_VERSION;
239                 int byteordercheck=1;
240                 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
241                 hello << ';';
242
243                 ss.add_callback(new_connection,bind(&test_hello::SeparatorMissing::send_hello, boost::ref(*this), hello.str(),&ss, _1));
244
245                 // max 10 sec
246                 for (int i=0; i < 10; i++)
247                     ss.fill_buffer(1000000);
248             } catch(...)
249             {
250                 std::cerr << "exception in child. ignoring\n";
251             }
252
253             // don't call atexit and stuff
254             _exit(0);
255         }
256
257         default:
258         // parent
259         {
260             string data;
261
262             // wait till server is up
263             sleep(1);
264             socket_client_connection sc("./socket");
265
266             command_client cc(&sc);
267
268             t2n_exception* ep=cc.get_constuctor_exception();
269
270             string errormsg;
271             if (ep)
272                 errormsg=ep->what();
273
274             BOOST_CHECK_EQUAL(string("illegal hello received (1. ;)"),errormsg);
275         }
276     }
277 }
278
279 BOOST_AUTO_TEST_CASE(WrongByteOrder)
280 {
281     switch(child_pid=fork())
282     {
283         case -1:
284         {
285             BOOST_FAIL("fork error");
286             break;
287         }
288         case 0:
289         // child
290         {
291             try
292             {
293                 socket_server ss("./socket");
294
295                 ostringstream hello;
296                 hello << "T2Nv" << PROTOCOL_VERSION << ';';
297                 int byteordercheck=1;
298                 int dst;
299                 char* si=(char*)&byteordercheck;
300                 char* di=(char*)&dst;
301
302                 di[0]=si[3];
303                 di[1]=si[2];
304                 di[2]=si[1];
305                 di[3]=si[0];
306
307                 hello.write((char*)&dst,sizeof(dst));
308                 hello << ';';
309
310                 ss.add_callback(new_connection,bind(&test_hello::WrongByteOrder::send_hello, boost::ref(*this), hello.str(),&ss, _1));
311
312                 // max 10 sec
313                 for (int i=0; i < 10; i++)
314                     ss.fill_buffer(1000000);
315             } catch(...)
316             {
317                 std::cerr << "exception in child. ignoring\n";
318             }
319
320             // don't call atexit and stuff
321             _exit(0);
322         }
323
324         default:
325         // parent
326         {
327             string data;
328
329             // wait till server is up
330             sleep(1);
331             socket_client_connection sc("./socket");
332
333             command_client cc(&sc);
334
335             t2n_exception* ep=cc.get_constuctor_exception();
336
337             string errormsg;
338             if (ep)
339                 errormsg=ep->what();
340
341             BOOST_CHECK_EQUAL(string("host byte order not matching"),errormsg);
342         }
343     }
344 }
345
346 BOOST_AUTO_TEST_CASE(OtherServerBig)
347 {
348     switch(child_pid=fork())
349     {
350         case -1:
351         {
352             BOOST_FAIL("fork error");
353             break;
354         }
355         case 0:
356         // child
357         {
358             try
359             {
360                 socket_server ss("./socket");
361
362                 ostringstream hello;
363                 // hmm, we got the wrong socket
364                 hello << "* OK intradev.net.lan Cyrus IMAP4 v2.2.13 server ready";
365
366                 ss.add_callback(new_connection,bind(&test_hello::OtherServerBig::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1));
367
368                 // max 3 sec
369                 for (int i=0; i < 3; i++)
370                     ss.fill_buffer(1000000);
371             } catch(...)
372             {
373                 std::cerr << "exception in child. ignoring\n";
374             }
375
376             // don't call atexit and stuff
377             _exit(0);
378         }
379
380         default:
381         // parent
382         {
383             string data;
384
385             // wait till server is up
386             sleep(1);
387             socket_client_connection sc("./socket");
388
389             command_client cc(&sc);
390
391             t2n_exception* ep=cc.get_constuctor_exception();
392
393             string errormsg;
394             if (ep)
395                 errormsg=ep->what();
396
397             BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg);
398         }
399     }
400 }
401
402 BOOST_AUTO_TEST_CASE(OtherServerSmall)
403 {
404     switch(child_pid=fork())
405     {
406         case -1:
407         {
408             BOOST_FAIL("fork error");
409             break;
410         }
411         case 0:
412         // child
413         {
414             try
415             {
416                 socket_server ss("./socket");
417
418                 ostringstream hello;
419                 // hmm, we got the wrong socket
420                 hello << "READY";
421
422                 ss.add_callback(new_connection,bind(&test_hello::OtherServerSmall::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1));
423
424                 // max 3 sec
425                 for (int i=0; i < 3; i++)
426                     ss.fill_buffer(1000000);
427             } catch(...)
428             {
429                 std::cerr << "exception in child. ignoring\n";
430             }
431
432             // don't call atexit and stuff
433             _exit(0);
434         }
435
436         default:
437         // parent
438         {
439             string data;
440
441             // wait till server is up
442             sleep(1);
443             socket_client_connection sc("./socket");
444
445             command_client cc(&sc);
446
447             t2n_exception* ep=cc.get_constuctor_exception();
448
449             string errormsg;
450             if (ep)
451                 errormsg=ep->what();
452
453             BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg);
454         }
455     }
456 }
457
458 BOOST_AUTO_TEST_SUITE_END()