OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium 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 <utility> | |
6 #include <vector> | |
7 | |
8 #include "gtest/gtest.h" | |
9 #include "mojo/public/cpp/bindings/array.h" | |
10 #include "mojo/public/cpp/bindings/binding.h" | |
11 #include "mojo/public/cpp/bindings/lib/array_internal.h" | |
12 #include "mojo/public/cpp/bindings/lib/array_serialization.h" | |
13 #include "mojo/public/cpp/bindings/lib/bounds_checker.h" | |
14 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" | |
15 #include "mojo/public/cpp/bindings/lib/map_serialization.h" | |
16 #include "mojo/public/cpp/bindings/string.h" | |
17 #include "mojo/public/cpp/test_support/test_utils.h" | |
18 #include "mojo/public/cpp/utility/run_loop.h" | |
19 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" | |
20 #include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h" | |
21 | |
22 namespace mojo { | |
23 namespace test { | |
24 | |
25 TEST(UnionTest, PlainOldDataGetterSetter) { | |
26 PodUnionPtr pod(PodUnion::New()); | |
27 | |
28 pod->set_f_int8(10); | |
29 EXPECT_EQ(10, pod->get_f_int8()); | |
30 EXPECT_TRUE(pod->is_f_int8()); | |
31 EXPECT_FALSE(pod->is_f_int8_other()); | |
32 EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT8); | |
33 | |
34 pod->set_f_uint8(11); | |
35 EXPECT_EQ(11, pod->get_f_uint8()); | |
36 EXPECT_TRUE(pod->is_f_uint8()); | |
37 EXPECT_FALSE(pod->is_f_int8()); | |
38 EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT8); | |
39 | |
40 pod->set_f_int16(12); | |
41 EXPECT_EQ(12, pod->get_f_int16()); | |
42 EXPECT_TRUE(pod->is_f_int16()); | |
43 EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT16); | |
44 | |
45 pod->set_f_uint16(13); | |
46 EXPECT_EQ(13, pod->get_f_uint16()); | |
47 EXPECT_TRUE(pod->is_f_uint16()); | |
48 EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT16); | |
49 | |
50 pod->set_f_int32(14); | |
51 EXPECT_EQ(14, pod->get_f_int32()); | |
52 EXPECT_TRUE(pod->is_f_int32()); | |
53 EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT32); | |
54 | |
55 pod->set_f_uint32(static_cast<uint32_t>(15)); | |
56 EXPECT_EQ(static_cast<uint32_t>(15), pod->get_f_uint32()); | |
57 EXPECT_TRUE(pod->is_f_uint32()); | |
58 EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT32); | |
59 | |
60 pod->set_f_int64(16); | |
61 EXPECT_EQ(16, pod->get_f_int64()); | |
62 EXPECT_TRUE(pod->is_f_int64()); | |
63 EXPECT_EQ(pod->which(), PodUnion::Tag::F_INT64); | |
64 | |
65 pod->set_f_uint64(static_cast<uint64_t>(17)); | |
66 EXPECT_EQ(static_cast<uint64_t>(17), pod->get_f_uint64()); | |
67 EXPECT_TRUE(pod->is_f_uint64()); | |
68 EXPECT_EQ(pod->which(), PodUnion::Tag::F_UINT64); | |
69 | |
70 pod->set_f_float(1.5); | |
71 EXPECT_EQ(1.5, pod->get_f_float()); | |
72 EXPECT_TRUE(pod->is_f_float()); | |
73 EXPECT_EQ(pod->which(), PodUnion::Tag::F_FLOAT); | |
74 | |
75 pod->set_f_double(1.9); | |
76 EXPECT_EQ(1.9, pod->get_f_double()); | |
77 EXPECT_TRUE(pod->is_f_double()); | |
78 EXPECT_EQ(pod->which(), PodUnion::Tag::F_DOUBLE); | |
79 | |
80 pod->set_f_bool(true); | |
81 EXPECT_TRUE(pod->get_f_bool()); | |
82 pod->set_f_bool(false); | |
83 EXPECT_FALSE(pod->get_f_bool()); | |
84 EXPECT_TRUE(pod->is_f_bool()); | |
85 EXPECT_EQ(pod->which(), PodUnion::Tag::F_BOOL); | |
86 | |
87 pod->set_f_enum(AnEnum::SECOND); | |
88 EXPECT_EQ(AnEnum::SECOND, pod->get_f_enum()); | |
89 EXPECT_TRUE(pod->is_f_enum()); | |
90 EXPECT_EQ(pod->which(), PodUnion::Tag::F_ENUM); | |
91 } | |
92 | |
93 TEST(UnionTest, PodEquals) { | |
94 PodUnionPtr pod1(PodUnion::New()); | |
95 PodUnionPtr pod2(PodUnion::New()); | |
96 | |
97 pod1->set_f_int8(10); | |
98 pod2->set_f_int8(10); | |
99 EXPECT_TRUE(pod1.Equals(pod2)); | |
100 | |
101 pod2->set_f_int8(11); | |
102 EXPECT_FALSE(pod1.Equals(pod2)); | |
103 | |
104 pod2->set_f_int8_other(10); | |
105 EXPECT_FALSE(pod1.Equals(pod2)); | |
106 } | |
107 | |
108 TEST(UnionTest, PodClone) { | |
109 PodUnionPtr pod(PodUnion::New()); | |
110 pod->set_f_int8(10); | |
111 | |
112 PodUnionPtr pod_clone = pod.Clone(); | |
113 EXPECT_EQ(10, pod_clone->get_f_int8()); | |
114 EXPECT_TRUE(pod_clone->is_f_int8()); | |
115 EXPECT_EQ(pod_clone->which(), PodUnion::Tag::F_INT8); | |
116 } | |
117 | |
118 TEST(UnionTest, PodSerialization) { | |
119 PodUnionPtr pod1(PodUnion::New()); | |
120 pod1->set_f_int8(10); | |
121 | |
122 size_t size = GetSerializedSize_(pod1); | |
123 EXPECT_EQ(16U, size); | |
124 | |
125 mojo::internal::FixedBufferForTesting buf(size); | |
126 auto* data = internal::PodUnion_Data::New(&buf); | |
127 SerializeUnion_(pod1.get(), &buf, &data); | |
128 | |
129 PodUnionPtr pod2(PodUnion::New()); | |
130 Deserialize_(data, pod2.get()); | |
131 | |
132 EXPECT_EQ(10, pod2->get_f_int8()); | |
133 EXPECT_TRUE(pod2->is_f_int8()); | |
134 EXPECT_EQ(pod2->which(), PodUnion::Tag::F_INT8); | |
135 } | |
136 | |
137 TEST(UnionTest, EnumSerialization) { | |
138 PodUnionPtr pod1(PodUnion::New()); | |
139 pod1->set_f_enum(AnEnum::SECOND); | |
140 | |
141 size_t size = GetSerializedSize_(pod1); | |
142 EXPECT_EQ(16U, size); | |
143 | |
144 mojo::internal::FixedBufferForTesting buf(size); | |
145 auto* data = internal::PodUnion_Data::New(&buf); | |
146 SerializeUnion_(pod1.get(), &buf, &data); | |
147 | |
148 PodUnionPtr pod2 = PodUnion::New(); | |
149 Deserialize_(data, pod2.get()); | |
150 | |
151 EXPECT_EQ(AnEnum::SECOND, pod2->get_f_enum()); | |
152 EXPECT_TRUE(pod2->is_f_enum()); | |
153 EXPECT_EQ(pod2->which(), PodUnion::Tag::F_ENUM); | |
154 } | |
155 | |
156 TEST(UnionTest, PodValidation) { | |
157 PodUnionPtr pod(PodUnion::New()); | |
158 pod->set_f_int8(10); | |
159 | |
160 size_t size = GetSerializedSize_(pod); | |
161 EXPECT_EQ(16U, size); | |
162 | |
163 mojo::internal::FixedBufferForTesting buf(size); | |
164 auto* data = internal::PodUnion_Data::New(&buf); | |
165 SerializeUnion_(pod.get(), &buf, &data); | |
166 std::vector<Handle> handles; | |
167 data->EncodePointersAndHandles(&handles); | |
168 EXPECT_TRUE(handles.empty()); | |
169 | |
170 void* raw_buf = buf.Leak(); | |
171 mojo::internal::BoundsChecker bounds_checker(data, | |
172 static_cast<uint32_t>(size), 0); | |
173 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
174 internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false, | |
175 nullptr)); | |
176 free(raw_buf); | |
177 } | |
178 | |
179 TEST(UnionTest, SerializeNotNull) { | |
180 PodUnionPtr pod(PodUnion::New()); | |
181 pod->set_f_int8(0); | |
182 size_t size = GetSerializedSize_(pod); | |
183 mojo::internal::FixedBufferForTesting buf(size); | |
184 auto* data = internal::PodUnion_Data::New(&buf); | |
185 SerializeUnion_(pod.get(), &buf, &data); | |
186 EXPECT_FALSE(data->is_null()); | |
187 } | |
188 | |
189 TEST(UnionTest, SerializeIsNull) { | |
190 PodUnionPtr pod; | |
191 size_t size = GetSerializedSize_(pod); | |
192 EXPECT_EQ(16U, size); | |
193 mojo::internal::FixedBufferForTesting buf(size); | |
194 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); | |
195 | |
196 // Check that dirty output buffers are handled correctly by serialization. | |
197 data->size = 16U; | |
198 data->tag = PodUnion::Tag::F_UINT16; | |
199 data->data.f_f_int16 = 20; | |
200 | |
201 SerializeUnion_(pod.get(), &buf, &data); | |
202 EXPECT_TRUE(data->is_null()); | |
203 | |
204 PodUnionPtr pod2 = PodUnion::New(); | |
205 Deserialize_(data, pod2.get()); | |
206 EXPECT_EQ(pod2->which(), PodUnion::Tag::__UNKNOWN__); | |
207 | |
208 { | |
209 PodUnionPtr pod; | |
210 size_t size = GetSerializedSize_(pod); | |
211 EXPECT_EQ(16U, size); | |
212 mojo::internal::FixedBufferForTesting buf(size); | |
213 auto* data = internal::PodUnion_Data::New(&buf); | |
214 SerializeUnion_(pod.get(), &buf, &data); | |
215 EXPECT_EQ(static_cast<internal::PodUnion_Data::PodUnion_Tag>(0), data->tag); | |
216 EXPECT_EQ(0u, data->size); | |
217 EXPECT_EQ(0u, data->data.unknown); | |
218 } | |
219 } | |
220 | |
221 TEST(UnionTest, NullValidation) { | |
222 void* buf = nullptr; | |
223 mojo::internal::BoundsChecker bounds_checker(buf, 0, 0); | |
224 EXPECT_EQ( | |
225 mojo::internal::ValidationError::NONE, | |
226 internal::PodUnion_Data::Validate(buf, &bounds_checker, false, nullptr)); | |
227 } | |
228 | |
229 TEST(UnionTest, OutOfAlignmentValidation) { | |
230 size_t size = sizeof(internal::PodUnion_Data); | |
231 // Get an aligned object and shift the alignment. | |
232 mojo::internal::FixedBufferForTesting aligned_buf(size + 1); | |
233 void* raw_buf = aligned_buf.Leak(); | |
234 char* buf = reinterpret_cast<char*>(raw_buf) + 1; | |
235 | |
236 internal::PodUnion_Data* data = | |
237 reinterpret_cast<internal::PodUnion_Data*>(buf); | |
238 mojo::internal::BoundsChecker bounds_checker(data, | |
239 static_cast<uint32_t>(size), 0); | |
240 EXPECT_NE( | |
241 mojo::internal::ValidationError::NONE, | |
242 internal::PodUnion_Data::Validate(buf, &bounds_checker, false, nullptr)); | |
243 free(raw_buf); | |
244 } | |
245 | |
246 TEST(UnionTest, OOBValidation) { | |
247 size_t size = sizeof(internal::PodUnion_Data) - 1; | |
248 mojo::internal::FixedBufferForTesting buf(size); | |
249 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); | |
250 mojo::internal::BoundsChecker bounds_checker(data, | |
251 static_cast<uint32_t>(size), 0); | |
252 void* raw_buf = buf.Leak(); | |
253 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
254 internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false, | |
255 nullptr)); | |
256 free(raw_buf); | |
257 } | |
258 | |
259 TEST(UnionTest, UnknownTagDeserialization) { | |
260 size_t size = sizeof(internal::PodUnion_Data); | |
261 mojo::internal::FixedBufferForTesting buf(size); | |
262 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); | |
263 data->size = size; | |
264 data->tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(100); | |
265 | |
266 PodUnionPtr pod2 = PodUnion::New(); | |
267 Deserialize_(data, pod2.get()); | |
268 | |
269 EXPECT_TRUE(pod2->has_unknown_tag()); | |
270 } | |
271 | |
272 TEST(UnionTest, UnknownTagValidation) { | |
273 size_t size = sizeof(internal::PodUnion_Data); | |
274 mojo::internal::FixedBufferForTesting buf(size); | |
275 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); | |
276 data->size = size; | |
277 data->tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(100); | |
278 mojo::internal::BoundsChecker bounds_checker(data, | |
279 static_cast<uint32_t>(size), 0); | |
280 void* raw_buf = buf.Leak(); | |
281 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
282 internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false, | |
283 nullptr)); | |
284 free(raw_buf); | |
285 } | |
286 | |
287 TEST(UnionTest, StringGetterSetter) { | |
288 ObjectUnionPtr pod(ObjectUnion::New()); | |
289 | |
290 String hello("hello world"); | |
291 pod->set_f_string(hello); | |
292 EXPECT_EQ(hello, pod->get_f_string()); | |
293 EXPECT_TRUE(pod->is_f_string()); | |
294 EXPECT_EQ(pod->which(), ObjectUnion::Tag::F_STRING); | |
295 } | |
296 | |
297 TEST(UnionTest, StringEquals) { | |
298 ObjectUnionPtr pod1(ObjectUnion::New()); | |
299 ObjectUnionPtr pod2(ObjectUnion::New()); | |
300 | |
301 pod1->set_f_string("hello world"); | |
302 pod2->set_f_string("hello world"); | |
303 EXPECT_TRUE(pod1.Equals(pod2)); | |
304 | |
305 pod2->set_f_string("hello universe"); | |
306 EXPECT_FALSE(pod1.Equals(pod2)); | |
307 } | |
308 | |
309 TEST(UnionTest, StringClone) { | |
310 ObjectUnionPtr pod(ObjectUnion::New()); | |
311 | |
312 String hello("hello world"); | |
313 pod->set_f_string(hello); | |
314 ObjectUnionPtr pod_clone = pod.Clone(); | |
315 EXPECT_EQ(hello, pod_clone->get_f_string()); | |
316 EXPECT_TRUE(pod_clone->is_f_string()); | |
317 EXPECT_EQ(pod_clone->which(), ObjectUnion::Tag::F_STRING); | |
318 } | |
319 | |
320 TEST(UnionTest, StringSerialization) { | |
321 ObjectUnionPtr pod1(ObjectUnion::New()); | |
322 | |
323 String hello("hello world"); | |
324 pod1->set_f_string(hello); | |
325 | |
326 size_t size = GetSerializedSize_(pod1); | |
327 mojo::internal::FixedBufferForTesting buf(size); | |
328 auto* data = internal::ObjectUnion_Data::New(&buf); | |
329 SerializeUnion_(pod1.get(), &buf, &data); | |
330 | |
331 std::vector<Handle> handles; | |
332 data->EncodePointersAndHandles(&handles); | |
333 data->DecodePointersAndHandles(&handles); | |
334 | |
335 ObjectUnionPtr pod2 = ObjectUnion::New(); | |
336 Deserialize_(data, pod2.get()); | |
337 EXPECT_EQ(hello, pod2->get_f_string()); | |
338 EXPECT_TRUE(pod2->is_f_string()); | |
339 EXPECT_EQ(pod2->which(), ObjectUnion::Tag::F_STRING); | |
340 } | |
341 | |
342 TEST(UnionTest, NullStringValidation) { | |
343 size_t size = sizeof(internal::ObjectUnion_Data); | |
344 mojo::internal::FixedBufferForTesting buf(size); | |
345 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); | |
346 data->size = 16; | |
347 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; | |
348 data->data.unknown = 0x0; | |
349 mojo::internal::BoundsChecker bounds_checker(data, | |
350 static_cast<uint32_t>(size), 0); | |
351 void* raw_buf = buf.Leak(); | |
352 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
353 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
354 false, nullptr)); | |
355 free(raw_buf); | |
356 } | |
357 | |
358 TEST(UnionTest, StringPointerOverflowValidation) { | |
359 size_t size = sizeof(internal::ObjectUnion_Data); | |
360 mojo::internal::FixedBufferForTesting buf(size); | |
361 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); | |
362 data->size = 16; | |
363 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; | |
364 data->data.unknown = 0xFFFFFFFFFFFFFFFF; | |
365 mojo::internal::BoundsChecker bounds_checker(data, | |
366 static_cast<uint32_t>(size), 0); | |
367 void* raw_buf = buf.Leak(); | |
368 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
369 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
370 false, nullptr)); | |
371 free(raw_buf); | |
372 } | |
373 | |
374 TEST(UnionTest, StringValidateOOB) { | |
375 size_t size = 32; | |
376 mojo::internal::FixedBufferForTesting buf(size); | |
377 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); | |
378 data->size = 16; | |
379 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; | |
380 | |
381 data->data.f_f_string.offset = 8; | |
382 char* ptr = reinterpret_cast<char*>(&data->data.f_f_string); | |
383 mojo::internal::ArrayHeader* array_header = | |
384 reinterpret_cast<mojo::internal::ArrayHeader*>(ptr + *ptr); | |
385 array_header->num_bytes = 20; // This should go out of bounds. | |
386 array_header->num_elements = 20; | |
387 mojo::internal::BoundsChecker bounds_checker(data, 32, 0); | |
388 void* raw_buf = buf.Leak(); | |
389 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
390 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
391 false, nullptr)); | |
392 free(raw_buf); | |
393 } | |
394 | |
395 // TODO(azani): Move back in array_unittest.cc when possible. | |
396 // Array tests | |
397 TEST(UnionTest, PodUnionInArray) { | |
398 SmallStructPtr small_struct(SmallStruct::New()); | |
399 small_struct->pod_union_array = Array<PodUnionPtr>::New(2); | |
400 small_struct->pod_union_array[0] = PodUnion::New(); | |
401 small_struct->pod_union_array[1] = PodUnion::New(); | |
402 | |
403 small_struct->pod_union_array[0]->set_f_int8(10); | |
404 small_struct->pod_union_array[1]->set_f_int16(12); | |
405 | |
406 EXPECT_EQ(10, small_struct->pod_union_array[0]->get_f_int8()); | |
407 EXPECT_EQ(12, small_struct->pod_union_array[1]->get_f_int16()); | |
408 } | |
409 | |
410 TEST(UnionTest, PodUnionInArraySerialization) { | |
411 auto array = Array<PodUnionPtr>::New(2); | |
412 array[0] = PodUnion::New(); | |
413 array[1] = PodUnion::New(); | |
414 | |
415 array[0]->set_f_int8(10); | |
416 array[1]->set_f_int16(12); | |
417 EXPECT_EQ(2U, array.size()); | |
418 | |
419 size_t size = GetSerializedSize_(array); | |
420 EXPECT_EQ(40U, size); | |
421 | |
422 mojo::internal::FixedBufferForTesting buf(size); | |
423 mojo::internal::Array_Data<internal::PodUnion_Data>* data = nullptr; | |
424 mojo::internal::ArrayValidateParams validate_params(0, false, nullptr); | |
425 SerializeArray_(&array, &buf, &data, &validate_params); | |
426 | |
427 Array<PodUnionPtr> array2; | |
428 Deserialize_(data, &array2); | |
429 | |
430 EXPECT_EQ(2U, array2.size()); | |
431 | |
432 EXPECT_EQ(10, array2[0]->get_f_int8()); | |
433 EXPECT_EQ(12, array2[1]->get_f_int16()); | |
434 } | |
435 | |
436 TEST(UnionTest, PodUnionInArrayValidation) { | |
437 auto array = Array<PodUnionPtr>::New(2); | |
438 array[0] = PodUnion::New(); | |
439 array[1] = PodUnion::New(); | |
440 | |
441 array[0]->set_f_int8(10); | |
442 array[1]->set_f_int16(12); | |
443 | |
444 size_t size = GetSerializedSize_(array); | |
445 | |
446 mojo::internal::FixedBufferForTesting buf(size); | |
447 mojo::internal::Array_Data<internal::PodUnion_Data>* data = nullptr; | |
448 mojo::internal::ArrayValidateParams validate_params(0, false, nullptr); | |
449 SerializeArray_(&array, &buf, &data, &validate_params); | |
450 | |
451 std::vector<Handle> handles; | |
452 data->EncodePointersAndHandles(&handles); | |
453 EXPECT_TRUE(handles.empty()); | |
454 | |
455 void* raw_buf = buf.Leak(); | |
456 mojo::internal::BoundsChecker bounds_checker(data, | |
457 static_cast<uint32_t>(size), 1); | |
458 | |
459 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
460 Array<PodUnionPtr>::Data_::Validate(raw_buf, &bounds_checker, | |
461 &validate_params, nullptr)); | |
462 free(raw_buf); | |
463 } | |
464 TEST(UnionTest, PodUnionInArraySerializationWithNull) { | |
465 auto array = Array<PodUnionPtr>::New(2); | |
466 array[0] = PodUnion::New(); | |
467 | |
468 array[0]->set_f_int8(10); | |
469 EXPECT_EQ(2U, array.size()); | |
470 | |
471 size_t size = GetSerializedSize_(array); | |
472 EXPECT_EQ(40U, size); | |
473 | |
474 mojo::internal::FixedBufferForTesting buf(size); | |
475 mojo::internal::Array_Data<internal::PodUnion_Data>* data = nullptr; | |
476 mojo::internal::ArrayValidateParams validate_params(0, true, nullptr); | |
477 SerializeArray_(&array, &buf, &data, &validate_params); | |
478 | |
479 Array<PodUnionPtr> array2; | |
480 Deserialize_(data, &array2); | |
481 | |
482 EXPECT_EQ(2U, array2.size()); | |
483 | |
484 EXPECT_EQ(10, array2[0]->get_f_int8()); | |
485 EXPECT_TRUE(array2[1].is_null()); | |
486 } | |
487 | |
488 // TODO(azani): Move back in struct_unittest.cc when possible. | |
489 // Struct tests | |
490 TEST(UnionTest, Clone_Union) { | |
491 SmallStructPtr small_struct(SmallStruct::New()); | |
492 small_struct->pod_union = PodUnion::New(); | |
493 small_struct->pod_union->set_f_int8(10); | |
494 | |
495 SmallStructPtr clone = small_struct.Clone(); | |
496 EXPECT_EQ(10, clone->pod_union->get_f_int8()); | |
497 } | |
498 | |
499 // Serialization test of a struct with a union of plain old data. | |
500 TEST(UnionTest, Serialization_UnionOfPods) { | |
501 SmallStructPtr small_struct(SmallStruct::New()); | |
502 small_struct->pod_union = PodUnion::New(); | |
503 small_struct->pod_union->set_f_int32(10); | |
504 | |
505 size_t size = GetSerializedSize_(*small_struct); | |
506 | |
507 mojo::internal::FixedBufferForTesting buf(size); | |
508 internal::SmallStruct_Data* data = nullptr; | |
509 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
510 Serialize_(small_struct.get(), &buf, &data)); | |
511 | |
512 SmallStructPtr deserialized(SmallStruct::New()); | |
513 Deserialize_(data, deserialized.get()); | |
514 | |
515 EXPECT_EQ(10, deserialized->pod_union->get_f_int32()); | |
516 } | |
517 | |
518 // Serialization test of a struct with a union of structs. | |
519 TEST(UnionTest, Serialization_UnionOfObjects) { | |
520 SmallObjStructPtr obj_struct(SmallObjStruct::New()); | |
521 obj_struct->obj_union = ObjectUnion::New(); | |
522 String hello("hello world"); | |
523 obj_struct->obj_union->set_f_string(hello); | |
524 | |
525 size_t size = GetSerializedSize_(*obj_struct); | |
526 | |
527 mojo::internal::FixedBufferForTesting buf(size); | |
528 internal::SmallObjStruct_Data* data = nullptr; | |
529 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
530 Serialize_(obj_struct.get(), &buf, &data)); | |
531 | |
532 std::vector<Handle> handles; | |
533 data->EncodePointersAndHandles(&handles); | |
534 data->DecodePointersAndHandles(&handles); | |
535 | |
536 SmallObjStructPtr deserialized(SmallObjStruct::New()); | |
537 Deserialize_(data, deserialized.get()); | |
538 | |
539 EXPECT_EQ(hello, deserialized->obj_union->get_f_string()); | |
540 } | |
541 | |
542 // Validation test of a struct with a union. | |
543 TEST(UnionTest, Validation_UnionsInStruct) { | |
544 SmallStructPtr small_struct(SmallStruct::New()); | |
545 small_struct->pod_union = PodUnion::New(); | |
546 small_struct->pod_union->set_f_int32(10); | |
547 | |
548 size_t size = GetSerializedSize_(*small_struct); | |
549 | |
550 mojo::internal::FixedBufferForTesting buf(size); | |
551 internal::SmallStruct_Data* data = nullptr; | |
552 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
553 Serialize_(small_struct.get(), &buf, &data)); | |
554 | |
555 std::vector<Handle> handles; | |
556 data->EncodePointersAndHandles(&handles); | |
557 EXPECT_TRUE(handles.empty()); | |
558 | |
559 void* raw_buf = buf.Leak(); | |
560 mojo::internal::BoundsChecker bounds_checker(data, | |
561 static_cast<uint32_t>(size), 0); | |
562 EXPECT_EQ( | |
563 mojo::internal::ValidationError::NONE, | |
564 internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker, nullptr)); | |
565 free(raw_buf); | |
566 } | |
567 | |
568 // Validation test of a struct union fails due to unknown union tag. | |
569 TEST(UnionTest, Validation_PodUnionInStruct_Failure) { | |
570 SmallStructPtr small_struct(SmallStruct::New()); | |
571 small_struct->pod_union = PodUnion::New(); | |
572 small_struct->pod_union->set_f_int32(10); | |
573 | |
574 size_t size = GetSerializedSize_(*small_struct); | |
575 | |
576 mojo::internal::FixedBufferForTesting buf(size); | |
577 internal::SmallStruct_Data* data = nullptr; | |
578 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
579 Serialize_(small_struct.get(), &buf, &data)); | |
580 data->pod_union.tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(100); | |
581 | |
582 std::vector<Handle> handles; | |
583 data->EncodePointersAndHandles(&handles); | |
584 EXPECT_TRUE(handles.empty()); | |
585 | |
586 void* raw_buf = buf.Leak(); | |
587 mojo::internal::BoundsChecker bounds_checker(data, | |
588 static_cast<uint32_t>(size), 0); | |
589 EXPECT_EQ( | |
590 mojo::internal::ValidationError::NONE, | |
591 internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker, nullptr)); | |
592 free(raw_buf); | |
593 } | |
594 | |
595 // Validation fails due to non-nullable null union in struct. | |
596 TEST(UnionTest, Validation_NullUnion_Failure) { | |
597 SmallStructNonNullableUnionPtr small_struct( | |
598 SmallStructNonNullableUnion::New()); | |
599 | |
600 size_t size = GetSerializedSize_(*small_struct); | |
601 | |
602 mojo::internal::FixedBufferForTesting buf(size); | |
603 internal::SmallStructNonNullableUnion_Data* data = | |
604 internal::SmallStructNonNullableUnion_Data::New(&buf); | |
605 | |
606 void* raw_buf = buf.Leak(); | |
607 mojo::internal::BoundsChecker bounds_checker(data, | |
608 static_cast<uint32_t>(size), 0); | |
609 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
610 internal::SmallStructNonNullableUnion_Data::Validate( | |
611 raw_buf, &bounds_checker, nullptr)); | |
612 free(raw_buf); | |
613 } | |
614 | |
615 // Validation passes with nullable null union. | |
616 TEST(UnionTest, Validation_NullableUnion) { | |
617 SmallStructPtr small_struct(SmallStruct::New()); | |
618 | |
619 size_t size = GetSerializedSize_(*small_struct); | |
620 | |
621 mojo::internal::FixedBufferForTesting buf(size); | |
622 internal::SmallStruct_Data* data = nullptr; | |
623 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
624 Serialize_(small_struct.get(), &buf, &data)); | |
625 | |
626 std::vector<Handle> handles; | |
627 data->EncodePointersAndHandles(&handles); | |
628 EXPECT_TRUE(handles.empty()); | |
629 | |
630 void* raw_buf = buf.Leak(); | |
631 mojo::internal::BoundsChecker bounds_checker(data, | |
632 static_cast<uint32_t>(size), 0); | |
633 EXPECT_EQ( | |
634 mojo::internal::ValidationError::NONE, | |
635 internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker, nullptr)); | |
636 free(raw_buf); | |
637 } | |
638 | |
639 // Serialize a null union and deserialize it back to check that we have a null | |
640 // union. | |
641 TEST(UnionTest, Deserialize_NullableUnion) { | |
642 char buf[1024]; | |
643 SmallStructPtr small_struct = SmallStruct::New(); | |
644 small_struct->Serialize(buf, sizeof(buf)); | |
645 EXPECT_TRUE(small_struct->pod_union.is_null()); | |
646 | |
647 SmallStructPtr deserialized_struct = SmallStruct::New(); | |
648 EXPECT_TRUE(deserialized_struct->Deserialize(buf, sizeof(buf))); | |
649 EXPECT_TRUE(deserialized_struct->pod_union.is_null()); | |
650 } | |
651 | |
652 // Validation passes with nullable null union containing non-nullable objects. | |
653 TEST(UnionTest, Validation_NullableObjectUnion) { | |
654 StructNullObjectUnionPtr small_struct(StructNullObjectUnion::New()); | |
655 | |
656 size_t size = GetSerializedSize_(*small_struct); | |
657 | |
658 mojo::internal::FixedBufferForTesting buf(size); | |
659 internal::StructNullObjectUnion_Data* data = nullptr; | |
660 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
661 Serialize_(small_struct.get(), &buf, &data)); | |
662 | |
663 std::vector<Handle> handles; | |
664 data->EncodePointersAndHandles(&handles); | |
665 EXPECT_TRUE(handles.empty()); | |
666 | |
667 void* raw_buf = buf.Leak(); | |
668 mojo::internal::BoundsChecker bounds_checker(data, | |
669 static_cast<uint32_t>(size), 0); | |
670 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
671 internal::StructNullObjectUnion_Data::Validate( | |
672 raw_buf, &bounds_checker, nullptr)); | |
673 free(raw_buf); | |
674 } | |
675 | |
676 // TODO(azani): Move back in map_unittest.cc when possible. | |
677 // Map Tests | |
678 TEST(UnionTest, PodUnionInMap) { | |
679 SmallStructPtr small_struct(SmallStruct::New()); | |
680 small_struct->pod_union_map = Map<String, PodUnionPtr>(); | |
681 small_struct->pod_union_map.insert("one", PodUnion::New()); | |
682 small_struct->pod_union_map.insert("two", PodUnion::New()); | |
683 | |
684 small_struct->pod_union_map["one"]->set_f_int8(8); | |
685 small_struct->pod_union_map["two"]->set_f_int16(16); | |
686 | |
687 EXPECT_EQ(8, small_struct->pod_union_map["one"]->get_f_int8()); | |
688 EXPECT_EQ(16, small_struct->pod_union_map["two"]->get_f_int16()); | |
689 } | |
690 | |
691 TEST(UnionTest, PodUnionInMapSerialization) { | |
692 Map<String, PodUnionPtr> map; | |
693 map.insert("one", PodUnion::New()); | |
694 map.insert("two", PodUnion::New()); | |
695 | |
696 map["one"]->set_f_int8(8); | |
697 map["two"]->set_f_int16(16); | |
698 | |
699 size_t size = GetSerializedSize_(map); | |
700 EXPECT_EQ(120U, size); | |
701 | |
702 mojo::internal::FixedBufferForTesting buf(size); | |
703 mojo::internal::Map_Data<mojo::internal::String_Data*, | |
704 internal::PodUnion_Data>* data = nullptr; | |
705 mojo::internal::ArrayValidateParams validate_params(0, false, nullptr); | |
706 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
707 SerializeMap_(&map, &buf, &data, &validate_params)); | |
708 | |
709 Map<String, PodUnionPtr> map2; | |
710 Deserialize_(data, &map2); | |
711 | |
712 EXPECT_EQ(8, map2["one"]->get_f_int8()); | |
713 EXPECT_EQ(16, map2["two"]->get_f_int16()); | |
714 } | |
715 | |
716 TEST(UnionTest, PodUnionInMapSerializationWithNull) { | |
717 Map<String, PodUnionPtr> map; | |
718 map.insert("one", PodUnion::New()); | |
719 map.insert("two", nullptr); | |
720 | |
721 map["one"]->set_f_int8(8); | |
722 | |
723 size_t size = GetSerializedSize_(map); | |
724 EXPECT_EQ(120U, size); | |
725 | |
726 mojo::internal::FixedBufferForTesting buf(size); | |
727 mojo::internal::Map_Data<mojo::internal::String_Data*, | |
728 internal::PodUnion_Data>* data = nullptr; | |
729 mojo::internal::ArrayValidateParams validate_params(0, true, nullptr); | |
730 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
731 SerializeMap_(&map, &buf, &data, &validate_params)); | |
732 | |
733 Map<String, PodUnionPtr> map2; | |
734 Deserialize_(data, &map2); | |
735 | |
736 EXPECT_EQ(8, map2["one"]->get_f_int8()); | |
737 EXPECT_TRUE(map2["two"].is_null()); | |
738 } | |
739 | |
740 TEST(UnionTest, StructInUnionGetterSetterPasser) { | |
741 DummyStructPtr dummy(DummyStruct::New()); | |
742 dummy->f_int8 = 8; | |
743 | |
744 ObjectUnionPtr obj(ObjectUnion::New()); | |
745 obj->set_f_dummy(dummy.Pass()); | |
746 | |
747 EXPECT_EQ(8, obj->get_f_dummy()->f_int8); | |
748 } | |
749 | |
750 TEST(UnionTest, StructInUnionSerialization) { | |
751 DummyStructPtr dummy(DummyStruct::New()); | |
752 dummy->f_int8 = 8; | |
753 | |
754 ObjectUnionPtr obj(ObjectUnion::New()); | |
755 obj->set_f_dummy(dummy.Pass()); | |
756 | |
757 size_t size = GetSerializedSize_(obj); | |
758 EXPECT_EQ(32U, size); | |
759 | |
760 mojo::internal::FixedBufferForTesting buf(size); | |
761 auto* data = internal::ObjectUnion_Data::New(&buf); | |
762 SerializeUnion_(obj.get(), &buf, &data); | |
763 | |
764 std::vector<Handle> handles; | |
765 data->EncodePointersAndHandles(&handles); | |
766 data->DecodePointersAndHandles(&handles); | |
767 | |
768 ObjectUnionPtr obj2 = ObjectUnion::New(); | |
769 Deserialize_(data, obj2.get()); | |
770 EXPECT_EQ(8, obj2->get_f_dummy()->f_int8); | |
771 } | |
772 | |
773 TEST(UnionTest, StructInUnionValidation) { | |
774 DummyStructPtr dummy(DummyStruct::New()); | |
775 dummy->f_int8 = 8; | |
776 | |
777 ObjectUnionPtr obj(ObjectUnion::New()); | |
778 obj->set_f_dummy(dummy.Pass()); | |
779 | |
780 size_t size = GetSerializedSize_(obj); | |
781 | |
782 mojo::internal::FixedBufferForTesting buf(size); | |
783 auto* data = internal::ObjectUnion_Data::New(&buf); | |
784 SerializeUnion_(obj.get(), &buf, &data); | |
785 | |
786 std::vector<Handle> handles; | |
787 data->EncodePointersAndHandles(&handles); | |
788 EXPECT_TRUE(handles.empty()); | |
789 | |
790 void* raw_buf = buf.Leak(); | |
791 mojo::internal::BoundsChecker bounds_checker(data, | |
792 static_cast<uint32_t>(size), 0); | |
793 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
794 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
795 false, nullptr)); | |
796 free(raw_buf); | |
797 } | |
798 | |
799 TEST(UnionTest, StructInUnionValidationNonNullable) { | |
800 DummyStructPtr dummy(nullptr); | |
801 | |
802 ObjectUnionPtr obj(ObjectUnion::New()); | |
803 obj->set_f_dummy(dummy.Pass()); | |
804 | |
805 size_t size = GetSerializedSize_(obj); | |
806 | |
807 mojo::internal::FixedBufferForTesting buf(size); | |
808 auto* data = internal::ObjectUnion_Data::New(&buf); | |
809 SerializeUnion_(obj.get(), &buf, &data); | |
810 | |
811 std::vector<Handle> handles; | |
812 data->EncodePointersAndHandles(&handles); | |
813 EXPECT_TRUE(handles.empty()); | |
814 | |
815 void* raw_buf = buf.Leak(); | |
816 mojo::internal::BoundsChecker bounds_checker(data, | |
817 static_cast<uint32_t>(size), 0); | |
818 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
819 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
820 false, nullptr)); | |
821 free(raw_buf); | |
822 } | |
823 | |
824 TEST(UnionTest, StructInUnionValidationNullable) { | |
825 DummyStructPtr dummy(nullptr); | |
826 | |
827 ObjectUnionPtr obj(ObjectUnion::New()); | |
828 obj->set_f_nullable(dummy.Pass()); | |
829 | |
830 size_t size = GetSerializedSize_(obj); | |
831 | |
832 mojo::internal::FixedBufferForTesting buf(size); | |
833 auto* data = internal::ObjectUnion_Data::New(&buf); | |
834 SerializeUnion_(obj.get(), &buf, &data); | |
835 | |
836 std::vector<Handle> handles; | |
837 data->EncodePointersAndHandles(&handles); | |
838 EXPECT_TRUE(handles.empty()); | |
839 | |
840 void* raw_buf = buf.Leak(); | |
841 mojo::internal::BoundsChecker bounds_checker(data, | |
842 static_cast<uint32_t>(size), 0); | |
843 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
844 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
845 false, nullptr)); | |
846 free(raw_buf); | |
847 } | |
848 | |
849 TEST(UnionTest, ArrayInUnionGetterSetter) { | |
850 auto array = Array<int8_t>::New(2); | |
851 array[0] = 8; | |
852 array[1] = 9; | |
853 | |
854 ObjectUnionPtr obj(ObjectUnion::New()); | |
855 obj->set_f_array_int8(array.Pass()); | |
856 | |
857 EXPECT_EQ(8, obj->get_f_array_int8()[0]); | |
858 EXPECT_EQ(9, obj->get_f_array_int8()[1]); | |
859 } | |
860 | |
861 TEST(UnionTest, ArrayInUnionSerialization) { | |
862 auto array = Array<int8_t>::New(2); | |
863 array[0] = 8; | |
864 array[1] = 9; | |
865 | |
866 ObjectUnionPtr obj(ObjectUnion::New()); | |
867 obj->set_f_array_int8(array.Pass()); | |
868 | |
869 size_t size = GetSerializedSize_(obj); | |
870 EXPECT_EQ(32U, size); | |
871 | |
872 mojo::internal::FixedBufferForTesting buf(size); | |
873 auto* data = internal::ObjectUnion_Data::New(&buf); | |
874 SerializeUnion_(obj.get(), &buf, &data); | |
875 | |
876 std::vector<Handle> handles; | |
877 data->EncodePointersAndHandles(&handles); | |
878 data->DecodePointersAndHandles(&handles); | |
879 | |
880 ObjectUnionPtr obj2 = ObjectUnion::New(); | |
881 Deserialize_(data, obj2.get()); | |
882 | |
883 EXPECT_EQ(8, obj2->get_f_array_int8()[0]); | |
884 EXPECT_EQ(9, obj2->get_f_array_int8()[1]); | |
885 } | |
886 | |
887 TEST(UnionTest, ArrayInUnionValidation) { | |
888 auto array = Array<int8_t>::New(2); | |
889 array[0] = 8; | |
890 array[1] = 9; | |
891 | |
892 ObjectUnionPtr obj(ObjectUnion::New()); | |
893 obj->set_f_array_int8(array.Pass()); | |
894 | |
895 size_t size = GetSerializedSize_(obj); | |
896 mojo::internal::FixedBufferForTesting buf(size); | |
897 auto* data = internal::ObjectUnion_Data::New(&buf); | |
898 SerializeUnion_(obj.get(), &buf, &data); | |
899 | |
900 std::vector<Handle> handles; | |
901 data->EncodePointersAndHandles(&handles); | |
902 EXPECT_TRUE(handles.empty()); | |
903 | |
904 void* raw_buf = buf.Leak(); | |
905 mojo::internal::BoundsChecker bounds_checker(data, | |
906 static_cast<uint32_t>(size), 0); | |
907 | |
908 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
909 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
910 false, nullptr)); | |
911 free(raw_buf); | |
912 } | |
913 | |
914 TEST(UnionTest, MapInUnionGetterSetter) { | |
915 Map<String, int8_t> map; | |
916 map.insert("one", 1); | |
917 map.insert("two", 2); | |
918 | |
919 ObjectUnionPtr obj(ObjectUnion::New()); | |
920 obj->set_f_map_int8(map.Pass()); | |
921 | |
922 EXPECT_EQ(1, obj->get_f_map_int8()["one"]); | |
923 EXPECT_EQ(2, obj->get_f_map_int8()["two"]); | |
924 } | |
925 | |
926 TEST(UnionTest, MapInUnionSerialization) { | |
927 Map<String, int8_t> map; | |
928 map.insert("one", 1); | |
929 map.insert("two", 2); | |
930 | |
931 ObjectUnionPtr obj(ObjectUnion::New()); | |
932 obj->set_f_map_int8(map.Pass()); | |
933 | |
934 size_t size = GetSerializedSize_(obj); | |
935 EXPECT_EQ(112U, size); | |
936 | |
937 mojo::internal::FixedBufferForTesting buf(size); | |
938 auto* data = internal::ObjectUnion_Data::New(&buf); | |
939 SerializeUnion_(obj.get(), &buf, &data); | |
940 | |
941 std::vector<Handle> handles; | |
942 data->EncodePointersAndHandles(&handles); | |
943 data->DecodePointersAndHandles(&handles); | |
944 | |
945 ObjectUnionPtr obj2 = ObjectUnion::New(); | |
946 Deserialize_(data, obj2.get()); | |
947 | |
948 EXPECT_EQ(1, obj2->get_f_map_int8()["one"]); | |
949 EXPECT_EQ(2, obj2->get_f_map_int8()["two"]); | |
950 } | |
951 | |
952 TEST(UnionTest, MapInUnionValidation) { | |
953 Map<String, int8_t> map; | |
954 map.insert("one", 1); | |
955 map.insert("two", 2); | |
956 | |
957 ObjectUnionPtr obj(ObjectUnion::New()); | |
958 obj->set_f_map_int8(map.Pass()); | |
959 | |
960 size_t size = GetSerializedSize_(obj); | |
961 EXPECT_EQ(112U, size); | |
962 | |
963 mojo::internal::FixedBufferForTesting buf(size); | |
964 auto* data = internal::ObjectUnion_Data::New(&buf); | |
965 SerializeUnion_(obj.get(), &buf, &data); | |
966 | |
967 std::vector<Handle> handles; | |
968 data->EncodePointersAndHandles(&handles); | |
969 EXPECT_TRUE(handles.empty()); | |
970 | |
971 void* raw_buf = buf.Leak(); | |
972 mojo::internal::BoundsChecker bounds_checker(data, | |
973 static_cast<uint32_t>(size), 0); | |
974 | |
975 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
976 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
977 false, nullptr)); | |
978 free(raw_buf); | |
979 } | |
980 | |
981 TEST(UnionTest, UnionInUnionGetterSetter) { | |
982 PodUnionPtr pod(PodUnion::New()); | |
983 pod->set_f_int8(10); | |
984 | |
985 ObjectUnionPtr obj(ObjectUnion::New()); | |
986 obj->set_f_pod_union(pod.Pass()); | |
987 | |
988 EXPECT_EQ(10, obj->get_f_pod_union()->get_f_int8()); | |
989 } | |
990 | |
991 TEST(UnionTest, UnionInUnionSerialization) { | |
992 PodUnionPtr pod(PodUnion::New()); | |
993 pod->set_f_int8(10); | |
994 | |
995 ObjectUnionPtr obj(ObjectUnion::New()); | |
996 obj->set_f_pod_union(pod.Pass()); | |
997 | |
998 size_t size = GetSerializedSize_(obj); | |
999 EXPECT_EQ(32U, size); | |
1000 | |
1001 mojo::internal::FixedBufferForTesting buf(size); | |
1002 auto* data = internal::ObjectUnion_Data::New(&buf); | |
1003 SerializeUnion_(obj.get(), &buf, &data); | |
1004 | |
1005 std::vector<Handle> handles; | |
1006 data->EncodePointersAndHandles(&handles); | |
1007 data->DecodePointersAndHandles(&handles); | |
1008 | |
1009 ObjectUnionPtr obj2 = ObjectUnion::New(); | |
1010 Deserialize_(data, obj2.get()); | |
1011 EXPECT_EQ(10, obj2->get_f_pod_union()->get_f_int8()); | |
1012 } | |
1013 | |
1014 TEST(UnionTest, UnionInUnionValidation) { | |
1015 PodUnionPtr pod(PodUnion::New()); | |
1016 pod->set_f_int8(10); | |
1017 | |
1018 ObjectUnionPtr obj(ObjectUnion::New()); | |
1019 obj->set_f_pod_union(pod.Pass()); | |
1020 | |
1021 size_t size = GetSerializedSize_(obj); | |
1022 EXPECT_EQ(32U, size); | |
1023 | |
1024 mojo::internal::FixedBufferForTesting buf(size); | |
1025 auto* data = internal::ObjectUnion_Data::New(&buf); | |
1026 SerializeUnion_(obj.get(), &buf, &data); | |
1027 | |
1028 std::vector<Handle> handles; | |
1029 data->EncodePointersAndHandles(&handles); | |
1030 | |
1031 void* raw_buf = buf.Leak(); | |
1032 mojo::internal::BoundsChecker bounds_checker(data, | |
1033 static_cast<uint32_t>(size), 0); | |
1034 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
1035 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
1036 false, nullptr)); | |
1037 free(raw_buf); | |
1038 } | |
1039 | |
1040 TEST(UnionTest, UnionInUnionValidationNonNullable) { | |
1041 PodUnionPtr pod(nullptr); | |
1042 | |
1043 ObjectUnionPtr obj(ObjectUnion::New()); | |
1044 obj->set_f_pod_union(pod.Pass()); | |
1045 | |
1046 size_t size = GetSerializedSize_(obj); | |
1047 | |
1048 mojo::internal::FixedBufferForTesting buf(size); | |
1049 auto* data = internal::ObjectUnion_Data::New(&buf); | |
1050 SerializeUnion_(obj.get(), &buf, &data); | |
1051 std::vector<Handle> handles; | |
1052 data->EncodePointersAndHandles(&handles); | |
1053 | |
1054 void* raw_buf = buf.Leak(); | |
1055 mojo::internal::BoundsChecker bounds_checker(data, | |
1056 static_cast<uint32_t>(size), 0); | |
1057 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
1058 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, | |
1059 false, nullptr)); | |
1060 free(raw_buf); | |
1061 } | |
1062 | |
1063 TEST(UnionTest, HandleInUnionGetterSetter) { | |
1064 ScopedMessagePipeHandle pipe0; | |
1065 ScopedMessagePipeHandle pipe1; | |
1066 | |
1067 CreateMessagePipe(nullptr, &pipe0, &pipe1); | |
1068 | |
1069 HandleUnionPtr handle(HandleUnion::New()); | |
1070 handle->set_f_message_pipe(pipe1.Pass()); | |
1071 | |
1072 std::string golden("hello world"); | |
1073 WriteTextMessage(pipe0.get(), golden); | |
1074 | |
1075 std::string actual; | |
1076 ReadTextMessage(handle->get_f_message_pipe().get(), &actual); | |
1077 | |
1078 EXPECT_EQ(golden, actual); | |
1079 } | |
1080 | |
1081 TEST(UnionTest, HandleInUnionSerialization) { | |
1082 ScopedMessagePipeHandle pipe0; | |
1083 ScopedMessagePipeHandle pipe1; | |
1084 | |
1085 CreateMessagePipe(nullptr, &pipe0, &pipe1); | |
1086 | |
1087 HandleUnionPtr handle(HandleUnion::New()); | |
1088 handle->set_f_message_pipe(pipe1.Pass()); | |
1089 | |
1090 size_t size = GetSerializedSize_(handle); | |
1091 EXPECT_EQ(16U, size); | |
1092 | |
1093 mojo::internal::FixedBufferForTesting buf(size); | |
1094 auto* data = internal::HandleUnion_Data::New(&buf); | |
1095 SerializeUnion_(handle.get(), &buf, &data); | |
1096 | |
1097 std::vector<Handle> handles; | |
1098 data->EncodePointersAndHandles(&handles); | |
1099 EXPECT_EQ(1U, handles.size()); | |
1100 data->DecodePointersAndHandles(&handles); | |
1101 | |
1102 HandleUnionPtr handle2(HandleUnion::New()); | |
1103 Deserialize_(data, handle2.get()); | |
1104 | |
1105 std::string golden("hello world"); | |
1106 WriteTextMessage(pipe0.get(), golden); | |
1107 | |
1108 std::string actual; | |
1109 ReadTextMessage(handle2->get_f_message_pipe().get(), &actual); | |
1110 | |
1111 EXPECT_EQ(golden, actual); | |
1112 } | |
1113 | |
1114 TEST(UnionTest, HandleInUnionValidation) { | |
1115 ScopedMessagePipeHandle pipe0; | |
1116 ScopedMessagePipeHandle pipe1; | |
1117 | |
1118 CreateMessagePipe(nullptr, &pipe0, &pipe1); | |
1119 | |
1120 HandleUnionPtr handle(HandleUnion::New()); | |
1121 handle->set_f_message_pipe(pipe1.Pass()); | |
1122 | |
1123 size_t size = GetSerializedSize_(handle); | |
1124 EXPECT_EQ(16U, size); | |
1125 | |
1126 mojo::internal::FixedBufferForTesting buf(size); | |
1127 auto* data = internal::HandleUnion_Data::New(&buf); | |
1128 SerializeUnion_(handle.get(), &buf, &data); | |
1129 | |
1130 std::vector<Handle> handles; | |
1131 data->EncodePointersAndHandles(&handles); | |
1132 | |
1133 void* raw_buf = buf.Leak(); | |
1134 mojo::internal::BoundsChecker bounds_checker(data, | |
1135 static_cast<uint32_t>(size), 1); | |
1136 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
1137 internal::HandleUnion_Data::Validate(raw_buf, &bounds_checker, | |
1138 false, nullptr)); | |
1139 free(raw_buf); | |
1140 } | |
1141 | |
1142 TEST(UnionTest, HandleInUnionValidationNull) { | |
1143 ScopedMessagePipeHandle pipe; | |
1144 HandleUnionPtr handle(HandleUnion::New()); | |
1145 handle->set_f_message_pipe(pipe.Pass()); | |
1146 | |
1147 size_t size = GetSerializedSize_(handle); | |
1148 EXPECT_EQ(16U, size); | |
1149 | |
1150 mojo::internal::FixedBufferForTesting buf(size); | |
1151 auto* data = internal::HandleUnion_Data::New(&buf); | |
1152 SerializeUnion_(handle.get(), &buf, &data); | |
1153 | |
1154 std::vector<Handle> handles; | |
1155 data->EncodePointersAndHandles(&handles); | |
1156 | |
1157 void* raw_buf = buf.Leak(); | |
1158 mojo::internal::BoundsChecker bounds_checker(data, | |
1159 static_cast<uint32_t>(size), 1); | |
1160 EXPECT_NE(mojo::internal::ValidationError::NONE, | |
1161 internal::HandleUnion_Data::Validate(raw_buf, &bounds_checker, | |
1162 false, nullptr)); | |
1163 free(raw_buf); | |
1164 } | |
1165 | |
1166 class SmallCacheImpl : public SmallCache { | |
1167 public: | |
1168 SmallCacheImpl() : int_value_(0) {} | |
1169 ~SmallCacheImpl() override {} | |
1170 int64_t int_value() const { return int_value_; } | |
1171 | |
1172 private: | |
1173 void SetIntValue(int64_t int_value) override { int_value_ = int_value; } | |
1174 void GetIntValue(const GetIntValueCallback& callback) override { | |
1175 callback.Run(int_value_); | |
1176 } | |
1177 | |
1178 int64_t int_value_; | |
1179 }; | |
1180 | |
1181 TEST(UnionTest, InterfaceInUnion) { | |
1182 RunLoop run_loop; | |
1183 SmallCacheImpl impl; | |
1184 SmallCachePtr ptr; | |
1185 Binding<SmallCache> bindings(&impl, GetProxy(&ptr)); | |
1186 | |
1187 HandleUnionPtr handle(HandleUnion::New()); | |
1188 handle->set_f_small_cache(ptr.Pass()); | |
1189 | |
1190 auto small_cache = | |
1191 SmallCachePtr::Create(std::move(handle->get_f_small_cache())); | |
1192 small_cache->SetIntValue(10); | |
1193 run_loop.RunUntilIdle(); | |
1194 EXPECT_EQ(10, impl.int_value()); | |
1195 } | |
1196 | |
1197 TEST(UnionTest, InterfaceInUnionSerialization) { | |
1198 RunLoop run_loop; | |
1199 SmallCacheImpl impl; | |
1200 SmallCachePtr ptr; | |
1201 Binding<SmallCache> bindings(&impl, GetProxy(&ptr)); | |
1202 | |
1203 HandleUnionPtr handle(HandleUnion::New()); | |
1204 handle->set_f_small_cache(ptr.Pass()); | |
1205 size_t size = GetSerializedSize_(handle); | |
1206 EXPECT_EQ(16U, size); | |
1207 | |
1208 mojo::internal::FixedBufferForTesting buf(size); | |
1209 auto* data = internal::HandleUnion_Data::New(&buf); | |
1210 SerializeUnion_(handle.get(), &buf, &data); | |
1211 | |
1212 std::vector<Handle> handles; | |
1213 data->EncodePointersAndHandles(&handles); | |
1214 EXPECT_EQ(1U, handles.size()); | |
1215 data->DecodePointersAndHandles(&handles); | |
1216 | |
1217 HandleUnionPtr handle2(HandleUnion::New()); | |
1218 Deserialize_(data, handle2.get()); | |
1219 | |
1220 auto small_cache = | |
1221 SmallCachePtr::Create(std::move(handle2->get_f_small_cache())); | |
1222 small_cache->SetIntValue(10); | |
1223 run_loop.RunUntilIdle(); | |
1224 EXPECT_EQ(10, impl.int_value()); | |
1225 } | |
1226 | |
1227 class UnionInterfaceImpl : public UnionInterface { | |
1228 public: | |
1229 UnionInterfaceImpl() {} | |
1230 ~UnionInterfaceImpl() override {} | |
1231 | |
1232 private: | |
1233 void Echo(PodUnionPtr in, const EchoCallback& callback) override { | |
1234 callback.Run(in.Pass()); | |
1235 } | |
1236 }; | |
1237 | |
1238 TEST(UnionTest, UnionInInterface) { | |
1239 RunLoop run_loop; | |
1240 UnionInterfaceImpl impl; | |
1241 UnionInterfacePtr ptr; | |
1242 Binding<UnionInterface> bindings(&impl, GetProxy(&ptr)); | |
1243 | |
1244 PodUnionPtr pod(PodUnion::New()); | |
1245 pod->set_f_int16(16); | |
1246 | |
1247 ptr->Echo(pod.Pass(), | |
1248 [](PodUnionPtr out) { EXPECT_EQ(16, out->get_f_int16()); }); | |
1249 run_loop.RunUntilIdle(); | |
1250 } | |
1251 | |
1252 } // namespace test | |
1253 } // namespace mojo | |
OLD | NEW |