zeshuai007 | c80b8bb | 2020-07-23 09:43:41 +0800 | [diff] [blame] | 1 | /* |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one |
| 3 | * or more contributor license agreements. See the NOTICE file |
| 4 | * distributed with this work for additional information |
| 5 | * regarding copyright ownership. The ASF licenses this file |
| 6 | * to you under the Apache License, Version 2.0 (the |
| 7 | * "License"); you may not use this file except in compliance |
| 8 | * with the License. You may obtain a copy of the License at |
| 9 | * |
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | * |
| 12 | * Unless required by applicable law or agreed to in writing, |
| 13 | * software distributed under the License is distributed on an |
| 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| 15 | * KIND, either express or implied. See the License for the |
| 16 | * specific language governing permissions and limitations |
| 17 | * under the License. |
| 18 | */ |
| 19 | |
| 20 | /* Disable string-function optimizations when glibc is used, as these produce |
| 21 | compiler warnings about string length when a string function is used inside |
| 22 | a call to g_assert () */ |
| 23 | #if !defined(__APPLE__) && !defined(__FreeBSD__) && \ |
| 24 | !defined(__OpenBSD__) && !defined(__NetBSD__) |
| 25 | #include <features.h> |
| 26 | #endif |
| 27 | |
| 28 | #ifdef __GLIBC__ |
| 29 | #define __NO_STRING_INLINES 1 |
| 30 | #endif |
| 31 | |
| 32 | #include <unistd.h> |
| 33 | #include <stdlib.h> |
| 34 | #include <stdio.h> |
| 35 | #include <netdb.h> |
| 36 | #include <string.h> |
| 37 | #include <sys/wait.h> |
| 38 | |
| 39 | #include <thrift/c_glib/protocol/thrift_protocol.h> |
| 40 | #include <thrift/c_glib/transport/thrift_socket.h> |
| 41 | #include <thrift/c_glib/transport/thrift_server_socket.h> |
| 42 | #include <thrift/c_glib/transport/thrift_framed_transport.h> |
| 43 | |
| 44 | #define TEST_BOOL TRUE |
| 45 | #define TEST_BYTE 123 |
| 46 | #define TEST_I16 12345 |
| 47 | #define TEST_I32 1234567890 |
| 48 | #define TEST_I64 123456789012345 |
| 49 | #define TEST_NI16 (-12345) |
| 50 | #define TEST_NI32 (-1234567890) |
| 51 | #define TEST_NI64 (-123456789012345) |
| 52 | #define TEST_DOUBLE 1234567890.123 |
| 53 | #define TEST_STRING "this is a test string 1234567890!@#$%^&*()" |
| 54 | #define TEST_PORT 51199 |
| 55 | |
| 56 | #define MAX_MESSAGE_SIZE 2 |
| 57 | |
| 58 | static int transport_read_count = 0; |
| 59 | static int transport_read_error = 0; |
| 60 | static int transport_read_error_at = -1; |
| 61 | gint32 |
| 62 | my_thrift_transport_read_all (ThriftTransport *transport, gpointer buf, |
| 63 | guint32 len, GError **error) |
| 64 | { |
| 65 | if (transport_read_count != transport_read_error_at |
| 66 | && transport_read_error == 0) |
| 67 | { |
| 68 | transport_read_count++; |
| 69 | return thrift_transport_read_all (transport, buf, len, error); |
| 70 | } |
| 71 | return -1; |
| 72 | } |
| 73 | |
| 74 | static int transport_write_count = 0; |
| 75 | static int transport_write_error = 0; |
| 76 | static int transport_write_error_at = -1; |
| 77 | gboolean |
| 78 | my_thrift_transport_write (ThriftTransport *transport, const gpointer buf, |
| 79 | const guint32 len, GError **error) |
| 80 | { |
| 81 | if (transport_write_count != transport_write_error_at |
| 82 | && transport_write_error == 0) |
| 83 | { |
| 84 | transport_write_count++; |
| 85 | return thrift_transport_write (transport, buf, len, error); |
| 86 | } |
| 87 | return FALSE; |
| 88 | } |
| 89 | |
| 90 | #define thrift_transport_read_all my_thrift_transport_read_all |
| 91 | #define thrift_transport_write my_thrift_transport_write |
| 92 | #include "../src/thrift/c_glib/protocol/thrift_compact_protocol.c" |
| 93 | #undef thrift_transport_read_all |
| 94 | #undef thrift_transport_write |
| 95 | |
| 96 | static void thrift_server_complex_types (const int port); |
| 97 | |
| 98 | static void |
| 99 | test_create_and_destroy (void) |
| 100 | { |
| 101 | GObject *object = NULL; |
| 102 | |
| 103 | /* create an object and then destroy it */ |
| 104 | object = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, NULL); |
| 105 | g_assert (object != NULL); |
| 106 | g_object_unref (object); |
| 107 | } |
| 108 | |
| 109 | static void |
| 110 | test_initialize (void) |
| 111 | { |
| 112 | ThriftSocket *tsocket = NULL; |
| 113 | ThriftCompactProtocol *protocol = NULL; |
| 114 | ThriftSocket *temp = NULL; |
| 115 | ThriftConfiguration *tconfiguration = NULL; |
| 116 | ThriftConfiguration *tempconf = NULL; |
| 117 | glong tempsize = 0; |
| 118 | |
| 119 | /* create a ThriftConfiguration */ |
| 120 | tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, |
| 121 | "max_frame_size", MAX_MESSAGE_SIZE, NULL); |
| 122 | /* create a ThriftTransport */ |
| 123 | tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", |
| 124 | "port", 51188, "configuration", tconfiguration, |
| 125 | "remainingmessagesize", MAX_MESSAGE_SIZE, NULL); |
| 126 | g_assert (tsocket != NULL); |
| 127 | /* fetch the properties */ |
| 128 | g_object_get (G_OBJECT (tconfiguration), "max_message_size", &tempsize, NULL); |
| 129 | g_assert (tempsize == MAX_MESSAGE_SIZE); |
| 130 | /* fetch the properties */ |
| 131 | g_object_get (G_OBJECT (tsocket), "remainingmessagesize", &tempsize, NULL); |
| 132 | g_assert (tempsize == MAX_MESSAGE_SIZE); |
| 133 | /* fetch the properties */ |
| 134 | g_object_get (G_OBJECT (tsocket), "configuration", &tempconf, NULL); |
| 135 | g_object_unref (tempconf); |
| 136 | /* create a ThriftCompactProtocol using the Transport */ |
| 137 | protocol = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", |
| 138 | tsocket, NULL); |
| 139 | g_assert (protocol != NULL); |
| 140 | /* fetch the properties */ |
| 141 | g_object_get (G_OBJECT (protocol), "transport", &temp, NULL); |
| 142 | g_object_unref (temp); |
| 143 | |
| 144 | /* clean up memory */ |
| 145 | g_object_unref (protocol); |
| 146 | g_object_unref (tsocket); |
| 147 | } |
| 148 | |
| 149 | |
| 150 | static void |
| 151 | test_read_and_write_complex_types (void) |
| 152 | { |
| 153 | int status; |
| 154 | pid_t pid; |
| 155 | ThriftSocket *tsocket = NULL; |
| 156 | ThriftTransport *transport = NULL; |
| 157 | ThriftCompactProtocol *tc = NULL; |
| 158 | ThriftProtocol *protocol = NULL; |
| 159 | int port = TEST_PORT; |
| 160 | |
| 161 | /* fork a server from the client */ |
| 162 | pid = fork (); |
| 163 | g_assert (pid >= 0); |
| 164 | |
| 165 | if (pid == 0) |
| 166 | { |
| 167 | /* child listens */ |
| 168 | thrift_server_complex_types (port); |
| 169 | exit (0); |
| 170 | } else { |
| 171 | /* parent. wait a bit for the socket to be created. */ |
| 172 | sleep (1); |
| 173 | |
| 174 | /* create a ThriftSocket */ |
| 175 | tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost", |
| 176 | "port", port, NULL); |
| 177 | transport = THRIFT_TRANSPORT (tsocket); |
| 178 | thrift_transport_open (transport, NULL); |
| 179 | g_assert (thrift_transport_is_open (transport)); |
| 180 | |
| 181 | /* create a ThriftCompactTransport */ |
| 182 | tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", |
| 183 | tsocket, NULL); |
| 184 | protocol = THRIFT_PROTOCOL (tc); |
| 185 | g_assert (protocol != NULL); |
| 186 | |
| 187 | g_assert (thrift_compact_protocol_write_map_begin (protocol, T_VOID, T_BYTE, |
| 188 | 1, NULL) > 0); |
| 189 | g_assert (thrift_compact_protocol_write_map_end (protocol, NULL) == 0); |
| 190 | |
| 191 | g_assert (thrift_compact_protocol_write_map_begin (protocol, T_VOID, T_BYTE, |
| 192 | 3, NULL) > 0); |
| 193 | g_assert (thrift_compact_protocol_write_map_end (protocol, NULL) == 0); |
| 194 | |
| 195 | g_assert (thrift_compact_protocol_write_list_begin (protocol, T_BYTE, |
| 196 | 1, NULL) > 0); |
| 197 | g_assert (thrift_compact_protocol_write_list_end (protocol, NULL) == 0); |
| 198 | |
| 199 | g_assert (thrift_compact_protocol_write_list_begin (protocol, T_I32, |
| 200 | 3, NULL) > 0); |
| 201 | g_assert (thrift_compact_protocol_write_list_end (protocol, NULL) == 0); |
| 202 | |
| 203 | /* clean up */ |
| 204 | thrift_transport_close (transport, NULL); |
| 205 | g_object_unref (tsocket); |
| 206 | g_object_unref (protocol); |
| 207 | g_assert (wait (&status) == pid); |
| 208 | g_assert (status == 0); |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | |
| 213 | static void |
| 214 | thrift_server_complex_types (const int port) |
| 215 | { |
| 216 | ThriftServerTransport *transport = NULL; |
| 217 | ThriftTransport *client = NULL; |
| 218 | ThriftCompactProtocol *tc = NULL; |
| 219 | ThriftProtocol *protocol = NULL; |
zeshuai007 | 997e2d4 | 2020-09-29 14:43:18 +0800 | [diff] [blame] | 220 | ThriftType element_type, key_type, value_type; |
zeshuai007 | c80b8bb | 2020-07-23 09:43:41 +0800 | [diff] [blame] | 221 | guint32 size = 0; |
| 222 | |
| 223 | ThriftConfiguration *tconfiguration = g_object_new (THRIFT_TYPE_CONFIGURATION, "max_message_size", MAX_MESSAGE_SIZE, |
| 224 | "max_frame_size", MAX_MESSAGE_SIZE, NULL); |
| 225 | ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET, |
| 226 | "port", port, "configuration", tconfiguration, NULL); |
| 227 | transport = THRIFT_SERVER_TRANSPORT (tsocket); |
| 228 | THRIFT_SERVER_TRANSPORT_GET_CLASS (tsocket)->resetConsumedMessageSize(transport, -1, NULL); |
| 229 | thrift_server_transport_listen (transport, NULL); |
| 230 | client = thrift_server_transport_accept (transport, NULL); |
| 231 | g_assert (client != NULL); |
| 232 | |
| 233 | tc = g_object_new (THRIFT_TYPE_COMPACT_PROTOCOL, "transport", |
| 234 | client, NULL); |
| 235 | protocol = THRIFT_PROTOCOL (tc); |
| 236 | |
| 237 | g_assert (thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, |
| 238 | &size, NULL) > 0); |
| 239 | g_assert (thrift_compact_protocol_read_map_end (protocol, NULL) == 0); |
| 240 | |
| 241 | g_assert (thrift_compact_protocol_read_map_begin (protocol, &key_type, &value_type, |
| 242 | &size, NULL) == -1); |
| 243 | g_assert (thrift_compact_protocol_read_map_end (protocol, NULL) == 0); |
| 244 | |
| 245 | g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type, |
| 246 | &size, NULL) > 0); |
| 247 | g_assert (thrift_compact_protocol_read_list_end (protocol, NULL) == 0); |
| 248 | |
| 249 | g_assert (thrift_compact_protocol_read_list_begin (protocol, &element_type, |
| 250 | &size, NULL) == -1); |
| 251 | g_assert (thrift_compact_protocol_read_list_end (protocol, NULL) == 0); |
| 252 | |
| 253 | g_object_unref (client); |
| 254 | g_object_unref (tsocket); |
| 255 | g_object_unref (tconfiguration); |
| 256 | } |
| 257 | |
| 258 | |
| 259 | int |
| 260 | main (int argc, char *argv[]) |
| 261 | { |
| 262 | #if (!GLIB_CHECK_VERSION (2, 36, 0)) |
| 263 | g_type_init (); |
| 264 | #endif |
| 265 | |
| 266 | g_test_init (&argc, &argv, NULL); |
| 267 | |
| 268 | g_test_add_func ("/testthriftcompactreadcheck/CreateAndDestroy", |
| 269 | test_create_and_destroy); |
| 270 | g_test_add_func ("/testthriftcompactreadcheck/Initialize", test_initialize); |
| 271 | g_test_add_func ("/testthriftcompactreadcheck/ReadAndWriteComplexTypes", |
| 272 | test_read_and_write_complex_types); |
| 273 | |
| 274 | return g_test_run (); |
| 275 | } |