1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <unittest/unittest.h>
6 
7 #include <fidl/flat_ast.h>
8 #include <fidl/lexer.h>
9 #include <fidl/parser.h>
10 #include <fidl/source_file.h>
11 
12 #include "test_library.h"
13 
14 namespace {
15 
16 class MaxBytesLibrary : public TestLibrary {
17 public:
MaxBytesLibrary()18     MaxBytesLibrary()
19         : TestLibrary("max_bytes.fidl", R"FIDL(
20 library fidl.test.maxbytes;
21 
22 struct OneBool {
23   bool b;
24 };
25 
26 struct OptionalOneBool {
27   OneBool? s;
28 };
29 
30 struct TwoBools {
31   bool a;
32   bool b;
33 };
34 
35 struct OptionalTwoBools {
36   TwoBools? s;
37 };
38 
39 struct BoolAndU32 {
40   bool b;
41   uint32 u;
42 };
43 
44 struct OptionalBoolAndU32 {
45   BoolAndU32? s;
46 };
47 
48 struct BoolAndU64 {
49   bool b;
50   uint64 u;
51 };
52 
53 struct OptionalBoolAndU64 {
54   BoolAndU64? s;
55 };
56 
57 union UnionOfThings {
58   OneBool ob;
59   BoolAndU64 bu;
60 };
61 
62 struct OptionalUnion {
63   UnionOfThings? u;
64 };
65 
66 struct PaddedVector {
67   vector<int32>:3 pv;
68 };
69 
70 struct UnboundedVector {
71   vector<int32> uv;
72 };
73 
74 struct UnboundedVectors {
75   vector<int32> uv1;
76   vector<int32> uv2;
77 };
78 
79 struct ShortString {
80   string:5 s;
81 };
82 
83 struct UnboundedString {
84   string s;
85 };
86 
87 struct AnArray {
88   array<int64>:5 a;
89 };
90 
91 table TableWithOneBool {
92   1: bool b;
93 };
94 
95 table TableWithOptionalOneBool {
96   1: OneBool s;
97 };
98 
99 table TableWithOptionalTableWithOneBool {
100   1: TableWithOneBool s;
101 };
102 
103 table TableWithTwoBools {
104   1: bool a;
105   2: bool b;
106 };
107 
108 table TableWithOptionalTwoBools {
109   1: TwoBools s;
110 };
111 
112 table TableWithOptionalTableWithTwoBools {
113   1: TableWithTwoBools s;
114 };
115 
116 table TableWithBoolAndU32 {
117   1: bool b;
118   2: uint32 u;
119 };
120 
121 table TableWithOptionalBoolAndU32 {
122   1: BoolAndU32 s;
123 };
124 
125 table TableWithOptionalTableWithBoolAndU32 {
126   1: TableWithBoolAndU32 s;
127 };
128 
129 table TableWithBoolAndU64 {
130   1: bool b;
131   2: uint64 u;
132 };
133 
134 table TableWithOptionalBoolAndU64 {
135   1: BoolAndU64 s;
136 };
137 
138 table TableWithOptionalTableWithBoolAndU64 {
139   1: TableWithBoolAndU64 s;
140 };
141 
142 table TableWithOptionalUnion {
143   1: UnionOfThings u;
144 };
145 
146 table TableWithPaddedVector {
147   1: vector<int32>:3 pv;
148 };
149 
150 table TableWithUnboundedVector {
151   1: vector<int32> uv;
152 };
153 
154 table TableWithUnboundedVectors {
155   1: vector<int32> uv1;
156   2: vector<int32> uv2;
157 };
158 
159 table TableWithShortString {
160   1: string:5 s;
161 };
162 
163 table TableWithUnboundedString {
164   1: string s;
165 };
166 
167 table TableWithAnArray {
168   1: array<int64>:5 a;
169 };
170 
171 )FIDL") {}
172 };
173 
simple_structs(void)174 static bool simple_structs(void) {
175     BEGIN_TEST;
176 
177     MaxBytesLibrary test_library;
178     EXPECT_TRUE(test_library.Compile());
179 
180     auto one_bool = test_library.LookupStruct("OneBool");
181     EXPECT_NONNULL(one_bool);
182     EXPECT_EQ(one_bool->typeshape.Size(), 1);
183     EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 0);
184 
185     auto two_bools = test_library.LookupStruct("TwoBools");
186     EXPECT_NONNULL(two_bools);
187     EXPECT_EQ(two_bools->typeshape.Size(), 2);
188     EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 0);
189 
190     auto bool_and_u32 = test_library.LookupStruct("BoolAndU32");
191     EXPECT_NONNULL(bool_and_u32);
192     EXPECT_EQ(bool_and_u32->typeshape.Size(), 8);
193     EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 0);
194 
195     auto bool_and_u64 = test_library.LookupStruct("BoolAndU64");
196     EXPECT_NONNULL(bool_and_u64);
197     EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
198     EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 0);
199 
200     END_TEST;
201 }
202 
simple_tables(void)203 static bool simple_tables(void) {
204     BEGIN_TEST;
205 
206     MaxBytesLibrary test_library;
207     EXPECT_TRUE(test_library.Compile());
208 
209     auto one_bool = test_library.LookupTable("TableWithOneBool");
210     EXPECT_NONNULL(one_bool);
211     EXPECT_EQ(one_bool->typeshape.Size(), 16);
212     EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 24);
213 
214     auto two_bools = test_library.LookupTable("TableWithTwoBools");
215     EXPECT_NONNULL(two_bools);
216     EXPECT_EQ(two_bools->typeshape.Size(), 16);
217     EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 48);
218 
219     auto bool_and_u32 = test_library.LookupTable("TableWithBoolAndU32");
220     EXPECT_NONNULL(bool_and_u32);
221     EXPECT_EQ(bool_and_u32->typeshape.Size(), 16);
222     EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 48);
223 
224     auto bool_and_u64 = test_library.LookupTable("TableWithBoolAndU64");
225     EXPECT_NONNULL(bool_and_u64);
226     EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
227     EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 48);
228 
229     END_TEST;
230 }
231 
optional_structs(void)232 static bool optional_structs(void) {
233     BEGIN_TEST;
234 
235     MaxBytesLibrary test_library;
236     EXPECT_TRUE(test_library.Compile());
237 
238     auto one_bool = test_library.LookupStruct("OptionalOneBool");
239     EXPECT_NONNULL(one_bool);
240     EXPECT_EQ(one_bool->typeshape.Size(), 8);
241     EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 8);
242 
243     auto two_bools = test_library.LookupStruct("OptionalTwoBools");
244     EXPECT_NONNULL(two_bools);
245     EXPECT_EQ(two_bools->typeshape.Size(), 8);
246     EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 8);
247 
248     auto bool_and_u32 = test_library.LookupStruct("OptionalBoolAndU32");
249     EXPECT_NONNULL(bool_and_u32);
250     EXPECT_EQ(bool_and_u32->typeshape.Size(), 8);
251     EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 8);
252 
253     auto bool_and_u64 = test_library.LookupStruct("OptionalBoolAndU64");
254     EXPECT_NONNULL(bool_and_u64);
255     EXPECT_EQ(bool_and_u64->typeshape.Size(), 8);
256     EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 16);
257 
258     END_TEST;
259 }
260 
optional_tables(void)261 static bool optional_tables(void) {
262     BEGIN_TEST;
263 
264     MaxBytesLibrary test_library;
265     EXPECT_TRUE(test_library.Compile());
266 
267     auto one_bool = test_library.LookupTable("TableWithOptionalOneBool");
268     EXPECT_NONNULL(one_bool);
269     EXPECT_EQ(one_bool->typeshape.Size(), 16);
270     EXPECT_EQ(one_bool->typeshape.MaxOutOfLine(), 24);
271 
272     auto table_with_one_bool = test_library.LookupTable("TableWithOptionalTableWithOneBool");
273     EXPECT_NONNULL(table_with_one_bool);
274     EXPECT_EQ(table_with_one_bool->typeshape.Size(), 16);
275     EXPECT_EQ(table_with_one_bool->typeshape.MaxOutOfLine(), 56);
276 
277     auto two_bools = test_library.LookupTable("TableWithOptionalTwoBools");
278     EXPECT_NONNULL(two_bools);
279     EXPECT_EQ(two_bools->typeshape.Size(), 16);
280     EXPECT_EQ(two_bools->typeshape.MaxOutOfLine(), 24);
281 
282     auto table_with_two_bools = test_library.LookupTable("TableWithOptionalTableWithTwoBools");
283     EXPECT_NONNULL(table_with_two_bools);
284     EXPECT_EQ(table_with_two_bools->typeshape.Size(), 16);
285     EXPECT_EQ(table_with_two_bools->typeshape.MaxOutOfLine(), 80);
286 
287     auto bool_and_u32 = test_library.LookupTable("TableWithOptionalBoolAndU32");
288     EXPECT_NONNULL(bool_and_u32);
289     EXPECT_EQ(bool_and_u32->typeshape.Size(), 16);
290     EXPECT_EQ(bool_and_u32->typeshape.MaxOutOfLine(), 24);
291 
292     auto table_with_bool_and_u32 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU32");
293     EXPECT_NONNULL(table_with_bool_and_u32);
294     EXPECT_EQ(table_with_bool_and_u32->typeshape.Size(), 16);
295     EXPECT_EQ(table_with_bool_and_u32->typeshape.MaxOutOfLine(), 80);
296 
297     auto bool_and_u64 = test_library.LookupTable("TableWithOptionalBoolAndU64");
298     EXPECT_NONNULL(bool_and_u64);
299     EXPECT_EQ(bool_and_u64->typeshape.Size(), 16);
300     EXPECT_EQ(bool_and_u64->typeshape.MaxOutOfLine(), 32);
301 
302     auto table_with_bool_and_u64 = test_library.LookupTable("TableWithOptionalTableWithBoolAndU64");
303     EXPECT_NONNULL(table_with_bool_and_u64);
304     EXPECT_EQ(table_with_bool_and_u64->typeshape.Size(), 16);
305     EXPECT_EQ(table_with_bool_and_u64->typeshape.MaxOutOfLine(), 80);
306 
307     END_TEST;
308 }
309 
unions(void)310 static bool unions(void) {
311     BEGIN_TEST;
312 
313     MaxBytesLibrary test_library;
314     EXPECT_TRUE(test_library.Compile());
315 
316     auto a_union = test_library.LookupUnion("UnionOfThings");
317     EXPECT_NONNULL(a_union);
318     EXPECT_EQ(a_union->typeshape.Size(), 24);
319     EXPECT_EQ(a_union->typeshape.MaxOutOfLine(), 0);
320 
321     auto optional_union = test_library.LookupStruct("OptionalUnion");
322     EXPECT_NONNULL(optional_union);
323     EXPECT_EQ(optional_union->typeshape.Size(), 8);
324     EXPECT_EQ(optional_union->typeshape.MaxOutOfLine(), 24);
325 
326     auto table_with_optional_union = test_library.LookupTable("TableWithOptionalUnion");
327     EXPECT_NONNULL(table_with_optional_union);
328     EXPECT_EQ(table_with_optional_union->typeshape.Size(), 16);
329     EXPECT_EQ(table_with_optional_union->typeshape.MaxOutOfLine(), 40);
330 
331     END_TEST;
332 }
333 
vectors(void)334 static bool vectors(void) {
335     BEGIN_TEST;
336 
337     MaxBytesLibrary test_library;
338     EXPECT_TRUE(test_library.Compile());
339 
340     auto padded_vector = test_library.LookupStruct("PaddedVector");
341     EXPECT_NONNULL(padded_vector);
342     EXPECT_EQ(padded_vector->typeshape.Size(), 16);
343     EXPECT_EQ(padded_vector->typeshape.MaxOutOfLine(), 16);
344 
345     auto unbounded_vector = test_library.LookupStruct("UnboundedVector");
346     EXPECT_NONNULL(unbounded_vector);
347     EXPECT_EQ(unbounded_vector->typeshape.Size(), 16);
348     EXPECT_EQ(unbounded_vector->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
349 
350     auto unbounded_vectors = test_library.LookupStruct("UnboundedVectors");
351     EXPECT_NONNULL(unbounded_vectors);
352     EXPECT_EQ(unbounded_vectors->typeshape.Size(), 32);
353     EXPECT_EQ(unbounded_vectors->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
354 
355     auto table_with_padded_vector = test_library.LookupTable("TableWithPaddedVector");
356     EXPECT_NONNULL(table_with_padded_vector);
357     EXPECT_EQ(table_with_padded_vector->typeshape.Size(), 16);
358     EXPECT_EQ(table_with_padded_vector->typeshape.MaxOutOfLine(), 48);
359 
360     auto table_with_unbounded_vector = test_library.LookupTable("TableWithUnboundedVector");
361     EXPECT_NONNULL(table_with_unbounded_vector);
362     EXPECT_EQ(table_with_unbounded_vector->typeshape.Size(), 16);
363     EXPECT_EQ(table_with_unbounded_vector->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
364 
365     auto table_with_unbounded_vectors = test_library.LookupTable("TableWithUnboundedVectors");
366     EXPECT_NONNULL(table_with_unbounded_vectors);
367     EXPECT_EQ(table_with_unbounded_vectors->typeshape.Size(), 16);
368     EXPECT_EQ(table_with_unbounded_vectors->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
369 
370     END_TEST;
371 }
372 
strings(void)373 static bool strings(void) {
374     BEGIN_TEST;
375 
376     MaxBytesLibrary test_library;
377     EXPECT_TRUE(test_library.Compile());
378 
379     auto short_string = test_library.LookupStruct("ShortString");
380     EXPECT_NONNULL(short_string);
381     EXPECT_EQ(short_string->typeshape.Size(), 16);
382     EXPECT_EQ(short_string->typeshape.MaxOutOfLine(), 8);
383 
384     auto unbounded_string = test_library.LookupStruct("UnboundedString");
385     EXPECT_NONNULL(unbounded_string);
386     EXPECT_EQ(unbounded_string->typeshape.Size(), 16);
387     EXPECT_EQ(unbounded_string->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
388 
389     auto table_with_short_string = test_library.LookupTable("TableWithShortString");
390     EXPECT_NONNULL(table_with_short_string);
391     EXPECT_EQ(table_with_short_string->typeshape.Size(), 16);
392     EXPECT_EQ(table_with_short_string->typeshape.MaxOutOfLine(), 40);
393 
394     auto table_with_unbounded_string = test_library.LookupTable("TableWithUnboundedString");
395     EXPECT_NONNULL(table_with_unbounded_string);
396     EXPECT_EQ(table_with_unbounded_string->typeshape.Size(), 16);
397     EXPECT_EQ(table_with_unbounded_string->typeshape.MaxOutOfLine(), std::numeric_limits<uint32_t>::max());
398 
399     END_TEST;
400 }
401 
arrays(void)402 static bool arrays(void) {
403     BEGIN_TEST;
404 
405     MaxBytesLibrary test_library;
406     EXPECT_TRUE(test_library.Compile());
407 
408     auto an_array = test_library.LookupStruct("AnArray");
409     EXPECT_NONNULL(an_array);
410     EXPECT_EQ(an_array->typeshape.Size(), 40);
411     EXPECT_EQ(an_array->typeshape.MaxOutOfLine(), 0);
412 
413     auto table_with_an_array = test_library.LookupTable("TableWithAnArray");
414     EXPECT_NONNULL(table_with_an_array);
415     EXPECT_EQ(table_with_an_array->typeshape.Size(), 16);
416     EXPECT_EQ(table_with_an_array->typeshape.MaxOutOfLine(), 56);
417 
418     END_TEST;
419 }
420 
421 } // namespace
422 
423 BEGIN_TEST_CASE(max_bytes_tests);
424 RUN_TEST(simple_structs);
425 RUN_TEST(simple_tables);
426 RUN_TEST(optional_structs);
427 RUN_TEST(optional_tables);
428 RUN_TEST(unions);
429 RUN_TEST(vectors);
430 RUN_TEST(strings);
431 RUN_TEST(arrays);
432 END_TEST_CASE(max_bytes_tests);
433