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