blob: 2a2ed5727bc4fe5fe073dbaaab02c239f73737c0 [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file tests the C buffer API (the functions declared in
// mojo/public/c/include/mojo/system/buffer.h).
#include <mojo/system/buffer.h>
#include <mojo/result.h>
#include <mojo/system/handle.h>
#include "gtest/gtest.h"
namespace {
const MojoHandleRights kDefaultSharedBufferHandleRights =
MOJO_HANDLE_RIGHT_DUPLICATE | MOJO_HANDLE_RIGHT_TRANSFER |
MOJO_HANDLE_RIGHT_GET_OPTIONS | MOJO_HANDLE_RIGHT_SET_OPTIONS |
MOJO_HANDLE_RIGHT_MAP_READABLE | MOJO_HANDLE_RIGHT_MAP_WRITABLE |
MOJO_HANDLE_RIGHT_MAP_EXECUTABLE;
// The only handle that's guaranteed to be invalid is |MOJO_HANDLE_INVALID|.
// Tests that everything that takes a handle properly recognizes it.
TEST(BufferTest, InvalidHandle) {
MojoHandle out_handle = MOJO_HANDLE_INVALID;
EXPECT_EQ(
MOJO_RESULT_INVALID_ARGUMENT,
MojoDuplicateBufferHandle(MOJO_HANDLE_INVALID, nullptr, &out_handle));
MojoBufferInformation buffer_info = {};
EXPECT_EQ(
MOJO_RESULT_INVALID_ARGUMENT,
MojoGetBufferInformation(MOJO_HANDLE_INVALID, &buffer_info,
static_cast<uint32_t>(sizeof(buffer_info))));
void* write_pointer = nullptr;
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
MojoMapBuffer(MOJO_HANDLE_INVALID, 0u, 1u, &write_pointer,
MOJO_MAP_BUFFER_FLAG_NONE));
// This isn't an "invalid handle" test, but we'll throw it in here anyway
// (since it involves a look-up).
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoUnmapBuffer(nullptr));
}
TEST(BufferTest, Basic) {
// Create a shared buffer (|h0|).
MojoHandle h0 = MOJO_HANDLE_INVALID;
EXPECT_EQ(MOJO_RESULT_OK, MojoCreateSharedBuffer(nullptr, 100, &h0));
EXPECT_NE(h0, MOJO_HANDLE_INVALID);
// The handle should have the correct rights.
MojoHandleRights rights = MOJO_HANDLE_RIGHT_NONE;
EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(h0, &rights));
EXPECT_EQ(kDefaultSharedBufferHandleRights, rights);
// Check information about the buffer from |h0|.
MojoBufferInformation info = {};
static const uint32_t kInfoSize = static_cast<uint32_t>(sizeof(info));
EXPECT_EQ(MOJO_RESULT_OK, MojoGetBufferInformation(h0, &info, kInfoSize));
EXPECT_EQ(kInfoSize, info.struct_size);
EXPECT_EQ(MOJO_BUFFER_INFORMATION_FLAG_NONE, info.flags);
EXPECT_EQ(100u, info.num_bytes);
// Map everything.
void* pointer = nullptr;
EXPECT_EQ(MOJO_RESULT_OK,
MojoMapBuffer(h0, 0, 100, &pointer, MOJO_MAP_BUFFER_FLAG_NONE));
ASSERT_TRUE(pointer);
static_cast<char*>(pointer)[50] = 'x';
// Duplicate |h0| to |h1|.
MojoHandle h1 = MOJO_HANDLE_INVALID;
EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateHandle(h0, &h1));
EXPECT_NE(h1, MOJO_HANDLE_INVALID);
EXPECT_NE(h1, h0);
// The new handle should have the correct rights.
rights = MOJO_HANDLE_RIGHT_NONE;
EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(h1, &rights));
EXPECT_EQ(kDefaultSharedBufferHandleRights, rights);
// Check information about the buffer from |h1|.
info = MojoBufferInformation();
EXPECT_EQ(MOJO_RESULT_OK, MojoGetBufferInformation(h1, &info, kInfoSize));
EXPECT_EQ(kInfoSize, info.struct_size);
EXPECT_EQ(MOJO_BUFFER_INFORMATION_FLAG_NONE, info.flags);
EXPECT_EQ(100u, info.num_bytes);
// Close |h0|.
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0));
// The mapping should still be good.
static_cast<char*>(pointer)[51] = 'y';
// Unmap it.
EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(pointer));
// Map half of |h1|.
pointer = nullptr;
EXPECT_EQ(MOJO_RESULT_OK,
MojoMapBuffer(h1, 50, 50, &pointer, MOJO_MAP_BUFFER_FLAG_NONE));
ASSERT_TRUE(pointer);
// It should have what we wrote.
EXPECT_EQ('x', static_cast<char*>(pointer)[0]);
EXPECT_EQ('y', static_cast<char*>(pointer)[1]);
// Unmap it.
EXPECT_EQ(MOJO_RESULT_OK, MojoUnmapBuffer(pointer));
// Test duplication with reduced rights.
MojoHandle h2 = MOJO_HANDLE_INVALID;
EXPECT_EQ(MOJO_RESULT_OK, MojoDuplicateHandleWithReducedRights(
h1, MOJO_HANDLE_RIGHT_DUPLICATE, &h2));
EXPECT_NE(h2, MOJO_HANDLE_INVALID);
EXPECT_NE(h2, h1);
// |h2| should have the correct rights.
rights = MOJO_HANDLE_RIGHT_NONE;
EXPECT_EQ(MOJO_RESULT_OK, MojoGetRights(h2, &rights));
EXPECT_EQ(kDefaultSharedBufferHandleRights & ~MOJO_HANDLE_RIGHT_DUPLICATE,
rights);
// Trying to duplicate |h2| should fail.
MojoHandle h3 = MOJO_HANDLE_INVALID;
EXPECT_EQ(MOJO_RESULT_PERMISSION_DENIED, MojoDuplicateHandle(h2, &h3));
EXPECT_EQ(MOJO_HANDLE_INVALID, h3);
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1));
EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2));
}
// TODO(vtl): Add multi-threaded tests.
} // namespace