license section
[libt2n] / test / hello.cpp
... / ...
CommitLineData
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
18#include <boost/bind.hpp>
19
20#include <cppunit/extensions/TestFactoryRegistry.h>
21#include <cppunit/ui/text/TestRunner.h>
22#include <cppunit/extensions/HelperMacros.h>
23
24#include <t2n_exception.hxx>
25#include <socket_client.hxx>
26#include <socket_server.hxx>
27#include <command_client.hxx>
28
29#ifdef HAVE_CONFIG_H
30#include <config.h>
31#endif
32
33using namespace std;
34using namespace libt2n;
35using namespace CppUnit;
36
37// this is an evil hack to get access to real_write, don't ever do this in an app!!!
38class real_write_connection: public socket_server_connection
39{
40 public:
41 void real_write(const std::string& data)
42 { socket_write(data); }
43};
44
45class test_hello : public TestFixture
46{
47 CPPUNIT_TEST_SUITE(test_hello);
48
49 CPPUNIT_TEST(HelloOk);
50 CPPUNIT_TEST(BadTag);
51 CPPUNIT_TEST(BadVersion);
52 CPPUNIT_TEST(SeparatorMissing);
53 CPPUNIT_TEST(WrongByteOrder);
54 CPPUNIT_TEST(OtherServerBig);
55 CPPUNIT_TEST(OtherServerSmall);
56
57 CPPUNIT_TEST_SUITE_END();
58
59 public:
60
61 void setUp()
62 { }
63
64 void tearDown()
65 { }
66
67 void send_hello(string hello_string, socket_server* ss, int conn_id)
68 {
69 server_connection *sc=ss->get_connection(conn_id);
70 sc->write(hello_string);
71 }
72
73 void send_raw_socket(string hello_string, socket_server* ss, int conn_id)
74 {
75 socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id));
76
77 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
78 real_write_connection *rwc=(real_write_connection*)ssc;
79 rwc->real_write(hello_string);
80 }
81
82 void HelloOk()
83 {
84 pid_t pid;
85
86 switch(pid=fork())
87 {
88 case -1:
89 {
90 CPPUNIT_FAIL("fork error");
91 break;
92 }
93 case 0:
94 // child
95 {
96 socket_server ss("./socket");
97
98 ostringstream hello;
99 hello << "T2Nv" << PROTOCOL_VERSION << ';';
100 int byteordercheck=1;
101 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
102 hello << ';';
103
104 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
105
106 // max 10 sec
107 for (int i=0; i < 10; i++)
108 ss.fill_buffer(1000000);
109 // don't call atexit and stuff
110 _exit(0);
111 }
112
113 default:
114 // parent
115 {
116 string data;
117
118 // wait till server is up
119 sleep(1);
120 socket_client_connection sc("./socket");
121 command_client cc(sc);
122 }
123 }
124 }
125
126 void BadTag()
127 {
128 pid_t pid;
129
130 switch(pid=fork())
131 {
132 case -1:
133 {
134 CPPUNIT_FAIL("fork error");
135 break;
136 }
137 case 0:
138 // child
139 {
140 socket_server ss("./socket");
141
142 ostringstream hello;
143 hello << "XYZ 123";
144
145 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
146
147 // max 10 sec
148 for (int i=0; i < 10; i++)
149 ss.fill_buffer(1000000);
150 // don't call atexit and stuff
151 _exit(0);
152 }
153
154 default:
155 // parent
156 {
157 string data;
158
159 // wait till server is up
160 sleep(1);
161 socket_client_connection sc("./socket");
162
163 string errormsg;
164
165 try
166 {
167 command_client cc(sc);
168 }
169 catch(t2n_version_mismatch &e)
170 { errormsg=e.what(); }
171 catch(...)
172 { throw; }
173
174 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
175 }
176 }
177 }
178
179 void BadVersion()
180 {
181 pid_t pid;
182
183 switch(pid=fork())
184 {
185 case -1:
186 {
187 CPPUNIT_FAIL("fork error");
188 break;
189 }
190 case 0:
191 // child
192 {
193 socket_server ss("./socket");
194
195 ostringstream hello;
196 // lets hope we don't ever get near such a version number...
197 hello << "T2Nv" << 4982271 << ';';
198 int byteordercheck=1;
199 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
200 hello << ';';
201
202 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
203
204 // max 10 sec
205 for (int i=0; i < 10; i++)
206 ss.fill_buffer(1000000);
207 // don't call atexit and stuff
208 _exit(0);
209 }
210
211 default:
212 // parent
213 {
214 string data;
215
216 // wait till server is up
217 sleep(1);
218 socket_client_connection sc("./socket");
219
220 string errormsg;
221
222 try
223 {
224 command_client cc(sc);
225 }
226 catch(t2n_version_mismatch &e)
227 { errormsg=e.what(); }
228 catch(...)
229 { throw; }
230
231 CPPUNIT_ASSERT_EQUAL(string("not compatible with the server protocol version"),errormsg);
232 }
233 }
234 }
235
236 void SeparatorMissing()
237 {
238 pid_t pid;
239
240 switch(pid=fork())
241 {
242 case -1:
243 {
244 CPPUNIT_FAIL("fork error");
245 break;
246 }
247 case 0:
248 // child
249 {
250 socket_server ss("./socket");
251
252 ostringstream hello;
253 hello << "T2Nv" << PROTOCOL_VERSION;
254 int byteordercheck=1;
255 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
256 hello << ';';
257
258 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
259
260 // max 10 sec
261 for (int i=0; i < 10; i++)
262 ss.fill_buffer(1000000);
263 // don't call atexit and stuff
264 _exit(0);
265 }
266
267 default:
268 // parent
269 {
270 string data;
271
272 // wait till server is up
273 sleep(1);
274 socket_client_connection sc("./socket");
275
276 string errormsg;
277
278 try
279 {
280 command_client cc(sc);
281 }
282 catch(t2n_version_mismatch &e)
283 { errormsg=e.what(); }
284 catch(...)
285 { throw; }
286
287 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (1. ;)"),errormsg);
288 }
289 }
290 }
291
292 void WrongByteOrder()
293 {
294 pid_t pid;
295
296 switch(pid=fork())
297 {
298 case -1:
299 {
300 CPPUNIT_FAIL("fork error");
301 break;
302 }
303 case 0:
304 // child
305 {
306 socket_server ss("./socket");
307
308 ostringstream hello;
309 hello << "T2Nv" << PROTOCOL_VERSION << ';';
310 int byteordercheck=1;
311 int dst;
312 char* si=(char*)&byteordercheck;
313 char* di=(char*)&dst;
314
315 di[0]=si[3];
316 di[1]=si[2];
317 di[2]=si[1];
318 di[3]=si[0];
319
320 hello.write((char*)&dst,sizeof(dst));
321 hello << ';';
322
323 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
324
325 // max 10 sec
326 for (int i=0; i < 10; i++)
327 ss.fill_buffer(1000000);
328 // don't call atexit and stuff
329 _exit(0);
330 }
331
332 default:
333 // parent
334 {
335 string data;
336
337 // wait till server is up
338 sleep(1);
339 socket_client_connection sc("./socket");
340
341 string errormsg;
342
343 try
344 {
345 command_client cc(sc);
346 }
347 catch(t2n_version_mismatch &e)
348 { errormsg=e.what(); }
349 catch(...)
350 { throw; }
351
352 CPPUNIT_ASSERT_EQUAL(string("host byte order not matching"),errormsg);
353 }
354 }
355 }
356
357 void OtherServerBig()
358 {
359 pid_t pid;
360
361 switch(pid=fork())
362 {
363 case -1:
364 {
365 CPPUNIT_FAIL("fork error");
366 break;
367 }
368 case 0:
369 // child
370 {
371 socket_server ss("./socket");
372
373 ostringstream hello;
374 // hmm, we got the wrong socket
375 hello << "* OK intradev.net.lan Cyrus IMAP4 v2.2.13 server ready";
376
377 ss.add_callback(new_connection,bind(&test_hello::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1));
378
379 // max 3 sec
380 for (int i=0; i < 3; i++)
381 ss.fill_buffer(1000000);
382 // don't call atexit and stuff
383 _exit(0);
384 }
385
386 default:
387 // parent
388 {
389 string data;
390
391 // wait till server is up
392 sleep(1);
393 socket_client_connection sc("./socket");
394
395 string errormsg;
396
397 try
398 {
399 command_client cc(sc);
400 }
401 catch(t2n_version_mismatch &e)
402 { errormsg=e.what(); }
403 catch(...)
404 { throw; }
405
406 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
407 }
408 }
409 }
410
411 void OtherServerSmall()
412 {
413 pid_t pid;
414
415 switch(pid=fork())
416 {
417 case -1:
418 {
419 CPPUNIT_FAIL("fork error");
420 break;
421 }
422 case 0:
423 // child
424 {
425 socket_server ss("./socket");
426
427 ostringstream hello;
428 // hmm, we got the wrong socket
429 hello << "READY";
430
431 ss.add_callback(new_connection,bind(&test_hello::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1));
432
433 // max 3 sec
434 for (int i=0; i < 3; i++)
435 ss.fill_buffer(1000000);
436 // don't call atexit and stuff
437 _exit(0);
438 }
439
440 default:
441 // parent
442 {
443 string data;
444
445 // wait till server is up
446 sleep(1);
447 socket_client_connection sc("./socket");
448
449 string errormsg;
450
451 try
452 {
453 command_client cc(sc);
454 }
455 catch(t2n_version_mismatch &e)
456 { errormsg=e.what(); }
457 catch(...)
458 { throw; }
459
460 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
461 }
462 }
463 }
464
465};
466
467CPPUNIT_TEST_SUITE_REGISTRATION(test_hello);