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 #if !defined(__APPLE__) && !defined(__FreeBSD__) && \
24     !defined(__OpenBSD__) && !defined(__NetBSD__)
25 #include <features.h>
26 #endif
27 
28 #ifdef __GLIBC__
29 #define __NO_STRING_INLINES 1
30 #endif
31 
32 #include <unistd.h>
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <netdb.h>
36 #include <string.h>
37 #include <sys/wait.h>
38 
39 #include <thrift/c_glib/protocol/thrift_protocol.h>
40 #include <thrift/c_glib/transport/thrift_socket.h>
41 #include <thrift/c_glib/transport/thrift_server_socket.h>
42 #include <thrift/c_glib/transport/thrift_framed_transport.h>
43 
44 #define TEST_BOOL TRUE
45 #define TEST_BYTE 123
46 #define TEST_I16 12345
47 #define TEST_I32 1234567890
48 #define TEST_I64 123456789012345
49 #define TEST_NI16 (-12345)
50 #define TEST_NI32 (-1234567890)
51 #define TEST_NI64 (-123456789012345)
52 #define TEST_DOUBLE 1234567890.123
53 #define TEST_STRING "this is a test string 1234567890!@#$%^&*()"
54 #define TEST_PORT 51199
55 
56 static int transport_read_count = 0;
57 static int transport_read_error = 0;
58 static int transport_read_error_at = -1;
59 gint32
my_thrift_transport_read_all(ThriftTransport * transport,gpointer buf,guint32 len,GError ** error)60 my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf,
61                               guint32 len, GError **error)
62 {
63   if (transport_read_count != transport_read_error_at
64       && transport_read_error == 0)
65   {
66     transport_read_count++;
67     return thrift_transport_read_all (transport, buf, len, error);
68   }
69   return -1;
70 }
71 
72 static int transport_write_count = 0;
73 static int transport_write_error = 0;
74 static int transport_write_error_at = -1;
75 gboolean
my_thrift_transport_write(ThriftTransport * transport,const gpointer buf,const guint32 len,GError ** error)76 my_thrift_transport_write (ThriftTransport *transport, const gpointer buf,
77                            const guint32 len, GError **error)
78 {
79   if (transport_write_count != transport_write_error_at
80       && transport_write_error == 0)
81   {
82     transport_write_count++;
83     return thrift_transport_write (transport, buf, len, error);
84   }
85   return FALSE;
86 }
87 
88 #define thrift_transport_read_all my_thrift_transport_read_all
89 #define thrift_transport_write my_thrift_transport_write
90 #include "../src/thrift/c_glib/protocol/thrift_compact_protocol.c"
91 #undef thrift_transport_read_all
92 #undef thrift_transport_write
93 
94 static void thrift_server_primitives (const int port);
95 static void thrift_server_complex_types (const int port);
96 static void thrift_server_many_frames (const int port);
97 
98 static void
test_create_and_destroy(void)99 test_create_and_destroy (void)
100 {
101   GObject *object = NULL;
102 
103   /* create an object and then destroy it */
104   object = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, NULL);
105   g_assert (object != NULL);
106   g_object_unref (object);
107 }
108 
109 static void
test_initialize(void)110 test_initialize (void)
111 {
112   ThriftSocket *tsocket = NULL;
113   ThriftCompactProtocol *protocol = NULL;
114   ThriftSocket *temp = NULL;
115 
116   /* create a ThriftTransport */
117   tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
118                           "port", 51188, NULL);
119   g_assert (tsocket != NULL);
120   /* create a ThriftCompactProtocol using the Transport */
121   protocol = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
122                            tsocket, NULL);
123   g_assert (protocol != NULL);
124   /* fetch the properties */
125   g_object_get (G_OBJECT (protocol), "transport", &temp, NULL);
126   g_object_unref (temp);
127 
128   /* clean up memory */
129   g_object_unref (protocol);
130   g_object_unref (tsocket);
131 }
132 
133 static void
test_read_and_write_primitives(void)134 test_read_and_write_primitives (void)
135 {
136   int status;
137   pid_t pid;
138   ThriftSocket *tsocket = NULL;
139   ThriftTransport *transport = NULL;
140   ThriftCompactProtocol *tc = NULL;
141   ThriftProtocol *protocol = NULL;
142   gpointer binary = (gpointer *) TEST_STRING;
143   guint32 len = strlen (TEST_STRING);
144   int port = TEST_PORT;
145 
146   /* fork a server from the client */
147   pid = fork ();
148   g_assert (pid >= 0);
149 
150   if (pid == 0)
151   {
152     /* child listens */
153     thrift_server_primitives (port);
154     exit (0);
155   } else {
156     /* parent.  wait a bit for the socket to be created. */
157     sleep (1);
158 
159     /* create a ThriftSocket */
160     tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
161                             "port", port, NULL);
162     transport = THRIFT_TRANSPORT (tsocket);
163     thrift_transport_open (transport, NULL);
164     g_assert (thrift_transport_is_open (transport));
165 
166     /* create a ThriftCompactTransport */
167     tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
168                        tsocket, NULL);
169     protocol = THRIFT_PROTOCOL (tc);
170     g_assert (protocol != NULL);
171 
172     /* write a bunch of primitives */
173     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
174     g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE, NULL) > 0);
175     g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
176     g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
177     g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
178     g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16, NULL) > 0);
179     g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32, NULL) > 0);
180     g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64, NULL) > 0);
181     g_assert (thrift_compact_protocol_write_i16 (protocol, 2, NULL) > 0);
182     g_assert (thrift_compact_protocol_write_i32 (protocol, 2, NULL) > 0);
183     g_assert (thrift_compact_protocol_write_i64 (protocol, 2, NULL) > 0);
184     g_assert (thrift_compact_protocol_write_i16 (protocol, -2, NULL) > 0);
185     g_assert (thrift_compact_protocol_write_i32 (protocol, -2, NULL) > 0);
186     g_assert (thrift_compact_protocol_write_i64 (protocol, -2, NULL) > 0);
187     g_assert (thrift_compact_protocol_write_double (protocol,
188                                                  TEST_DOUBLE, NULL) > 0);
189     g_assert (thrift_compact_protocol_write_string (protocol,
190                                                  TEST_STRING, NULL) > 0);
191     g_assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0);
192     g_assert (thrift_compact_protocol_write_binary (protocol, binary,
193                                                  len, NULL) > 0);
194     g_assert (thrift_compact_protocol_write_binary (protocol, NULL, 0, NULL) > 0);
195     g_assert (thrift_compact_protocol_write_binary (protocol, binary,
196                                                  len, NULL) > 0);
197 
198     /* test write errors */
199     transport_write_error = 1;
200     g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE,
201                                                NULL) == -1);
202     g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) == -1);
203     g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) == -1);
204     g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) == -1);
205     g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16,
206                                                NULL) == -1);
207     g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32,
208                                                NULL) == -1);
209     g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64,
210                                                NULL) == -1);
211     g_assert (thrift_compact_protocol_write_double (protocol, TEST_DOUBLE,
212                                                  NULL) == -1);
213     g_assert (thrift_compact_protocol_write_binary (protocol, binary, len,
214                                                  NULL) == -1);
215     transport_write_error = 0;
216 
217     /* test binary partial failure */
218     transport_write_count = 0;
219     transport_write_error_at = 1;
220     g_assert (thrift_compact_protocol_write_binary (protocol, binary,
221                                                  len, NULL) == -1);
222     transport_write_error_at = -1;
223 
224     /* clean up */
225     thrift_transport_close (transport, NULL);
226     g_object_unref (tsocket);
227     g_object_unref (protocol);
228     g_assert (wait (&status) == pid);
229     g_assert (status == 0);
230   }
231 }
232 
233 static void
test_read_and_write_complex_types(void)234 test_read_and_write_complex_types (void)
235 {
236   int status;
237   pid_t pid;
238   ThriftSocket *tsocket = NULL;
239   ThriftTransport *transport = NULL;
240   ThriftCompactProtocol *tc = NULL;
241   ThriftProtocol *protocol = NULL;
242   int port = TEST_PORT;
243 
244   /* fork a server from the client */
245   pid = fork ();
246   g_assert (pid >= 0);
247 
248   if (pid == 0)
249   {
250     /* child listens */
251     thrift_server_complex_types (port);
252     exit (0);
253   } else {
254     /* parent.  wait a bit for the socket to be created. */
255     sleep (1);
256 
257     /* create a ThriftSocket */
258     tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
259                             "port", port, NULL);
260     transport = THRIFT_TRANSPORT (tsocket);
261     thrift_transport_open (transport, NULL);
262     g_assert (thrift_transport_is_open (transport));
263 
264     /* create a ThriftCompactTransport */
265     tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
266                        tsocket, NULL);
267     protocol = THRIFT_PROTOCOL (tc);
268     g_assert (protocol != NULL);
269 
270     /* test structures */
271     g_assert (thrift_compact_protocol_write_struct_begin (protocol,
272                                                        NULL, NULL) == 0);
273     g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0);
274 
275     /* test field state w.r.t. deltas */
276 
277     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
278                                                        T_DOUBLE, 1, NULL) == 1);
279     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
280                                                        T_DOUBLE,
281                                                        16, NULL) == 1);
282     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
283                                                        T_DOUBLE,
284                                                        17, NULL) == 1);
285     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
286                                                        T_DOUBLE,
287                                                        15, NULL) > 1);
288     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
289                                                        T_DOUBLE,
290                                                        30, NULL) == 1);
291     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
292                                                        T_DOUBLE,
293                                                        46, NULL) > 1);
294     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
295                                                        T_DOUBLE,
296                                                        47, NULL) == 1);
297 
298     /* test fields */
299     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
300                                                        T_DOUBLE,
301                                                        1, NULL) > 1);
302     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
303 
304     /* test field state w.r.t. structs */
305 
306     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
307                                                        T_DOUBLE,
308                                                        1, NULL) > 1);
309     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
310     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
311                                                        T_DOUBLE,
312                                                        16, NULL) == 1);
313     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
314 
315     g_assert (thrift_compact_protocol_write_struct_begin (protocol,
316                                                        NULL, NULL) == 0);
317     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
318                                                        T_DOUBLE,
319                                                        17, NULL) > 1);
320     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
321 
322     g_assert (thrift_compact_protocol_write_struct_begin (protocol,
323                                                        NULL, NULL) == 0);
324     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
325                                                        T_DOUBLE,
326                                                        18, NULL) > 1);
327     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
328     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
329                                                        T_DOUBLE,
330                                                        19, NULL) == 1);
331     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
332     g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0);
333 
334     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
335                                                        T_DOUBLE,
336                                                        18, NULL) == 1);
337     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
338     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
339                                                        T_DOUBLE,
340                                                        25, NULL) == 1);
341     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
342     g_assert (thrift_compact_protocol_write_struct_end (protocol, NULL) == 0);
343 
344     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
345                                                        T_DOUBLE,
346                                                        17, NULL) == 1);
347     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
348 
349     /* test field state w.r.t. bools */
350 
351     /* deltas */
352     /* non-bool field -> bool field -> non-bool field */
353     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
354                                                        T_DOUBLE,
355                                                        18, NULL) == 1);
356     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
357     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
358                                                        19, NULL) == 0);
359     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL,
360                                                 NULL) == 1);
361     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
362     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
363                                                        T_DOUBLE,
364                                                        20, NULL) == 1);
365     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
366     /* bool -> bool field -> bool */
367     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
368     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
369                                                        21, NULL) == 0);
370     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL,
371                                                 NULL) == 1);
372     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
373     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
374 
375     /* no deltas */
376     /* non-bool field -> bool field -> non-bool field */
377     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
378                                                        T_DOUBLE,
379                                                        1, NULL) > 1);
380     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
381     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
382                                                       1, NULL) == 0);
383     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 1);
384     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
385     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
386                                                        T_DOUBLE,
387                                                        1, NULL) > 1);
388     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
389     /* bool -> bool field -> bool */
390     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
391     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test", T_BOOL,
392                                                       1, NULL) == 0);
393     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 1);
394     g_assert (thrift_compact_protocol_write_field_end (protocol, NULL) == 0);
395     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL, NULL) > 0);
396 
397     /* test write error */
398     transport_write_error = 1;
399     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
400                                                        T_DOUBLE,
401                                                        1, NULL) == -1);
402     transport_write_error = 0;
403 
404     /* test 2nd write error */
405     transport_write_count = 0;
406     transport_write_error_at = 1;
407     g_assert (thrift_compact_protocol_write_field_begin (protocol, "test",
408                                                        T_DOUBLE,
409                                                        1, NULL) == -1);
410     transport_write_error_at = -1;
411 
412     /* test 2nd read failure on a field */
413     thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL);
414 
415     /* test write_field_stop */
416     g_assert (thrift_compact_protocol_write_field_stop (protocol, NULL) > 0);
417 
418     /* write a map */
419     g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE,
420                                                      T_DOUBLE,
421                                                      1, NULL) > 0);
422     g_assert (thrift_compact_protocol_write_map_end (protocol, NULL) == 0);
423 
424     /* test 1st read failure on map---nothing to do on our side */
425 
426     /* test 2nd read failure on a map */
427     thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL);
428 
429     /* test 1st write failure on a map */
430     transport_write_error = 1;
431     g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE,
432                                                      T_DOUBLE,
433                                                      1, NULL) == -1);
434     transport_write_error = 0;
435 
436     /* test 2nd write failure on a map */
437     transport_write_count = 0;
438     transport_write_error_at = 1;
439     g_assert (thrift_compact_protocol_write_map_begin (protocol, T_DOUBLE,
440                                                      T_DOUBLE,
441                                                      1, NULL) == -1);
442     transport_write_error_at = -1;
443 
444     /* test negative map size */
445     thrift_compact_protocol_write_varint32 (tc, -10, NULL);
446     thrift_compact_protocol_write_byte (protocol, T_DOUBLE, NULL);
447 
448     /* test list operations */
449     g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
450                                                      15, NULL) > 0);
451     g_assert (thrift_compact_protocol_write_list_end (protocol, NULL) == 0);
452 
453     /* test 1st read failure on a small list---nothing to do on our end */
454 
455     /* test 1st read failure on a big list---nothing to do on our end */
456 
457     /* test 2nd read failure on a big list */
458     thrift_compact_protocol_write_byte (protocol, (gint8) 0xf0, NULL);
459 
460     /* test negative list size */
461     thrift_compact_protocol_write_byte (protocol, (gint8) 0xf0, NULL);
462     thrift_compact_protocol_write_varint32 (tc, -10, NULL);
463 
464     /* test first write error on a small list */
465     transport_write_error = 1;
466     g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
467                                                      14, NULL) == -1);
468     transport_write_error = 0;
469 
470     /* test first write error on a big list */
471     transport_write_error = 1;
472     g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
473                                                      15, NULL) == -1);
474     transport_write_error = 0;
475 
476     /* test 2nd write error on a big list */
477     transport_write_count = 0;
478     transport_write_error_at = 1;
479     g_assert (thrift_compact_protocol_write_list_begin (protocol, T_DOUBLE,
480                                                      15, NULL) == -1);
481     transport_write_error_at = -1;
482 
483     /* test set operation s*/
484     g_assert (thrift_compact_protocol_write_set_begin (protocol, T_DOUBLE,
485                                                     1, NULL) > 0);
486     g_assert (thrift_compact_protocol_write_set_end (protocol, NULL) == 0);
487 
488     /* invalid protocol */
489     g_assert (thrift_compact_protocol_write_byte (protocol, 0, NULL) > 0);
490 
491     /* invalid version */
492     g_assert (thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u,
493                                                 NULL) > 0);
494     g_assert (thrift_compact_protocol_write_byte (protocol, 0, NULL) > 0);
495 
496     /* send a valid message */
497     g_assert (thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u,
498                                                 NULL) > 0);
499     g_assert (thrift_compact_protocol_write_byte (protocol, 0x01u, NULL) > 0);
500     thrift_compact_protocol_write_varint32 (tc, 1, NULL);
501     thrift_compact_protocol_write_string (protocol, "test", NULL);
502 
503     /* broken 2nd read */
504     thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL);
505 
506     /* send a broken 3rd read */
507     thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL);
508     thrift_compact_protocol_write_byte (protocol, 0x01u, NULL);
509 
510     /* send a broken 4th read */
511     thrift_compact_protocol_write_byte (protocol, (gint8) 0x82u, NULL);
512     thrift_compact_protocol_write_byte (protocol, 0x01u, NULL);
513     thrift_compact_protocol_write_varint32 (tc, 1, NULL);
514 
515     /* send a valid message */
516     g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
517                                                         T_CALL, 1, NULL) > 0);
518 
519     g_assert (thrift_compact_protocol_write_message_end (protocol, NULL) == 0);
520 
521     /* send broken writes */
522     transport_write_error = 1;
523     g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
524                                                         T_CALL, 1, NULL) == -1);
525     transport_write_error = 0;
526 
527     transport_write_count = 0;
528     transport_write_error_at = 1;
529     g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
530                                                         T_CALL, 1, NULL) == -1);
531     transport_write_error_at = -1;
532 
533     transport_write_count = 0;
534     transport_write_error_at = 2;
535     g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
536                                                         T_CALL, 1, NULL) == -1);
537     transport_write_error_at = -1;
538 
539     transport_write_count = 0;
540     transport_write_error_at = 3;
541     g_assert (thrift_compact_protocol_write_message_begin (protocol, "test",
542                                                         T_CALL, 1, NULL) == -1);
543     transport_write_error_at = -1;
544 
545     /* clean up */
546     thrift_transport_close (transport, NULL);
547     g_object_unref (tsocket);
548     g_object_unref (protocol);
549     g_assert (wait (&status) == pid);
550     g_assert (status == 0);
551   }
552 }
553 
554 static void
test_read_and_write_many_frames(void)555 test_read_and_write_many_frames (void)
556 {
557   int status;
558   pid_t pid;
559   ThriftSocket *tsocket = NULL;
560   ThriftTransport *transport = NULL;
561   ThriftFramedTransport *ft = NULL;
562   ThriftCompactProtocol *tc = NULL;
563   ThriftProtocol *protocol = NULL;
564   gpointer binary = (gpointer *) TEST_STRING;
565   const guint32 len = strlen (TEST_STRING);
566   int port = TEST_PORT;
567 
568   /* fork a server from the client */
569   pid = fork ();
570   g_assert (pid >= 0);
571 
572   if (pid == 0)
573   {
574     /* child listens */
575     thrift_server_many_frames (port);
576     exit (0);
577   } else {
578     /* parent.  wait a bit for the socket to be created. */
579     sleep (1);
580 
581     /* create a ThriftSocket */
582     tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
583                             "port", port, NULL);
584     g_assert (tsocket != NULL);
585     transport = THRIFT_TRANSPORT (tsocket);
586 
587     /* wrap in a framed transport */
588     ft = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport", transport,
589                        "w_buf_size", 1, NULL);
590     g_assert (ft != NULL);
591     transport = THRIFT_TRANSPORT (ft);
592 
593     thrift_transport_open (transport, NULL);
594     g_assert (thrift_transport_is_open (transport));
595 
596     /* create a compact protocol */
597     tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
598                        transport, NULL);
599     protocol = THRIFT_PROTOCOL (tc);
600     g_assert (protocol != NULL);
601 
602     /* write a bunch of primitives */
603     g_assert (thrift_compact_protocol_write_bool (protocol, TEST_BOOL,
604                                                 NULL) > 0);
605     thrift_transport_flush (transport, NULL);
606     g_assert (thrift_compact_protocol_write_byte (protocol, TEST_BYTE,
607                                                 NULL) > 0);
608     thrift_transport_flush (transport, NULL);
609     g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_I16, NULL) > 0);
610     thrift_transport_flush (transport, NULL);
611     g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_I32, NULL) > 0);
612     thrift_transport_flush (transport, NULL);
613     g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_I64, NULL) > 0);
614     thrift_transport_flush (transport, NULL);
615     g_assert (thrift_compact_protocol_write_i16 (protocol, TEST_NI16, NULL) > 0);
616     thrift_transport_flush (transport, NULL);
617     g_assert (thrift_compact_protocol_write_i32 (protocol, TEST_NI32, NULL) > 0);
618     thrift_transport_flush (transport, NULL);
619     g_assert (thrift_compact_protocol_write_i64 (protocol, TEST_NI64, NULL) > 0);
620     thrift_transport_flush (transport, NULL);
621     g_assert (thrift_compact_protocol_write_i16 (protocol, 2, NULL) > 0);
622     thrift_transport_flush (transport, NULL);
623     g_assert (thrift_compact_protocol_write_i32 (protocol, 2, NULL) > 0);
624     thrift_transport_flush (transport, NULL);
625     g_assert (thrift_compact_protocol_write_i64 (protocol, 2, NULL) > 0);
626     thrift_transport_flush (transport, NULL);
627     g_assert (thrift_compact_protocol_write_i16 (protocol, -2, NULL) > 0);
628     thrift_transport_flush (transport, NULL);
629     g_assert (thrift_compact_protocol_write_i32 (protocol, -2, NULL) > 0);
630     thrift_transport_flush (transport, NULL);
631     g_assert (thrift_compact_protocol_write_i64 (protocol, -2, NULL) > 0);
632     thrift_transport_flush (transport, NULL);
633     g_assert (thrift_compact_protocol_write_double (protocol,
634                                                  TEST_DOUBLE, NULL) > 0);
635     thrift_transport_flush (transport, NULL);
636     g_assert (thrift_compact_protocol_write_string (protocol,
637                                                  TEST_STRING, NULL) > 0);
638     thrift_transport_flush (transport, NULL);
639     g_assert (thrift_compact_protocol_write_string (protocol, "", NULL) > 0);
640     thrift_transport_flush (transport, NULL);
641     g_assert (thrift_compact_protocol_write_binary (protocol, binary,
642                                                  len, NULL) > 0);
643     thrift_transport_flush (transport, NULL);
644     g_assert (thrift_compact_protocol_write_binary (protocol, NULL,
645                                                   0, NULL) > 0);
646     thrift_transport_flush (transport, NULL);
647     g_assert (thrift_compact_protocol_write_binary (protocol, binary,
648                                                  len, NULL) > 0);
649     thrift_transport_flush (transport, NULL);
650 
651     /* clean up */
652     thrift_transport_write_end (transport, NULL);
653     thrift_transport_close (transport, NULL);
654     g_object_unref (ft);
655     g_object_unref (tsocket);
656     g_object_unref (tc);
657     g_assert (wait (&status) == pid);
658     g_assert (status == 0);
659   }
660 }
661 
662 
663 static void
thrift_server_primitives(const int port)664 thrift_server_primitives (const int port)
665 {
666   ThriftServerTransport *transport = NULL;
667   ThriftTransport *client = NULL;
668   ThriftCompactProtocol *tc = NULL;
669   ThriftProtocol *protocol = NULL;
670   gboolean value_boolean = FALSE;
671   gint8 value_byte = 0,
672     zigzag_p16 = 0, zigzag_p32 = 0, zigzag_p64 = 0,
673     zigzag_n16 = 0, zigzag_n32 = 0, zigzag_n64 = 0;
674   gint16 value_16 = 0;
675   gint32 value_32 = 0;
676   gint64 value_64 = 0;
677   gint16 value_n16 = 0;
678   gint32 value_n32 = 0;
679   gint64 value_n64 = 0;
680   gdouble value_double = 0;
681   gchar *string = NULL;
682   gchar *empty_string = NULL;
683   gpointer binary = NULL;
684   guint32 len = 0;
685   void *comparator = (void *) TEST_STRING;
686 
687   ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
688                                               "port", port, NULL);
689   transport = THRIFT_SERVER_TRANSPORT (tsocket);
690   thrift_server_transport_listen (transport, NULL);
691   client = thrift_server_transport_accept (transport, NULL);
692   g_assert (client != NULL);
693 
694   tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
695                       client, NULL);
696   protocol = THRIFT_PROTOCOL (tc);
697 
698   g_assert (thrift_compact_protocol_read_bool (protocol,
699                                             &value_boolean, NULL) > 0);
700   g_assert (thrift_compact_protocol_read_byte (protocol, &value_byte, NULL) > 0);
701   g_assert (thrift_compact_protocol_read_i16 (protocol, &value_16, NULL) > 0);
702   g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) > 0);
703   g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) > 0);
704   g_assert (thrift_compact_protocol_read_i16 (protocol, &value_n16, NULL) > 0);
705   g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) > 0);
706   g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) > 0);
707   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p16, NULL) > 0);
708   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p32, NULL) > 0);
709   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p64, NULL) > 0);
710   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n16, NULL) > 0);
711   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n32, NULL) > 0);
712   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n64, NULL) > 0);
713   g_assert (thrift_compact_protocol_read_double (protocol,
714                                               &value_double, NULL) > 0);
715   g_assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0);
716   g_assert (thrift_compact_protocol_read_string (protocol, &empty_string,
717                                                NULL) > 0);
718   g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
719                                               &len, NULL) > 0);
720 
721   g_assert (value_boolean == TEST_BOOL);
722   g_assert (value_byte == TEST_BYTE);
723   g_assert (value_16 == TEST_I16);
724   g_assert (value_32 == TEST_I32);
725   g_assert (value_64 == TEST_I64);
726   g_assert (value_n16 == TEST_NI16);
727   g_assert (value_n32 == TEST_NI32);
728   g_assert (value_n64 == TEST_NI64);
729   g_assert (zigzag_p16 == 4);
730   g_assert (zigzag_p32 == 4);
731   g_assert (zigzag_p64 == 4);
732   g_assert (zigzag_n16 == 3);
733   g_assert (zigzag_n32 == 3);
734   g_assert (zigzag_n64 == 3);
735   g_assert (value_double == TEST_DOUBLE);
736   g_assert (strcmp (TEST_STRING, string) == 0);
737   g_assert (strcmp ("", empty_string) == 0);
738   g_assert (memcmp (comparator, binary, len) == 0);
739 
740   g_free (string);
741   g_free (empty_string);
742   g_free (binary);
743 
744   g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
745                                                &len, NULL) > 0);
746   g_assert (binary == NULL);
747   g_assert (len == 0);
748   g_free (binary);
749 
750   transport_read_count = 0;
751   transport_read_error_at = 0;
752   g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
753                                               &len, NULL) == -1);
754   transport_read_error_at = -1;
755 
756   transport_read_count = 0;
757   transport_read_error_at = 1;
758   g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
759                                               &len, NULL) == -1);
760   transport_read_error_at = -1;
761 
762   transport_read_error = 1;
763   g_assert (thrift_compact_protocol_read_bool (protocol,
764                                             &value_boolean, NULL) == -1);
765   g_assert (thrift_compact_protocol_read_byte (protocol,
766                                             &value_byte, NULL) == -1);
767   g_assert (thrift_compact_protocol_read_i16 (protocol,
768                                            &value_16, NULL) == -1);
769   g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) == -1);
770   g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) == -1);
771   g_assert (thrift_compact_protocol_read_i16 (protocol,
772                                            &value_n16, NULL) == -1);
773   g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) == -1);
774   g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) == -1);
775   g_assert (thrift_compact_protocol_read_double (protocol,
776                                               &value_double, NULL) == -1);
777   transport_read_error = 0;
778 
779   /* test partial write failure */
780   thrift_protocol_read_i32 (protocol, &value_32, NULL);
781 
782   thrift_transport_read_end (client, NULL);
783   thrift_transport_close (client, NULL);
784 
785   g_object_unref (tc);
786   g_object_unref (client);
787   g_object_unref (tsocket);
788 }
789 
790 static void
thrift_server_complex_types(const int port)791 thrift_server_complex_types (const int port)
792 {
793   ThriftServerTransport *transport = NULL;
794   ThriftTransport *client = NULL;
795   ThriftCompactProtocol *tc = NULL;
796   ThriftProtocol *protocol = NULL;
797   gchar *struct_name = NULL;
798   gchar *field_name = NULL;
799   gchar *message_name = NULL;
800   ThriftType element_type, key_type, value_type, field_type;
801   ThriftMessageType message_type;
802   gboolean value_boolean = ! TEST_BOOL;
803   gint8 value = 0;
804   gint16 field_id = 0;
805   guint32 size = 0;
806   gint32 seqid = 0;
807   gint8 version_and_type = 0;
808   gint8 protocol_id = 0;
809 
810   ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
811                                               "port", port, NULL);
812   transport = THRIFT_SERVER_TRANSPORT (tsocket);
813   thrift_server_transport_listen (transport, NULL);
814   client = thrift_server_transport_accept (transport, NULL);
815   g_assert (client != NULL);
816 
817   tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
818                       client, NULL);
819   protocol = THRIFT_PROTOCOL (tc);
820 
821   /* test struct operations */
822 
823   thrift_compact_protocol_read_struct_begin (protocol, &struct_name, NULL);
824   thrift_compact_protocol_read_struct_end (protocol, NULL);
825 
826   /* test field state w.r.t. deltas */
827 
828   field_id = 0;
829   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
830                                                     &field_type,
831                                            &field_id, NULL) == 1);
832   g_assert (field_id == 1);
833   field_id = 0;
834   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
835                                                     &field_type,
836                                            &field_id, NULL) == 1);
837   g_assert (field_id == 16);
838   field_id = 0;
839   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
840                                                     &field_type,
841                                            &field_id, NULL) == 1);
842   g_assert (field_id == 17);
843   field_id = 0;
844   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
845                                                     &field_type,
846                                            &field_id, NULL) > 1);
847   g_assert (field_id == 15);
848   field_id = 0;
849   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
850                                                     &field_type,
851                                            &field_id, NULL) == 1);
852   g_assert (field_id == 30);
853   field_id = 0;
854   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
855                                                     &field_type,
856                                            &field_id, NULL) > 1);
857   g_assert (field_id == 46);
858   field_id = 0;
859   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
860                                                     &field_type,
861                                            &field_id, NULL) == 1);
862   g_assert (field_id == 47);
863   field_id = 0;
864 
865   /* test field operations */
866 
867   thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type,
868                                            &field_id, NULL);
869   thrift_compact_protocol_read_field_end (protocol, NULL);
870 
871   /* test field state w.r.t. structs */
872 
873   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
874                                                     &field_type,
875                                                     &field_id, NULL) > 1);
876   g_assert (field_id == 1);
877   field_id = 0;
878   thrift_compact_protocol_read_field_end (protocol, NULL);
879   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
880                                                     &field_type,
881                                                     &field_id, NULL) == 1);
882   g_assert (field_id == 16);
883   field_id = 0;
884   thrift_compact_protocol_read_field_end (protocol, NULL);
885 
886   g_assert (thrift_compact_protocol_read_struct_begin (protocol,
887                                                      &struct_name, NULL) == 0);
888   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
889                                                     &field_type,
890                                                     &field_id, NULL) > 1);
891   g_assert (field_id == 17);
892   field_id = 0;
893   thrift_compact_protocol_read_field_end (protocol, NULL);
894 
895   g_assert (thrift_compact_protocol_read_struct_begin (protocol,
896                                                      &struct_name, NULL) == 0);
897   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
898                                                     &field_type,
899                                                     &field_id, NULL) > 1);
900   g_assert (field_id == 18);
901   field_id = 0;
902   thrift_compact_protocol_read_field_end (protocol, NULL);
903   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
904                                                     &field_type,
905                                                     &field_id, NULL) == 1);
906   g_assert (field_id == 19);
907   field_id = 0;
908   thrift_compact_protocol_read_field_end (protocol, NULL);
909   g_assert (thrift_compact_protocol_read_struct_end (protocol, NULL) == 0);
910 
911   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
912                                                     &field_type,
913                                                     &field_id, NULL) == 1);
914   g_assert (field_id == 18);
915   field_id = 0;
916   thrift_compact_protocol_read_field_end (protocol, NULL);
917   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
918                                                     &field_type,
919                                                     &field_id, NULL) == 1);
920   g_assert (field_id == 25);
921   field_id = 0;
922   thrift_compact_protocol_read_field_end (protocol, NULL);
923   g_assert (thrift_compact_protocol_read_struct_end (protocol, NULL) == 0);
924 
925   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
926                                                     &field_type,
927                                                     &field_id, NULL) == 1);
928   g_assert (field_id == 17);
929   field_id = 0;
930   thrift_compact_protocol_read_field_end (protocol, NULL);
931 
932   /* test field state w.r.t. bools */
933 
934   /* deltas */
935   /* non-bool field -> bool field -> non-bool field */
936   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
937                                                     &field_type,
938                                            &field_id, NULL) == 1);
939   thrift_compact_protocol_read_field_end (protocol, NULL);
940   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
941                                                     &field_type,
942                                            &field_id, NULL) == 1);
943   g_assert (field_type == T_BOOL);
944   g_assert (thrift_compact_protocol_read_bool (protocol,
945                                             &value_boolean, NULL) == 0);
946   g_assert (value_boolean == TEST_BOOL);
947   value_boolean = ! TEST_BOOL;
948   thrift_compact_protocol_read_field_end (protocol, NULL);
949   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
950                                                     &field_type,
951                                            &field_id, NULL) == 1);
952   thrift_compact_protocol_read_field_end (protocol, NULL);
953   /* bool -> bool field -> bool */
954   g_assert (thrift_compact_protocol_read_bool (protocol,
955                                             &value_boolean, NULL) > 0);
956   g_assert (value_boolean == TEST_BOOL);
957   value_boolean = ! TEST_BOOL;
958   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
959                                                     &field_type,
960                                            &field_id, NULL) == 1);
961   g_assert (field_type == T_BOOL);
962   g_assert (thrift_compact_protocol_read_bool (protocol,
963                                             &value_boolean, NULL) == 0);
964   g_assert (value_boolean == TEST_BOOL);
965   value_boolean = ! TEST_BOOL;
966   thrift_compact_protocol_read_field_end (protocol, NULL);
967   g_assert (thrift_compact_protocol_read_bool (protocol,
968                                             &value_boolean, NULL) > 0);
969   g_assert (value_boolean == TEST_BOOL);
970   value_boolean = ! TEST_BOOL;
971 
972   /* no deltas */
973   /* non-bool field -> bool field -> non-bool field */
974   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
975                                                     &field_type,
976                                            &field_id, NULL) > 1);
977   thrift_compact_protocol_read_field_end (protocol, NULL);
978   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
979                                                     &field_type,
980                                            &field_id, NULL) > 1);
981   g_assert (field_type == T_BOOL);
982   g_assert (thrift_compact_protocol_read_bool (protocol,
983                                             &value_boolean, NULL) == 0);
984   g_assert (value_boolean == TEST_BOOL);
985   value_boolean = ! TEST_BOOL;
986   thrift_compact_protocol_read_field_end (protocol, NULL);
987   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
988                                                     &field_type,
989                                            &field_id, NULL) > 1);
990   thrift_compact_protocol_read_field_end (protocol, NULL);
991   /* bool -> bool field -> bool */
992   g_assert (thrift_compact_protocol_read_bool (protocol,
993                                             &value_boolean, NULL) > 0);
994   g_assert (value_boolean == TEST_BOOL);
995   value_boolean = ! TEST_BOOL;
996   g_assert (thrift_compact_protocol_read_field_begin (protocol, &field_name,
997                                                     &field_type,
998                                            &field_id, NULL) > 1);
999   g_assert (field_type == T_BOOL);
1000   g_assert (thrift_compact_protocol_read_bool (protocol,
1001                                             &value_boolean, NULL) == 0);
1002   g_assert (value_boolean == TEST_BOOL);
1003   value_boolean = ! TEST_BOOL;
1004   thrift_compact_protocol_read_field_end (protocol, NULL);
1005   g_assert (thrift_compact_protocol_read_bool (protocol,
1006                                             &value_boolean, NULL) > 0);
1007   g_assert (value_boolean == TEST_BOOL);
1008   value_boolean = ! TEST_BOOL;
1009 
1010   /* test first read error on a field */
1011   transport_read_error = 1;
1012   g_assert (thrift_compact_protocol_read_field_begin (protocol,
1013                                                    &field_name, &field_type,
1014                                                    &field_id, NULL) == -1);
1015   transport_read_error = 0;
1016 
1017   /* test 2nd write failure */
1018   thrift_compact_protocol_read_byte (protocol, &value, NULL);
1019 
1020   /* test 2nd read failure on a field */
1021   transport_read_count = 0;
1022   transport_read_error_at = 1;
1023   g_assert (thrift_compact_protocol_read_field_begin (protocol,
1024                                                    &field_name, &field_type,
1025                                                    &field_id, NULL) == -1);
1026   transport_read_error_at = -1;
1027 
1028   /* test field stop */
1029   thrift_compact_protocol_read_field_begin (protocol, &field_name, &field_type,
1030                                            &field_id, NULL);
1031 
1032   /* test map operations */
1033 
1034   thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type,
1035                                          &size, NULL);
1036   thrift_compact_protocol_read_map_end (protocol, NULL);
1037 
1038   /* test 1st read failure on a map */
1039   transport_read_count = 0;
1040   transport_read_error_at = 0;
1041   g_assert (thrift_compact_protocol_read_map_begin (protocol,
1042                                                  &key_type, &value_type,
1043                                                  &size, NULL) == -1);
1044   transport_read_error_at = -1;
1045 
1046   /* test 2nd read failure on a map */
1047   transport_read_count = 0;
1048   transport_read_error_at = 1;
1049   g_assert (thrift_compact_protocol_read_map_begin (protocol,
1050                                                  &key_type, &value_type,
1051                                                  &size, NULL) == -1);
1052   transport_read_error_at = -1;
1053 
1054   /* test 1st write failure on map---nothing to do on our side */
1055 
1056   /* test 2nd write failure */
1057   thrift_compact_protocol_read_byte (protocol, &value, NULL);
1058 
1059   /* test negative map size */
1060   g_assert (thrift_compact_protocol_read_map_begin (protocol,
1061                                                  &key_type, &value_type,
1062                                                  &size, NULL) == -1);
1063 
1064   /* test list operations */
1065   thrift_compact_protocol_read_list_begin (protocol, &element_type, &size,
1066                                            NULL);
1067   thrift_compact_protocol_read_list_end (protocol, NULL);
1068 
1069   /* test small list 1st read failure */
1070   transport_read_error = 1;
1071   g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type,
1072                                                   &size, NULL) == -1);
1073   transport_read_error = 0;
1074 
1075   /* test big list 1st read failure */
1076   transport_read_error = 1;
1077   g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type,
1078                                                   &size, NULL) == -1);
1079   transport_read_error = 0;
1080 
1081   /* test big list 2nd read failure */
1082   transport_read_count = 0;
1083   transport_read_error_at = 1;
1084   thrift_compact_protocol_read_list_begin (protocol, &element_type, &size,
1085                                            NULL);
1086   transport_read_error_at = -1;
1087 
1088   /* test negative list size failure */
1089   thrift_compact_protocol_read_list_begin (protocol, &element_type, &size,
1090                                            NULL);
1091 
1092   /* test small list 1st write failure---nothing to do on our end */
1093 
1094   /* test big list 1st write failure---nothing to do on our end */
1095 
1096   /* test big list 2nd write failure */
1097   thrift_compact_protocol_read_byte (protocol, &value, NULL);
1098 
1099   /* test set operations */
1100   thrift_compact_protocol_read_set_begin (protocol, &element_type, &size, NULL);
1101   thrift_compact_protocol_read_set_end (protocol, NULL);
1102 
1103   /* broken read */
1104   transport_read_error = 1;
1105   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1106                                                      &message_type, &seqid,
1107                                                      NULL) == -1);
1108   transport_read_error = 0;
1109 
1110   /* invalid protocol */
1111   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1112                                                      &message_type, &seqid,
1113                                                      NULL) == -1);
1114 
1115   /* invalid version */
1116   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1117                                                      &message_type, &seqid,
1118                                                      NULL) == -1);
1119 
1120   /* read a valid message */
1121   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1122                                                      &message_type, &seqid,
1123                                                      NULL) > 0);
1124   g_free (message_name);
1125 
1126   /* broken 2nd read on a message */
1127   transport_read_count = 0;
1128   transport_read_error_at = 1;
1129   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1130                                                      &message_type, &seqid,
1131                                                      NULL) == -1);
1132   transport_read_error_at = -1;
1133 
1134   /* broken 3rd read on a message */
1135   transport_read_count = 0;
1136   transport_read_error_at = 2;
1137   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1138                                                      &message_type, &seqid,
1139                                                      NULL) == -1);
1140   transport_read_error_at = -1;
1141 
1142   /* broken 4th read on a message */
1143   transport_read_count = 0;
1144   transport_read_error_at = 3;
1145   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1146                                                      &message_type, &seqid,
1147                                                      NULL) == -1);
1148   transport_read_error_at = -1;
1149 
1150   /* read a valid message */
1151   g_assert (thrift_compact_protocol_read_message_begin (protocol, &message_name,
1152                                                      &message_type, &seqid,
1153                                                      NULL) > 0);
1154   g_free (message_name);
1155 
1156   g_assert (thrift_compact_protocol_read_message_end (protocol, NULL) == 0);
1157 
1158   /* handle 2nd write failure on a message */
1159   thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL);
1160 
1161   /* handle 3rd write failure on a message */
1162   thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL);
1163   thrift_compact_protocol_read_byte (protocol, &version_and_type, NULL);
1164 
1165   /* handle 4th write failure on a message */
1166   thrift_compact_protocol_read_byte (protocol, &protocol_id, NULL);
1167   thrift_compact_protocol_read_byte (protocol, &version_and_type, NULL);
1168   thrift_compact_protocol_read_varint32 (tc, &seqid, NULL);
1169 
1170   g_object_unref (client);
1171   g_object_unref (tsocket);
1172 }
1173 
1174 static void
thrift_server_many_frames(const int port)1175 thrift_server_many_frames (const int port)
1176 {
1177   ThriftServerTransport *transport = NULL;
1178   ThriftTransport *client = NULL;
1179   ThriftCompactProtocol *tcp = NULL;
1180   ThriftProtocol *protocol = NULL;
1181   ThriftServerSocket *tsocket = NULL;
1182   gboolean value_boolean = FALSE;
1183   gint8 value_byte = 0,
1184     zigzag_p16 = 0, zigzag_p32 = 0, zigzag_p64 = 0,
1185     zigzag_n16 = 0, zigzag_n32 = 0, zigzag_n64 = 0;
1186   gint16 value_16 = 0;
1187   gint32 value_32 = 0;
1188   gint64 value_64 = 0;
1189   gint16 value_n16 = 0;
1190   gint32 value_n32 = 0;
1191   gint64 value_n64 = 0;
1192   gdouble value_double = 0;
1193   gchar *string = NULL;
1194   gchar *empty_string = NULL;
1195   gpointer binary = NULL;
1196   guint32 len = 0;
1197   void *comparator = (void *) TEST_STRING;
1198 
1199   tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, "port", port, NULL);
1200   transport = THRIFT_SERVER_TRANSPORT (tsocket);
1201   thrift_server_transport_listen (transport, NULL);
1202 
1203   /* wrap the client in a framed transport */
1204   client = g_object_new (THRIFT_TYPE_FRAMED_TRANSPORT, "transport",
1205                          thrift_server_transport_accept (transport, NULL),
1206                          "r_buf_size", 1, NULL);
1207   g_assert (client != NULL);
1208 
1209   tcp = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport",
1210                       client, NULL);
1211   protocol = THRIFT_PROTOCOL (tcp);
1212 
1213   g_assert (thrift_compact_protocol_read_bool (protocol,
1214                                             &value_boolean, NULL) > 0);
1215   g_assert (thrift_compact_protocol_read_byte (protocol, &value_byte, NULL) > 0);
1216   g_assert (thrift_compact_protocol_read_i16 (protocol, &value_16, NULL) > 0);
1217   g_assert (thrift_compact_protocol_read_i32 (protocol, &value_32, NULL) > 0);
1218   g_assert (thrift_compact_protocol_read_i64 (protocol, &value_64, NULL) > 0);
1219   g_assert (thrift_compact_protocol_read_i16 (protocol, &value_n16, NULL) > 0);
1220   g_assert (thrift_compact_protocol_read_i32 (protocol, &value_n32, NULL) > 0);
1221   g_assert (thrift_compact_protocol_read_i64 (protocol, &value_n64, NULL) > 0);
1222   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p16, NULL) > 0);
1223   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p32, NULL) > 0);
1224   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_p64, NULL) > 0);
1225   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n16, NULL) > 0);
1226   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n32, NULL) > 0);
1227   g_assert (thrift_compact_protocol_read_byte (protocol, &zigzag_n64, NULL) > 0);
1228   g_assert (thrift_compact_protocol_read_double (protocol,
1229                                               &value_double, NULL) > 0);
1230   g_assert (thrift_compact_protocol_read_string (protocol, &string, NULL) > 0);
1231   g_assert (thrift_compact_protocol_read_string (protocol, &empty_string,
1232                                                NULL) > 0);
1233   g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
1234                                               &len, NULL) > 0);
1235 
1236   g_assert (value_boolean == TEST_BOOL);
1237   g_assert (value_byte == TEST_BYTE);
1238   g_assert (value_16 == TEST_I16);
1239   g_assert (value_32 == TEST_I32);
1240   g_assert (value_64 == TEST_I64);
1241   g_assert (value_n16 == TEST_NI16);
1242   g_assert (value_n32 == TEST_NI32);
1243   g_assert (value_n64 == TEST_NI64);
1244   g_assert (zigzag_p16 == 4);
1245   g_assert (zigzag_p32 == 4);
1246   g_assert (zigzag_p64 == 4);
1247   g_assert (zigzag_n16 == 3);
1248   g_assert (zigzag_n32 == 3);
1249   g_assert (zigzag_n64 == 3);
1250   g_assert (value_double == TEST_DOUBLE);
1251   g_assert (strcmp (TEST_STRING, string) == 0);
1252   g_assert (strcmp ("", empty_string) == 0);
1253   g_assert (memcmp (comparator, binary, len) == 0);
1254 
1255   g_free (string);
1256   g_free (empty_string);
1257   g_free (binary);
1258 
1259   g_assert (thrift_compact_protocol_read_binary (protocol, &binary,
1260                                                &len, NULL) > 0);
1261   g_assert (binary == NULL);
1262   g_assert (len == 0);
1263   g_free (binary);
1264 
1265   thrift_transport_read_end (client, NULL);
1266   thrift_transport_close (client, NULL);
1267 
1268   g_object_unref (tcp);
1269   g_object_unref (client);
1270   g_object_unref (tsocket);
1271 }
1272 
1273 int
main(int argc,char * argv[])1274 main (int argc, char *argv[])
1275 {
1276 #if (!GLIB_CHECK_VERSION (2, 36, 0))
1277   g_type_init ();
1278 #endif
1279 
1280   g_test_init (&argc, &argv, NULL);
1281 
1282   g_test_add_func ("/testcompactprotocol/CreateAndDestroy",
1283                    test_create_and_destroy);
1284   g_test_add_func ("/testcompactprotocol/Initialize", test_initialize);
1285   g_test_add_func ("/testcompactprotocol/ReadAndWritePrimitives",
1286                    test_read_and_write_primitives);
1287   g_test_add_func ("/testcompactprotocol/ReadAndWriteComplexTypes",
1288                    test_read_and_write_complex_types);
1289   g_test_add_func ("/testcompactprotocol/ReadAndWriteManyFrames",
1290                    test_read_and_write_many_frames);
1291 
1292   return g_test_run ();
1293 }
1294