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 <string.h> | |
6 | |
7 #include <type_traits> | |
8 | |
9 #include "gtest/gtest.h" | |
10 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" | |
11 #include "mojo/public/cpp/bindings/lib/validation_errors.h" | |
12 #include "mojo/public/cpp/system/message_pipe.h" | |
13 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" | |
14 | |
15 namespace mojo { | |
16 namespace test { | |
17 namespace { | |
18 | |
19 static_assert(std::is_same<std::underlying_type<ScopedConstants::EType>::type, | |
20 int32_t>::value, | |
21 "The underlying type of mojom generated enums must be int32_t."); | |
22 | |
23 RectPtr MakeRect(int32_t factor = 1) { | |
24 RectPtr rect(Rect::New()); | |
25 rect->x = 1 * factor; | |
26 rect->y = 2 * factor; | |
27 rect->width = 10 * factor; | |
28 rect->height = 20 * factor; | |
29 return rect; | |
30 } | |
31 | |
32 void CheckRect(const Rect& rect, int32_t factor = 1) { | |
33 EXPECT_EQ(1 * factor, rect.x); | |
34 EXPECT_EQ(2 * factor, rect.y); | |
35 EXPECT_EQ(10 * factor, rect.width); | |
36 EXPECT_EQ(20 * factor, rect.height); | |
37 } | |
38 | |
39 MultiVersionStructPtr MakeMultiVersionStruct() { | |
40 MultiVersionStructPtr output(MultiVersionStruct::New()); | |
41 output->f_int32 = 123; | |
42 output->f_rect = MakeRect(5); | |
43 output->f_string = "hello"; | |
44 output->f_array = Array<int8_t>::New(3); | |
45 output->f_array[0] = 10; | |
46 output->f_array[1] = 9; | |
47 output->f_array[2] = 8; | |
48 MessagePipe pipe; | |
49 output->f_message_pipe = pipe.handle0.Pass(); | |
50 output->f_int16 = 42; | |
51 | |
52 return output; | |
53 } | |
54 | |
55 template <typename U, typename T> | |
56 U SerializeAndDeserialize(T input) { | |
57 typedef typename mojo::internal::WrapperTraits<T>::DataType InputDataType; | |
58 typedef typename mojo::internal::WrapperTraits<U>::DataType OutputDataType; | |
59 | |
60 size_t size = GetSerializedSize_(*input); | |
61 mojo::internal::FixedBufferForTesting buf(size + 32); | |
62 InputDataType data; | |
63 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
64 Serialize_(input.get(), &buf, &data)); | |
65 | |
66 std::vector<Handle> handles; | |
67 data->EncodePointersAndHandles(&handles); | |
68 | |
69 // Set the subsequent area to a special value, so that we can find out if we | |
70 // mistakenly access the area. | |
71 void* subsequent_area = buf.Allocate(32); | |
72 memset(subsequent_area, 0xAA, 32); | |
73 | |
74 OutputDataType output_data = reinterpret_cast<OutputDataType>(data); | |
75 output_data->DecodePointersAndHandles(&handles); | |
76 | |
77 using RawUType = typename mojo::internal::RemoveStructPtr<U>::type; | |
78 U output(RawUType::New()); | |
79 Deserialize_(output_data, output.get()); | |
80 return output; | |
81 } | |
82 | |
83 } // namespace | |
84 | |
85 TEST(StructTest, Rect) { | |
86 RectPtr rect; | |
87 EXPECT_FALSE(rect); | |
88 EXPECT_TRUE(rect.is_null()); | |
89 EXPECT_TRUE(!rect); | |
90 EXPECT_FALSE(rect); | |
91 | |
92 rect = nullptr; | |
93 EXPECT_FALSE(rect); | |
94 EXPECT_TRUE(rect.is_null()); | |
95 EXPECT_TRUE(!rect); | |
96 EXPECT_FALSE(rect); | |
97 | |
98 rect = MakeRect(); | |
99 EXPECT_TRUE(rect); | |
100 EXPECT_FALSE(rect.is_null()); | |
101 EXPECT_FALSE(!rect); | |
102 EXPECT_TRUE(rect); | |
103 | |
104 RectPtr null_rect = nullptr; | |
105 EXPECT_FALSE(null_rect); | |
106 EXPECT_TRUE(null_rect.is_null()); | |
107 EXPECT_TRUE(!null_rect); | |
108 EXPECT_FALSE(null_rect); | |
109 | |
110 CheckRect(*rect); | |
111 } | |
112 | |
113 TEST(StructTest, Clone) { | |
114 NamedRegionPtr region; | |
115 | |
116 NamedRegionPtr clone_region = region.Clone(); | |
117 EXPECT_TRUE(clone_region.is_null()); | |
118 | |
119 region = NamedRegion::New(); | |
120 clone_region = region.Clone(); | |
121 EXPECT_TRUE(clone_region->name.is_null()); | |
122 EXPECT_TRUE(clone_region->rects.is_null()); | |
123 | |
124 region->name = "hello world"; | |
125 clone_region = region.Clone(); | |
126 EXPECT_EQ(region->name, clone_region->name); | |
127 | |
128 region->rects = Array<RectPtr>::New(2); | |
129 region->rects[1] = MakeRect(); | |
130 clone_region = region.Clone(); | |
131 EXPECT_EQ(2u, clone_region->rects.size()); | |
132 EXPECT_TRUE(clone_region->rects[0].is_null()); | |
133 CheckRect(*clone_region->rects[1]); | |
134 | |
135 // NoDefaultFieldValues contains handles, so Clone() is not available, but | |
136 // NoDefaultFieldValuesPtr should still compile. | |
137 NoDefaultFieldValuesPtr no_default_field_values(NoDefaultFieldValues::New()); | |
138 EXPECT_FALSE(no_default_field_values->f13.is_valid()); | |
139 } | |
140 | |
141 // Serialization test of a struct with no pointer or handle members. | |
142 TEST(StructTest, Serialization_Basic) { | |
143 RectPtr rect(MakeRect()); | |
144 | |
145 size_t size = GetSerializedSize_(*rect); | |
146 EXPECT_EQ(8U + 16U, size); | |
147 | |
148 mojo::internal::FixedBufferForTesting buf(size); | |
149 internal::Rect_Data* data; | |
150 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
151 Serialize_(rect.get(), &buf, &data)); | |
152 | |
153 RectPtr rect2(Rect::New()); | |
154 Deserialize_(data, rect2.get()); | |
155 | |
156 CheckRect(*rect2); | |
157 } | |
158 | |
159 // Construction of a struct with struct pointers from null. | |
160 TEST(StructTest, Construction_StructPointers) { | |
161 RectPairPtr pair; | |
162 EXPECT_TRUE(pair.is_null()); | |
163 | |
164 pair = RectPair::New(); | |
165 EXPECT_FALSE(pair.is_null()); | |
166 EXPECT_TRUE(pair->first.is_null()); | |
167 EXPECT_TRUE(pair->first.is_null()); | |
168 | |
169 pair = nullptr; | |
170 EXPECT_TRUE(pair.is_null()); | |
171 } | |
172 | |
173 // Serialization test of a struct with struct pointers. | |
174 TEST(StructTest, Serialization_StructPointers) { | |
175 RectPairPtr pair(RectPair::New()); | |
176 pair->first = MakeRect(); | |
177 pair->second = MakeRect(); | |
178 | |
179 size_t size = GetSerializedSize_(*pair); | |
180 EXPECT_EQ(8U + 16U + 2 * (8U + 16U), size); | |
181 | |
182 mojo::internal::FixedBufferForTesting buf(size); | |
183 internal::RectPair_Data* data; | |
184 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
185 Serialize_(pair.get(), &buf, &data)); | |
186 | |
187 RectPairPtr pair2(RectPair::New()); | |
188 Deserialize_(data, pair2.get()); | |
189 | |
190 CheckRect(*pair2->first); | |
191 CheckRect(*pair2->second); | |
192 } | |
193 | |
194 // Serialization test of a struct with an array member. | |
195 TEST(StructTest, Serialization_ArrayPointers) { | |
196 NamedRegionPtr region(NamedRegion::New()); | |
197 region->name = "region"; | |
198 region->rects = Array<RectPtr>::New(4); | |
199 for (size_t i = 0; i < region->rects.size(); ++i) | |
200 region->rects[i] = MakeRect(static_cast<int32_t>(i) + 1); | |
201 | |
202 size_t size = GetSerializedSize_(*region); | |
203 EXPECT_EQ(8U + // header | |
204 8U + // name pointer | |
205 8U + // rects pointer | |
206 8U + // name header | |
207 8U + // name payload (rounded up) | |
208 8U + // rects header | |
209 4 * 8U + // rects payload (four pointers) | |
210 4 * (8U + // rect header | |
211 16U), // rect payload (four ints) | |
212 size); | |
213 | |
214 mojo::internal::FixedBufferForTesting buf(size); | |
215 internal::NamedRegion_Data* data; | |
216 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
217 Serialize_(region.get(), &buf, &data)); | |
218 | |
219 NamedRegionPtr region2(NamedRegion::New()); | |
220 Deserialize_(data, region2.get()); | |
221 | |
222 EXPECT_EQ(String("region"), region2->name); | |
223 | |
224 EXPECT_EQ(4U, region2->rects.size()); | |
225 for (size_t i = 0; i < region2->rects.size(); ++i) | |
226 CheckRect(*region2->rects[i], static_cast<int32_t>(i) + 1); | |
227 } | |
228 | |
229 // Serialization test of a struct with null array pointers. | |
230 TEST(StructTest, Serialization_NullArrayPointers) { | |
231 NamedRegionPtr region(NamedRegion::New()); | |
232 EXPECT_TRUE(region->name.is_null()); | |
233 EXPECT_TRUE(region->rects.is_null()); | |
234 | |
235 size_t size = GetSerializedSize_(*region); | |
236 EXPECT_EQ(8U + // header | |
237 8U + // name pointer | |
238 8U, // rects pointer | |
239 size); | |
240 | |
241 mojo::internal::FixedBufferForTesting buf(size); | |
242 internal::NamedRegion_Data* data; | |
243 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
244 Serialize_(region.get(), &buf, &data)); | |
245 | |
246 NamedRegionPtr region2(NamedRegion::New()); | |
247 Deserialize_(data, region2.get()); | |
248 | |
249 EXPECT_TRUE(region2->name.is_null()); | |
250 EXPECT_TRUE(region2->rects.is_null()); | |
251 } | |
252 | |
253 TEST(StructTest, Serialization_InterfaceRequest) { | |
254 ContainsInterfaceRequest iface_req_struct; | |
255 | |
256 auto size = GetSerializedSize_(iface_req_struct); | |
257 EXPECT_EQ(8U // struct header | |
258 + 4U // interface request handle | |
259 + 4U, // interface request nullable handle | |
260 size); | |
261 | |
262 mojo::internal::FixedBufferForTesting buf(size * 2); | |
263 ContainsInterfaceRequest::Data_* data; | |
264 | |
265 // Test failure when non-nullable interface request is null. | |
266 EXPECT_EQ(mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE, | |
267 Serialize_(&iface_req_struct, &buf, &data)); | |
268 | |
269 SomeInterfacePtr i_ptr; | |
270 iface_req_struct.req = GetProxy(&i_ptr); | |
271 EXPECT_TRUE(iface_req_struct.req.is_pending()); | |
272 | |
273 EXPECT_EQ(mojo::internal::ValidationError::NONE, | |
274 Serialize_(&iface_req_struct, &buf, &data)); | |
275 EXPECT_FALSE(iface_req_struct.req.is_pending()); | |
276 | |
277 Deserialize_(data, &iface_req_struct); | |
278 EXPECT_TRUE(iface_req_struct.req.is_pending()); | |
279 } | |
280 | |
281 // Tests deserializing structs as a newer version. | |
282 TEST(StructTest, Versioning_OldToNew) { | |
283 { | |
284 MultiVersionStructV0Ptr input(MultiVersionStructV0::New()); | |
285 input->f_int32 = 123; | |
286 MultiVersionStructPtr expected_output(MultiVersionStruct::New()); | |
287 expected_output->f_int32 = 123; | |
288 | |
289 MultiVersionStructPtr output = | |
290 SerializeAndDeserialize<MultiVersionStructPtr>(input.Pass()); | |
291 EXPECT_TRUE(output); | |
292 EXPECT_TRUE(output->Equals(*expected_output)); | |
293 } | |
294 | |
295 { | |
296 MultiVersionStructV1Ptr input(MultiVersionStructV1::New()); | |
297 input->f_int32 = 123; | |
298 input->f_rect = MakeRect(5); | |
299 MultiVersionStructPtr expected_output(MultiVersionStruct::New()); | |
300 expected_output->f_int32 = 123; | |
301 expected_output->f_rect = MakeRect(5); | |
302 | |
303 MultiVersionStructPtr output = | |
304 SerializeAndDeserialize<MultiVersionStructPtr>(input.Pass()); | |
305 EXPECT_TRUE(output); | |
306 EXPECT_TRUE(output->Equals(*expected_output)); | |
307 } | |
308 | |
309 { | |
310 MultiVersionStructV3Ptr input(MultiVersionStructV3::New()); | |
311 input->f_int32 = 123; | |
312 input->f_rect = MakeRect(5); | |
313 input->f_string = "hello"; | |
314 MultiVersionStructPtr expected_output(MultiVersionStruct::New()); | |
315 expected_output->f_int32 = 123; | |
316 expected_output->f_rect = MakeRect(5); | |
317 expected_output->f_string = "hello"; | |
318 | |
319 MultiVersionStructPtr output = | |
320 SerializeAndDeserialize<MultiVersionStructPtr>(input.Pass()); | |
321 EXPECT_TRUE(output); | |
322 EXPECT_TRUE(output->Equals(*expected_output)); | |
323 } | |
324 | |
325 { | |
326 MultiVersionStructV5Ptr input(MultiVersionStructV5::New()); | |
327 input->f_int32 = 123; | |
328 input->f_rect = MakeRect(5); | |
329 input->f_string = "hello"; | |
330 input->f_array = Array<int8_t>::New(3); | |
331 input->f_array[0] = 10; | |
332 input->f_array[1] = 9; | |
333 input->f_array[2] = 8; | |
334 MultiVersionStructPtr expected_output(MultiVersionStruct::New()); | |
335 expected_output->f_int32 = 123; | |
336 expected_output->f_rect = MakeRect(5); | |
337 expected_output->f_string = "hello"; | |
338 expected_output->f_array = Array<int8_t>::New(3); | |
339 expected_output->f_array[0] = 10; | |
340 expected_output->f_array[1] = 9; | |
341 expected_output->f_array[2] = 8; | |
342 | |
343 MultiVersionStructPtr output = | |
344 SerializeAndDeserialize<MultiVersionStructPtr>(input.Pass()); | |
345 EXPECT_TRUE(output); | |
346 EXPECT_TRUE(output->Equals(*expected_output)); | |
347 } | |
348 | |
349 { | |
350 MultiVersionStructV7Ptr input(MultiVersionStructV7::New()); | |
351 input->f_int32 = 123; | |
352 input->f_rect = MakeRect(5); | |
353 input->f_string = "hello"; | |
354 input->f_array = Array<int8_t>::New(3); | |
355 input->f_array[0] = 10; | |
356 input->f_array[1] = 9; | |
357 input->f_array[2] = 8; | |
358 MessagePipe pipe; | |
359 input->f_message_pipe = pipe.handle0.Pass(); | |
360 | |
361 MultiVersionStructPtr expected_output(MultiVersionStruct::New()); | |
362 expected_output->f_int32 = 123; | |
363 expected_output->f_rect = MakeRect(5); | |
364 expected_output->f_string = "hello"; | |
365 expected_output->f_array = Array<int8_t>::New(3); | |
366 expected_output->f_array[0] = 10; | |
367 expected_output->f_array[1] = 9; | |
368 expected_output->f_array[2] = 8; | |
369 // Save the raw handle value separately so that we can compare later. | |
370 MojoHandle expected_handle = input->f_message_pipe.get().value(); | |
371 | |
372 MultiVersionStructPtr output = | |
373 SerializeAndDeserialize<MultiVersionStructPtr>(input.Pass()); | |
374 EXPECT_TRUE(output); | |
375 EXPECT_EQ(expected_handle, output->f_message_pipe.get().value()); | |
376 output->f_message_pipe.reset(); | |
377 EXPECT_TRUE(output->Equals(*expected_output)); | |
378 } | |
379 } | |
380 | |
381 // Tests deserializing structs as an older version. | |
382 TEST(StructTest, Versioning_NewToOld) { | |
383 { | |
384 MultiVersionStructPtr input = MakeMultiVersionStruct(); | |
385 MultiVersionStructV7Ptr expected_output(MultiVersionStructV7::New()); | |
386 expected_output->f_int32 = 123; | |
387 expected_output->f_rect = MakeRect(5); | |
388 expected_output->f_string = "hello"; | |
389 expected_output->f_array = Array<int8_t>::New(3); | |
390 expected_output->f_array[0] = 10; | |
391 expected_output->f_array[1] = 9; | |
392 expected_output->f_array[2] = 8; | |
393 // Save the raw handle value separately so that we can compare later. | |
394 MojoHandle expected_handle = input->f_message_pipe.get().value(); | |
395 | |
396 MultiVersionStructV7Ptr output = | |
397 SerializeAndDeserialize<MultiVersionStructV7Ptr>(input.Pass()); | |
398 EXPECT_TRUE(output); | |
399 EXPECT_EQ(expected_handle, output->f_message_pipe.get().value()); | |
400 output->f_message_pipe.reset(); | |
401 EXPECT_TRUE(output->Equals(*expected_output)); | |
402 } | |
403 | |
404 { | |
405 MultiVersionStructPtr input = MakeMultiVersionStruct(); | |
406 MultiVersionStructV5Ptr expected_output(MultiVersionStructV5::New()); | |
407 expected_output->f_int32 = 123; | |
408 expected_output->f_rect = MakeRect(5); | |
409 expected_output->f_string = "hello"; | |
410 expected_output->f_array = Array<int8_t>::New(3); | |
411 expected_output->f_array[0] = 10; | |
412 expected_output->f_array[1] = 9; | |
413 expected_output->f_array[2] = 8; | |
414 | |
415 MultiVersionStructV5Ptr output = | |
416 SerializeAndDeserialize<MultiVersionStructV5Ptr>(input.Pass()); | |
417 EXPECT_TRUE(output); | |
418 EXPECT_TRUE(output->Equals(*expected_output)); | |
419 } | |
420 | |
421 { | |
422 MultiVersionStructPtr input = MakeMultiVersionStruct(); | |
423 MultiVersionStructV3Ptr expected_output(MultiVersionStructV3::New()); | |
424 expected_output->f_int32 = 123; | |
425 expected_output->f_rect = MakeRect(5); | |
426 expected_output->f_string = "hello"; | |
427 | |
428 MultiVersionStructV3Ptr output = | |
429 SerializeAndDeserialize<MultiVersionStructV3Ptr>(input.Pass()); | |
430 EXPECT_TRUE(output); | |
431 EXPECT_TRUE(output->Equals(*expected_output)); | |
432 } | |
433 | |
434 { | |
435 MultiVersionStructPtr input = MakeMultiVersionStruct(); | |
436 MultiVersionStructV1Ptr expected_output(MultiVersionStructV1::New()); | |
437 expected_output->f_int32 = 123; | |
438 expected_output->f_rect = MakeRect(5); | |
439 | |
440 MultiVersionStructV1Ptr output = | |
441 SerializeAndDeserialize<MultiVersionStructV1Ptr>(input.Pass()); | |
442 EXPECT_TRUE(output); | |
443 EXPECT_TRUE(output->Equals(*expected_output)); | |
444 } | |
445 | |
446 { | |
447 MultiVersionStructPtr input = MakeMultiVersionStruct(); | |
448 MultiVersionStructV0Ptr expected_output(MultiVersionStructV0::New()); | |
449 expected_output->f_int32 = 123; | |
450 | |
451 MultiVersionStructV0Ptr output = | |
452 SerializeAndDeserialize<MultiVersionStructV0Ptr>(input.Pass()); | |
453 EXPECT_TRUE(output); | |
454 EXPECT_TRUE(output->Equals(*expected_output)); | |
455 } | |
456 } | |
457 | |
458 } // namespace test | |
459 } // namespace mojo | |
OLD | NEW |