• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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