Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: mojo/public/cpp/bindings/tests/serialization_api_unittest.cc

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 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 "gtest/gtest.h"
6 #include "mojo/public/cpp/bindings/array.h"
7 #include "mojo/public/cpp/bindings/lib/array_serialization.h"
8 #include "mojo/public/cpp/bindings/lib/validation_errors.h"
9 #include "mojo/public/cpp/system/message_pipe.h"
10 #include "mojo/public/interfaces/bindings/tests/rect.mojom.h"
11 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h"
12
13 namespace mojo {
14 namespace test {
15 namespace {
16
17 class StructSerializationAPITest : public testing::Test {
18 public:
19 // We Serialize and Deserialize the given |Type|, and expect the given
20 // serialization warnings. We also validate (and expect a given error) in
21 // between serialization and deserialization.
22 template <typename Type>
23 void SerializeAndDeserialize(
24 Type* val,
25 mojo::internal::ValidationError expected_validation_error) {
26 size_t bytes_written = 0;
27 size_t num_bytes = val->GetSerializedSize();
28 std::vector<uint8_t> bytes(num_bytes + 1);
29
30 // Last byte is a magic value, helps catch a buffer overflow for
31 // serialization.
32 bytes[num_bytes] = 170;
33 val->Serialize(bytes.data(), num_bytes, &bytes_written);
34 EXPECT_EQ(170u, bytes[num_bytes]);
35 EXPECT_EQ(num_bytes, bytes_written);
36
37 mojo::internal::BoundsChecker bounds_checker(bytes.data(), num_bytes, 0);
38 auto actual_validation_error =
39 Type::Data_::Validate(bytes.data(), &bounds_checker, nullptr);
40 EXPECT_EQ(expected_validation_error, actual_validation_error);
41
42 Type out_val;
43 bool deserialize_ret = out_val.Deserialize(bytes.data(), bytes.size());
44 if (actual_validation_error == mojo::internal::ValidationError::NONE) {
45 EXPECT_TRUE(val->Equals(out_val));
46 }
47 EXPECT_EQ(actual_validation_error == mojo::internal::ValidationError::NONE,
48 deserialize_ret);
49 }
50 };
51
52 TEST_F(StructSerializationAPITest, GetSerializedSize) {
53 Rect rect;
54 // 8 byte struct header
55 // + 16 bytes worth of fields
56 EXPECT_EQ(24u, rect.GetSerializedSize());
57
58 HandleStruct handle_struct;
59 // 8 byte struct header
60 // + 4 byte handle
61 // + 8 bytes for offset/pointer for Array.
62 // + 0 bytes for uninitialized Array.
63 // + 4-byte to make the struct 8-byte aligned.
64 EXPECT_EQ(24u, handle_struct.GetSerializedSize());
65
66 // + 8 bytes for initialized array, 0-sized array.
67 handle_struct.array_h = mojo::Array<mojo::ScopedMessagePipeHandle>::New(0);
68 EXPECT_EQ(32u, handle_struct.GetSerializedSize());
69
70 // + 4 bytes for array of size 1.
71 // + 4 more bytes to make the array serialization 8-byte aligned.
72 handle_struct.array_h = mojo::Array<mojo::ScopedMessagePipeHandle>::New(1);
73 EXPECT_EQ(16u, GetSerializedSize_(handle_struct.array_h));
74 EXPECT_EQ(40u, handle_struct.GetSerializedSize());
75 }
76
77 TEST_F(StructSerializationAPITest, BasicStructSerialization) {
78 {
79 SCOPED_TRACE("Rect");
80 Rect rect;
81 rect.x = 123;
82 rect.y = 456;
83 rect.width = 789;
84 rect.height = 999;
85 SerializeAndDeserialize(&rect, mojo::internal::ValidationError::NONE);
86 }
87
88 {
89 SCOPED_TRACE("DefaultFieldValues");
90 DefaultFieldValues default_values;
91 SerializeAndDeserialize(&default_values,
92 mojo::internal::ValidationError::NONE);
93 }
94
95 {
96 SCOPED_TRACE("NoDefaultFieldValues.Serialize() should fail");
97 NoDefaultFieldValues nd;
98 nd.f0 = true;
99 nd.f23 = mojo::Array<mojo::String>::New(10);
100
101 char buf[1000] = {};
102 EXPECT_FALSE(nd.Serialize(buf, sizeof(buf)));
103
104 size_t bytes_written = 0;
105 EXPECT_FALSE(nd.Serialize(buf, sizeof(buf), &bytes_written));
106 EXPECT_EQ(160UL, bytes_written);
107 // The Serialize() shouldn't get around to reserving space for the |f23|
108 // array field.
109 EXPECT_LT(bytes_written, nd.GetSerializedSize());
110 }
111 }
112
113 // This tests serialization of handles -- These should be deaths or
114 TEST_F(StructSerializationAPITest, HandlesSerialization) {
115 {
116 SCOPED_TRACE("Uninitialized Array");
117 HandleStruct handle_struct;
118 // TODO(vardhan): Once handles and pointers are encoded inline with
119 // serialization, validation should fail at
120 // ValidationError::UNEXPECTED_NULL_POINTER (which happens after the
121 // ValidationError::ILLEGAL_HANDLE error, which shouldn't happen since
122 // handles will be encoded even on failures).
123 SerializeAndDeserialize(&handle_struct,
124 mojo::internal::ValidationError::ILLEGAL_HANDLE);
125 }
126
127 {
128 SCOPED_TRACE("Uninitialized required Handle in an Array");
129 HandleStruct handle_struct;
130 handle_struct.array_h = Array<mojo::ScopedMessagePipeHandle>::New(1);
131 // This won't die (i.e., we don't need to EXPECT_DEATH) because the handle
132 // is invalid, so should be serializable. Instead, we live with a
133 // serialization error for an invalid handle.
134 // TODO(vardhan): This should be
135 // mojo::internal::ValidationError::UNEXPECTED_INVALID_HANDLE after handles
136 // are encoded inline with serialization.
137 SerializeAndDeserialize(&handle_struct,
138 mojo::internal::ValidationError::ILLEGAL_HANDLE);
139 }
140
141 // We shouldn't be able to serialize a valid handle.
142 {
143 SCOPED_TRACE("Serializing a Handle");
144 HandleStruct handle_struct;
145 handle_struct.h = MessagePipe().handle0.Pass();
146 handle_struct.array_h = Array<mojo::ScopedMessagePipeHandle>::New(0);
147 EXPECT_DEATH_IF_SUPPORTED({
148 SerializeAndDeserialize(&handle_struct,
149 mojo::internal::ValidationError::NONE);
150 }, "does not support handles");
151 }
152 }
153
154 // We should be able to Serialize/Deserialize a struct that has a nullable
155 // handle which is null.
156 TEST_F(StructSerializationAPITest, NullableHandleSerialization) {
157 NullableHandleStruct handle_struct;
158 handle_struct.data = 16;
159 SerializeAndDeserialize(&handle_struct,
160 mojo::internal::ValidationError::NONE);
161 }
162
163 // Test that |Deserialize()| appropriately fails on validation.
164 TEST_F(StructSerializationAPITest, DeserializationFailure) {
165 char buf[100] = {};
166 EmptyStruct es;
167
168 // Bounds checker should fail this, since buf_size is too small.
169 EXPECT_FALSE(es.Deserialize(buf, 1));
170
171 es.Serialize(buf, sizeof(buf));
172 EXPECT_TRUE(es.Deserialize(buf, sizeof(buf)));
173
174 // Invalid struct header: this should happen inside
175 // EmptyStruct::Data_::Validate()).
176 es.Serialize(buf, sizeof(buf));
177 EmptyStruct::Data_* es_data = reinterpret_cast<EmptyStruct::Data_*>(buf);
178 es_data->header_.num_bytes = 0;
179 EXPECT_FALSE(es.Deserialize(buf, sizeof(buf)));
180 }
181
182 TEST_F(StructSerializationAPITest, DeserializationWithoutValidation) {
183 const int32_t kMagic = 456;
184 char buf[100] = {};
185 ContainsOther::Data_* co_data = reinterpret_cast<ContainsOther::Data_*>(buf);
186 ContainsOther co;
187
188 // Success case.
189 co.other = kMagic;
190 EXPECT_TRUE(co.Serialize(buf, sizeof(buf)));
191 co.other = 0;
192 co.DeserializeWithoutValidation(buf);
193 EXPECT_EQ(kMagic, co.other);
194
195 // Invalid struct header, but will pass (i.e., won't crash) anyway because we
196 // don't Validate.
197 co_data->header_.num_bytes = 0u;
198 co.DeserializeWithoutValidation(buf);
199 EXPECT_EQ(kMagic, co_data->other);
200 EXPECT_EQ(0u, co_data->header_.num_bytes);
201 }
202
203 } // namespace
204 } // namespace test
205 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698