| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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 // TODO(vardhan): Needs a lot more testing. | |
| 6 | |
| 7 #include <mojo/bindings/union.h> | |
| 8 | |
| 9 #include <mojo/bindings/array.h> | |
| 10 | |
| 11 #include "mojo/public/c/bindings/tests/testing_util.h" | |
| 12 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom-c.h" | |
| 13 #include "mojo/public/interfaces/bindings/tests/test_unions.mojom-c.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 struct mojo_test_StructOfUnionOfReferences* MakeStructOfUnionReference( | |
| 19 struct MojomBuffer* buf) { | |
| 20 auto* struct_with_union = | |
| 21 static_cast<struct mojo_test_StructOfUnionOfReferences*>( | |
| 22 MojomBuffer_Allocate( | |
| 23 buf, sizeof(struct mojo_test_StructOfUnionOfReferences))); | |
| 24 | |
| 25 *struct_with_union = mojo_test_StructOfUnionOfReferences{ | |
| 26 // header | |
| 27 { | |
| 28 sizeof(struct mojo_test_StructOfUnionOfReferences), 0, | |
| 29 }, | |
| 30 { | |
| 31 0u, mojo_test_UnionOfReferences_Tag__UNKNOWN__, {}, | |
| 32 } // null | |
| 33 }; | |
| 34 return struct_with_union; | |
| 35 } | |
| 36 | |
| 37 // Test serialization when a union points to a union. | |
| 38 TEST(UnionSerializationTest, UnionOfUnion) { | |
| 39 char buffer_bytes[1000] = {0}; | |
| 40 struct MojomBuffer buf = {buffer_bytes, sizeof(buffer_bytes), 0}; | |
| 41 struct mojo_test_StructOfUnionOfReferences* struct_with_union = | |
| 42 MakeStructOfUnionReference(&buf); | |
| 43 | |
| 44 EXPECT_EQ(8u + 1 * 16u, // 1 union type (set to null) | |
| 45 mojo_test_StructOfUnionOfReferences_ComputeSerializedSize( | |
| 46 struct_with_union)); | |
| 47 | |
| 48 struct_with_union->u.size = 16u; | |
| 49 EXPECT_EQ(8u + 1 * 16u, // 1 union type (not null, but unknown) | |
| 50 mojo_test_StructOfUnionOfReferences_ComputeSerializedSize( | |
| 51 struct_with_union)); | |
| 52 | |
| 53 // Test when a union points to a union. | |
| 54 struct mojo_test_PodUnion* pod_union = | |
| 55 static_cast<struct mojo_test_PodUnion*>( | |
| 56 MojomBuffer_Allocate(&buf, sizeof(struct mojo_test_PodUnion))); | |
| 57 *pod_union = mojo_test_PodUnion{ | |
| 58 16u, mojo_test_PodUnion_Tag_f_int8, {13}, | |
| 59 }; | |
| 60 struct_with_union->u.tag = mojo_test_UnionOfReferences_Tag_pod_union; | |
| 61 struct_with_union->u.data.f_pod_union.ptr = pod_union; | |
| 62 EXPECT_EQ(8u + 1 * 16u // 1 union type (set to PodUnion) | |
| 63 + 16u, // PodUnion is out of line. | |
| 64 mojo_test_StructOfUnionOfReferences_ComputeSerializedSize( | |
| 65 struct_with_union)); | |
| 66 | |
| 67 // We save the underlying (unencoded) buffer. We can compare the two after | |
| 68 // deserialization to make sure deserialization is correct. | |
| 69 char buffer_bytes_copy[sizeof(buffer_bytes)]; | |
| 70 memcpy(buffer_bytes_copy, buffer_bytes, sizeof(buffer_bytes_copy)); | |
| 71 | |
| 72 mojo_test_StructOfUnionOfReferences_EncodePointersAndHandles( | |
| 73 struct_with_union, buf.num_bytes_used, NULL); | |
| 74 | |
| 75 EXPECT_EQ(sizeof(struct mojo_test_StructOfUnionOfReferences) - | |
| 76 offsetof(struct mojo_test_StructOfUnionOfReferences, u.data), | |
| 77 struct_with_union->u.data.f_pod_union.offset); | |
| 78 | |
| 79 mojo_test_StructOfUnionOfReferences_DecodePointersAndHandles( | |
| 80 struct_with_union, buf.num_bytes_used, NULL, 0); | |
| 81 EXPECT_EQ(0, memcmp(buf.buf, buffer_bytes_copy, buf.num_bytes_used)); | |
| 82 | |
| 83 { | |
| 84 char buffer_bytes2[sizeof(buffer_bytes)] = {0}; | |
| 85 struct MojomBuffer buf2 = {buffer_bytes2, sizeof(buffer_bytes2), 0}; | |
| 86 CopyAndCompare( | |
| 87 &buf2, struct_with_union, buf.num_bytes_used, | |
| 88 mojo_test_StructOfUnionOfReferences_DeepCopy, | |
| 89 mojo_test_StructOfUnionOfReferences_EncodePointersAndHandles, | |
| 90 mojo_test_StructOfUnionOfReferences_DecodePointersAndHandles); | |
| 91 } | |
| 92 } | |
| 93 | |
| 94 // Test when a union points to a struct. | |
| 95 TEST(UnionSerializationTest, UnionOfStruct) { | |
| 96 char buffer_bytes[1000]; | |
| 97 MojomBuffer buf = {buffer_bytes, sizeof(buffer_bytes), 0}; | |
| 98 | |
| 99 struct mojo_test_StructOfUnionOfReferences* struct_with_union = | |
| 100 MakeStructOfUnionReference(&buf); | |
| 101 | |
| 102 struct mojo_test_DummyStruct* dummy_struct = | |
| 103 static_cast<struct mojo_test_DummyStruct*>( | |
| 104 MojomBuffer_Allocate(&buf, sizeof(struct mojo_test_DummyStruct))); | |
| 105 *dummy_struct = mojo_test_DummyStruct{ | |
| 106 // header | |
| 107 { | |
| 108 sizeof(struct mojo_test_DummyStruct), | |
| 109 0u // version | |
| 110 }, | |
| 111 13, // int8 | |
| 112 {}, // padding | |
| 113 }; | |
| 114 struct_with_union->u.size = 16u; | |
| 115 struct_with_union->u.tag = mojo_test_UnionOfReferences_Tag_dummy_struct; | |
| 116 struct_with_union->u.data.f_dummy_struct.ptr = dummy_struct; | |
| 117 | |
| 118 EXPECT_EQ(8u + 1 * 16u // 1 union type (set to DummyStruct) | |
| 119 + 16u, // DummyStruct is out of line. | |
| 120 mojo_test_StructOfUnionOfReferences_ComputeSerializedSize( | |
| 121 struct_with_union)); | |
| 122 | |
| 123 // We save the underlying (unencoded) buffer. We can compare the two after | |
| 124 // deserialization to make sure deserialization is correct. | |
| 125 char buffer_bytes_copy[sizeof(buffer_bytes)]; | |
| 126 memcpy(buffer_bytes_copy, buffer_bytes, sizeof(buffer_bytes_copy)); | |
| 127 | |
| 128 mojo_test_StructOfUnionOfReferences_EncodePointersAndHandles( | |
| 129 struct_with_union, buf.num_bytes_used, NULL); | |
| 130 | |
| 131 EXPECT_EQ(sizeof(struct mojo_test_StructOfUnionOfReferences) - | |
| 132 offsetof(struct mojo_test_StructOfUnionOfReferences, u.data), | |
| 133 struct_with_union->u.data.f_dummy_struct.offset); | |
| 134 | |
| 135 mojo_test_StructOfUnionOfReferences_DecodePointersAndHandles( | |
| 136 struct_with_union, buf.num_bytes_used, NULL, 0); | |
| 137 EXPECT_EQ(0, memcmp(buf.buf, buffer_bytes_copy, buf.num_bytes_used)); | |
| 138 | |
| 139 { | |
| 140 char buffer_bytes2[sizeof(buffer_bytes)] = {0}; | |
| 141 struct MojomBuffer buf2 = {buffer_bytes2, sizeof(buffer_bytes2), 0}; | |
| 142 CopyAndCompare( | |
| 143 &buf2, struct_with_union, buf.num_bytes_used, | |
| 144 mojo_test_StructOfUnionOfReferences_DeepCopy, | |
| 145 mojo_test_StructOfUnionOfReferences_EncodePointersAndHandles, | |
| 146 mojo_test_StructOfUnionOfReferences_DecodePointersAndHandles); | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 // Test when a union points to an array of int32 | |
| 151 TEST(UnionSerializationTest, UnionOfArray) { | |
| 152 char buffer_bytes[1000]; | |
| 153 MojomBuffer buf = {buffer_bytes, sizeof(buffer_bytes), 0}; | |
| 154 struct mojo_test_StructOfUnionOfReferences* struct_with_union = | |
| 155 MakeStructOfUnionReference(&buf); | |
| 156 | |
| 157 struct MojomArrayHeader* array_of_int32 = | |
| 158 MojomArray_New(&buf, 5, sizeof(int32_t)); | |
| 159 *MOJOM_ARRAY_INDEX(array_of_int32, int32_t, 0) = 13; | |
| 160 *MOJOM_ARRAY_INDEX(array_of_int32, int32_t, 1) = 13; | |
| 161 *MOJOM_ARRAY_INDEX(array_of_int32, int32_t, 2) = 13; | |
| 162 *MOJOM_ARRAY_INDEX(array_of_int32, int32_t, 3) = 13; | |
| 163 *MOJOM_ARRAY_INDEX(array_of_int32, int32_t, 4) = 13; | |
| 164 struct_with_union->u.size = 16u; | |
| 165 struct_with_union->u.tag = mojo_test_UnionOfReferences_Tag_int_array; | |
| 166 struct_with_union->u.data.f_int_array.ptr = array_of_int32; | |
| 167 | |
| 168 EXPECT_EQ(8u + 1 * 16u // 1 union type (set to int array) | |
| 169 + (8 + 4u * 5) // mojom array of 5 int32s | |
| 170 + 4u, // padding for the mojom array | |
| 171 mojo_test_StructOfUnionOfReferences_ComputeSerializedSize( | |
| 172 struct_with_union)); | |
| 173 | |
| 174 // We save the underlying (unencoded) buffer. We can compare the two after | |
| 175 // deserialization to make sure deserialization is correct. | |
| 176 char buffer_bytes_copy[sizeof(buffer_bytes)]; | |
| 177 memcpy(buffer_bytes_copy, buffer_bytes, sizeof(buffer_bytes_copy)); | |
| 178 | |
| 179 struct MojomHandleBuffer handle_buf = {NULL, 0u, 0u}; | |
| 180 mojo_test_StructOfUnionOfReferences_EncodePointersAndHandles( | |
| 181 struct_with_union, buf.num_bytes_used, &handle_buf); | |
| 182 EXPECT_EQ(0u, handle_buf.num_handles_used); | |
| 183 | |
| 184 EXPECT_EQ(sizeof(struct mojo_test_StructOfUnionOfReferences) - | |
| 185 offsetof(struct mojo_test_StructOfUnionOfReferences, u.data), | |
| 186 struct_with_union->u.data.f_int_array.offset); | |
| 187 | |
| 188 mojo_test_StructOfUnionOfReferences_DecodePointersAndHandles( | |
| 189 struct_with_union, buf.num_bytes_used, NULL, 0); | |
| 190 EXPECT_EQ(0, memcmp(buf.buf, buffer_bytes_copy, buf.num_bytes_used)); | |
| 191 | |
| 192 { | |
| 193 char buffer_bytes2[sizeof(buffer_bytes)] = {0}; | |
| 194 struct MojomBuffer buf2 = {buffer_bytes2, sizeof(buffer_bytes2), 0}; | |
| 195 CopyAndCompare( | |
| 196 &buf2, struct_with_union, buf.num_bytes_used, | |
| 197 mojo_test_StructOfUnionOfReferences_DeepCopy, | |
| 198 mojo_test_StructOfUnionOfReferences_EncodePointersAndHandles, | |
| 199 mojo_test_StructOfUnionOfReferences_DecodePointersAndHandles); | |
| 200 } | |
| 201 } | |
| 202 | |
| 203 } // namespace | |
| OLD | NEW |