Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / mojo / system / shared_buffer_dispatcher_unittest.cc
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 "mojo/system/shared_buffer_dispatcher.h"
6
7 #include <limits>
8
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "mojo/embedder/platform_shared_buffer.h"
12 #include "mojo/embedder/simple_platform_support.h"
13 #include "mojo/system/dispatcher.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace mojo {
17 namespace system {
18 namespace {
19
20 // NOTE(vtl): There's currently not much to test for in
21 // |SharedBufferDispatcher::ValidateCreateOptions()|, but the tests should be
22 // expanded if/when options are added, so I've kept the general form of the
23 // tests from data_pipe_unittest.cc.
24
25 const uint32_t kSizeOfCreateOptions = sizeof(MojoCreateSharedBufferOptions);
26
27 // Does a cursory sanity check of |validated_options|. Calls
28 // |ValidateCreateOptions()| on already-validated options. The validated options
29 // should be valid, and the revalidated copy should be the same.
30 void RevalidateCreateOptions(
31     const MojoCreateSharedBufferOptions& validated_options) {
32   EXPECT_EQ(kSizeOfCreateOptions, validated_options.struct_size);
33   // Nothing to check for flags.
34
35   MojoCreateSharedBufferOptions revalidated_options = {};
36   EXPECT_EQ(MOJO_RESULT_OK,
37             SharedBufferDispatcher::ValidateCreateOptions(
38                 MakeUserPointer(&validated_options), &revalidated_options));
39   EXPECT_EQ(validated_options.struct_size, revalidated_options.struct_size);
40   EXPECT_EQ(validated_options.flags, revalidated_options.flags);
41 }
42
43 class SharedBufferDispatcherTest : public testing::Test {
44  public:
45   SharedBufferDispatcherTest() {}
46   virtual ~SharedBufferDispatcherTest() {}
47
48   embedder::PlatformSupport* platform_support() { return &platform_support_; }
49
50  private:
51   embedder::SimplePlatformSupport platform_support_;
52
53   DISALLOW_COPY_AND_ASSIGN(SharedBufferDispatcherTest);
54 };
55
56 // Tests valid inputs to |ValidateCreateOptions()|.
57 TEST_F(SharedBufferDispatcherTest, ValidateCreateOptionsValid) {
58   // Default options.
59   {
60     MojoCreateSharedBufferOptions validated_options = {};
61     EXPECT_EQ(MOJO_RESULT_OK,
62               SharedBufferDispatcher::ValidateCreateOptions(
63                   NullUserPointer(), &validated_options));
64     RevalidateCreateOptions(validated_options);
65   }
66
67   // Different flags.
68   MojoCreateSharedBufferOptionsFlags flags_values[] = {
69       MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE};
70   for (size_t i = 0; i < arraysize(flags_values); i++) {
71     const MojoCreateSharedBufferOptionsFlags flags = flags_values[i];
72
73     // Different capacities (size 1).
74     for (uint32_t capacity = 1; capacity <= 100 * 1000 * 1000; capacity *= 10) {
75       MojoCreateSharedBufferOptions options = {
76           kSizeOfCreateOptions,  // |struct_size|.
77           flags                  // |flags|.
78       };
79       MojoCreateSharedBufferOptions validated_options = {};
80       EXPECT_EQ(MOJO_RESULT_OK,
81                 SharedBufferDispatcher::ValidateCreateOptions(
82                     MakeUserPointer(&options), &validated_options))
83           << capacity;
84       RevalidateCreateOptions(validated_options);
85       EXPECT_EQ(options.flags, validated_options.flags);
86     }
87   }
88 }
89
90 TEST_F(SharedBufferDispatcherTest, ValidateCreateOptionsInvalid) {
91   // Invalid |struct_size|.
92   {
93     MojoCreateSharedBufferOptions options = {
94         1,                                           // |struct_size|.
95         MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE  // |flags|.
96     };
97     MojoCreateSharedBufferOptions unused;
98     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
99               SharedBufferDispatcher::ValidateCreateOptions(
100                   MakeUserPointer(&options), &unused));
101   }
102
103   // Unknown |flags|.
104   {
105     MojoCreateSharedBufferOptions options = {
106         kSizeOfCreateOptions,  // |struct_size|.
107         ~0u                    // |flags|.
108     };
109     MojoCreateSharedBufferOptions unused;
110     EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
111               SharedBufferDispatcher::ValidateCreateOptions(
112                   MakeUserPointer(&options), &unused));
113   }
114 }
115
116 TEST_F(SharedBufferDispatcherTest, CreateAndMapBuffer) {
117   scoped_refptr<SharedBufferDispatcher> dispatcher;
118   EXPECT_EQ(MOJO_RESULT_OK,
119             SharedBufferDispatcher::Create(
120                 platform_support(),
121                 SharedBufferDispatcher::kDefaultCreateOptions,
122                 100,
123                 &dispatcher));
124   ASSERT_TRUE(dispatcher.get());
125   EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher->GetType());
126
127   // Make a couple of mappings.
128   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping1;
129   EXPECT_EQ(
130       MOJO_RESULT_OK,
131       dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping1));
132   ASSERT_TRUE(mapping1);
133   ASSERT_TRUE(mapping1->GetBase());
134   EXPECT_EQ(100u, mapping1->GetLength());
135   // Write something.
136   static_cast<char*>(mapping1->GetBase())[50] = 'x';
137
138   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping2;
139   EXPECT_EQ(
140       MOJO_RESULT_OK,
141       dispatcher->MapBuffer(50, 50, MOJO_MAP_BUFFER_FLAG_NONE, &mapping2));
142   ASSERT_TRUE(mapping2);
143   ASSERT_TRUE(mapping2->GetBase());
144   EXPECT_EQ(50u, mapping2->GetLength());
145   EXPECT_EQ('x', static_cast<char*>(mapping2->GetBase())[0]);
146
147   EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
148
149   // Check that we can still read/write to mappings after the dispatcher has
150   // gone away.
151   static_cast<char*>(mapping2->GetBase())[1] = 'y';
152   EXPECT_EQ('y', static_cast<char*>(mapping1->GetBase())[51]);
153 }
154
155 TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandle) {
156   scoped_refptr<SharedBufferDispatcher> dispatcher1;
157   EXPECT_EQ(MOJO_RESULT_OK,
158             SharedBufferDispatcher::Create(
159                 platform_support(),
160                 SharedBufferDispatcher::kDefaultCreateOptions,
161                 100,
162                 &dispatcher1));
163
164   // Map and write something.
165   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping;
166   EXPECT_EQ(
167       MOJO_RESULT_OK,
168       dispatcher1->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
169   static_cast<char*>(mapping->GetBase())[0] = 'x';
170   mapping.reset();
171
172   // Duplicate |dispatcher1| and then close it.
173   scoped_refptr<Dispatcher> dispatcher2;
174   EXPECT_EQ(
175       MOJO_RESULT_OK,
176       dispatcher1->DuplicateBufferHandle(NullUserPointer(), &dispatcher2));
177   ASSERT_TRUE(dispatcher2.get());
178   EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher2->GetType());
179
180   EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
181
182   // Map |dispatcher2| and read something.
183   EXPECT_EQ(
184       MOJO_RESULT_OK,
185       dispatcher2->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
186   EXPECT_EQ('x', static_cast<char*>(mapping->GetBase())[0]);
187
188   EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
189 }
190
191 TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsValid) {
192   scoped_refptr<SharedBufferDispatcher> dispatcher1;
193   EXPECT_EQ(MOJO_RESULT_OK,
194             SharedBufferDispatcher::Create(
195                 platform_support(),
196                 SharedBufferDispatcher::kDefaultCreateOptions,
197                 100,
198                 &dispatcher1));
199
200   MojoDuplicateBufferHandleOptions options[] = {
201       {sizeof(MojoDuplicateBufferHandleOptions),
202        MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE},
203       {sizeof(MojoDuplicateBufferHandleOptionsFlags), ~0u}};
204   for (size_t i = 0; i < arraysize(options); i++) {
205     scoped_refptr<Dispatcher> dispatcher2;
206     EXPECT_EQ(MOJO_RESULT_OK,
207               dispatcher1->DuplicateBufferHandle(MakeUserPointer(&options[i]),
208                                                  &dispatcher2));
209     ASSERT_TRUE(dispatcher2.get());
210     EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher2->GetType());
211     EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
212   }
213
214   EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
215 }
216
217 TEST_F(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsInvalid) {
218   scoped_refptr<SharedBufferDispatcher> dispatcher1;
219   EXPECT_EQ(MOJO_RESULT_OK,
220             SharedBufferDispatcher::Create(
221                 platform_support(),
222                 SharedBufferDispatcher::kDefaultCreateOptions,
223                 100,
224                 &dispatcher1));
225
226   // Invalid |struct_size|.
227   {
228     MojoDuplicateBufferHandleOptions options = {
229         1u, MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE};
230     scoped_refptr<Dispatcher> dispatcher2;
231     EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
232               dispatcher1->DuplicateBufferHandle(MakeUserPointer(&options),
233                                                  &dispatcher2));
234     EXPECT_FALSE(dispatcher2.get());
235   }
236
237   // Unknown |flags|.
238   {
239     MojoDuplicateBufferHandleOptions options = {
240         sizeof(MojoDuplicateBufferHandleOptions), ~0u};
241     scoped_refptr<Dispatcher> dispatcher2;
242     EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
243               dispatcher1->DuplicateBufferHandle(MakeUserPointer(&options),
244                                                  &dispatcher2));
245     EXPECT_FALSE(dispatcher2.get());
246   }
247
248   EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
249 }
250
251 TEST_F(SharedBufferDispatcherTest, CreateInvalidNumBytes) {
252   // Size too big.
253   scoped_refptr<SharedBufferDispatcher> dispatcher;
254   EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
255             SharedBufferDispatcher::Create(
256                 platform_support(),
257                 SharedBufferDispatcher::kDefaultCreateOptions,
258                 std::numeric_limits<uint64_t>::max(),
259                 &dispatcher));
260   EXPECT_FALSE(dispatcher.get());
261
262   // Zero size.
263   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
264             SharedBufferDispatcher::Create(
265                 platform_support(),
266                 SharedBufferDispatcher::kDefaultCreateOptions,
267                 0,
268                 &dispatcher));
269   EXPECT_FALSE(dispatcher.get());
270 }
271
272 TEST_F(SharedBufferDispatcherTest, MapBufferInvalidArguments) {
273   scoped_refptr<SharedBufferDispatcher> dispatcher;
274   EXPECT_EQ(MOJO_RESULT_OK,
275             SharedBufferDispatcher::Create(
276                 platform_support(),
277                 SharedBufferDispatcher::kDefaultCreateOptions,
278                 100,
279                 &dispatcher));
280
281   scoped_ptr<embedder::PlatformSharedBufferMapping> mapping;
282   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
283             dispatcher->MapBuffer(0, 101, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
284   EXPECT_FALSE(mapping);
285
286   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
287             dispatcher->MapBuffer(1, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
288   EXPECT_FALSE(mapping);
289
290   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
291             dispatcher->MapBuffer(0, 0, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
292   EXPECT_FALSE(mapping);
293
294   EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
295 }
296
297 }  // namespace
298 }  // namespace system
299 }  // namespace mojo