• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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