blob: 2a667950b00e6d99018cb9d7fc86af74c2889fa3 [file] [log] [blame]
Roger Meierb3c84092014-09-01 21:53:40 +02001/*
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#include <glib-object.h>
21#include <inttypes.h>
22#include <signal.h>
23#include <stdio.h>
24#include <string.h>
25
26#include <sys/time.h>
27
28#include <thrift/c_glib/thrift.h>
29#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
30#include <thrift/c_glib/transport/thrift_buffered_transport.h>
31#include <thrift/c_glib/transport/thrift_framed_transport.h>
32#include <thrift/c_glib/transport/thrift_socket.h>
33#include <thrift/c_glib/transport/thrift_transport.h>
34
35#include "../gen-c_glib/t_test_thrift_test.h"
36
37/* Handle SIGPIPE signals (indicating the server has closed the
38 connection prematurely) by outputting an error message before
39 exiting. */
40static void
41sigpipe_handler (int signal_number) {
42 THRIFT_UNUSED_VAR (signal_number);
43
44 /* Flush standard output to make sure the test results so far are
45 logged */
46 fflush (stdout);
47
48 fputs ("Broken pipe (server closed connection prematurely)\n", stderr);
49 fflush (stderr);
50
51 /* Re-raise the signal, this time invoking the default signal
52 handler, to terminate the program */
53 raise (SIGPIPE);
54}
55
56/* Compare two gint32 values. Used for sorting and finding integer
57 values within a GList. */
58static gint
59gint32_compare (gconstpointer a, gconstpointer b) {
60 gint32 int32_a = *(gint32 *)a;
61 gint32 int32_b = *(gint32 *)b;
62 int result = 0;
63
64 if (int32_a < int32_b)
65 result = -1;
66 else if (int32_a > int32_b)
67 result = 1;
68
69 return result;
70}
71
72int
73main (int argc, char **argv) {
74 static gchar *host = NULL;
75 static gint port = 9090;
76 static gchar *transport_option = NULL;
77 static gchar *protocol_option = NULL;
78 static gint num_tests = 1;
79
80 static
81 GOptionEntry option_entries[] ={
82 { "host", 0, 0, G_OPTION_ARG_STRING, &host,
83 "Host to connect (=localhost)", NULL },
84 { "port", 0, 0, G_OPTION_ARG_INT, &port,
85 "Port number to connect (=9090)", NULL },
86 { "transport", 0, 0, G_OPTION_ARG_STRING, &transport_option,
87 "Transport: buffered, framed (=buffered)", NULL },
88 { "protocol", 0, 0, G_OPTION_ARG_STRING, &protocol_option,
89 "Protocol: binary (=binary)", NULL },
90 { "testloops", 'n', 0, G_OPTION_ARG_INT, &num_tests,
91 "Number of tests (=1)", NULL },
92 { NULL }
93 };
94
95 struct sigaction sigpipe_action;
96
97 GType transport_type = THRIFT_TYPE_BUFFERED_TRANSPORT;
98 gchar *transport_name = "buffered";
99 GType protocol_type = THRIFT_TYPE_BINARY_PROTOCOL;
100 gchar *protocol_name = "binary";
101
102 ThriftSocket *socket;
103 ThriftTransport *transport;
104 ThriftProtocol *protocol;
105
106 TTestThriftTestIf *test_client;
107
108 struct timeval time_start, time_stop, time_elapsed;
109 guint64 time_elapsed_usec, time_total_usec = 0;
110 guint64 time_min_usec = G_MAXUINT64, time_max_usec = 0, time_avg_usec;
111
112 GOptionContext *option_context;
113 gboolean options_valid = TRUE;
114 int test_num = 0;
115 int fail_count = 0;
116 GError *error = NULL;
117
118 /* Configure and parse our command-line options */
119 option_context = g_option_context_new (NULL);
120 g_option_context_add_main_entries (option_context,
121 option_entries,
122 NULL);
123 if (g_option_context_parse (option_context,
124 &argc,
125 &argv,
126 &error) == FALSE) {
127 fprintf (stderr, "%s\n", error->message);
128 return 255;
129 }
130 g_option_context_free (option_context);
131
132 /* Set remaining default values for unspecified options */
133 if (host == NULL)
134 host = g_strdup ("localhost");
135
136 /* Validate the parsed options */
137 if (protocol_option != NULL &&
138 strncmp (protocol_option, "binary", 7) != 0) {
139 fprintf (stderr, "Unknown protocol type %s\n", protocol_option);
140 options_valid = FALSE;
141 }
142
143 if (transport_option != NULL) {
144 if (strncmp (transport_option, "framed", 7) == 0) {
145 transport_type = THRIFT_TYPE_FRAMED_TRANSPORT;
146 transport_name = "framed";
147 }
148 else if (strncmp (transport_option, "buffered", 9) != 0) {
149 fprintf (stderr, "Unknown transport type %s\n", transport_option);
150 options_valid = FALSE;
151 }
152 }
153
154 if (options_valid == FALSE)
155 return 254;
156
157 printf ("Connecting (%s/%s) to: %s:%d\n",
158 transport_name,
159 protocol_name,
160 host,
161 port);
162
163 /* Install our SIGPIPE handler, which outputs an error message to
164 standard error before exiting so testers can know what
165 happened */
166 memset (&sigpipe_action, 0, sizeof (sigpipe_action));
167 sigpipe_action.sa_handler = sigpipe_handler;
168 sigpipe_action.sa_flags = SA_RESETHAND;
169 sigaction (SIGPIPE, &sigpipe_action, NULL);
170
171 /* Establish all our connection objects */
172 socket = g_object_new (THRIFT_TYPE_SOCKET,
173 "hostname", host,
174 "port", port,
175 NULL);
176 transport = g_object_new (transport_type,
177 "transport", socket,
178 NULL);
179 protocol = g_object_new (protocol_type,
180 "transport", transport,
181 NULL);
182 test_client = g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT,
183 "input_protocol", protocol,
184 "output_protocol", protocol,
185 NULL);
186
187 /* Execute the actual tests */
188 for (test_num = 0; test_num < num_tests; ++test_num) {
189 if (thrift_transport_open (transport, &error) == TRUE) {
190 gchar *string = NULL;
191 gint8 byte = 0;
192 gint32 int32 = 0;
193 gint64 int64 = 0;
194 gdouble dub = 0;
195
196 gint byte_thing, i32_thing, inner_byte_thing, inner_i32_thing;
197 gint64 i64_thing, inner_i64_thing;
198
199 TTestXtruct *xtruct_out, *xtruct_in, *inner_xtruct_in;
200 TTestXtruct2 *xtruct2_out, *xtruct2_in;
201
202 GHashTable *map_out, *map_in, *inner_map_in;
203 GHashTable *set_out, *set_in;
204 gpointer key, value;
205 gint32 *i32_key_ptr, *i32_value_ptr;
206 GHashTableIter hash_table_iter, inner_hash_table_iter;
207 GList *keys_out, *keys_in, *keys_elem;
208
209 GArray *list_out, *list_in;
210
211 TTestNumberz numberz;
212
213 TTestUserId user_id, *user_id_ptr;
214
215 TTestInsanity *insanity_out, *insanity_in;
216 GHashTable *user_map;
217 GHashTableIter user_map_iter;
218 GPtrArray *xtructs;
219
220 TTestXception *xception = NULL;
221 TTestXception2 *xception2 = NULL;
222
223 gboolean oneway_result;
224 struct timeval oneway_start, oneway_end, oneway_elapsed;
225 gint oneway_elapsed_usec;
226
227 gboolean first;
228 gint32 i, j;
229
230 printf ("Test #%d, connect %s:%d\n", test_num + 1, host, port);
231 gettimeofday (&time_start, NULL);
232
233 /* These test routines have been ported from the C++ test
234 client, care being taken to ensure their output remains as
235 close as possible to the original to facilitate diffs.
236
237 For simplicity comments have been omitted, but every routine
238 has the same basic structure:
239
240 - Create and populate data structures as necessary.
241
242 - Format and output (to the console) a representation of the
243 outgoing data.
244
245 - Issue the remote method call to the server.
246
247 - Format and output a representation of the returned data.
248
249 - Verify the returned data matches what was expected.
250
251 - Deallocate any created data structures.
252
253 Note the recognized values and expected behaviour of each
254 remote method are described in ThriftTest.thrift, which
255 you'll find in the top-level "test" folder. */
256
257 /**
258 * VOID TEST
259 */
260 printf ("testVoid()");
261 if (t_test_thrift_test_if_test_void (test_client, &error) == TRUE) {
262 printf (" = void\n");
263 }
264 else {
265 printf ("%s\n", error->message);
266 g_error_free (error);
267 error = NULL;
268
269 fail_count++;
270 }
271
272 /**
273 * STRING TEST
274 */
275 printf ("testString(\"Test\")");
276 if (t_test_thrift_test_if_test_string (test_client,
277 &string,
278 "Test",
279 &error) == TRUE) {
280 printf (" = \"%s\"\n", string);
281 if (strncmp (string, "Test", 5) != 0)
282 fail_count++;
283
284 g_free (string);
285 string = NULL;
286 }
287 else {
288 printf ("%s\n", error->message);
289 g_error_free (error);
290 error = NULL;
291
292 fail_count++;
293 }
294
295 /**
296 * BYTE TEST
297 */
298 printf ("testByte(1)");
299 if (t_test_thrift_test_if_test_byte (test_client,
300 &byte,
301 1,
302 &error) == TRUE) {
303 printf (" = %d\n", byte);
304 if (byte != 1)
305 fail_count++;
306 }
307 else {
308 printf ("%s\n", error->message);
309 g_error_free (error);
310 error = NULL;
311
312 fail_count++;
313 }
314
315 /**
316 * I32 TEST
317 */
318 printf ("testI32(-1)");
319 if (t_test_thrift_test_if_test_i32 (test_client,
320 &int32,
321 -1,
322 &error) == TRUE) {
323 printf (" = %d\n", int32);
324 if (int32 != -1)
325 fail_count++;
326 }
327 else {
328 printf ("%s\n", error->message);
329 g_error_free (error);
330 error = NULL;
331
332 fail_count++;
333 }
334
335 /**
336 * I64 TEST
337 */
338 printf ("testI64(-34359738368)");
339 if (t_test_thrift_test_if_test_i64 (test_client,
340 &int64,
341 (gint64)-34359738368,
342 &error) == TRUE) {
343 printf (" = %" PRId64 "\n", int64);
344 if (int64 != (gint64)-34359738368)
345 fail_count++;
346 }
347 else {
348 printf ("%s\n", error->message);
349 g_error_free (error);
350 error = NULL;
351
352 fail_count++;
353 }
354
355 /**
356 * DOUBLE TEST
357 */
358 printf("testDouble(-5.2098523)");
359 if (t_test_thrift_test_if_test_double (test_client,
360 &dub,
361 -5.2098523,
362 &error) == TRUE) {
363 printf (" = %f\n", dub);
364 if ((dub - (-5.2098523)) > 0.001)
365 fail_count++;
366 }
367 else {
368 printf ("%s\n", error->message);
369 g_error_free (error);
370 error = NULL;
371
372 fail_count++;
373 }
374
375 /**
376 * STRUCT TEST
377 */
378 printf ("testStruct({\"Zero\", 1, -3, -5})");
379 xtruct_out = g_object_new (T_TEST_TYPE_XTRUCT,
380 "string_thing", "Zero",
381 "byte_thing", 1,
382 "i32_thing", -3,
383 "i64_thing", -5LL,
384 NULL);
385 xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);
386
387 if (t_test_thrift_test_if_test_struct (test_client,
388 &xtruct_in,
389 xtruct_out,
390 &error) == TRUE) {
391 g_object_get (xtruct_in,
392 "string_thing", &string,
393 "byte_thing", &byte_thing,
394 "i32_thing", &i32_thing,
395 "i64_thing", &i64_thing,
396 NULL);
397
398 printf (" = {\"%s\", %d, %d, %" PRId64 "}\n",
399 string,
400 byte_thing,
401 i32_thing,
402 i64_thing);
403 if ((string == NULL || strncmp (string, "Zero", 5) != 0) ||
404 byte_thing != 1 ||
405 i32_thing != -3 ||
406 i64_thing != (gint64)-5)
407 fail_count++;
408 }
409 else {
410 printf ("%s\n", error->message);
411 g_error_free (error);
412 error = NULL;
413
414 fail_count++;
415 }
416 g_object_unref (xtruct_in);
417
418 /**
419 * NESTED STRUCT TEST
420 */
421 printf ("testNest({1, {\"Zero\", 1, -3, -5}), 5}");
422 xtruct2_out = g_object_new (T_TEST_TYPE_XTRUCT2,
423 "byte_thing", 1,
424 "struct_thing", xtruct_out,
425 "i32_thing", 5,
426 NULL);
427 xtruct2_in = g_object_new (T_TEST_TYPE_XTRUCT2, NULL);
428
429 if (t_test_thrift_test_if_test_nest (test_client,
430 &xtruct2_in,
431 xtruct2_out,
432 &error) == TRUE) {
433 g_object_get (xtruct2_in,
434 "byte_thing", &byte_thing,
435 "struct_thing", &xtruct_in,
436 "i32_thing", &i32_thing,
437 NULL);
438 g_object_get (xtruct_in,
439 "string_thing", &string,
440 "byte_thing", &inner_byte_thing,
441 "i32_thing", &inner_i32_thing,
442 "i64_thing", &inner_i64_thing,
443 NULL);
444
445 printf (" = {%d, {\"%s\", %d, %d, %" PRId64 "}, %d}\n",
446 byte_thing,
447 string,
448 inner_byte_thing,
449 inner_i32_thing,
450 inner_i64_thing,
451 i32_thing);
452 if (byte_thing != 1 ||
453 (string == NULL || strncmp (string, "Zero", 5) != 0) ||
454 inner_byte_thing != 1 ||
455 inner_i32_thing != -3 ||
456 inner_i64_thing != (gint64)-5 ||
457 i32_thing != 5)
458 fail_count++;
459 }
460 else {
461 printf ("%s\n", error->message);
462 g_error_free (error);
463 error = NULL;
464
465 fail_count++;
466 }
467
468 g_object_unref (xtruct_in);
469 g_object_unref (xtruct2_in);
470 g_object_unref (xtruct2_out);
471 g_object_unref (xtruct_out);
472
473 /**
474 * MAP TEST
475 */
476 map_out = g_hash_table_new_full (g_int_hash,
477 g_int_equal,
478 g_free,
479 g_free);
480 for (i = 0; i < 5; ++i) {
481 i32_key_ptr = g_malloc (sizeof *i32_key_ptr);
482 i32_value_ptr = g_malloc (sizeof *i32_value_ptr);
483
484 *i32_key_ptr = i;
485 *i32_value_ptr = i - 10;
486
487 g_hash_table_insert (map_out, i32_key_ptr, i32_value_ptr);
488 }
489 printf ("testMap({");
490 first = TRUE;
491 g_hash_table_iter_init (&hash_table_iter, map_out);
492 while (g_hash_table_iter_next (&hash_table_iter,
493 &key,
494 &value) == TRUE) {
495 if (first == TRUE)
496 first = FALSE;
497 else
498 printf (", ");
499
500 printf ("%d => %d", *(gint32 *)key, *(gint32 *)value);
501 }
502 printf ("})");
503
504 map_in = g_hash_table_new_full (g_int_hash,
505 g_int_equal,
506 g_free,
507 g_free);
508
509 if (t_test_thrift_test_if_test_map (test_client,
510 &map_in,
511 map_out,
512 &error) == TRUE) {
513 printf (" = {");
514 first = TRUE;
515 g_hash_table_iter_init (&hash_table_iter, map_in);
516 while (g_hash_table_iter_next (&hash_table_iter,
517 &key,
518 &value) == TRUE) {
519 if (first == TRUE)
520 first = FALSE;
521 else
522 printf (", ");
523
524 printf ("%d => %d", *(gint32 *)key, *(gint32 *)value);
525 }
526 printf ("}\n");
527
528 if (g_hash_table_size (map_in) != g_hash_table_size (map_out))
529 fail_count++;
530 else {
531 g_hash_table_iter_init (&hash_table_iter, map_out);
532 while (g_hash_table_iter_next (&hash_table_iter,
533 &key,
534 &value) == TRUE) {
535 gpointer in_value = g_hash_table_lookup (map_in, key);
536 if (in_value == NULL ||
537 *(gint32 *)in_value != *(gint32 *)value) {
538 fail_count++;
539 break;
540 }
541 }
542 }
543 }
544 else {
545 printf ("%s\n", error->message);
546 g_error_free (error);
547 error = NULL;
548
549 fail_count++;
550 }
551
552 g_hash_table_unref (map_in);
553 g_hash_table_unref (map_out);
554
555 /**
556 * STRING MAP TEST
557 */
558 map_out = g_hash_table_new_full (g_str_hash,
559 g_str_equal,
560 NULL,
561 NULL);
562 g_hash_table_insert (map_out, "a", "2");
563 g_hash_table_insert (map_out, "b", "blah");
564 g_hash_table_insert (map_out, "some", "thing");
565 printf ("testStringMap({");
566 first = TRUE;
567 g_hash_table_iter_init (&hash_table_iter, map_out);
568 while (g_hash_table_iter_next (&hash_table_iter,
569 &key,
570 &value) == TRUE) {
571 if (first == TRUE)
572 first = FALSE;
573 else
574 printf (", ");
575
576 printf ("\"%s\" => \"%s\"", (gchar *)key, (gchar *)value);
577 }
578 printf (")}");
579
580 map_in = g_hash_table_new_full (g_str_hash,
581 g_str_equal,
582 g_free,
583 g_free);
584
585 if (t_test_thrift_test_if_test_string_map (test_client,
586 &map_in,
587 map_out,
588 &error) == TRUE) {
589 printf (" = {");
590 first = TRUE;
591 g_hash_table_iter_init (&hash_table_iter, map_in);
592 while (g_hash_table_iter_next (&hash_table_iter,
593 &key,
594 &value) == TRUE) {
595 if (first == TRUE)
596 first = FALSE;
597 else
598 printf (", ");
599
600 printf ("\"%s\" => \"%s\"", (gchar *)key, (gchar *)value);
601 }
602 printf ("}\n");
603
604 if (g_hash_table_size (map_in) != g_hash_table_size (map_out))
605 fail_count++;
606 else {
607 g_hash_table_iter_init (&hash_table_iter, map_out);
608 while (g_hash_table_iter_next (&hash_table_iter,
609 &key,
610 &value) == TRUE) {
611 gpointer in_value = g_hash_table_lookup (map_in, key);
612 if (in_value == NULL ||
613 strcmp ((gchar *)in_value, (gchar *)value) != 0) {
614 fail_count++;
615 break;
616 }
617 }
618 }
619 }
620 else {
621 printf ("%s\n", error->message);
622 g_error_free (error);
623 error = NULL;
624
625 fail_count++;
626 }
627
628 g_hash_table_unref (map_in);
629 g_hash_table_unref (map_out);
630
631 /**
632 * SET TEST
633 */
634 set_out = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, NULL);
635 for (i = -2; i < 3; ++i) {
636 i32_key_ptr = g_malloc (sizeof *i32_key_ptr);
637 *i32_key_ptr = i;
638
639 g_hash_table_insert (set_out, i32_key_ptr, NULL);
640 }
641 printf ("testSet({");
642 first = TRUE;
643 keys_out = g_hash_table_get_keys (set_out);
644 keys_elem = keys_out;
645 while (keys_elem != NULL) {
646 if (first == TRUE)
647 first = FALSE;
648 else
649 printf (", ");
650
651 printf ("%d", *(gint32 *)keys_elem->data);
652
653 keys_elem = keys_elem->next;
654 }
655 printf ("})");
656
657 set_in = g_hash_table_new_full (g_int_hash, g_int_equal, g_free, NULL);
658
659 if (t_test_thrift_test_if_test_set (test_client,
660 &set_in,
661 set_out,
662 &error) == TRUE) {
663 printf(" = {");
664 first = TRUE;
665 keys_in = g_hash_table_get_keys (set_in);
666 keys_elem = keys_in;
667 while (keys_elem != NULL) {
668 if (first == TRUE)
669 first = FALSE;
670 else
671 printf (", ");
672
673 printf ("%d", *(gint32 *)keys_elem->data);
674
675 keys_elem = keys_elem->next;
676 }
677 printf ("}\n");
678
679 if (g_list_length (keys_in) != g_list_length (keys_out))
680 fail_count++;
681 else {
682 keys_elem = keys_out;
683 while (keys_elem != NULL) {
684 if (g_list_find_custom (keys_in,
685 keys_elem->data,
686 gint32_compare) == NULL) {
687 fail_count++;
688 break;
689 }
690
691 keys_elem = keys_elem->next;
692 }
693 }
694
695 g_list_free (keys_in);
696 }
697 else {
698 printf ("%s\n", error->message);
699 g_error_free (error);
700 error = NULL;
701
702 fail_count++;
703 }
704
705 g_hash_table_unref (set_in);
706 g_list_free (keys_out);
707 g_hash_table_unref (set_out);
708
709 /**
710 * LIST TEST
711 */
712 list_out = g_array_new (FALSE, TRUE, sizeof (gint32));
713 for (i = -2; i < 3; ++i) {
714 g_array_append_val (list_out, i);
715 }
716 printf ("testList({");
717 first = TRUE;
718 for (i = 0; i < (gint32)list_out->len; ++i) {
719 if (first == TRUE)
720 first = FALSE;
721 else
722 printf (", ");
723
724 printf ("%d", g_array_index (list_out, gint32, i));
725 }
726 printf ("})");
727
728 list_in = g_array_new (FALSE, TRUE, sizeof (gint32));
729
730 if (t_test_thrift_test_if_test_list (test_client,
731 &list_in,
732 list_out,
733 &error) == TRUE) {
734 printf (" = {");
735 first = TRUE;
736 for (i = 0; i < (gint32)list_in->len; ++i) {
737 if (first == TRUE)
738 first = FALSE;
739 else
740 printf (", ");
741
742 printf ("%d", g_array_index (list_in, gint32, i));
743 }
744 printf ("}\n");
745
746 if (list_in->len != list_out->len ||
747 memcmp (list_in->data,
748 list_out->data,
749 list_in->len * sizeof (gint32)) != 0)
750 fail_count++;
751 }
752 else {
753 printf ("%s\n", error->message);
754 g_error_free (error);
755 error = NULL;
756
757 fail_count++;
758 }
759
760 g_array_unref (list_in);
761 g_array_unref (list_out);
762
763 /**
764 * ENUM TEST
765 */
766 printf("testEnum(ONE)");
767 if (t_test_thrift_test_if_test_enum (test_client,
768 &numberz,
769 T_TEST_NUMBERZ_ONE,
770 &error) == TRUE) {
771 printf(" = %d\n", numberz);
772 if (numberz != T_TEST_NUMBERZ_ONE)
773 fail_count++;
774 }
775 else {
776 printf ("%s\n", error->message);
777 g_error_free (error);
778 error = NULL;
779
780 fail_count++;
781 }
782
783 printf("testEnum(TWO)");
784 if (t_test_thrift_test_if_test_enum (test_client,
785 &numberz,
786 T_TEST_NUMBERZ_TWO,
787 &error) == TRUE) {
788 printf(" = %d\n", numberz);
789 if (numberz != T_TEST_NUMBERZ_TWO)
790 fail_count++;
791 }
792 else {
793 printf ("%s\n", error->message);
794 g_error_free (error);
795 error = NULL;
796
797 fail_count++;
798 }
799
800 printf("testEnum(THREE)");
801 if (t_test_thrift_test_if_test_enum (test_client,
802 &numberz,
803 T_TEST_NUMBERZ_THREE,
804 &error) == TRUE) {
805 printf(" = %d\n", numberz);
806 if (numberz != T_TEST_NUMBERZ_THREE)
807 fail_count++;
808 }
809 else {
810 printf ("%s\n", error->message);
811 g_error_free (error);
812 error = NULL;
813
814 fail_count++;
815 }
816
817 printf("testEnum(FIVE)");
818 if (t_test_thrift_test_if_test_enum (test_client,
819 &numberz,
820 T_TEST_NUMBERZ_FIVE,
821 &error) == TRUE) {
822 printf(" = %d\n", numberz);
823 if (numberz != T_TEST_NUMBERZ_FIVE)
824 fail_count++;
825 }
826 else {
827 printf ("%s\n", error->message);
828 g_error_free (error);
829 error = NULL;
830
831 fail_count++;
832 }
833
834 printf("testEnum(EIGHT)");
835 if (t_test_thrift_test_if_test_enum (test_client,
836 &numberz,
837 T_TEST_NUMBERZ_EIGHT,
838 &error) == TRUE) {
839 printf(" = %d\n", numberz);
840 if (numberz != T_TEST_NUMBERZ_EIGHT)
841 fail_count++;
842 }
843 else {
844 printf ("%s\n", error->message);
845 g_error_free (error);
846 error = NULL;
847
848 fail_count++;
849 }
850
851 /**
852 * TYPEDEF TEST
853 */
854 printf ("testTypedef(309858235082523)");
855 if (t_test_thrift_test_if_test_typedef (test_client,
856 &user_id,
857 309858235082523LL,
858 &error) == TRUE) {
859 printf(" = %" PRId64 "\n", user_id);
860 if (user_id != 309858235082523LL)
861 fail_count++;
862 }
863 else {
864 printf ("%s\n", error->message);
865 g_error_free (error);
866 error = NULL;
867
868 fail_count++;
869 }
870
871 /**
872 * NESTED MAP TEST
873 */
874 printf ("testMapMap(1)");
875 map_in = g_hash_table_new_full (g_int_hash,
876 g_int_equal,
877 g_free,
878 (GDestroyNotify)g_hash_table_unref);
879 if (t_test_thrift_test_if_test_map_map (test_client,
880 &map_in,
881 1,
882 &error) == TRUE) {
883 g_hash_table_iter_init (&hash_table_iter, map_in);
884
885 printf (" = {");
886 while (g_hash_table_iter_next (&hash_table_iter,
887 &key,
888 &value) == TRUE) {
889 printf ("%d => {", *(gint32 *)key);
890
891 g_hash_table_iter_init (&inner_hash_table_iter,
892 (GHashTable *)value);
893 while (g_hash_table_iter_next (&inner_hash_table_iter,
894 &key,
895 &value) == TRUE) {
896 printf ("%d => %d, ", *(gint32 *)key, *(gint32 *)value);
897 }
898
899 printf ("}, ");
900 }
901 printf ("}\n");
902
903 if (g_hash_table_size (map_in) != 2)
904 fail_count++;
905 else {
906 gint32 inner_keys[] = {1, 2, 3, 4};
907 gint32 i32_key;
908
909 i32_key = -4;
910 inner_map_in = g_hash_table_lookup (map_in, &i32_key);
911 if (inner_map_in == NULL ||
912 g_hash_table_size (inner_map_in) != 4)
913 fail_count++;
914 else {
915 keys_in = g_hash_table_get_keys (inner_map_in);
916 keys_in = g_list_sort (keys_in, gint32_compare);
917
918 for (i = 0; i < 4; i++) {
919 keys_elem = g_list_nth (keys_in, 3 - i);
920
921 if (*(gint32 *)keys_elem->data != (-1 * inner_keys[i]) ||
922 *(gint32 *)g_hash_table_lookup (inner_map_in,
923 keys_elem->data) !=
924 (-1 * inner_keys[i])) {
925 fail_count++;
926 break;
927 }
928 }
929
930 g_list_free (keys_in);
931 }
932
933 i32_key = 4;
934 inner_map_in = g_hash_table_lookup (map_in, &i32_key);
935 if (inner_map_in == NULL ||
936 g_hash_table_size (inner_map_in) != 4)
937 fail_count++;
938 else {
939 keys_in = g_hash_table_get_keys (inner_map_in);
940 keys_in = g_list_sort (keys_in, gint32_compare);
941
942 for (i = 0; i < 4; i++) {
943 keys_elem = g_list_nth (keys_in, i);
944
945 if (*(gint32 *)keys_elem->data != inner_keys[i] ||
946 *(gint32 *)g_hash_table_lookup (inner_map_in,
947 keys_elem->data) !=
948 inner_keys[i]) {
949 fail_count++;
950 break;
951 }
952 }
953
954 g_list_free (keys_in);
955 }
956 }
957 }
958 else {
959 printf ("%s\n", error->message);
960 g_error_free (error);
961 error = NULL;
962
963 fail_count++;
964 }
965
966 g_hash_table_unref (map_in);
967
968 /**
969 * INSANITY TEST
970 */
971 insanity_out = g_object_new (T_TEST_TYPE_INSANITY, NULL);
972 g_object_get (insanity_out,
973 "userMap", &user_map,
974 "xtructs", &xtructs,
975 NULL);
976
977 numberz = T_TEST_NUMBERZ_FIVE;
978 user_id_ptr = g_malloc (sizeof *user_id_ptr);
979 *user_id_ptr = 5000;
980 g_hash_table_insert (user_map, (gpointer)numberz, user_id_ptr);
981 g_hash_table_unref (user_map);
982
983 xtruct_out = g_object_new (T_TEST_TYPE_XTRUCT,
984 "string_thing", "Truck",
985 "byte_thing", 8,
986 "i32_thing", 8,
987 "i64_thing", 8,
988 NULL);
989 g_ptr_array_add (xtructs, xtruct_out);
990 g_ptr_array_unref (xtructs);
991
992 map_in = g_hash_table_new_full (g_int64_hash,
993 g_int64_equal,
994 g_free,
995 (GDestroyNotify)g_hash_table_unref);
996
997 printf("testInsanity()");
998 if (t_test_thrift_test_if_test_insanity (test_client,
999 &map_in,
1000 insanity_out,
1001 &error) == TRUE) {
1002 printf (" = {");
1003 g_hash_table_iter_init (&hash_table_iter, map_in);
1004 while (g_hash_table_iter_next (&hash_table_iter,
1005 &key,
1006 &value) == TRUE) {
1007 printf ("%" PRId64 " => {", *(TTestUserId *)key);
1008
1009 g_hash_table_iter_init (&inner_hash_table_iter,
1010 (GHashTable *)value);
1011 while (g_hash_table_iter_next (&inner_hash_table_iter,
1012 &key,
1013 &value) == TRUE) {
1014 printf ("%d => {", (TTestNumberz)key);
1015
1016 g_object_get ((TTestInsanity *)value,
1017 "userMap", &user_map,
1018 "xtructs", &xtructs,
1019 NULL);
1020
1021 printf ("{");
1022 g_hash_table_iter_init (&user_map_iter, user_map);
1023 while (g_hash_table_iter_next (&user_map_iter,
1024 &key,
1025 &value) == TRUE) {
1026 printf ("%d => %" PRId64 ", ",
1027 (TTestNumberz)key,
1028 *(TTestUserId *)value);
1029 }
1030 printf ("}, ");
1031 g_hash_table_unref (user_map);
1032
1033 printf("{");
1034 for (i = 0; i < (gint32)xtructs->len; ++i) {
1035 xtruct_in = g_ptr_array_index (xtructs, i);
1036 g_object_get (xtruct_in,
1037 "string_thing", &string,
1038 "byte_thing", &byte_thing,
1039 "i32_thing", &i32_thing,
1040 "i64_thing", &i64_thing,
1041 NULL);
1042
1043 printf ("{\"%s\", %d, %d, %" PRId64 "}, ",
1044 string,
1045 byte_thing,
1046 i32_thing,
1047 i64_thing);
1048 }
1049 printf ("}");
1050 g_ptr_array_unref (xtructs);
1051
1052 printf ("}, ");
1053 }
1054 printf("}, ");
1055 }
1056 printf("}\n");
1057
1058 if (g_hash_table_size (map_in) != 2)
1059 fail_count++;
1060 else {
1061 TTestNumberz numberz_key_values[] = {
1062 T_TEST_NUMBERZ_TWO, T_TEST_NUMBERZ_THREE
1063 };
1064 gint user_map_values[] = { 5, 8 };
1065 TTestUserId user_id_key;
1066
1067 user_id_key = 1;
1068 inner_map_in = g_hash_table_lookup (map_in, &user_id_key);
1069 if (inner_map_in == NULL ||
1070 g_hash_table_size (inner_map_in) != 2)
1071 fail_count++;
1072 else {
1073 TTestNumberz numberz_key;
1074
1075 for (i = 0; i < 2; ++i) {
1076 numberz_key = numberz_key_values[i];
1077 insanity_in =
1078 g_hash_table_lookup (inner_map_in,
1079 (gconstpointer)numberz_key);
1080 if (insanity_in == NULL)
1081 fail_count++;
1082 else {
1083 g_object_get (insanity_in,
1084 "userMap", &user_map,
1085 "xtructs", &xtructs,
1086 NULL);
1087
1088 if (user_map == NULL)
1089 fail_count++;
1090 else {
1091 if (g_hash_table_size (user_map) != 2)
1092 fail_count++;
1093 else {
1094 for (j = 0; j < 2; ++j) {
1095 numberz_key = (TTestNumberz)user_map_values[j];
1096
1097 value =
1098 g_hash_table_lookup (user_map,
1099 (gconstpointer)numberz_key);
1100 if (value == NULL ||
1101 *(TTestUserId *)value != (TTestUserId)user_map_values[j])
1102 fail_count++;
1103 }
1104 }
1105
1106 g_hash_table_unref (user_map);
1107 }
1108
1109 if (xtructs == NULL)
1110 fail_count++;
1111 else {
1112 if (xtructs->len != 2)
1113 fail_count++;
1114 else {
1115 xtruct_in = g_ptr_array_index (xtructs, 0);
1116 g_object_get (xtruct_in,
1117 "string_thing", &string,
1118 "byte_thing", &byte_thing,
1119 "i32_thing", &i32_thing,
1120 "i64_thing", &i64_thing,
1121 NULL);
1122 if ((string == NULL ||
1123 strncmp (string, "Goodbye4", 9) != 0) ||
1124 byte_thing != 4 ||
1125 i32_thing != 4 ||
1126 i64_thing != 4)
1127 fail_count++;
1128
1129 if (string != NULL)
1130 g_free (string);
1131
1132 xtruct_in = g_ptr_array_index (xtructs, 1);
1133 g_object_get (xtruct_in,
1134 "string_thing", &string,
1135 "byte_thing", &byte_thing,
1136 "i32_thing", &i32_thing,
1137 "i64_thing", &i64_thing,
1138 NULL);
1139 if ((string == NULL ||
1140 strncmp (string, "Hello2", 7) != 0) ||
1141 byte_thing != 2 ||
1142 i32_thing != 2 ||
1143 i64_thing != 2)
1144 fail_count++;
1145
1146 if (string != NULL)
1147 g_free (string);
1148 }
1149
1150 g_ptr_array_unref (xtructs);
1151 }
1152 }
1153 }
1154 }
1155
1156 user_id_key = 2;
1157 inner_map_in = g_hash_table_lookup (map_in, &user_id_key);
1158 if (inner_map_in == NULL ||
1159 g_hash_table_size (inner_map_in) != 1)
1160 fail_count++;
1161 else {
1162 insanity_in =
1163 g_hash_table_lookup (inner_map_in,
1164 (gconstpointer)T_TEST_NUMBERZ_SIX);
1165 if (insanity_in == NULL)
1166 fail_count++;
1167 else {
1168 g_object_get (insanity_in,
1169 "userMap", &user_map,
1170 "xtructs", &xtructs,
1171 NULL);
1172
1173 if (user_map == NULL)
1174 fail_count++;
1175 else {
1176 if (g_hash_table_size (user_map) != 0)
1177 fail_count++;
1178
1179 g_hash_table_unref (user_map);
1180 }
1181
1182 if (xtructs == NULL)
1183 fail_count++;
1184 else {
1185 if (xtructs->len != 0)
1186 fail_count++;
1187
1188 g_ptr_array_unref (xtructs);
1189 }
1190 }
1191 }
1192 }
1193 }
1194 else {
1195 printf ("%s\n", error->message);
1196 g_error_free (error);
1197 error = NULL;
1198
1199 fail_count++;
1200 }
1201
1202 g_hash_table_unref (map_in);
1203 g_object_unref (insanity_out);
1204
1205 /* test exception */
1206 printf ("testClient.testException(\"Xception\") =>");
1207 if (t_test_thrift_test_if_test_exception (test_client,
1208 "Xception",
1209 &xception,
1210 &error) == FALSE &&
1211 xception != NULL) {
1212 g_object_get (xception,
1213 "errorCode", &int32,
1214 "message", &string,
1215 NULL);
1216 printf (" {%u, \"%s\"}\n", int32, string);
1217 g_free (string);
1218
1219 g_object_unref (xception);
1220 xception = NULL;
1221
1222 g_error_free (error);
1223 error = NULL;
1224 }
1225 else {
1226 printf (" void\nFAILURE\n");
1227 fail_count++;
1228
1229 if (xception != NULL) {
1230 g_object_unref (xception);
1231 xception = NULL;
1232 }
1233
1234 if (error != NULL) {
1235 g_error_free (error);
1236 error = NULL;
1237 }
1238 }
1239
1240 printf ("testClient.testException(\"TException\") =>");
1241 if (t_test_thrift_test_if_test_exception (test_client,
1242 "TException",
1243 &xception,
1244 &error) == FALSE &&
1245 xception == NULL &&
1246 error != NULL) {
1247 printf (" Caught TException\n");
1248
1249 g_error_free (error);
1250 error = NULL;
1251 }
1252 else {
1253 printf (" void\nFAILURE\n");
1254 fail_count++;
1255
1256 if (xception != NULL) {
1257 g_object_unref (xception);
1258 xception = NULL;
1259 }
1260
1261 if (error != NULL) {
1262 g_error_free (error);
1263 error = NULL;
1264 }
1265 }
1266
1267 printf ("testClient.testException(\"success\") =>");
1268 if (t_test_thrift_test_if_test_exception (test_client,
1269 "success",
1270 &xception,
1271 &error) == TRUE)
1272 printf (" void\n");
1273 else {
1274 printf (" void\nFAILURE\n");
1275 fail_count++;
1276
1277 if (xception != NULL) {
1278 g_object_unref (xception);
1279 xception = NULL;
1280 }
1281
1282 g_error_free (error);
1283 error = NULL;
1284 }
1285
1286 g_assert (error == NULL);
1287
1288 /* test multi exception */
1289 printf ("testClient.testMultiException(\"Xception\", \"test 1\") =>");
1290 xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);
1291 if (t_test_thrift_test_if_test_multi_exception (test_client,
1292 &xtruct_in,
1293 "Xception",
1294 "test 1",
1295 &xception,
1296 &xception2,
1297 &error) == FALSE &&
1298 xception != NULL &&
1299 xception2 == NULL) {
1300 g_object_get (xception,
1301 "errorCode", &int32,
1302 "message", &string,
1303 NULL);
1304 printf (" {%u, \"%s\"}\n", int32, string);
1305 g_free (string);
1306
1307 g_object_unref (xception);
1308 xception = NULL;
1309
1310 g_error_free (error);
1311 error = NULL;
1312 }
1313 else {
1314 printf (" result\nFAILURE\n");
1315 fail_count++;
1316
1317 if (xception != NULL) {
1318 g_object_unref (xception);
1319 xception = NULL;
1320 }
1321
1322 if (xception2 != NULL) {
1323 g_object_unref (xception2);
1324 xception = NULL;
1325 }
1326
1327 if (error != NULL) {
1328 g_error_free (error);
1329 error = NULL;
1330 }
1331 }
1332 g_object_unref (xtruct_in);
1333
1334 printf ("testClient.testMultiException(\"Xception2\", \"test 2\") =>");
1335 xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);
1336 if (t_test_thrift_test_if_test_multi_exception (test_client,
1337 &xtruct_in,
1338 "Xception2",
1339 "test 2",
1340 &xception,
1341 &xception2,
1342 &error) == FALSE &&
1343 xception == NULL &&
1344 xception2 != NULL) {
1345 g_object_get (xception2,
1346 "errorCode", &int32,
1347 "struct_thing", &inner_xtruct_in,
1348 NULL);
1349 g_object_get (inner_xtruct_in,
1350 "string_thing", &string,
1351 NULL);
1352 printf (" {%u, {\"%s\"}}\n", int32, string);
1353 g_free (string);
1354
1355 g_object_unref (inner_xtruct_in);
1356 inner_xtruct_in = NULL;
1357
1358 g_object_unref (xception2);
1359 xception2 = NULL;
1360
1361 g_error_free (error);
1362 error = NULL;
1363 }
1364 else {
1365 printf (" result\nFAILURE\n");
1366 fail_count++;
1367
1368 if (xception != NULL) {
1369 g_object_unref (xception);
1370 xception = NULL;
1371 }
1372
1373 if (xception2 != NULL) {
1374 g_object_unref (xception2);
1375 xception = NULL;
1376 }
1377
1378 if (error != NULL) {
1379 g_error_free (error);
1380 error = NULL;
1381 }
1382 }
1383 g_object_unref (xtruct_in);
1384
1385 printf ("testClient.testMultiException(\"success\", \"test 3\") =>");
1386 xtruct_in = g_object_new (T_TEST_TYPE_XTRUCT, NULL);
1387 if (t_test_thrift_test_if_test_multi_exception (test_client,
1388 &xtruct_in,
1389 "success",
1390 "test 3",
1391 &xception,
1392 &xception2,
1393 &error) == TRUE &&
1394 xception == NULL &&
1395 xception2 == NULL) {
1396 g_object_get (xtruct_in,
1397 "string_thing", &string,
1398 NULL);
1399 printf (" {{\"%s\"}}\n", string);
1400 g_free (string);
1401 }
1402 else {
1403 printf (" result\nFAILURE\n");
1404 fail_count++;
1405
1406 if (xception != NULL) {
1407 g_object_unref (xception);
1408 xception = NULL;
1409 }
1410
1411 if (xception2 != NULL) {
1412 g_object_unref (xception2);
1413 xception = NULL;
1414 }
1415
1416 if (error != NULL) {
1417 g_error_free (error);
1418 error = NULL;
1419 }
1420 }
1421 g_object_unref (xtruct_in);
1422
1423 /* test oneway void */
1424 printf ("testClient.testOneway(1) =>");
1425 gettimeofday (&oneway_start, NULL);
1426 oneway_result = t_test_thrift_test_if_test_oneway (test_client,
1427 1,
1428 &error);
1429 gettimeofday (&oneway_end, NULL);
1430 timersub (&oneway_end, &oneway_start, &oneway_elapsed);
1431 oneway_elapsed_usec =
1432 oneway_elapsed.tv_sec * 1000 * 1000 + oneway_elapsed.tv_usec;
1433
1434 if (oneway_result == TRUE) {
1435 if (oneway_elapsed_usec > 200 * 1000) {
1436 printf (" FAILURE - took %.2f ms\n",
1437 (double)oneway_elapsed_usec / 1000.0);
1438 fail_count++;
1439 }
1440 else
1441 printf (" success - took %.2f ms\n",
1442 (double)oneway_elapsed_usec / 1000.0);
1443 }
1444 else {
1445 printf ("%s\n", error->message);
1446 g_error_free (error);
1447 error = NULL;
1448
1449 fail_count++;
1450 }
1451
1452 /**
1453 * redo a simple test after the oneway to make sure we aren't "off by
1454 * one" -- if the server treated oneway void like normal void, this next
1455 * test will fail since it will get the void confirmation rather than
1456 * the correct result. In this circumstance, the client will receive the
1457 * error:
1458 *
1459 * application error: Wrong method name
1460 */
1461 /**
1462 * I32 TEST
1463 */
1464 printf ("re-test testI32(-1)");
1465 if (t_test_thrift_test_if_test_i32 (test_client,
1466 &int32,
1467 -1,
1468 &error) == TRUE) {
1469 printf (" = %d\n", int32);
1470 if (int32 != -1)
1471 fail_count++;
1472 }
1473 else {
1474 printf ("%s\n", error->message);
1475 g_error_free (error);
1476 error = NULL;
1477
1478 fail_count++;
1479 }
1480
1481 gettimeofday (&time_stop, NULL);
1482 timersub (&time_stop, &time_start, &time_elapsed);
1483 time_elapsed_usec =
1484 time_elapsed.tv_sec * 1000 * 1000 + time_elapsed.tv_usec;
1485
1486 printf("Total time: %" PRIu64 " us\n", time_elapsed_usec);
1487
1488 time_total_usec += time_elapsed_usec;
1489 if (time_elapsed_usec < time_min_usec)
1490 time_min_usec = time_elapsed_usec;
1491 if (time_elapsed_usec > time_max_usec)
1492 time_max_usec = time_elapsed_usec;
1493
1494 thrift_transport_close (transport, &error);
1495 }
1496 else {
1497 printf ("Connect failed: %s\n", error->message);
1498 g_error_free (error);
1499 error = NULL;
1500
1501 return 1;
1502 }
1503 }
1504
1505 /* All done---output statistics */
1506 puts ("\nAll tests done.");
1507
1508 time_avg_usec = time_total_usec / num_tests;
1509
1510 printf ("Min time: %" PRIu64 " us\n", time_min_usec);
1511 printf ("Max time: %" PRIu64 " us\n", time_max_usec);
1512 printf ("Avg time: %" PRIu64 " us\n", time_avg_usec);
1513
1514 g_object_unref (test_client);
1515 g_object_unref (protocol);
1516 g_object_unref (transport);
1517 g_free (host);
1518
1519 return fail_count;
1520}