diff options
Diffstat (limited to 'mojo/public/cpp/system/tests/core_unittest.cc')
-rw-r--r-- | mojo/public/cpp/system/tests/core_unittest.cc | 510 |
1 files changed, 0 insertions, 510 deletions
diff --git a/mojo/public/cpp/system/tests/core_unittest.cc b/mojo/public/cpp/system/tests/core_unittest.cc deleted file mode 100644 index 40a94f0..0000000 --- a/mojo/public/cpp/system/tests/core_unittest.cc +++ /dev/null @@ -1,510 +0,0 @@ -// Copyright 2014 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++ Mojo system core wrappers. -// TODO(vtl): Maybe rename "CoreCppTest" -> "CoreTest" if/when this gets -// compiled into a different binary from the C API tests. - -#include "mojo/public/cpp/system/core.h" - -#include <stddef.h> -#include <stdint.h> -#include <map> -#include <utility> - -#include "mojo/public/cpp/system/wait.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace mojo { -namespace { - -const MojoHandleSignals kSignalReadableWritable = - MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; - -const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | - MOJO_HANDLE_SIGNAL_WRITABLE | - MOJO_HANDLE_SIGNAL_PEER_CLOSED; - -TEST(CoreCppTest, GetTimeTicksNow) { - const MojoTimeTicks start = GetTimeTicksNow(); - EXPECT_NE(static_cast<MojoTimeTicks>(0), start) - << "GetTimeTicksNow should return nonzero value"; -} - -TEST(CoreCppTest, Basic) { - // Basic |Handle| implementation: - { - EXPECT_EQ(MOJO_HANDLE_INVALID, kInvalidHandleValue); - - Handle h0; - EXPECT_EQ(kInvalidHandleValue, h0.value()); - EXPECT_EQ(kInvalidHandleValue, *h0.mutable_value()); - EXPECT_FALSE(h0.is_valid()); - - Handle h1(static_cast<MojoHandle>(123)); - EXPECT_EQ(static_cast<MojoHandle>(123), h1.value()); - EXPECT_EQ(static_cast<MojoHandle>(123), *h1.mutable_value()); - EXPECT_TRUE(h1.is_valid()); - *h1.mutable_value() = static_cast<MojoHandle>(456); - EXPECT_EQ(static_cast<MojoHandle>(456), h1.value()); - EXPECT_TRUE(h1.is_valid()); - - h1.swap(h0); - EXPECT_EQ(static_cast<MojoHandle>(456), h0.value()); - EXPECT_TRUE(h0.is_valid()); - EXPECT_FALSE(h1.is_valid()); - - h1.set_value(static_cast<MojoHandle>(789)); - h0.swap(h1); - EXPECT_EQ(static_cast<MojoHandle>(789), h0.value()); - EXPECT_TRUE(h0.is_valid()); - EXPECT_EQ(static_cast<MojoHandle>(456), h1.value()); - EXPECT_TRUE(h1.is_valid()); - - // Make sure copy constructor works. - Handle h2(h0); - EXPECT_EQ(static_cast<MojoHandle>(789), h2.value()); - // And assignment. - h2 = h1; - EXPECT_EQ(static_cast<MojoHandle>(456), h2.value()); - - // Make sure that we can put |Handle|s into |std::map|s. - h0 = Handle(static_cast<MojoHandle>(987)); - h1 = Handle(static_cast<MojoHandle>(654)); - h2 = Handle(static_cast<MojoHandle>(321)); - Handle h3; - std::map<Handle, int> handle_to_int; - handle_to_int[h0] = 0; - handle_to_int[h1] = 1; - handle_to_int[h2] = 2; - handle_to_int[h3] = 3; - - EXPECT_EQ(4u, handle_to_int.size()); - EXPECT_FALSE(handle_to_int.find(h0) == handle_to_int.end()); - EXPECT_EQ(0, handle_to_int[h0]); - EXPECT_FALSE(handle_to_int.find(h1) == handle_to_int.end()); - EXPECT_EQ(1, handle_to_int[h1]); - EXPECT_FALSE(handle_to_int.find(h2) == handle_to_int.end()); - EXPECT_EQ(2, handle_to_int[h2]); - EXPECT_FALSE(handle_to_int.find(h3) == handle_to_int.end()); - EXPECT_EQ(3, handle_to_int[h3]); - EXPECT_TRUE(handle_to_int.find(Handle(static_cast<MojoHandle>(13579))) == - handle_to_int.end()); - - // TODO(vtl): With C++11, support |std::unordered_map|s, etc. (Or figure out - // how to support the variations of |hash_map|.) - } - - // |Handle|/|ScopedHandle| functions: - { - ScopedHandle h; - - EXPECT_EQ(kInvalidHandleValue, h.get().value()); - - // This should be a no-op. - Close(std::move(h)); - - // It should still be invalid. - EXPECT_EQ(kInvalidHandleValue, h.get().value()); - - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - Wait(h.get(), ~MOJO_HANDLE_SIGNAL_NONE)); - - std::vector<Handle> wh; - wh.push_back(h.get()); - std::vector<MojoHandleSignals> sigs; - sigs.push_back(~MOJO_HANDLE_SIGNAL_NONE); - size_t result_index; - MojoResult rv = WaitMany(wh.data(), sigs.data(), wh.size(), &result_index); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, rv); - } - - // |MakeScopedHandle| (just compilation tests): - { - EXPECT_FALSE(MakeScopedHandle(Handle()).is_valid()); - EXPECT_FALSE(MakeScopedHandle(MessagePipeHandle()).is_valid()); - EXPECT_FALSE(MakeScopedHandle(DataPipeProducerHandle()).is_valid()); - EXPECT_FALSE(MakeScopedHandle(DataPipeConsumerHandle()).is_valid()); - EXPECT_FALSE(MakeScopedHandle(SharedBufferHandle()).is_valid()); - } - - // |MessagePipeHandle|/|ScopedMessagePipeHandle| functions: - { - MessagePipeHandle h_invalid; - EXPECT_FALSE(h_invalid.is_valid()); - EXPECT_EQ( - MOJO_RESULT_INVALID_ARGUMENT, - WriteMessageRaw( - h_invalid, nullptr, 0, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); - char buffer[10] = {0}; - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - WriteMessageRaw(h_invalid, - buffer, - sizeof(buffer), - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - ReadMessageRaw(h_invalid, - nullptr, - nullptr, - nullptr, - nullptr, - MOJO_READ_MESSAGE_FLAG_NONE)); - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - ReadMessageRaw(h_invalid, - buffer, - &buffer_size, - nullptr, - nullptr, - MOJO_READ_MESSAGE_FLAG_NONE)); - - // Basic tests of waiting and closing. - MojoHandle hv0 = kInvalidHandleValue; - { - ScopedMessagePipeHandle h0; - ScopedMessagePipeHandle h1; - EXPECT_FALSE(h0.get().is_valid()); - EXPECT_FALSE(h1.get().is_valid()); - - CreateMessagePipe(nullptr, &h0, &h1); - EXPECT_TRUE(h0.get().is_valid()); - EXPECT_TRUE(h1.get().is_valid()); - EXPECT_NE(h0.get().value(), h1.get().value()); - // Save the handle values, so we can check that things got closed - // correctly. - hv0 = h0.get().value(); - MojoHandle hv1 = h1.get().value(); - MojoHandleSignalsState state = h0->QuerySignalsState(); - - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, state.satisfied_signals); - EXPECT_EQ(kSignalAll, state.satisfiable_signals); - - std::vector<Handle> wh; - wh.push_back(h0.get()); - wh.push_back(h1.get()); - std::vector<MojoHandleSignals> sigs; - sigs.push_back(MOJO_HANDLE_SIGNAL_READABLE); - sigs.push_back(MOJO_HANDLE_SIGNAL_WRITABLE); - std::vector<MojoHandleSignalsState> states(sigs.size()); - - size_t result_index; - MojoResult rv = WaitMany(wh.data(), sigs.data(), wh.size(), &result_index, - states.data()); - EXPECT_EQ(MOJO_RESULT_OK, rv); - EXPECT_EQ(1u, result_index); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, states[0].satisfied_signals); - EXPECT_EQ(kSignalAll, states[0].satisfiable_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, states[1].satisfied_signals); - EXPECT_EQ(kSignalAll, states[1].satisfiable_signals); - - // Test closing |h1| explicitly. - Close(std::move(h1)); - EXPECT_FALSE(h1.get().is_valid()); - - // Make sure |h1| is closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - Wait(Handle(hv1), ~MOJO_HANDLE_SIGNAL_NONE)); - - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE, &state)); - - EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); - } - // |hv0| should have been closed when |h0| went out of scope, so this close - // should fail. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0)); - - // Actually test writing/reading messages. - { - ScopedMessagePipeHandle h0; - ScopedMessagePipeHandle h1; - CreateMessagePipe(nullptr, &h0, &h1); - - const char kHello[] = "hello"; - const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h0.get(), - kHello, - kHelloSize, - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - MojoHandleSignalsState state; - EXPECT_EQ(MOJO_RESULT_OK, - Wait(h1.get(), MOJO_HANDLE_SIGNAL_READABLE, &state)); - EXPECT_EQ(kSignalReadableWritable, state.satisfied_signals); - EXPECT_EQ(kSignalAll, state.satisfiable_signals); - - char buffer[10] = {0}; - uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); - EXPECT_EQ(MOJO_RESULT_OK, - ReadMessageRaw(h1.get(), - buffer, - &buffer_size, - nullptr, - nullptr, - MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, buffer_size); - EXPECT_STREQ(kHello, buffer); - - // Send a handle over the previously-establish message pipe. Use the - // |MessagePipe| wrapper (to test it), which automatically creates a - // message pipe. - MessagePipe mp; - - // Write a message to |mp.handle0|, before we send |mp.handle1|. - const char kWorld[] = "world!"; - const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(mp.handle0.get(), - kWorld, - kWorldSize, - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - // Send |mp.handle1| over |h1| to |h0|. - MojoHandle handles[5]; - handles[0] = mp.handle1.release().value(); - EXPECT_NE(kInvalidHandleValue, handles[0]); - EXPECT_FALSE(mp.handle1.get().is_valid()); - uint32_t handles_count = 1; - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h1.get(), - kHello, - kHelloSize, - handles, - handles_count, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - // |handles[0]| should actually be invalid now. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handles[0])); - - // Read "hello" and the sent handle. - EXPECT_EQ(MOJO_RESULT_OK, - Wait(h0.get(), MOJO_HANDLE_SIGNAL_READABLE, &state)); - EXPECT_EQ(kSignalReadableWritable, state.satisfied_signals); - EXPECT_EQ(kSignalAll, state.satisfiable_signals); - - memset(buffer, 0, sizeof(buffer)); - buffer_size = static_cast<uint32_t>(sizeof(buffer)); - for (size_t i = 0; i < arraysize(handles); i++) - handles[i] = kInvalidHandleValue; - handles_count = static_cast<uint32_t>(arraysize(handles)); - EXPECT_EQ(MOJO_RESULT_OK, - ReadMessageRaw(h0.get(), - buffer, - &buffer_size, - handles, - &handles_count, - MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, buffer_size); - EXPECT_STREQ(kHello, buffer); - EXPECT_EQ(1u, handles_count); - EXPECT_NE(kInvalidHandleValue, handles[0]); - - // Read from the sent/received handle. - mp.handle1.reset(MessagePipeHandle(handles[0])); - // Save |handles[0]| to check that it gets properly closed. - hv0 = handles[0]; - - EXPECT_EQ(MOJO_RESULT_OK, - Wait(mp.handle1.get(), MOJO_HANDLE_SIGNAL_READABLE, &state)); - EXPECT_EQ(kSignalReadableWritable, state.satisfied_signals); - EXPECT_EQ(kSignalAll, state.satisfiable_signals); - - memset(buffer, 0, sizeof(buffer)); - buffer_size = static_cast<uint32_t>(sizeof(buffer)); - for (size_t i = 0; i < arraysize(handles); i++) - handles[i] = kInvalidHandleValue; - handles_count = static_cast<uint32_t>(arraysize(handles)); - EXPECT_EQ(MOJO_RESULT_OK, - ReadMessageRaw(mp.handle1.get(), - buffer, - &buffer_size, - handles, - &handles_count, - MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kWorldSize, buffer_size); - EXPECT_STREQ(kWorld, buffer); - EXPECT_EQ(0u, handles_count); - } - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(hv0)); - } - - // TODO(vtl): Test |CloseRaw()|. - // TODO(vtl): Test |reset()| more thoroughly? -} - -TEST(CoreCppTest, TearDownWithMessagesEnqueued) { - // Tear down a message pipe which still has a message enqueued, with the - // message also having a valid message pipe handle. - { - ScopedMessagePipeHandle h0; - ScopedMessagePipeHandle h1; - CreateMessagePipe(nullptr, &h0, &h1); - - // Send a handle over the previously-establish message pipe. - ScopedMessagePipeHandle h2; - ScopedMessagePipeHandle h3; - if (CreateMessagePipe(nullptr, &h2, &h3) != MOJO_RESULT_OK) - CreateMessagePipe(nullptr, &h2, &h3); // Must be old EDK. - - // Write a message to |h2|, before we send |h3|. - const char kWorld[] = "world!"; - const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h2.get(), - kWorld, - kWorldSize, - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - // And also a message to |h3|. - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h3.get(), - kWorld, - kWorldSize, - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - // Send |h3| over |h1| to |h0|. - const char kHello[] = "hello"; - const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); - MojoHandle h3_value; - h3_value = h3.release().value(); - EXPECT_NE(kInvalidHandleValue, h3_value); - EXPECT_FALSE(h3.get().is_valid()); - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h1.get(), - kHello, - kHelloSize, - &h3_value, - 1, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - // |h3_value| should actually be invalid now. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value())); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value())); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value())); - } - - // Do this in a different order: make the enqueued message pipe handle only - // half-alive. - { - ScopedMessagePipeHandle h0; - ScopedMessagePipeHandle h1; - CreateMessagePipe(nullptr, &h0, &h1); - - // Send a handle over the previously-establish message pipe. - ScopedMessagePipeHandle h2; - ScopedMessagePipeHandle h3; - if (CreateMessagePipe(nullptr, &h2, &h3) != MOJO_RESULT_OK) - CreateMessagePipe(nullptr, &h2, &h3); // Must be old EDK. - - // Write a message to |h2|, before we send |h3|. - const char kWorld[] = "world!"; - const uint32_t kWorldSize = static_cast<uint32_t>(sizeof(kWorld)); - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h2.get(), - kWorld, - kWorldSize, - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - // And also a message to |h3|. - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h3.get(), - kWorld, - kWorldSize, - nullptr, - 0, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - - // Send |h3| over |h1| to |h0|. - const char kHello[] = "hello"; - const uint32_t kHelloSize = static_cast<uint32_t>(sizeof(kHello)); - MojoHandle h3_value; - h3_value = h3.release().value(); - EXPECT_NE(kInvalidHandleValue, h3_value); - EXPECT_FALSE(h3.get().is_valid()); - EXPECT_EQ(MOJO_RESULT_OK, - WriteMessageRaw(h1.get(), - kHello, - kHelloSize, - &h3_value, - 1, - MOJO_WRITE_MESSAGE_FLAG_NONE)); - // |h3_value| should actually be invalid now. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(h3_value)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h2.release().value())); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h0.release().value())); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(h1.release().value())); - } -} - -TEST(CoreCppTest, ScopedHandleMoveCtor) { - ScopedSharedBufferHandle buffer1 = SharedBufferHandle::Create(1024); - EXPECT_TRUE(buffer1.is_valid()); - - ScopedSharedBufferHandle buffer2 = SharedBufferHandle::Create(1024); - EXPECT_TRUE(buffer2.is_valid()); - - // If this fails to close buffer1, ScopedHandleBase::CloseIfNecessary() will - // assert. - buffer1 = std::move(buffer2); - - EXPECT_TRUE(buffer1.is_valid()); - EXPECT_FALSE(buffer2.is_valid()); -} - -TEST(CoreCppTest, BasicSharedBuffer) { - ScopedSharedBufferHandle h0 = SharedBufferHandle::Create(100); - ASSERT_TRUE(h0.is_valid()); - - // Map everything. - ScopedSharedBufferMapping mapping = h0->Map(100); - ASSERT_TRUE(mapping); - static_cast<char*>(mapping.get())[50] = 'x'; - - // Duplicate |h0| to |h1|. - ScopedSharedBufferHandle h1 = - h0->Clone(SharedBufferHandle::AccessMode::READ_ONLY); - ASSERT_TRUE(h1.is_valid()); - - // Close |h0|. - h0.reset(); - - // The mapping should still be good. - static_cast<char*>(mapping.get())[51] = 'y'; - - // Unmap it. - mapping.reset(); - - // Map half of |h1|. - mapping = h1->MapAtOffset(50, 50); - ASSERT_TRUE(mapping); - - // It should have what we wrote. - EXPECT_EQ('x', static_cast<char*>(mapping.get())[0]); - EXPECT_EQ('y', static_cast<char*>(mapping.get())[1]); - - // Unmap it. - mapping.reset(); - h1.reset(); - - // Creating a 1 EB shared buffer should fail without crashing. - EXPECT_FALSE(SharedBufferHandle::Create(1ULL << 60).is_valid()); -} - -// TODO(vtl): Write data pipe tests. - -} // namespace -} // namespace mojo |