libt2n: (gerd) make sure no exception is thrown in command_client constructor, fix...
[libt2n] / test / hello.cpp
CommitLineData
04d86ba4
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>
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);
b604df5f
GE
54 CPPUNIT_TEST(OtherServerBig);
55 CPPUNIT_TEST(OtherServerSmall);
04d86ba4
GE
56
57 CPPUNIT_TEST_SUITE_END();
58
b5922184
GE
59 pid_t child_pid;
60
04d86ba4
GE
61 public:
62
63 void setUp()
64 { }
65
66 void tearDown()
b5922184
GE
67 {
68 // make sure the server-child is dead before the next test runs
69 kill(child_pid,SIGKILL);
70 sleep(1);
71 }
04d86ba4
GE
72
73 void send_hello(string hello_string, socket_server* ss, int conn_id)
74 {
75 server_connection *sc=ss->get_connection(conn_id);
76 sc->write(hello_string);
77 }
78
79 void send_raw_socket(string hello_string, socket_server* ss, int conn_id)
80 {
81 socket_server_connection *ssc=dynamic_cast<socket_server_connection*>(ss->get_connection(conn_id));
82
83 // this is an evil hack to get access to real_write, don't ever do this in an app!!!
84 real_write_connection *rwc=(real_write_connection*)ssc;
85 rwc->real_write(hello_string);
86 }
87
88 void HelloOk()
89 {
b5922184 90 switch(child_pid=fork())
04d86ba4
GE
91 {
92 case -1:
93 {
94 CPPUNIT_FAIL("fork error");
95 break;
96 }
97 case 0:
98 // child
99 {
100 socket_server ss("./socket");
101
102 ostringstream hello;
103 hello << "T2Nv" << PROTOCOL_VERSION << ';';
104 int byteordercheck=1;
105 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
106 hello << ';';
107
108 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
109
110 // max 10 sec
111 for (int i=0; i < 10; i++)
112 ss.fill_buffer(1000000);
113 // don't call atexit and stuff
114 _exit(0);
115 }
116
117 default:
118 // parent
119 {
120 string data;
121
122 // wait till server is up
123 sleep(1);
124 socket_client_connection sc("./socket");
fb3345ad 125 command_client cc(&sc);
04d86ba4
GE
126 }
127 }
128 }
129
130 void BadTag()
131 {
b5922184 132 switch(child_pid=fork())
04d86ba4
GE
133 {
134 case -1:
135 {
136 CPPUNIT_FAIL("fork error");
137 break;
138 }
139 case 0:
140 // child
141 {
142 socket_server ss("./socket");
143
144 ostringstream hello;
145 hello << "XYZ 123";
146
147 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
148
149 // max 10 sec
150 for (int i=0; i < 10; i++)
151 ss.fill_buffer(1000000);
152 // don't call atexit and stuff
153 _exit(0);
154 }
155
156 default:
157 // parent
158 {
159 string data;
160
161 // wait till server is up
162 sleep(1);
163 socket_client_connection sc("./socket");
164
b5922184
GE
165 command_client cc(&sc);
166
167 t2n_exception* ep=cc.get_constuctor_exception();
04d86ba4 168
b5922184
GE
169 string errormsg;
170 if (ep)
171 errormsg=ep->what();
04d86ba4
GE
172
173 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
174 }
175 }
176 }
177
178 void BadVersion()
179 {
b5922184 180 switch(child_pid=fork())
04d86ba4
GE
181 {
182 case -1:
183 {
184 CPPUNIT_FAIL("fork error");
185 break;
186 }
187 case 0:
188 // child
189 {
190 socket_server ss("./socket");
191
192 ostringstream hello;
193 // lets hope we don't ever get near such a version number...
194 hello << "T2Nv" << 4982271 << ';';
195 int byteordercheck=1;
196 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
197 hello << ';';
198
199 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
200
201 // max 10 sec
202 for (int i=0; i < 10; i++)
203 ss.fill_buffer(1000000);
204 // don't call atexit and stuff
205 _exit(0);
206 }
207
208 default:
209 // parent
210 {
211 string data;
212
213 // wait till server is up
214 sleep(1);
215 socket_client_connection sc("./socket");
216
b5922184 217 command_client cc(&sc);
04d86ba4 218
b5922184
GE
219 t2n_exception* ep=cc.get_constuctor_exception();
220
221 string errormsg;
222 if (ep)
223 errormsg=ep->what();
04d86ba4
GE
224
225 CPPUNIT_ASSERT_EQUAL(string("not compatible with the server protocol version"),errormsg);
226 }
227 }
228 }
229
230 void SeparatorMissing()
231 {
b5922184 232 switch(child_pid=fork())
04d86ba4
GE
233 {
234 case -1:
235 {
236 CPPUNIT_FAIL("fork error");
237 break;
238 }
239 case 0:
240 // child
241 {
242 socket_server ss("./socket");
243
244 ostringstream hello;
245 hello << "T2Nv" << PROTOCOL_VERSION;
246 int byteordercheck=1;
247 hello.write((char*)&byteordercheck,sizeof(byteordercheck));
248 hello << ';';
249
250 ss.add_callback(new_connection,bind(&test_hello::send_hello, boost::ref(*this), hello.str(),&ss, _1));
251
252 // max 10 sec
253 for (int i=0; i < 10; i++)
254 ss.fill_buffer(1000000);
255 // don't call atexit and stuff
256 _exit(0);
257 }
258
259 default:
260 // parent
261 {
262 string data;
263
264 // wait till server is up
265 sleep(1);
266 socket_client_connection sc("./socket");
267
b5922184 268 command_client cc(&sc);
04d86ba4 269
b5922184
GE
270 t2n_exception* ep=cc.get_constuctor_exception();
271
272 string errormsg;
273 if (ep)
274 errormsg=ep->what();
04d86ba4
GE
275
276 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (1. ;)"),errormsg);
277 }
278 }
279 }
280
281 void WrongByteOrder()
282 {
b5922184 283 switch(child_pid=fork())
04d86ba4
GE
284 {
285 case -1:
286 {
287 CPPUNIT_FAIL("fork error");
288 break;
289 }
290 case 0:
291 // child
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::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 // don't call atexit and stuff
316 _exit(0);
317 }
318
319 default:
320 // parent
321 {
322 string data;
323
324 // wait till server is up
325 sleep(1);
326 socket_client_connection sc("./socket");
327
b5922184 328 command_client cc(&sc);
04d86ba4 329
b5922184
GE
330 t2n_exception* ep=cc.get_constuctor_exception();
331
332 string errormsg;
333 if (ep)
334 errormsg=ep->what();
04d86ba4
GE
335
336 CPPUNIT_ASSERT_EQUAL(string("host byte order not matching"),errormsg);
337 }
338 }
339 }
340
b604df5f 341 void OtherServerBig()
04d86ba4 342 {
b5922184 343 switch(child_pid=fork())
04d86ba4
GE
344 {
345 case -1:
346 {
347 CPPUNIT_FAIL("fork error");
348 break;
349 }
350 case 0:
351 // child
352 {
353 socket_server ss("./socket");
354
355 ostringstream hello;
356 // hmm, we got the wrong socket
357 hello << "* OK intradev.net.lan Cyrus IMAP4 v2.2.13 server ready";
358
359 ss.add_callback(new_connection,bind(&test_hello::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1));
360
361 // max 3 sec
362 for (int i=0; i < 3; i++)
363 ss.fill_buffer(1000000);
364 // don't call atexit and stuff
365 _exit(0);
366 }
367
368 default:
369 // parent
370 {
371 string data;
372
373 // wait till server is up
374 sleep(1);
375 socket_client_connection sc("./socket");
376
b5922184
GE
377 command_client cc(&sc);
378
379 t2n_exception* ep=cc.get_constuctor_exception();
04d86ba4 380
b5922184
GE
381 string errormsg;
382 if (ep)
383 errormsg=ep->what();
04d86ba4
GE
384
385 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
386 }
387 }
388 }
389
b604df5f
GE
390 void OtherServerSmall()
391 {
b5922184 392 switch(child_pid=fork())
b604df5f
GE
393 {
394 case -1:
395 {
396 CPPUNIT_FAIL("fork error");
397 break;
398 }
399 case 0:
400 // child
401 {
402 socket_server ss("./socket");
403
404 ostringstream hello;
405 // hmm, we got the wrong socket
406 hello << "READY";
407
408 ss.add_callback(new_connection,bind(&test_hello::send_raw_socket, boost::ref(*this), hello.str(),&ss, _1));
409
410 // max 3 sec
411 for (int i=0; i < 3; i++)
412 ss.fill_buffer(1000000);
413 // don't call atexit and stuff
414 _exit(0);
415 }
416
417 default:
418 // parent
419 {
420 string data;
421
422 // wait till server is up
423 sleep(1);
424 socket_client_connection sc("./socket");
425
b5922184 426 command_client cc(&sc);
b604df5f 427
b5922184
GE
428 t2n_exception* ep=cc.get_constuctor_exception();
429
430 string errormsg;
431 if (ep)
432 errormsg=ep->what();
b604df5f
GE
433
434 CPPUNIT_ASSERT_EQUAL(string("illegal hello received (T2N)"),errormsg);
435 }
436 }
437 }
438
04d86ba4
GE
439};
440
441CPPUNIT_TEST_SUITE_REGISTRATION(test_hello);