1 /* Test of generated code, with a special focus on features that are not used in
2 * descriptor.proto or conformance.proto (since these get some testing from
3 * upb/def.c and tests/conformance_upb.c, respectively).
4 */
5
6 #include "src/google/protobuf/test_messages_proto3.upb.h"
7 #include "tests/upb_test.h"
8 #include "tests/test.upb.h"
9
10 #define MIN(x, y) ((x) < (y) ? (x) : (y))
11
12 const char test_str[] = "abcdefg";
13 const char test_str2[] = "12345678910";
14 const char test_str3[] = "rstlnezxcvbnm";
15 const char test_str4[] = "just another test string";
16
17 const upb_strview test_str_view = {test_str, sizeof(test_str) - 1};
18 const upb_strview test_str_view2 = {test_str2, sizeof(test_str2) - 1};
19 const upb_strview test_str_view3 = {test_str3, sizeof(test_str3) - 1};
20 const upb_strview test_str_view4 = {test_str4, sizeof(test_str4) - 1};
21
22 const int32_t test_int32 = 10;
23 const int32_t test_int32_2 = -20;
24 const int32_t test_int32_3 = 30;
25 const int32_t test_int32_4 = -40;
26
test_scalars(void)27 static void test_scalars(void) {
28 upb_arena *arena = upb_arena_new();
29 protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
30 protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
31 protobuf_test_messages_proto3_TestAllTypesProto3 *msg2;
32 upb_strview serialized;
33 upb_strview val;
34
35 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int32(msg, 10);
36 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_int64(msg, 20);
37 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_uint32(msg, 30);
38 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_uint64(msg, 40);
39 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_float(msg, 50.5);
40 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_double(msg, 60.6);
41 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_bool(msg, 1);
42 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_string(
43 msg, test_str_view);
44
45 serialized.data = protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
46 msg, arena, &serialized.size);
47
48 msg2 = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
49 serialized.data, serialized.size, arena);
50
51 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_int32(
52 msg2) == 10);
53 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_int64(
54 msg2) == 20);
55 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint32(
56 msg2) == 30);
57 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_uint64(
58 msg2) == 40);
59 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_float(
60 msg2) - 50.5 < 0.01);
61 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_double(
62 msg2) - 60.6 < 0.01);
63 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_optional_bool(
64 msg2) == 1);
65 val = protobuf_test_messages_proto3_TestAllTypesProto3_optional_string(msg2);
66 ASSERT(upb_strview_eql(val, test_str_view));
67
68 upb_arena_free(arena);
69 }
70
test_utf8(void)71 static void test_utf8(void) {
72 const char invalid_utf8[] = "\xff";
73 const upb_strview invalid_utf8_view = upb_strview_make(invalid_utf8, 1);
74 upb_arena *arena = upb_arena_new();
75 upb_strview serialized;
76 protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
77 protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
78 protobuf_test_messages_proto3_TestAllTypesProto3 *msg2;
79
80 protobuf_test_messages_proto3_TestAllTypesProto3_set_optional_string(
81 msg, invalid_utf8_view);
82
83 serialized.data = protobuf_test_messages_proto3_TestAllTypesProto3_serialize(
84 msg, arena, &serialized.size);
85
86 msg2 = protobuf_test_messages_proto3_TestAllTypesProto3_parse(
87 serialized.data, serialized.size, arena);
88 ASSERT(msg2 == NULL);
89
90 upb_arena_free(arena);
91 }
92
check_string_map_empty(protobuf_test_messages_proto3_TestAllTypesProto3 * msg)93 static void check_string_map_empty(
94 protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
95 size_t iter = UPB_MAP_BEGIN;
96
97 ASSERT(
98 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_size(
99 msg) == 0);
100 ASSERT(
101 !protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
102 msg, &iter));
103 }
104
check_string_map_one_entry(protobuf_test_messages_proto3_TestAllTypesProto3 * msg)105 static void check_string_map_one_entry(
106 protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
107 const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry
108 *const_ent;
109 size_t iter;
110 upb_strview str;
111
112 ASSERT(
113 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_size(
114 msg) == 1);
115 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_get(
116 msg, test_str_view, &str));
117 ASSERT(upb_strview_eql(str, test_str_view2));
118
119 ASSERT(
120 !protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_get(
121 msg, test_str_view3, &str));
122
123 /* Test that iteration reveals a single k/v pair in the map. */
124 iter = UPB_MAP_BEGIN;
125 const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
126 msg, &iter);
127 ASSERT(const_ent);
128 ASSERT(upb_strview_eql(
129 test_str_view,
130 protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
131 const_ent)));
132 ASSERT(upb_strview_eql(
133 test_str_view2,
134 protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
135 const_ent)));
136
137 const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
138 msg, &iter);
139 ASSERT(!const_ent);
140 }
141
test_string_double_map(void)142 static void test_string_double_map(void) {
143 upb_arena *arena = upb_arena_new();
144 upb_strview serialized;
145 upb_test_MapTest *msg = upb_test_MapTest_new(arena);
146 upb_test_MapTest *msg2;
147 double val;
148
149 upb_test_MapTest_map_string_double_set(msg, test_str_view, 1.5, arena);
150 ASSERT(msg);
151 ASSERT(upb_test_MapTest_map_string_double_get(msg, test_str_view, &val));
152 ASSERT(val == 1.5);
153 val = 0;
154
155 serialized.data = upb_test_MapTest_serialize(msg, arena, &serialized.size);
156 ASSERT(serialized.data);
157
158 msg2 = upb_test_MapTest_parse(serialized.data, serialized.size, arena);
159 ASSERT(msg2);
160 ASSERT(upb_test_MapTest_map_string_double_get(msg2, test_str_view, &val));
161 ASSERT(val == 1.5);
162
163 upb_arena_free(arena);
164 }
165
test_string_map(void)166 static void test_string_map(void) {
167 upb_arena *arena = upb_arena_new();
168 protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
169 protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
170 const protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry
171 *const_ent;
172 size_t iter, count;
173
174 check_string_map_empty(msg);
175
176 /* Set map[test_str_view] = test_str_view2 */
177 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
178 msg, test_str_view, test_str_view2, arena);
179 check_string_map_one_entry(msg);
180
181 /* Deleting a non-existent key does nothing. */
182 ASSERT(
183 !protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_delete(
184 msg, test_str_view3));
185 check_string_map_one_entry(msg);
186
187 /* Deleting the key sets the map back to empty. */
188 ASSERT(
189 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_delete(
190 msg, test_str_view));
191 check_string_map_empty(msg);
192
193 /* Set two keys this time:
194 * map[test_str_view] = test_str_view2
195 * map[test_str_view3] = test_str_view4
196 */
197 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
198 msg, test_str_view, test_str_view2, arena);
199 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_set(
200 msg, test_str_view3, test_str_view4, arena);
201
202 /* Test iteration */
203 iter = UPB_MAP_BEGIN;
204 count = 0;
205
206 while (
207 (const_ent =
208 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_next(
209 msg, &iter)) != NULL) {
210 upb_strview key =
211 protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_key(
212 const_ent);
213 upb_strview val =
214 protobuf_test_messages_proto3_TestAllTypesProto3_MapStringStringEntry_value(
215 const_ent);
216
217 count++;
218 if (upb_strview_eql(key, test_str_view)) {
219 ASSERT(upb_strview_eql(val, test_str_view2));
220 } else {
221 ASSERT(upb_strview_eql(key, test_str_view3));
222 ASSERT(upb_strview_eql(val, test_str_view4));
223 }
224 }
225
226 ASSERT(count == 2);
227
228 /* Clearing the map goes back to empty. */
229 protobuf_test_messages_proto3_TestAllTypesProto3_map_string_string_clear(msg);
230 check_string_map_empty(msg);
231
232 upb_arena_free(arena);
233 }
234
check_int32_map_empty(protobuf_test_messages_proto3_TestAllTypesProto3 * msg)235 static void check_int32_map_empty(
236 protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
237 size_t iter = UPB_MAP_BEGIN;
238
239 ASSERT(
240 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_size(
241 msg) == 0);
242 ASSERT(
243 !protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
244 msg, &iter));
245 }
246
check_int32_map_one_entry(protobuf_test_messages_proto3_TestAllTypesProto3 * msg)247 static void check_int32_map_one_entry(
248 protobuf_test_messages_proto3_TestAllTypesProto3 *msg) {
249 const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry
250 *const_ent;
251 size_t iter;
252 int32_t val;
253
254 ASSERT(
255 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_size(
256 msg) == 1);
257 ASSERT(protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_get(
258 msg, test_int32, &val));
259 ASSERT(val == test_int32_2);
260
261 ASSERT(
262 !protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_get(
263 msg, test_int32_3, &val));
264
265 /* Test that iteration reveals a single k/v pair in the map. */
266 iter = UPB_MAP_BEGIN;
267 const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
268 msg, &iter);
269 ASSERT(const_ent);
270 ASSERT(
271 test_int32 ==
272 protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
273 const_ent));
274 ASSERT(
275 test_int32_2 ==
276 protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
277 const_ent));
278
279 const_ent = protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
280 msg, &iter);
281 ASSERT(!const_ent);
282 }
283
test_int32_map(void)284 static void test_int32_map(void) {
285 upb_arena *arena = upb_arena_new();
286 protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
287 protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
288 const protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry
289 *const_ent;
290 size_t iter, count;
291
292 check_int32_map_empty(msg);
293
294 /* Set map[test_int32] = test_int32_2 */
295 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
296 msg, test_int32, test_int32_2, arena);
297 check_int32_map_one_entry(msg);
298
299 /* Deleting a non-existent key does nothing. */
300 ASSERT(
301 !protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_delete(
302 msg, test_int32_3));
303 check_int32_map_one_entry(msg);
304
305 /* Deleting the key sets the map back to empty. */
306 ASSERT(
307 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_delete(
308 msg, test_int32));
309 check_int32_map_empty(msg);
310
311 /* Set two keys this time:
312 * map[test_int32] = test_int32_2
313 * map[test_int32_3] = test_int32_4
314 */
315 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
316 msg, test_int32, test_int32_2, arena);
317 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_set(
318 msg, test_int32_3, test_int32_4, arena);
319
320 /* Test iteration */
321 iter = UPB_MAP_BEGIN;
322 count = 0;
323
324 while (
325 (const_ent =
326 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_next(
327 msg, &iter)) != NULL) {
328 int32_t key =
329 protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_key(
330 const_ent);
331 int32_t val =
332 protobuf_test_messages_proto3_TestAllTypesProto3_MapInt32Int32Entry_value(
333 const_ent);
334
335 count++;
336 if (key == test_int32) {
337 ASSERT(val == test_int32_2);
338 } else {
339 ASSERT(key == test_int32_3);
340 ASSERT(val == test_int32_4);
341 }
342 }
343
344 ASSERT(count == 2);
345
346 /* Clearing the map goes back to empty. */
347 protobuf_test_messages_proto3_TestAllTypesProto3_map_int32_int32_clear(msg);
348 check_int32_map_empty(msg);
349
350 upb_arena_free(arena);
351 }
352
test_repeated(void)353 void test_repeated(void) {
354 upb_arena *arena = upb_arena_new();
355 protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
356 protobuf_test_messages_proto3_TestAllTypesProto3_new(arena);
357 size_t size;
358 const int *elems;
359
360 protobuf_test_messages_proto3_TestAllTypesProto3_add_repeated_int32(
361 msg, 5, arena);
362
363 elems = protobuf_test_messages_proto3_TestAllTypesProto3_repeated_int32(
364 msg, &size);
365
366 ASSERT(size == 1);
367 ASSERT(elems[0] == 5);
368
369 upb_arena_free(arena);
370 }
371
test_null_decode_buf(void)372 void test_null_decode_buf(void) {
373 upb_arena *arena = upb_arena_new();
374 protobuf_test_messages_proto3_TestAllTypesProto3 *msg =
375 protobuf_test_messages_proto3_TestAllTypesProto3_parse(NULL, 0, arena);
376 size_t size;
377
378 ASSERT(msg);
379 protobuf_test_messages_proto3_TestAllTypesProto3_serialize(msg, arena, &size);
380 ASSERT(size == 0);
381 upb_arena_free(arena);
382 }
383
test_status_truncation(void)384 void test_status_truncation(void) {
385 int i, j;
386 upb_status status;
387 upb_status status2;
388 for (i = 0; i < UPB_STATUS_MAX_MESSAGE + 20; i++) {
389 char *msg = malloc(i + 1);
390 int end;
391 char ch = (i % 96) + 33; /* Cycle through printable chars. */
392
393 for (j = 0; j < i; j++) {
394 msg[j] = ch;
395 }
396 msg[i] = '\0';
397
398 upb_status_seterrmsg(&status, msg);
399 upb_status_seterrf(&status2, "%s", msg);
400 end = MIN(i, UPB_STATUS_MAX_MESSAGE - 1);
401 ASSERT(strlen(status.msg) == end);
402 ASSERT(strlen(status2.msg) == end);
403
404 for (j = 0; j < end; j++) {
405 ASSERT(status.msg[j] == ch);
406 ASSERT(status2.msg[j] == ch);
407 }
408
409 free(msg);
410 }
411 }
412
run_tests(int argc,char * argv[])413 int run_tests(int argc, char *argv[]) {
414 test_scalars();
415 test_utf8();
416 test_string_map();
417 test_string_double_map();
418 test_int32_map();
419 test_repeated();
420 test_null_decode_buf();
421 test_status_truncation();
422 return 0;
423 }
424