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.
5 #include "mojo/system/shared_buffer_dispatcher.h"
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"
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.
25 const uint32_t kSizeOfCreateOptions
= sizeof(MojoCreateSharedBufferOptions
);
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.
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
);
43 class SharedBufferDispatcherTest
: public testing::Test
{
45 SharedBufferDispatcherTest() {}
46 virtual ~SharedBufferDispatcherTest() {}
48 embedder::PlatformSupport
* platform_support() { return &platform_support_
; }
51 embedder::SimplePlatformSupport platform_support_
;
53 DISALLOW_COPY_AND_ASSIGN(SharedBufferDispatcherTest
);
56 // Tests valid inputs to |ValidateCreateOptions()|.
57 TEST_F(SharedBufferDispatcherTest
, ValidateCreateOptionsValid
) {
60 MojoCreateSharedBufferOptions validated_options
= {};
61 EXPECT_EQ(MOJO_RESULT_OK
,
62 SharedBufferDispatcher::ValidateCreateOptions(
63 NullUserPointer(), &validated_options
));
64 RevalidateCreateOptions(validated_options
);
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
];
73 // Different capacities (size 1).
74 for (uint32_t capacity
= 1; capacity
<= 100 * 1000 * 1000; capacity
*= 10) {
75 MojoCreateSharedBufferOptions options
= {
76 kSizeOfCreateOptions
, // |struct_size|.
79 MojoCreateSharedBufferOptions validated_options
= {};
80 EXPECT_EQ(MOJO_RESULT_OK
,
81 SharedBufferDispatcher::ValidateCreateOptions(
82 MakeUserPointer(&options
), &validated_options
))
84 RevalidateCreateOptions(validated_options
);
85 EXPECT_EQ(options
.flags
, validated_options
.flags
);
90 TEST_F(SharedBufferDispatcherTest
, ValidateCreateOptionsInvalid
) {
91 // Invalid |struct_size|.
93 MojoCreateSharedBufferOptions options
= {
95 MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE
// |flags|.
97 MojoCreateSharedBufferOptions unused
;
98 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
99 SharedBufferDispatcher::ValidateCreateOptions(
100 MakeUserPointer(&options
), &unused
));
105 MojoCreateSharedBufferOptions options
= {
106 kSizeOfCreateOptions
, // |struct_size|.
109 MojoCreateSharedBufferOptions unused
;
110 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED
,
111 SharedBufferDispatcher::ValidateCreateOptions(
112 MakeUserPointer(&options
), &unused
));
116 TEST_F(SharedBufferDispatcherTest
, CreateAndMapBuffer
) {
117 scoped_refptr
<SharedBufferDispatcher
> dispatcher
;
118 EXPECT_EQ(MOJO_RESULT_OK
,
119 SharedBufferDispatcher::Create(
121 SharedBufferDispatcher::kDefaultCreateOptions
,
124 ASSERT_TRUE(dispatcher
.get());
125 EXPECT_EQ(Dispatcher::kTypeSharedBuffer
, dispatcher
->GetType());
127 // Make a couple of mappings.
128 scoped_ptr
<embedder::PlatformSharedBufferMapping
> mapping1
;
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());
136 static_cast<char*>(mapping1
->GetBase())[50] = 'x';
138 scoped_ptr
<embedder::PlatformSharedBufferMapping
> mapping2
;
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]);
147 EXPECT_EQ(MOJO_RESULT_OK
, dispatcher
->Close());
149 // Check that we can still read/write to mappings after the dispatcher has
151 static_cast<char*>(mapping2
->GetBase())[1] = 'y';
152 EXPECT_EQ('y', static_cast<char*>(mapping1
->GetBase())[51]);
155 TEST_F(SharedBufferDispatcherTest
, DuplicateBufferHandle
) {
156 scoped_refptr
<SharedBufferDispatcher
> dispatcher1
;
157 EXPECT_EQ(MOJO_RESULT_OK
,
158 SharedBufferDispatcher::Create(
160 SharedBufferDispatcher::kDefaultCreateOptions
,
164 // Map and write something.
165 scoped_ptr
<embedder::PlatformSharedBufferMapping
> mapping
;
168 dispatcher1
->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE
, &mapping
));
169 static_cast<char*>(mapping
->GetBase())[0] = 'x';
172 // Duplicate |dispatcher1| and then close it.
173 scoped_refptr
<Dispatcher
> dispatcher2
;
176 dispatcher1
->DuplicateBufferHandle(NullUserPointer(), &dispatcher2
));
177 ASSERT_TRUE(dispatcher2
.get());
178 EXPECT_EQ(Dispatcher::kTypeSharedBuffer
, dispatcher2
->GetType());
180 EXPECT_EQ(MOJO_RESULT_OK
, dispatcher1
->Close());
182 // Map |dispatcher2| and read something.
185 dispatcher2
->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE
, &mapping
));
186 EXPECT_EQ('x', static_cast<char*>(mapping
->GetBase())[0]);
188 EXPECT_EQ(MOJO_RESULT_OK
, dispatcher2
->Close());
191 TEST_F(SharedBufferDispatcherTest
, DuplicateBufferHandleOptionsValid
) {
192 scoped_refptr
<SharedBufferDispatcher
> dispatcher1
;
193 EXPECT_EQ(MOJO_RESULT_OK
,
194 SharedBufferDispatcher::Create(
196 SharedBufferDispatcher::kDefaultCreateOptions
,
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
]),
209 ASSERT_TRUE(dispatcher2
.get());
210 EXPECT_EQ(Dispatcher::kTypeSharedBuffer
, dispatcher2
->GetType());
211 EXPECT_EQ(MOJO_RESULT_OK
, dispatcher2
->Close());
214 EXPECT_EQ(MOJO_RESULT_OK
, dispatcher1
->Close());
217 TEST_F(SharedBufferDispatcherTest
, DuplicateBufferHandleOptionsInvalid
) {
218 scoped_refptr
<SharedBufferDispatcher
> dispatcher1
;
219 EXPECT_EQ(MOJO_RESULT_OK
,
220 SharedBufferDispatcher::Create(
222 SharedBufferDispatcher::kDefaultCreateOptions
,
226 // Invalid |struct_size|.
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
),
234 EXPECT_FALSE(dispatcher2
.get());
239 MojoDuplicateBufferHandleOptions options
= {
240 sizeof(MojoDuplicateBufferHandleOptions
), ~0u};
241 scoped_refptr
<Dispatcher
> dispatcher2
;
242 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED
,
243 dispatcher1
->DuplicateBufferHandle(MakeUserPointer(&options
),
245 EXPECT_FALSE(dispatcher2
.get());
248 EXPECT_EQ(MOJO_RESULT_OK
, dispatcher1
->Close());
251 TEST_F(SharedBufferDispatcherTest
, CreateInvalidNumBytes
) {
253 scoped_refptr
<SharedBufferDispatcher
> dispatcher
;
254 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED
,
255 SharedBufferDispatcher::Create(
257 SharedBufferDispatcher::kDefaultCreateOptions
,
258 std::numeric_limits
<uint64_t>::max(),
260 EXPECT_FALSE(dispatcher
.get());
263 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
264 SharedBufferDispatcher::Create(
266 SharedBufferDispatcher::kDefaultCreateOptions
,
269 EXPECT_FALSE(dispatcher
.get());
272 TEST_F(SharedBufferDispatcherTest
, MapBufferInvalidArguments
) {
273 scoped_refptr
<SharedBufferDispatcher
> dispatcher
;
274 EXPECT_EQ(MOJO_RESULT_OK
,
275 SharedBufferDispatcher::Create(
277 SharedBufferDispatcher::kDefaultCreateOptions
,
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
);
286 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
287 dispatcher
->MapBuffer(1, 100, MOJO_MAP_BUFFER_FLAG_NONE
, &mapping
));
288 EXPECT_FALSE(mapping
);
290 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT
,
291 dispatcher
->MapBuffer(0, 0, MOJO_MAP_BUFFER_FLAG_NONE
, &mapping
));
292 EXPECT_FALSE(mapping
);
294 EXPECT_EQ(MOJO_RESULT_OK
, dispatcher
->Close());
298 } // namespace system