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.h>
21
22 #include <thrift/c_glib/thrift_struct.h>
23 #include <thrift/c_glib/protocol/thrift_protocol.h>
24 #include <thrift/c_glib/protocol/thrift_binary_protocol.h>
25 #include <thrift/c_glib/transport/thrift_memory_buffer.h>
26 #include "gen-c_glib/t_test_optional_required_test_types.h"
27
28 #include "gen-c_glib/t_test_optional_required_test_types.c"
29
30 static void
write_to_read(ThriftStruct * w,ThriftStruct * r,GError ** write_error,GError ** read_error)31 write_to_read (ThriftStruct *w, ThriftStruct *r, GError **write_error,
32 GError **read_error)
33 {
34 ThriftMemoryBuffer *tbuffer = NULL;
35 ThriftProtocol *protocol = NULL;
36
37 tbuffer = g_object_new (THRIFT_TYPE_MEMORY_BUFFER, NULL);
38 protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL, "transport",
39 tbuffer, NULL);
40
41 thrift_struct_write (w, protocol, write_error);
42 thrift_struct_read (r, protocol, read_error);
43
44 g_object_unref (protocol);
45 g_object_unref (tbuffer);
46 }
47
48 static void
test_old_school1(void)49 test_old_school1 (void)
50 {
51 TTestOldSchool *o = NULL;
52
53 o = g_object_new (T_TEST_TYPE_OLD_SCHOOL, NULL);
54 o->im_int = 10;
55 o->im_str = g_strdup ("test");
56 o->im_big = g_ptr_array_new ();
57 g_ptr_array_free (o->im_big, TRUE);
58 o->im_big = NULL;
59 g_free (o->im_str);
60 o->im_str = NULL;
61 g_object_unref (o);
62 }
63
64 /**
65 * Write to read with optional fields
66 */
67 static void
test_simple(void)68 test_simple (void)
69 {
70 TTestSimple *s1 = NULL, *s2 = NULL, *s3 = NULL;
71
72 s1 = g_object_new (T_TEST_TYPE_SIMPLE, NULL);
73 s2 = g_object_new (T_TEST_TYPE_SIMPLE, NULL);
74 s3 = g_object_new (T_TEST_TYPE_SIMPLE, NULL);
75
76 /* write-to-read with optional fields */
77 s1->im_optional = 10;
78 g_assert (s1->__isset_im_default == FALSE);
79 g_assert (s1->__isset_im_optional == FALSE);
80 write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s2), NULL, NULL);
81 g_assert (s2->__isset_im_default == TRUE);
82 g_assert (s2->__isset_im_optional == FALSE);
83 g_assert (s2->im_optional == 0);
84
85 s1->__isset_im_optional = TRUE;
86 write_to_read (THRIFT_STRUCT (s1), THRIFT_STRUCT (s3), NULL, NULL);
87 g_assert (s3->__isset_im_default == TRUE);
88 g_assert (s3->__isset_im_optional == TRUE);
89 g_assert (s3->im_optional == 10);
90
91 g_object_unref (s1);
92 g_object_unref (s2);
93 }
94
95 /**
96 * Writing between optional and default
97 */
98 static void
test_tricky1(void)99 test_tricky1 (void)
100 {
101 TTestTricky1 *t1 = NULL;
102 TTestTricky2 *t2 = NULL;
103
104 t1 = g_object_new (T_TEST_TYPE_TRICKY1, NULL);
105 t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL);
106
107 t2->im_optional = 10;
108 write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t1), NULL, NULL);
109 write_to_read (THRIFT_STRUCT (t1), THRIFT_STRUCT (t2), NULL, NULL);
110
111 g_assert (t1->__isset_im_default == FALSE);
112 g_assert (t2->__isset_im_optional == TRUE);
113 g_assert (t1->im_default == t2->im_optional);
114 g_assert (t1->im_default == 0);
115
116 g_object_unref (t1);
117 g_object_unref (t2);
118 }
119
120 /**
121 * Writing between default and required.
122 */
123 static void
test_tricky2(void)124 test_tricky2 (void)
125 {
126 TTestTricky1 *t1 = NULL;
127 TTestTricky3 *t3 = NULL;
128
129 t1 = g_object_new (T_TEST_TYPE_TRICKY1, NULL);
130 t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL);
131
132 write_to_read (THRIFT_STRUCT (t1), THRIFT_STRUCT (t3), NULL, NULL);
133 write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t1), NULL, NULL);
134
135 g_assert (t1->__isset_im_default == TRUE);
136
137 g_object_unref (t1);
138 g_object_unref (t3);
139 }
140
141 /**
142 * Writing between optional and required.
143 */
144 static void
test_tricky3(void)145 test_tricky3 (void)
146 {
147 TTestTricky2 *t2 = NULL;
148 TTestTricky3 *t3 = NULL;
149
150 t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL);
151 t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL);
152
153 t2->__isset_im_optional = TRUE;
154
155 write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t3), NULL, NULL);
156 write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t2), NULL, NULL);
157
158 g_object_unref (t2);
159 g_object_unref (t3);
160 }
161
162 /**
163 * Catch an optional not set exception. To quote the
164 * C++ test, "Mu-hu-ha-ha-ha!"
165 */
166 static void
test_tricky4(void)167 test_tricky4 (void)
168 {
169 TTestTricky2 *t2 = NULL;
170 TTestTricky3 *t3 = NULL;
171 GError *read_error = NULL;
172
173 t2 = g_object_new (T_TEST_TYPE_TRICKY2, NULL);
174 t3 = g_object_new (T_TEST_TYPE_TRICKY3, NULL);
175
176 /* throws protocol exception */
177 write_to_read (THRIFT_STRUCT (t2), THRIFT_STRUCT (t3), NULL, &read_error);
178 g_assert (read_error != NULL);
179 g_error_free (read_error);
180
181 write_to_read (THRIFT_STRUCT (t3), THRIFT_STRUCT (t2), NULL, NULL);
182
183 g_assert (t2->__isset_im_optional);
184
185 g_object_unref (t2);
186 g_object_unref (t3);
187 }
188
189 static void
test_non_set_binary(void)190 test_non_set_binary (void)
191 {
192 TTestBinaries *b1 = NULL;
193 TTestBinaries *b2 = NULL;
194 GError *error = NULL;
195
196 b1 = g_object_new (T_TEST_TYPE_BINARIES, NULL);
197 b2 = g_object_new (T_TEST_TYPE_BINARIES, NULL);
198
199 write_to_read (THRIFT_STRUCT (b1), THRIFT_STRUCT (b2), NULL, &error);
200 g_assert(!error);
201 write_to_read (THRIFT_STRUCT (b2), THRIFT_STRUCT (b1), NULL, &error);
202 g_assert(!error);
203 /* OK. No segfault */
204
205 g_object_unref (b1);
206 g_object_unref (b2);
207 }
208
209 int
main(int argc,char * argv[])210 main(int argc, char *argv[])
211 {
212 #if (!GLIB_CHECK_VERSION (2, 36, 0))
213 g_type_init();
214 #endif
215
216 g_test_init (&argc, &argv, NULL);
217
218 g_test_add_func ("/testoptionalrequired/OldSchool", test_old_school1);
219 g_test_add_func ("/testoptionalrequired/Simple", test_simple);
220 g_test_add_func ("/testoptionalrequired/Tricky1", test_tricky1);
221 g_test_add_func ("/testoptionalrequired/Tricky2", test_tricky2);
222 g_test_add_func ("/testoptionalrequired/Tricky3", test_tricky3);
223 g_test_add_func ("/testoptionalrequired/Tricky4", test_tricky4);
224 g_test_add_func ("/testoptionalrequired/Binary", test_non_set_binary);
225
226 return g_test_run ();
227 }
228