1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /* Disable string-function optimizations when glibc is used, as these produce
21 compiler warnings about string length when a string function is used inside
22 a call to g_assert () */
23 #ifdef __GLIBC__
24 #include <features.h>
25 #define __NO_STRING_INLINES 1
26 #endif
27
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <netdb.h>
32 #include <string.h>
33 #include <sys/wait.h>
34
35 #include <thrift/c_glib/protocol/thrift_protocol.h>
36 #include <thrift/c_glib/transport/thrift_socket.h>
37 #include <thrift/c_glib/transport/thrift_server_socket.h>
38 #include <thrift/c_glib/transport/thrift_framed_transport.h>
39
40 #define TEST_BOOL TRUE
41 #define TEST_BYTE 123
42 #define TEST_I16 12345
43 #define TEST_I32 1234567890
44 #define TEST_I64 G_GINT64_CONSTANT (123456789012345)
45 #define TEST_DOUBLE 1234567890.123
46 #define TEST_STRING "this is a test string 1234567890!@#$%^&*()"
47 #define TEST_PORT 51199
48
49 static int transport_read_count = 0;
50 static int transport_read_error = 0;
51 static int transport_read_error_at = -1;
52 gint32
my_thrift_transport_read_all(ThriftTransport * transport,gpointer buf,guint32 len,GError ** error)53 my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf,
54 guint32 len, GError **error)
55 {
56 if (transport_read_count != transport_read_error_at
57 && transport_read_error == 0)
58 {
59 transport_read_count++;
60 return thrift_transport_read_all (transport, buf, len, error);
61 }
62 return -1;
63 }
64
65 static int transport_write_count = 0;
66 static int transport_write_error = 0;
67 static int transport_write_error_at = -1;
68 gboolean
my_thrift_transport_write(ThriftTransport * transport,const gpointer buf,const guint32 len,GError ** error)69 my_thrift_transport_write (ThriftTransport *transport, const gpointer buf,
70 const guint32 len, GError **error)
71 {
72 if (transport_write_count != transport_write_error_at
73 && transport_write_error == 0)
74 {
75 transport_write_count++;
76 return thrift_transport_write (transport, buf, len, error);
77 }
78 return FALSE;
79 }
80
81 #define thrift_transport_read_all my_thrift_transport_read_all
82 #define thrift_transport_write my_thrift_transport_write
83 #include "../src/thrift/c_glib/protocol/thrift_binary_protocol.c"
84 #undef thrift_transport_read_all
85 #undef thrift_transport_write
86
87 static void thrift_server_primitives (const int port);
88 static void thrift_server_complex_types (const int port);
89 static void thrift_server_many_frames (const int port);
90
91 static void
test_create_and_destroy(void)92 test_create_and_destroy(void)
93 {
94 GObject *object = NULL;
95
96 /* create an object and then destroy it */
97 object = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, NULL);
98 g_assert (object != NULL);
99 g_object_unref (object);
100 }
101
102 static void
test_initialize(void)103 test_initialize(void)
104 {
105 ThriftSocket *tsocket = NULL;
106 ThriftBinaryProtocol *protocol = NULL;
107 ThriftSocket *temp = NULL;
108
109 /* create a ThriftTransport */
110 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
111 "port", 51188, NULL);
112 g_assert (tsocket != NULL);
113 /* create a ThriftBinaryProtocol using the Transport */
114 protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
115 tsocket, NULL);
116 g_assert (protocol != NULL);
117 /* fetch the properties */
118 g_object_get (G_OBJECT(protocol), "transport", &temp, NULL);
119 g_object_unref (temp);
120
121 /* clean up memory */
122 g_object_unref (protocol);
123 g_object_unref (tsocket);
124 }
125
126 static void
test_read_and_write_primitives(void)127 test_read_and_write_primitives(void)
128 {
129 int status;
130 pid_t pid;
131 ThriftSocket *tsocket = NULL;
132 ThriftTransport *transport = NULL;
133 ThriftBinaryProtocol *tb = NULL;
134 ThriftProtocol *protocol = NULL;
135 gpointer binary = (gpointer *) TEST_STRING;
136 guint32 len = strlen (TEST_STRING);
137 int port = TEST_PORT;
138
139 /* fork a server from the client */
140 pid = fork ();
141 g_assert (pid >= 0);
142
143 if (pid == 0)
144 {
145 /* child listens */
146 thrift_server_primitives (port);
147 exit (0);
148 } else {
149 /* parent. wait a bit for the socket to be created. */
150 sleep (1);
151
152 /* create a ThriftSocket */
153 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
154 "port", port, NULL);
155 transport = THRIFT_TRANSPORT (tsocket);
156 thrift_transport_open (transport, NULL);
157 g_assert (thrift_transport_is_open (transport));
158
159 /* create a ThriftBinaryTransport */
160 tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
161 tsocket, NULL);
162 protocol = THRIFT_PROTOCOL (tb);
163 g_assert (protocol != NULL);
164
165 /* write a bunch of primitives */
166 g_assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
167 g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
168 g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
169 g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
170 g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
171 g_assert (thrift_binary_protocol_write_double (protocol,
172 TEST_DOUBLE, NULL) > 0);
173 g_assert (thrift_binary_protocol_write_string (protocol,
174 TEST_STRING, NULL) > 0);
175 g_assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0);
176 g_assert (thrift_binary_protocol_write_binary (protocol, binary,
177 len, NULL) > 0);
178 g_assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
179 g_assert (thrift_binary_protocol_write_binary (protocol, binary,
180 len, NULL) > 0);
181
182 /* test write errors */
183 transport_write_error = 1;
184 g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE,
185 NULL) == -1);
186 g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) == -1);
187 g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) == -1);
188 g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) == -1);
189 g_assert (thrift_binary_protocol_write_double (protocol, TEST_DOUBLE,
190 NULL) == -1);
191 g_assert (thrift_binary_protocol_write_binary (protocol, binary, len,
192 NULL) == -1);
193 transport_write_error = 0;
194
195 /* test binary partial failure */
196 transport_write_count = 0;
197 transport_write_error_at = 1;
198 g_assert (thrift_binary_protocol_write_binary (protocol, binary,
199 len, NULL) == -1);
200 transport_write_error_at = -1;
201
202 /* clean up */
203 thrift_transport_close (transport, NULL);
204 g_object_unref (tsocket);
205 g_object_unref (protocol);
206 g_assert (wait (&status) == pid);
207 g_assert (status == 0);
208 }
209 }
210
211 static void
test_read_and_write_complex_types(void)212 test_read_and_write_complex_types (void)
213 {
214 int status;
215 pid_t pid;
216 ThriftSocket *tsocket = NULL;
217 ThriftTransport *transport = NULL;
218 ThriftBinaryProtocol *tb = NULL;
219 ThriftProtocol *protocol = NULL;
220 int port = TEST_PORT;
221
222 /* fork a server from the client */
223 pid = fork ();
224 g_assert (pid >= 0);
225
226 if (pid == 0)
227 {
228 /* child listens */
229 thrift_server_complex_types (port);
230 exit (0);
231 } else {
232 /* parent. wait a bit for the socket to be created. */
233 sleep (1);
234
235 /* create a ThriftSocket */
236 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
237 "port", port, NULL);
238 transport = THRIFT_TRANSPORT (tsocket);
239 thrift_transport_open (transport, NULL);
240 g_assert (thrift_transport_is_open (transport));
241
242 /* create a ThriftBinaryTransport */
243 tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
244 tsocket, NULL);
245 protocol = THRIFT_PROTOCOL (tb);
246 g_assert (protocol != NULL);
247
248 /* test structures */
249 g_assert (thrift_binary_protocol_write_struct_begin (protocol,
250 NULL, NULL) == 0);
251 g_assert (thrift_binary_protocol_write_struct_end (protocol, NULL) == 0);
252
253 g_assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID,
254 1, NULL) > 0);
255 g_assert (thrift_binary_protocol_write_field_end (protocol, NULL) == 0);
256
257 /* test write error */
258 transport_write_error = 1;
259 g_assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID,
260 1, NULL) == -1);
261 transport_write_error = 0;
262
263 /* test 2nd write error */
264 transport_write_count = 0;
265 transport_write_error_at = 1;
266 g_assert (thrift_binary_protocol_write_field_begin (protocol, "test", T_VOID,
267 1, NULL) == -1);
268 transport_write_error_at = -1;
269
270 /* test 2nd read failure on a field */
271 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
272
273 /* test write_field_stop */
274 g_assert (thrift_binary_protocol_write_field_stop (protocol, NULL) > 0);
275
276 /* write a map */
277 g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
278 1, NULL) > 0);
279 g_assert (thrift_binary_protocol_write_map_end (protocol, NULL) == 0);
280
281 /* test 2nd read failure on a map */
282 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
283
284 /* test 3rd read failure on a map */
285 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
286 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
287
288 /* test 1st write failure on a map */
289 transport_write_error = 1;
290 g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
291 1, NULL) == -1);
292 transport_write_error = 0;
293
294 /* test 2nd write failure on a map */
295 transport_write_count = 0;
296 transport_write_error_at = 1;
297 g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
298 1, NULL) == -1);
299 transport_write_error_at = -1;
300
301 /* test 3rd write failure on a map */
302 transport_write_count = 0;
303 transport_write_error_at = 2;
304 g_assert (thrift_binary_protocol_write_map_begin (protocol, T_VOID, T_VOID,
305 1, NULL) == -1);
306 transport_write_error_at = -1;
307
308 /* test negative map size */
309 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
310 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
311 thrift_binary_protocol_write_i32 (protocol, -10, NULL);
312
313 /* test list operations */
314 g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
315 1, NULL) > 0);
316 g_assert (thrift_binary_protocol_write_list_end (protocol, NULL) == 0);
317
318 /* test 2nd read failure on a list */
319 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
320
321 /* test negative list size */
322 thrift_binary_protocol_write_byte (protocol, T_VOID, NULL);
323 thrift_binary_protocol_write_i32 (protocol, -10, NULL);
324
325 /* test first write error on a list */
326 transport_write_error = 1;
327 g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
328 1, NULL) == -1);
329 transport_write_error = 0;
330
331 /* test 2nd write error on a list */
332 transport_write_count = 0;
333 transport_write_error_at = 1;
334 g_assert (thrift_binary_protocol_write_list_begin (protocol, T_VOID,
335 1, NULL) == -1);
336 transport_write_error_at = -1;
337
338 /* test set operation s*/
339 g_assert (thrift_binary_protocol_write_set_begin (protocol, T_VOID,
340 1, NULL) > 0);
341 g_assert (thrift_binary_protocol_write_set_end (protocol, NULL) == 0);
342
343 /* invalid version */
344 g_assert (thrift_binary_protocol_write_i32 (protocol, -1, NULL) > 0);
345
346 /* sz > 0 for a message */
347 g_assert (thrift_binary_protocol_write_i32 (protocol, 1, NULL) > 0);
348
349 /* send a valid message */
350 thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL);
351 thrift_binary_protocol_write_string (protocol, "test", NULL);
352 thrift_binary_protocol_write_i32 (protocol, 1, NULL);
353
354 /* broken 2nd read */
355 thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL);
356
357 /* send a broken 3rd read */
358 thrift_binary_protocol_write_i32 (protocol, 0x80010000, NULL);
359 thrift_binary_protocol_write_string (protocol, "test", NULL);
360
361 /* send a valid message */
362 g_assert (thrift_binary_protocol_write_message_begin (protocol, "test",
363 T_CALL, 1, NULL) > 0);
364
365 g_assert (thrift_binary_protocol_write_message_end (protocol, NULL) == 0);
366
367 /* send broken writes */
368 transport_write_error = 1;
369 g_assert (thrift_binary_protocol_write_message_begin (protocol, "test",
370 T_CALL, 1, NULL) == -1);
371 transport_write_error = 0;
372
373 transport_write_count = 0;
374 transport_write_error_at = 2;
375 g_assert (thrift_binary_protocol_write_message_begin (protocol, "test",
376 T_CALL, 1, NULL) == -1);
377 transport_write_error_at = -1;
378
379 transport_write_count = 0;
380 transport_write_error_at = 3;
381 g_assert (thrift_binary_protocol_write_message_begin (protocol, "test",
382 T_CALL, 1, NULL) == -1);
383 transport_write_error_at = -1;
384
385 /* clean up */
386 thrift_transport_close (transport, NULL);
387 g_object_unref (tsocket);
388 g_object_unref (protocol);
389 g_assert (wait (&status) == pid);
390 g_assert (status == 0);
391 }
392 }
393
394 static void
test_read_and_write_many_frames(void)395 test_read_and_write_many_frames (void)
396 {
397 int status;
398 pid_t pid;
399 ThriftSocket *tsocket = NULL;
400 ThriftTransport *transport = NULL;
401 ThriftFramedTransport *ft = NULL;
402 ThriftBinaryProtocol *tb = NULL;
403 ThriftProtocol *protocol = NULL;
404 gpointer binary = (gpointer *) TEST_STRING;
405 const guint32 len = strlen (TEST_STRING);
406 int port = TEST_PORT;
407
408 /* fork a server from the client */
409 pid = fork ();
410 g_assert (pid >= 0);
411
412 if (pid == 0)
413 {
414 /* child listens */
415 thrift_server_many_frames (port);
416 exit (0);
417 } else {
418 /* parent. wait a bit for the socket to be created. */
419 sleep (1);
420
421 /* create a ThriftSocket */
422 tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
423 "port", port, NULL);
424 g_assert (tsocket != NULL);
425 transport = THRIFT_TRANSPORT (tsocket);
426
427 /* wrap in a framed transport */
428 ft = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", transport,
429 "w_buf_size", 1, NULL);
430 g_assert (ft != NULL);
431 transport = THRIFT_TRANSPORT (ft);
432
433 thrift_transport_open (transport, NULL);
434 g_assert (thrift_transport_is_open (transport));
435
436 /* create a binary protocol */
437 tb = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
438 transport, NULL);
439 protocol = THRIFT_PROTOCOL (tb);
440 g_assert (protocol != NULL);
441
442 /* write a bunch of primitives */
443 g_assert (thrift_binary_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
444 thrift_transport_flush (transport, NULL);
445 g_assert (thrift_binary_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
446 thrift_transport_flush (transport, NULL);
447 g_assert (thrift_binary_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
448 thrift_transport_flush (transport, NULL);
449 g_assert (thrift_binary_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
450 thrift_transport_flush (transport, NULL);
451 g_assert (thrift_binary_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
452 thrift_transport_flush (transport, NULL);
453 g_assert (thrift_binary_protocol_write_double (protocol,
454 TEST_DOUBLE, NULL) > 0);
455 thrift_transport_flush (transport, NULL);
456 g_assert (thrift_binary_protocol_write_string (protocol,
457 TEST_STRING, NULL) > 0);
458 thrift_transport_flush (transport, NULL);
459 g_assert (thrift_binary_protocol_write_string (protocol, "", NULL) > 0);
460 thrift_transport_flush (transport, NULL);
461 g_assert (thrift_binary_protocol_write_binary (protocol, binary,
462 len, NULL) > 0);
463 thrift_transport_flush (transport, NULL);
464 g_assert (thrift_binary_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
465 thrift_transport_flush (transport, NULL);
466 g_assert (thrift_binary_protocol_write_binary (protocol, binary,
467 len, NULL) > 0);
468 thrift_transport_flush (transport, NULL);
469
470 /* clean up */
471 thrift_transport_write_end (transport, NULL);
472 thrift_transport_close (transport, NULL);
473 g_object_unref (ft);
474 g_object_unref (tsocket);
475 g_object_unref (tb);
476 g_assert (wait (&status) == pid);
477 g_assert (status == 0);
478 }
479 }
480
481
482 static void
thrift_server_primitives(const int port)483 thrift_server_primitives (const int port)
484 {
485 ThriftServerTransport *transport = NULL;
486 ThriftTransport *client = NULL;
487 ThriftBinaryProtocol *tbp = NULL;
488 ThriftProtocol *protocol = NULL;
489 gboolean value_boolean = FALSE;
490 gint8 value_byte = 0;
491 gint16 value_16 = 0;
492 gint32 value_32 = 0;
493 gint64 value_64 = 0;
494 gdouble value_double = 0;
495 gchar *string = NULL;
496 gchar *empty_string = NULL;
497 gpointer binary = NULL;
498 guint32 len = 0;
499 void *comparator = (void *) TEST_STRING;
500
501 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
502 "port", port, NULL);
503 transport = THRIFT_SERVER_TRANSPORT (tsocket);
504 thrift_server_transport_listen (transport, NULL);
505 client = thrift_server_transport_accept (transport, NULL);
506 g_assert (client != NULL);
507
508 tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
509 client, NULL);
510 protocol = THRIFT_PROTOCOL (tbp);
511
512 g_assert (thrift_binary_protocol_read_bool (protocol,
513 &value_boolean, NULL) > 0);
514 g_assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0);
515 g_assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0);
516 g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0);
517 g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0);
518 g_assert (thrift_binary_protocol_read_double (protocol,
519 &value_double, NULL) > 0);
520 g_assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
521 g_assert (thrift_binary_protocol_read_string (protocol, &empty_string,
522 NULL) > 0);
523 g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
524 &len, NULL) > 0);
525
526 g_assert (value_boolean == TEST_BOOL);
527 g_assert (value_byte == TEST_BYTE);
528 g_assert (value_16 == TEST_I16);
529 g_assert (value_32 == TEST_I32);
530 g_assert (value_64 == TEST_I64);
531 g_assert (value_double == TEST_DOUBLE);
532 g_assert (strcmp (TEST_STRING, string) == 0);
533 g_assert (strcmp ("", empty_string) == 0);
534 g_assert (memcmp (comparator, binary, len) == 0);
535
536 g_free (string);
537 g_free (empty_string);
538 g_free (binary);
539
540 g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
541 &len, NULL) > 0);
542 g_assert (binary == NULL);
543 g_assert (len == 0);
544 g_free (binary);
545
546 transport_read_count = 0;
547 transport_read_error_at = 0;
548 g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
549 &len, NULL) == -1);
550 transport_read_error_at = -1;
551
552 transport_read_count = 0;
553 transport_read_error_at = 1;
554 g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
555 &len, NULL) == -1);
556 transport_read_error_at = -1;
557
558 transport_read_error = 1;
559 g_assert (thrift_binary_protocol_read_bool (protocol,
560 &value_boolean, NULL) == -1);
561 g_assert (thrift_binary_protocol_read_byte (protocol,
562 &value_byte, NULL) == -1);
563 g_assert (thrift_binary_protocol_read_i16 (protocol,
564 &value_16, NULL) == -1);
565 g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) == -1);
566 g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) == -1);
567 g_assert (thrift_binary_protocol_read_double (protocol,
568 &value_double, NULL) == -1);
569 transport_read_error = 0;
570
571 /* test partial write failure */
572 thrift_protocol_read_i32 (protocol, &value_32, NULL);
573
574 thrift_transport_read_end (client, NULL);
575 thrift_transport_close (client, NULL);
576
577 g_object_unref (tbp);
578 g_object_unref (client);
579 g_object_unref (tsocket);
580 }
581
582 static void
thrift_server_complex_types(const int port)583 thrift_server_complex_types (const int port)
584 {
585 ThriftServerTransport *transport = NULL;
586 ThriftTransport *client = NULL;
587 ThriftBinaryProtocol *tbp = NULL;
588 ThriftProtocol *protocol = NULL;
589 gchar *struct_name = NULL;
590 gchar *field_name = NULL;
591 gchar *message_name = NULL;
592 ThriftType element_type, key_type, value_type, field_type;
593 ThriftMessageType message_type;
594 gint8 value = 0;
595 gint16 field_id = 0;
596 guint32 size = 0;
597 gint32 seqid = 0;
598 gint32 version = 0;
599
600 ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
601 "port", port, NULL);
602 transport = THRIFT_SERVER_TRANSPORT (tsocket);
603 thrift_server_transport_listen (transport, NULL);
604 client = thrift_server_transport_accept (transport, NULL);
605 g_assert (client != NULL);
606
607 tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
608 client, NULL);
609 protocol = THRIFT_PROTOCOL (tbp);
610
611 thrift_binary_protocol_read_struct_begin (protocol, &struct_name, NULL);
612 thrift_binary_protocol_read_struct_end (protocol, NULL);
613
614 thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type,
615 &field_id, NULL);
616 thrift_binary_protocol_read_field_end (protocol, NULL);
617
618 /* test first read error on a field */
619 transport_read_error = 1;
620 g_assert (thrift_binary_protocol_read_field_begin (protocol,
621 &field_name, &field_type,
622 &field_id, NULL) == -1);
623 transport_read_error = 0;
624
625 /* test 2nd write failure */
626 thrift_binary_protocol_read_byte (protocol, &value, NULL);
627
628 /* test 2nd read failure on a field */
629 transport_read_count = 0;
630 transport_read_error_at = 1;
631 g_assert (thrift_binary_protocol_read_field_begin (protocol,
632 &field_name, &field_type,
633 &field_id, NULL) == -1);
634 transport_read_error_at = -1;
635
636 /* test field stop */
637 thrift_binary_protocol_read_field_begin (protocol, &field_name, &field_type,
638 &field_id, NULL);
639
640 thrift_binary_protocol_read_map_begin (protocol, &key_type, &value_type,
641 &size, NULL);
642 thrift_binary_protocol_read_map_end (protocol, NULL);
643
644 /* test read failure on a map */
645 transport_read_count = 0;
646 transport_read_error_at = 0;
647 g_assert (thrift_binary_protocol_read_map_begin (protocol,
648 &key_type, &value_type,
649 &size, NULL) == -1);
650 transport_read_error_at = -1;
651
652 /* test 2nd read failure on a map */
653 transport_read_count = 0;
654 transport_read_error_at = 1;
655 g_assert (thrift_binary_protocol_read_map_begin (protocol,
656 &key_type, &value_type,
657 &size, NULL) == -1);
658 transport_read_error_at = -1;
659
660 /* test 3rd read failure on a map */
661 transport_read_count = 0;
662 transport_read_error_at = 2;
663 g_assert (thrift_binary_protocol_read_map_begin (protocol,
664 &key_type, &value_type,
665 &size, NULL) == -1);
666 transport_read_error_at = -1;
667
668 /* test 2nd write failure */
669 thrift_binary_protocol_read_byte (protocol, &value, NULL);
670
671 /* test 3rd write failure */
672 thrift_binary_protocol_read_byte (protocol, &value, NULL);
673 thrift_binary_protocol_read_byte (protocol, &value, NULL);
674
675 /* test negative map size */
676 g_assert (thrift_binary_protocol_read_map_begin (protocol,
677 &key_type, &value_type,
678 &size, NULL) == -1);
679
680 /* test list operations */
681 thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL);
682 thrift_binary_protocol_read_list_end (protocol, NULL);
683
684 /* test read failure */
685 transport_read_error = 1;
686 g_assert (thrift_binary_protocol_read_list_begin (protocol, &element_type,
687 &size, NULL) == -1);
688 transport_read_error = 0;
689
690 /* test 2nd read failure */
691 transport_read_count = 0;
692 transport_read_error_at = 1;
693 thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL);
694 transport_read_error_at = -1;
695
696 /* test negative list size failure */
697 thrift_binary_protocol_read_list_begin (protocol, &element_type, &size, NULL);
698
699 /* test 2nd write failure */
700 thrift_binary_protocol_read_byte (protocol, &value, NULL);
701
702 /* test set operations */
703 thrift_binary_protocol_read_set_begin (protocol, &element_type, &size, NULL);
704 thrift_binary_protocol_read_set_end (protocol, NULL);
705
706 /* broken read */
707 transport_read_error = 1;
708 g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
709 &message_type, &seqid,
710 NULL) == -1);
711 transport_read_error = 0;
712
713 /* invalid protocol version */
714 g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
715 &message_type, &seqid,
716 NULL) == -1);
717
718 /* sz > 0 */
719 g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
720 &message_type, &seqid,
721 NULL) > 0);
722
723 /* read a valid message */
724 g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
725 &message_type, &seqid,
726 NULL) > 0);
727 g_free (message_name);
728
729 /* broken 2nd read on a message */
730 transport_read_count = 0;
731 transport_read_error_at = 1;
732 g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
733 &message_type, &seqid,
734 NULL) == -1);
735 transport_read_error_at = -1;
736
737 /* broken 3rd read on a message */
738 transport_read_count = 0;
739 transport_read_error_at = 3; /* read_string does two reads */
740 g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
741 &message_type, &seqid,
742 NULL) == -1);
743 g_free (message_name);
744 transport_read_error_at = -1;
745
746 /* read a valid message */
747 g_assert (thrift_binary_protocol_read_message_begin (protocol, &message_name,
748 &message_type, &seqid,
749 NULL) > 0);
750 g_free (message_name);
751
752 g_assert (thrift_binary_protocol_read_message_end (protocol, NULL) == 0);
753
754 /* handle 2nd write failure on a message */
755 thrift_binary_protocol_read_i32 (protocol, &version, NULL);
756
757 /* handle 2nd write failure on a message */
758 thrift_binary_protocol_read_i32 (protocol, &version, NULL);
759 thrift_binary_protocol_read_string (protocol, &message_name, NULL);
760
761 g_object_unref (client);
762 /* TODO: investigate g_object_unref (tbp); */
763 g_object_unref (tsocket);
764 }
765
766 static void
thrift_server_many_frames(const int port)767 thrift_server_many_frames (const int port)
768 {
769 ThriftServerTransport *transport = NULL;
770 ThriftTransport *client = NULL;
771 ThriftBinaryProtocol *tbp = NULL;
772 ThriftProtocol *protocol = NULL;
773 ThriftServerSocket *tsocket = NULL;
774 gboolean value_boolean = FALSE;
775 gint8 value_byte = 0;
776 gint16 value_16 = 0;
777 gint32 value_32 = 0;
778 gint64 value_64 = 0;
779 gdouble value_double = 0;
780 gchar *string = NULL;
781 gchar *empty_string = NULL;
782 gpointer binary = NULL;
783 guint32 len = 0;
784 void *comparator = (void *) TEST_STRING;
785
786 tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL);
787 transport = THRIFT_SERVER_TRANSPORT (tsocket);
788 thrift_server_transport_listen (transport, NULL);
789
790 /* wrap the client in a framed transport */
791 client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport",
792 thrift_server_transport_accept (transport, NULL),
793 "r_buf_size", 1, NULL);
794 g_assert (client != NULL);
795
796 tbp = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
797 client, NULL);
798 protocol = THRIFT_PROTOCOL (tbp);
799
800 g_assert (thrift_binary_protocol_read_bool (protocol,
801 &value_boolean, NULL) > 0);
802 g_assert (thrift_binary_protocol_read_byte (protocol, &value_byte, NULL) > 0);
803 g_assert (thrift_binary_protocol_read_i16 (protocol, &value_16, NULL) > 0);
804 g_assert (thrift_binary_protocol_read_i32 (protocol, &value_32, NULL) > 0);
805 g_assert (thrift_binary_protocol_read_i64 (protocol, &value_64, NULL) > 0);
806 g_assert (thrift_binary_protocol_read_double (protocol,
807 &value_double, NULL) > 0);
808 g_assert (thrift_binary_protocol_read_string (protocol, &string, NULL) > 0);
809 g_assert (thrift_binary_protocol_read_string (protocol, &empty_string,
810 NULL) > 0);
811 g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
812 &len, NULL) > 0);
813
814 g_assert (value_boolean == TEST_BOOL);
815 g_assert (value_byte == TEST_BYTE);
816 g_assert (value_16 == TEST_I16);
817 g_assert (value_32 == TEST_I32);
818 g_assert (value_64 == TEST_I64);
819 g_assert (value_double == TEST_DOUBLE);
820 g_assert (strcmp (TEST_STRING, string) == 0);
821 g_assert (strcmp ("", empty_string) == 0);
822 g_assert (memcmp (comparator, binary, len) == 0);
823
824 g_free (string);
825 g_free (empty_string);
826 g_free (binary);
827
828 g_assert (thrift_binary_protocol_read_binary (protocol, &binary,
829 &len, NULL) > 0);
830 g_assert (binary == NULL);
831 g_assert (len == 0);
832 g_free (binary);
833
834 thrift_transport_read_end (client, NULL);
835 thrift_transport_close (client, NULL);
836
837 g_object_unref (tbp);
838 g_object_unref (client);
839 g_object_unref (tsocket);
840 }
841
842 int
main(int argc,char * argv[])843 main(int argc, char *argv[])
844 {
845 #if (!GLIB_CHECK_VERSION (2, 36, 0))
846 g_type_init();
847 #endif
848
849 g_test_init (&argc, &argv, NULL);
850
851 g_test_add_func ("/testbinaryprotocol/CreateAndDestroy", test_create_and_destroy);
852 g_test_add_func ("/testbinaryprotocol/Initialize", test_initialize);
853 g_test_add_func ("/testbinaryprotocol/ReadAndWritePrimitives", test_read_and_write_primitives);
854 g_test_add_func ("/testbinaryprotocol/ReadAndWriteComplexTypes", test_read_and_write_complex_types);
855 g_test_add_func ("/testbinaryprotocol/ReadAndWriteManyFrames",
856 test_read_and_write_many_frames);
857
858 return g_test_run ();
859 }
860