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/system/dispatcher.h"
12 #include "mojo/system/raw_shared_buffer.h"
13 #include "testing/gtest/include/gtest/gtest.h"
19 // NOTE(vtl): There's currently not much to test for in
20 // |SharedBufferDispatcher::ValidateCreateOptions()|, but the tests should be
21 // expanded if/when options are added, so I've kept the general form of the
22 // tests from data_pipe_unittest.cc.
24 const uint32_t kSizeOfCreateOptions = sizeof(MojoCreateSharedBufferOptions);
26 // Does a cursory sanity check of |validated_options|. Calls
27 // |ValidateCreateOptions()| on already-validated options. The validated options
28 // should be valid, and the revalidated copy should be the same.
29 void RevalidateCreateOptions(
30 const MojoCreateSharedBufferOptions& validated_options) {
31 EXPECT_EQ(kSizeOfCreateOptions, validated_options.struct_size);
32 // Nothing to check for flags.
34 MojoCreateSharedBufferOptions revalidated_options = {};
35 EXPECT_EQ(MOJO_RESULT_OK,
36 SharedBufferDispatcher::ValidateCreateOptions(
37 &validated_options, &revalidated_options));
38 EXPECT_EQ(validated_options.struct_size, revalidated_options.struct_size);
39 EXPECT_EQ(validated_options.flags, revalidated_options.flags);
42 // Tests valid inputs to |ValidateCreateOptions()|.
43 TEST(SharedBufferDispatcherTest, ValidateCreateOptionsValid) {
46 MojoCreateSharedBufferOptions validated_options = {};
47 EXPECT_EQ(MOJO_RESULT_OK,
48 SharedBufferDispatcher::ValidateCreateOptions(
49 NULL, &validated_options));
50 RevalidateCreateOptions(validated_options);
54 MojoCreateSharedBufferOptionsFlags flags_values[] = {
55 MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE
57 for (size_t i = 0; i < arraysize(flags_values); i++) {
58 const MojoCreateSharedBufferOptionsFlags flags = flags_values[i];
60 // Different capacities (size 1).
61 for (uint32_t capacity = 1; capacity <= 100 * 1000 * 1000; capacity *= 10) {
62 MojoCreateSharedBufferOptions options = {
63 kSizeOfCreateOptions, // |struct_size|.
66 MojoCreateSharedBufferOptions validated_options = {};
67 EXPECT_EQ(MOJO_RESULT_OK,
68 SharedBufferDispatcher::ValidateCreateOptions(
69 &options, &validated_options))
71 RevalidateCreateOptions(validated_options);
72 EXPECT_EQ(options.flags, validated_options.flags);
77 TEST(SharedBufferDispatcherTest, ValidateCreateOptionsInvalid) {
78 // Invalid |struct_size|.
80 MojoCreateSharedBufferOptions options = {
82 MOJO_CREATE_SHARED_BUFFER_OPTIONS_FLAG_NONE // |flags|.
84 MojoCreateSharedBufferOptions unused;
85 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
86 SharedBufferDispatcher::ValidateCreateOptions(&options, &unused));
91 MojoCreateSharedBufferOptions options = {
92 kSizeOfCreateOptions, // |struct_size|.
95 MojoCreateSharedBufferOptions unused;
96 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
97 SharedBufferDispatcher::ValidateCreateOptions(&options, &unused));
101 TEST(SharedBufferDispatcherTest, CreateAndMapBuffer) {
102 scoped_refptr<SharedBufferDispatcher> dispatcher;
103 EXPECT_EQ(MOJO_RESULT_OK,
104 SharedBufferDispatcher::Create(
105 SharedBufferDispatcher::kDefaultCreateOptions, 100,
107 ASSERT_TRUE(dispatcher);
108 EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher->GetType());
110 // Make a couple of mappings.
111 scoped_ptr<RawSharedBufferMapping> mapping1;
112 EXPECT_EQ(MOJO_RESULT_OK,
113 dispatcher->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE,
115 ASSERT_TRUE(mapping1);
116 ASSERT_TRUE(mapping1->base());
117 EXPECT_EQ(100u, mapping1->length());
119 static_cast<char*>(mapping1->base())[50] = 'x';
121 scoped_ptr<RawSharedBufferMapping> mapping2;
122 EXPECT_EQ(MOJO_RESULT_OK,
123 dispatcher->MapBuffer(50, 50, MOJO_MAP_BUFFER_FLAG_NONE,
125 ASSERT_TRUE(mapping2);
126 ASSERT_TRUE(mapping2->base());
127 EXPECT_EQ(50u, mapping2->length());
128 EXPECT_EQ('x', static_cast<char*>(mapping2->base())[0]);
130 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
132 // Check that we can still read/write to mappings after the dispatcher has
134 static_cast<char*>(mapping2->base())[1] = 'y';
135 EXPECT_EQ('y', static_cast<char*>(mapping1->base())[51]);
138 TEST(SharedBufferDispatcher, DuplicateBufferHandle) {
139 scoped_refptr<SharedBufferDispatcher> dispatcher1;
140 EXPECT_EQ(MOJO_RESULT_OK,
141 SharedBufferDispatcher::Create(
142 SharedBufferDispatcher::kDefaultCreateOptions, 100,
145 // Map and write something.
146 scoped_ptr<RawSharedBufferMapping> mapping;
147 EXPECT_EQ(MOJO_RESULT_OK,
148 dispatcher1->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE,
150 static_cast<char*>(mapping->base())[0] = 'x';
153 // Duplicate |dispatcher1| and then close it.
154 scoped_refptr<Dispatcher> dispatcher2;
155 EXPECT_EQ(MOJO_RESULT_OK,
156 dispatcher1->DuplicateBufferHandle(NULL, &dispatcher2));
157 ASSERT_TRUE(dispatcher2);
158 EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher2->GetType());
160 EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
162 // Map |dispatcher2| and read something.
163 EXPECT_EQ(MOJO_RESULT_OK,
164 dispatcher2->MapBuffer(0, 100, MOJO_MAP_BUFFER_FLAG_NONE,
166 EXPECT_EQ('x', static_cast<char*>(mapping->base())[0]);
168 EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
171 TEST(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsValid) {
172 scoped_refptr<SharedBufferDispatcher> dispatcher1;
173 EXPECT_EQ(MOJO_RESULT_OK,
174 SharedBufferDispatcher::Create(
175 SharedBufferDispatcher::kDefaultCreateOptions, 100,
178 MojoDuplicateBufferHandleOptions options[] = {
179 {sizeof(MojoDuplicateBufferHandleOptions),
180 MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE},
181 {sizeof(MojoDuplicateBufferHandleOptionsFlags), ~0u}
183 for (size_t i = 0; i < arraysize(options); i++) {
184 scoped_refptr<Dispatcher> dispatcher2;
185 EXPECT_EQ(MOJO_RESULT_OK,
186 dispatcher1->DuplicateBufferHandle(&options[i], &dispatcher2));
187 ASSERT_TRUE(dispatcher2);
188 EXPECT_EQ(Dispatcher::kTypeSharedBuffer, dispatcher2->GetType());
189 EXPECT_EQ(MOJO_RESULT_OK, dispatcher2->Close());
192 EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
195 TEST(SharedBufferDispatcherTest, DuplicateBufferHandleOptionsInvalid) {
196 scoped_refptr<SharedBufferDispatcher> dispatcher1;
197 EXPECT_EQ(MOJO_RESULT_OK,
198 SharedBufferDispatcher::Create(
199 SharedBufferDispatcher::kDefaultCreateOptions, 100,
202 // Invalid |struct_size|.
204 MojoDuplicateBufferHandleOptions options = {
205 1u, MOJO_DUPLICATE_BUFFER_HANDLE_OPTIONS_FLAG_NONE
207 scoped_refptr<Dispatcher> dispatcher2;
208 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
209 dispatcher1->DuplicateBufferHandle(&options, &dispatcher2));
210 EXPECT_FALSE(dispatcher2);
215 MojoDuplicateBufferHandleOptions options = {
216 sizeof(MojoDuplicateBufferHandleOptions), ~0u
218 scoped_refptr<Dispatcher> dispatcher2;
219 EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED,
220 dispatcher1->DuplicateBufferHandle(&options, &dispatcher2));
221 EXPECT_FALSE(dispatcher2);
224 EXPECT_EQ(MOJO_RESULT_OK, dispatcher1->Close());
227 TEST(SharedBufferDispatcherTest, CreateInvalidNumBytes) {
229 scoped_refptr<SharedBufferDispatcher> dispatcher;
230 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
231 SharedBufferDispatcher::Create(
232 SharedBufferDispatcher::kDefaultCreateOptions,
233 std::numeric_limits<uint64_t>::max(), &dispatcher));
234 EXPECT_FALSE(dispatcher);
237 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
238 SharedBufferDispatcher::Create(
239 SharedBufferDispatcher::kDefaultCreateOptions, 0, &dispatcher));
240 EXPECT_FALSE(dispatcher);
243 TEST(SharedBufferDispatcherTest, MapBufferInvalidArguments) {
244 scoped_refptr<SharedBufferDispatcher> dispatcher;
245 EXPECT_EQ(MOJO_RESULT_OK,
246 SharedBufferDispatcher::Create(
247 SharedBufferDispatcher::kDefaultCreateOptions, 100,
250 scoped_ptr<RawSharedBufferMapping> mapping;
251 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
252 dispatcher->MapBuffer(0, 101, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
253 EXPECT_FALSE(mapping);
255 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
256 dispatcher->MapBuffer(1, 100, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
257 EXPECT_FALSE(mapping);
259 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
260 dispatcher->MapBuffer(0, 0, MOJO_MAP_BUFFER_FLAG_NONE, &mapping));
261 EXPECT_FALSE(mapping);
263 EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
267 } // namespace system