Migrate from cppunit to Boost.test
[libt2n] / test / hello.cpp
CommitLineData
19facd85
TJ
1/*
2Copyright (C) 2004 by Intra2net AG
04d86ba4 3
19facd85
TJ
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*/
04d86ba4
GE
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
307b5e74
TJ
35#define BOOST_TEST_DYN_LINK
36#include <boost/test/unit_test.hpp>
04d86ba4
GE
37
38#include <t2n_exception.hxx>
39#include <socket_client.hxx>
40#include <socket_server.hxx>
41#include <command_client.hxx>
42
307b5e74
TJ
43#include "test_fixtures.hxx"
44
04d86ba4
GE
45#ifdef HAVE_CONFIG_H
46#include <config.h>
47#endif
48
49using namespace std;
50using namespace libt2n;
04d86ba4
GE
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
307b5e74 60class test_helloFixture : public KillChildOnShutdownFixture
04d86ba4 61{
307b5e74 62protected:
04d86ba4
GE
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
307b5e74
TJ
78public:
79 test_helloFixture()
80 {
81 }
82
83 ~test_helloFixture()
04d86ba4 84 {
307b5e74
TJ
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:
04d86ba4 95 {
307b5e74
TJ
96 BOOST_FAIL("fork error");
97 break;
98 }
99 case 0:
100 // child
101 {
102 try
04d86ba4 103 {
307b5e74
TJ
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(...)
04d86ba4 118 {
307b5e74 119 std::cerr << "exception in child. ignoring\n";
04d86ba4
GE
120 }
121
307b5e74
TJ
122 // don't call atexit and stuff
123 _exit(0);
124 }
04d86ba4 125
307b5e74
TJ
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);
04d86ba4
GE
138 }
139 }
307b5e74 140}
04d86ba4 141
307b5e74
TJ
142BOOST_AUTO_TEST_CASE(BadTag)
143{
144 switch(child_pid=fork())
04d86ba4 145 {
307b5e74 146 case -1:
04d86ba4 147 {
307b5e74
TJ
148 BOOST_FAIL("fork error");
149 break;
150 }
151 case 0:
152 // child
153 {
154 try
04d86ba4 155 {
307b5e74 156 socket_server ss("./socket");
04d86ba4 157
307b5e74
TJ
158 ostringstream hello;
159 hello << "XYZ 123";
441d41fe 160
307b5e74 161 ss.add_callback(new_connection,bind(&test_hello::BadTag::send_hello, boost::ref(*this), hello.str(),&ss, _1));
04d86ba4 162
307b5e74
TJ
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";
04d86ba4
GE
169 }
170
307b5e74
TJ
171 // don't call atexit and stuff
172 _exit(0);
173 }
04d86ba4 174
307b5e74
TJ
175 default:
176 // parent
177 {
178 string data;
04d86ba4 179
307b5e74
TJ
180 // wait till server is up
181 sleep(1);
182 socket_client_connection sc("./socket");
b5922184 183
307b5e74 184 command_client cc(&sc);
04d86ba4 185
307b5e74 186 t2n_exception* ep=cc.get_constuctor_exception();
04d86ba4 187
307b5e74
TJ
188 string errormsg;
189 if (ep)
190 errormsg=ep->what();
191
192 BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg);
04d86ba4
GE
193 }
194 }
307b5e74 195}
04d86ba4 196
307b5e74
TJ
197BOOST_AUTO_TEST_CASE(BadVersion)
198{
199 switch(child_pid=fork())
04d86ba4 200 {
307b5e74 201 case -1:
04d86ba4 202 {
307b5e74
TJ
203 BOOST_FAIL("fork error");
204 break;
205 }
206 case 0:
207 // child
208 {
209 try
04d86ba4 210 {
307b5e74
TJ
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(...)
04d86ba4 226 {
307b5e74 227 std::cerr << "exception in child. ignoring\n";
04d86ba4
GE
228 }
229
307b5e74
TJ
230 // don't call atexit and stuff
231 _exit(0);
232 }
233
234 default:
235 // parent
236 {
237 string data;
04d86ba4 238
307b5e74
TJ
239 // wait till server is up
240 sleep(1);
241 socket_client_connection sc("./socket");
04d86ba4 242
307b5e74 243 command_client cc(&sc);
04d86ba4 244
307b5e74 245 t2n_exception* ep=cc.get_constuctor_exception();
b5922184 246
307b5e74
TJ
247 string errormsg;
248 if (ep)
249 errormsg=ep->what();
04d86ba4 250
307b5e74 251 BOOST_CHECK_EQUAL(string("not compatible with the server protocol version"),errormsg);
04d86ba4
GE
252 }
253 }
307b5e74 254}
04d86ba4 255
307b5e74
TJ
256BOOST_AUTO_TEST_CASE(SeparatorMissing)
257{
258 switch(child_pid=fork())
04d86ba4 259 {
307b5e74 260 case -1:
04d86ba4 261 {
307b5e74
TJ
262 BOOST_FAIL("fork error");
263 break;
264 }
265 case 0:
266 // child
267 {
268 try
04d86ba4 269 {
307b5e74
TJ
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(...)
04d86ba4 284 {
307b5e74 285 std::cerr << "exception in child. ignoring\n";
04d86ba4
GE
286 }
287
307b5e74
TJ
288 // don't call atexit and stuff
289 _exit(0);
290 }
04d86ba4 291
307b5e74
TJ
292 default:
293 // parent
294 {
295 string data;
04d86ba4 296
307b5e74
TJ
297 // wait till server is up
298 sleep(1);
299 socket_client_connection sc("./socket");
04d86ba4 300
307b5e74 301 command_client cc(&sc);
b5922184 302
307b5e74 303 t2n_exception* ep=cc.get_constuctor_exception();
04d86ba4 304
307b5e74
TJ
305 string errormsg;
306 if (ep)
307 errormsg=ep->what();
308
309 BOOST_CHECK_EQUAL(string("illegal hello received (1. ;)"),errormsg);
04d86ba4
GE
310 }
311 }
307b5e74 312}
04d86ba4 313
307b5e74
TJ
314BOOST_AUTO_TEST_CASE(WrongByteOrder)
315{
316 switch(child_pid=fork())
04d86ba4 317 {
307b5e74
TJ
318 case -1:
319 {
320 BOOST_FAIL("fork error");
321 break;
322 }
323 case 0:
324 // child
04d86ba4 325 {
307b5e74 326 try
04d86ba4 327 {
307b5e74
TJ
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(...)
04d86ba4 351 {
307b5e74 352 std::cerr << "exception in child. ignoring\n";
04d86ba4
GE
353 }
354
307b5e74
TJ
355 // don't call atexit and stuff
356 _exit(0);
357 }
04d86ba4 358
307b5e74
TJ
359 default:
360 // parent
361 {
362 string data;
04d86ba4 363
307b5e74
TJ
364 // wait till server is up
365 sleep(1);
366 socket_client_connection sc("./socket");
04d86ba4 367
307b5e74 368 command_client cc(&sc);
b5922184 369
307b5e74 370 t2n_exception* ep=cc.get_constuctor_exception();
04d86ba4 371
307b5e74
TJ
372 string errormsg;
373 if (ep)
374 errormsg=ep->what();
375
376 BOOST_CHECK_EQUAL(string("host byte order not matching"),errormsg);
04d86ba4
GE
377 }
378 }
307b5e74 379}
04d86ba4 380
307b5e74
TJ
381BOOST_AUTO_TEST_CASE(OtherServerBig)
382{
383 switch(child_pid=fork())
04d86ba4 384 {
307b5e74
TJ
385 case -1:
386 {
387 BOOST_FAIL("fork error");
388 break;
389 }
390 case 0:
391 // child
04d86ba4 392 {
307b5e74 393 try
04d86ba4 394 {
307b5e74
TJ
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(...)
04d86ba4 407 {
307b5e74 408 std::cerr << "exception in child. ignoring\n";
04d86ba4
GE
409 }
410
307b5e74
TJ
411 // don't call atexit and stuff
412 _exit(0);
413 }
04d86ba4 414
307b5e74
TJ
415 default:
416 // parent
417 {
418 string data;
04d86ba4 419
307b5e74
TJ
420 // wait till server is up
421 sleep(1);
422 socket_client_connection sc("./socket");
b5922184 423
307b5e74 424 command_client cc(&sc);
04d86ba4 425
307b5e74 426 t2n_exception* ep=cc.get_constuctor_exception();
04d86ba4 427
307b5e74
TJ
428 string errormsg;
429 if (ep)
430 errormsg=ep->what();
431
432 BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg);
04d86ba4
GE
433 }
434 }
307b5e74 435}
04d86ba4 436
307b5e74
TJ
437BOOST_AUTO_TEST_CASE(OtherServerSmall)
438{
439 switch(child_pid=fork())
b604df5f 440 {
307b5e74 441 case -1:
b604df5f 442 {
307b5e74
TJ
443 BOOST_FAIL("fork error");
444 break;
445 }
446 case 0:
447 // child
448 {
449 try
b604df5f 450 {
307b5e74
TJ
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(...)
b604df5f 463 {
307b5e74 464 std::cerr << "exception in child. ignoring\n";
b604df5f
GE
465 }
466
307b5e74
TJ
467 // don't call atexit and stuff
468 _exit(0);
469 }
b604df5f 470
307b5e74
TJ
471 default:
472 // parent
473 {
474 string data;
b604df5f 475
307b5e74
TJ
476 // wait till server is up
477 sleep(1);
478 socket_client_connection sc("./socket");
b604df5f 479
307b5e74 480 command_client cc(&sc);
b5922184 481
307b5e74 482 t2n_exception* ep=cc.get_constuctor_exception();
b604df5f 483
307b5e74
TJ
484 string errormsg;
485 if (ep)
486 errormsg=ep->what();
487
488 BOOST_CHECK_EQUAL(string("illegal hello received (T2N)"),errormsg);
b604df5f
GE
489 }
490 }
307b5e74 491}
b604df5f 492
307b5e74 493BOOST_AUTO_TEST_SUITE_END()