1 // Copyright 2013 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 "mojo/system/data_pipe.h"
6
7 #include <stddef.h>
8
9 #include <limits>
10
11 #include "base/basictypes.h"
12 #include "mojo/system/constants.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace mojo {
16 namespace system {
17 namespace {
18
19 const uint32_t kSizeOfCreateOptions =
20 static_cast<uint32_t>(sizeof(MojoCreateDataPipeOptions));
21
22 // Does a cursory sanity check of |validated_options|. Calls
23 // |ValidateCreateOptions()| on already-validated options. The validated options
24 // should be valid, and the revalidated copy should be the same.
RevalidateCreateOptions(const MojoCreateDataPipeOptions & validated_options)25 void RevalidateCreateOptions(
26 const MojoCreateDataPipeOptions& validated_options) {
27 EXPECT_EQ(kSizeOfCreateOptions, validated_options.struct_size);
28 // Nothing to check for flags.
29 EXPECT_GT(validated_options.element_num_bytes, 0u);
30 EXPECT_GT(validated_options.capacity_num_bytes, 0u);
31 EXPECT_EQ(0u,
32 validated_options.capacity_num_bytes %
33 validated_options.element_num_bytes);
34
35 MojoCreateDataPipeOptions revalidated_options = {};
36 EXPECT_EQ(MOJO_RESULT_OK,
37 DataPipe::ValidateCreateOptions(&validated_options,
38 &revalidated_options));
39 EXPECT_EQ(validated_options.struct_size, revalidated_options.struct_size);
40 EXPECT_EQ(validated_options.element_num_bytes,
41 revalidated_options.element_num_bytes);
42 EXPECT_EQ(validated_options.capacity_num_bytes,
43 revalidated_options.capacity_num_bytes);
44 EXPECT_EQ(validated_options.flags, revalidated_options.flags);
45 }
46
47 // Checks that a default-computed capacity is correct. (Does not duplicate the
48 // checks done by |RevalidateCreateOptions()|.)
CheckDefaultCapacity(const MojoCreateDataPipeOptions & validated_options)49 void CheckDefaultCapacity(const MojoCreateDataPipeOptions& validated_options) {
50 EXPECT_LE(validated_options.capacity_num_bytes,
51 kDefaultDataPipeCapacityBytes);
52 EXPECT_GT(validated_options.capacity_num_bytes +
53 validated_options.element_num_bytes,
54 kDefaultDataPipeCapacityBytes);
55 }
56
57 // Tests valid inputs to |ValidateCreateOptions()|.
TEST(DataPipeTest,ValidateCreateOptionsValid)58 TEST(DataPipeTest, ValidateCreateOptionsValid) {
59 // Default options.
60 {
61 MojoCreateDataPipeOptions validated_options = {};
62 EXPECT_EQ(MOJO_RESULT_OK,
63 DataPipe::ValidateCreateOptions(NULL, &validated_options));
64 RevalidateCreateOptions(validated_options);
65 CheckDefaultCapacity(validated_options);
66 }
67
68 // Size member, but nothing beyond.
69 {
70 MojoCreateDataPipeOptions options = {
71 offsetof(MojoCreateDataPipeOptions, flags) // |struct_size|.
72 };
73 MojoCreateDataPipeOptions validated_options = {};
74 EXPECT_EQ(MOJO_RESULT_OK,
75 DataPipe::ValidateCreateOptions(&options, &validated_options));
76 RevalidateCreateOptions(validated_options);
77 CheckDefaultCapacity(validated_options);
78 }
79
80 // Different flags.
81 MojoCreateDataPipeOptionsFlags flags_values[] = {
82 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
83 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD
84 };
85 for (size_t i = 0; i < arraysize(flags_values); i++) {
86 const MojoCreateDataPipeOptionsFlags flags = flags_values[i];
87
88 // Flags member, but nothing beyond.
89 {
90 MojoCreateDataPipeOptions options = {
91 // |struct_size|.
92 offsetof(MojoCreateDataPipeOptions, element_num_bytes),
93 flags // |flags|.
94 };
95 MojoCreateDataPipeOptions validated_options = {};
96 EXPECT_EQ(MOJO_RESULT_OK,
97 DataPipe::ValidateCreateOptions(&options, &validated_options));
98 RevalidateCreateOptions(validated_options);
99 EXPECT_EQ(options.flags, validated_options.flags);
100 CheckDefaultCapacity(validated_options);
101 }
102
103 // Different capacities (size 1).
104 for (uint32_t capacity = 1; capacity <= 100 * 1000 * 1000; capacity *= 10) {
105 MojoCreateDataPipeOptions options = {
106 kSizeOfCreateOptions, // |struct_size|.
107 flags, // |flags|.
108 1, // |element_num_bytes|.
109 capacity // |capacity_num_bytes|.
110 };
111 MojoCreateDataPipeOptions validated_options = {};
112 EXPECT_EQ(MOJO_RESULT_OK,
113 DataPipe::ValidateCreateOptions(&options, &validated_options))
114 << capacity;
115 RevalidateCreateOptions(validated_options);
116 EXPECT_EQ(options.flags, validated_options.flags);
117 EXPECT_EQ(options.element_num_bytes,
118 validated_options.element_num_bytes);
119 EXPECT_EQ(options.capacity_num_bytes,
120 validated_options.capacity_num_bytes);
121 }
122
123 // Small sizes.
124 for (uint32_t size = 1; size < 100; size++) {
125 // Different capacities.
126 for (uint32_t elements = 1; elements <= 1000 * 1000; elements *= 10) {
127 MojoCreateDataPipeOptions options = {
128 kSizeOfCreateOptions, // |struct_size|.
129 flags, // |flags|.
130 size, // |element_num_bytes|.
131 size * elements // |capacity_num_bytes|.
132 };
133 MojoCreateDataPipeOptions validated_options = {};
134 EXPECT_EQ(MOJO_RESULT_OK,
135 DataPipe::ValidateCreateOptions(&options, &validated_options))
136 << size << ", " << elements;
137 RevalidateCreateOptions(validated_options);
138 EXPECT_EQ(options.flags, validated_options.flags);
139 EXPECT_EQ(options.element_num_bytes,
140 validated_options.element_num_bytes);
141 EXPECT_EQ(options.capacity_num_bytes,
142 validated_options.capacity_num_bytes);
143 }
144
145 // Default capacity.
146 {
147 MojoCreateDataPipeOptions options = {
148 kSizeOfCreateOptions, // |struct_size|.
149 flags, // |flags|.
150 size, // |element_num_bytes|.
151 0 // |capacity_num_bytes|.
152 };
153 MojoCreateDataPipeOptions validated_options = {};
154 EXPECT_EQ(MOJO_RESULT_OK,
155 DataPipe::ValidateCreateOptions(&options, &validated_options))
156 << size;
157 RevalidateCreateOptions(validated_options);
158 EXPECT_EQ(options.flags, validated_options.flags);
159 EXPECT_EQ(options.element_num_bytes,
160 validated_options.element_num_bytes);
161 CheckDefaultCapacity(validated_options);
162 }
163
164 // No capacity field.
165 {
166 MojoCreateDataPipeOptions options = {
167 // |struct_size|.
168 offsetof(MojoCreateDataPipeOptions, capacity_num_bytes),
169 flags, // |flags|.
170 size // |element_num_bytes|.
171 };
172 MojoCreateDataPipeOptions validated_options = {};
173 EXPECT_EQ(MOJO_RESULT_OK,
174 DataPipe::ValidateCreateOptions(&options, &validated_options))
175 << size;
176 RevalidateCreateOptions(validated_options);
177 EXPECT_EQ(options.flags, validated_options.flags);
178 EXPECT_EQ(options.element_num_bytes,
179 validated_options.element_num_bytes);
180 CheckDefaultCapacity(validated_options);
181 }
182 }
183
184 // Larger sizes.
185 for (uint32_t size = 100; size <= 100 * 1000; size *= 10) {
186 // Capacity of 1000 elements.
187 {
188 MojoCreateDataPipeOptions options = {
189 kSizeOfCreateOptions, // |struct_size|.
190 flags, // |flags|.
191 size, // |element_num_bytes|.
192 1000 * size // |capacity_num_bytes|.
193 };
194 MojoCreateDataPipeOptions validated_options = {};
195 EXPECT_EQ(MOJO_RESULT_OK,
196 DataPipe::ValidateCreateOptions(&options, &validated_options))
197 << size;
198 RevalidateCreateOptions(validated_options);
199 EXPECT_EQ(options.flags, validated_options.flags);
200 EXPECT_EQ(options.element_num_bytes,
201 validated_options.element_num_bytes);
202 EXPECT_EQ(options.capacity_num_bytes,
203 validated_options.capacity_num_bytes);
204 }
205
206 // Default capacity.
207 {
208 MojoCreateDataPipeOptions options = {
209 kSizeOfCreateOptions, // |struct_size|.
210 flags, // |flags|.
211 size, // |element_num_bytes|.
212 0 // |capacity_num_bytes|.
213 };
214 MojoCreateDataPipeOptions validated_options = {};
215 EXPECT_EQ(MOJO_RESULT_OK,
216 DataPipe::ValidateCreateOptions(&options, &validated_options))
217 << size;
218 RevalidateCreateOptions(validated_options);
219 EXPECT_EQ(options.flags, validated_options.flags);
220 EXPECT_EQ(options.element_num_bytes,
221 validated_options.element_num_bytes);
222 CheckDefaultCapacity(validated_options);
223 }
224
225 // No capacity field.
226 {
227 MojoCreateDataPipeOptions options = {
228 // |struct_size|.
229 offsetof(MojoCreateDataPipeOptions, capacity_num_bytes),
230 flags, // |flags|.
231 size // |element_num_bytes|.
232 };
233 MojoCreateDataPipeOptions validated_options = {};
234 EXPECT_EQ(MOJO_RESULT_OK,
235 DataPipe::ValidateCreateOptions(&options, &validated_options))
236 << size;
237 RevalidateCreateOptions(validated_options);
238 EXPECT_EQ(options.flags, validated_options.flags);
239 EXPECT_EQ(options.element_num_bytes,
240 validated_options.element_num_bytes);
241 CheckDefaultCapacity(validated_options);
242 }
243 }
244 }
245 }
246
TEST(DataPipeTest,ValidateCreateOptionsInvalid)247 TEST(DataPipeTest, ValidateCreateOptionsInvalid) {
248 // Invalid |struct_size|.
249 {
250 MojoCreateDataPipeOptions options = {
251 1, // |struct_size|.
252 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
253 1, // |element_num_bytes|.
254 0 // |capacity_num_bytes|.
255 };
256 MojoCreateDataPipeOptions unused;
257 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
258 DataPipe::ValidateCreateOptions(&options, &unused));
259 }
260
261 // Unknown |flags|.
262 {
263 MojoCreateDataPipeOptions options = {
264 kSizeOfCreateOptions, // |struct_size|.
265 ~0u, // |flags|.
266 1, // |element_num_bytes|.
267 0 // |capacity_num_bytes|.
268 };
269 MojoCreateDataPipeOptions unused;
270 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
271 DataPipe::ValidateCreateOptions(&options, &unused));
272 }
273
274 // Invalid |element_num_bytes|.
275 {
276 MojoCreateDataPipeOptions options = {
277 kSizeOfCreateOptions, // |struct_size|.
278 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
279 0, // |element_num_bytes|.
280 1000 // |capacity_num_bytes|.
281 };
282 MojoCreateDataPipeOptions unused;
283 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
284 DataPipe::ValidateCreateOptions(&options, &unused));
285 }
286 // |element_num_bytes| too big.
287 {
288 MojoCreateDataPipeOptions options = {
289 kSizeOfCreateOptions, // |struct_size|.
290 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
291 std::numeric_limits<uint32_t>::max(), // |element_num_bytes|.
292 std::numeric_limits<uint32_t>::max() // |capacity_num_bytes|.
293 };
294 MojoCreateDataPipeOptions unused;
295 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
296 DataPipe::ValidateCreateOptions(&options, &unused));
297 }
298 {
299 MojoCreateDataPipeOptions options = {
300 kSizeOfCreateOptions, // |struct_size|.
301 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
302 std::numeric_limits<uint32_t>::max() - 1000, // |element_num_bytes|.
303 std::numeric_limits<uint32_t>::max() - 1000 // |capacity_num_bytes|.
304 };
305 MojoCreateDataPipeOptions unused;
306 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
307 DataPipe::ValidateCreateOptions(&options, &unused));
308 }
309
310 // Invalid |capacity_num_bytes|.
311 {
312 MojoCreateDataPipeOptions options = {
313 kSizeOfCreateOptions, // |struct_size|.
314 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
315 2, // |element_num_bytes|.
316 1 // |capacity_num_bytes|.
317 };
318 MojoCreateDataPipeOptions unused;
319 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
320 DataPipe::ValidateCreateOptions(&options, &unused));
321 }
322 {
323 MojoCreateDataPipeOptions options = {
324 kSizeOfCreateOptions, // |struct_size|.
325 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
326 2, // |element_num_bytes|.
327 111 // |capacity_num_bytes|.
328 };
329 MojoCreateDataPipeOptions unused;
330 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
331 DataPipe::ValidateCreateOptions(&options, &unused));
332 }
333 {
334 MojoCreateDataPipeOptions options = {
335 kSizeOfCreateOptions, // |struct_size|.
336 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
337 5, // |element_num_bytes|.
338 104 // |capacity_num_bytes|.
339 };
340 MojoCreateDataPipeOptions unused;
341 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
342 DataPipe::ValidateCreateOptions(&options, &unused));
343 }
344 // |capacity_num_bytes| too big.
345 {
346 MojoCreateDataPipeOptions options = {
347 kSizeOfCreateOptions, // |struct_size|.
348 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
349 8, // |element_num_bytes|.
350 0xffff0000 // |capacity_num_bytes|.
351 };
352 MojoCreateDataPipeOptions unused;
353 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
354 DataPipe::ValidateCreateOptions(&options, &unused));
355 }
356 }
357
358 } // namespace
359 } // namespace system
360 } // namespace mojo
361