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