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 16namespace mojo { 17namespace system { 18namespace { 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 25const 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. 30void 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 43class 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()|. 57TEST_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 90TEST_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 116TEST_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 155TEST_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 191TEST_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 217TEST_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 251TEST_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 272TEST_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 300