diff options
Diffstat (limited to 'mojo/edk/system/message_pipe_unittest.cc')
-rw-r--r-- | mojo/edk/system/message_pipe_unittest.cc | 699 |
1 files changed, 0 insertions, 699 deletions
diff --git a/mojo/edk/system/message_pipe_unittest.cc b/mojo/edk/system/message_pipe_unittest.cc deleted file mode 100644 index e6f1ff6..0000000 --- a/mojo/edk/system/message_pipe_unittest.cc +++ /dev/null @@ -1,699 +0,0 @@ -// Copyright 2013 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. - -#include <stdint.h> -#include <string.h> - -#include "base/memory/ref_counted.h" -#include "mojo/edk/system/test_utils.h" -#include "mojo/edk/test/mojo_test_base.h" -#include "mojo/public/c/system/core.h" -#include "mojo/public/c/system/types.h" - -namespace mojo { -namespace edk { -namespace { - -const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE | - MOJO_HANDLE_SIGNAL_WRITABLE | - MOJO_HANDLE_SIGNAL_PEER_CLOSED; -static const char kHelloWorld[] = "hello world"; - -class MessagePipeTest : public test::MojoTestBase { - public: - MessagePipeTest() { - CHECK_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &pipe0_, &pipe1_)); - } - - ~MessagePipeTest() override { - if (pipe0_ != MOJO_HANDLE_INVALID) - CHECK_EQ(MOJO_RESULT_OK, MojoClose(pipe0_)); - if (pipe1_ != MOJO_HANDLE_INVALID) - CHECK_EQ(MOJO_RESULT_OK, MojoClose(pipe1_)); - } - - MojoResult WriteMessage(MojoHandle message_pipe_handle, - const void* bytes, - uint32_t num_bytes) { - return MojoWriteMessage(message_pipe_handle, bytes, num_bytes, nullptr, 0, - MOJO_WRITE_MESSAGE_FLAG_NONE); - } - - MojoResult ReadMessage(MojoHandle message_pipe_handle, - void* bytes, - uint32_t* num_bytes, - bool may_discard = false) { - return MojoReadMessage(message_pipe_handle, bytes, num_bytes, nullptr, 0, - may_discard ? MOJO_READ_MESSAGE_FLAG_MAY_DISCARD : - MOJO_READ_MESSAGE_FLAG_NONE); - } - - MojoHandle pipe0_, pipe1_; - - private: - DISALLOW_COPY_AND_ASSIGN(MessagePipeTest); -}; - -using FuseMessagePipeTest = test::MojoTestBase; - -TEST_F(MessagePipeTest, WriteData) { - ASSERT_EQ(MOJO_RESULT_OK, - WriteMessage(pipe0_, kHelloWorld, sizeof(kHelloWorld))); -} - -// Tests: -// - only default flags -// - reading messages from a port -// - when there are no/one/two messages available for that port -// - with buffer size 0 (and null buffer) -- should get size -// - with too-small buffer -- should get size -// - also verify that buffers aren't modified when/where they shouldn't be -// - writing messages to a port -// - in the obvious scenarios (as above) -// - to a port that's been closed -// - writing a message to a port, closing the other (would be the source) port, -// and reading it -TEST_F(MessagePipeTest, Basic) { - int32_t buffer[2]; - const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); - uint32_t buffer_size; - - // Nothing to read yet on port 0. - buffer[0] = 123; - buffer[1] = 456; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe0_, buffer, &buffer_size)); - ASSERT_EQ(kBufferSize, buffer_size); - ASSERT_EQ(123, buffer[0]); - ASSERT_EQ(456, buffer[1]); - - // Ditto for port 1. - buffer[0] = 123; - buffer[1] = 456; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe1_, buffer, &buffer_size)); - - // Write from port 1 (to port 0). - buffer[0] = 789012345; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0]))); - - MojoHandleSignalsState state; - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Read from port 0. - buffer[0] = 123; - buffer[1] = 456; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe0_, buffer, &buffer_size)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - ASSERT_EQ(789012345, buffer[0]); - ASSERT_EQ(456, buffer[1]); - - // Read again from port 0 -- it should be empty. - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe0_, buffer, &buffer_size)); - - // Write two messages from port 0 (to port 1). - buffer[0] = 123456789; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, sizeof(buffer[0]))); - buffer[0] = 234567890; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, sizeof(buffer[0]))); - - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Read from port 1 with buffer size 0 (should get the size of next message). - // Also test that giving a null buffer is okay when the buffer size is 0. - buffer_size = 0; - ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, - ReadMessage(pipe1_, nullptr, &buffer_size)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - - // Read from port 1 with buffer size 1 (too small; should get the size of next - // message). - buffer[0] = 123; - buffer[1] = 456; - buffer_size = 1; - ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, - ReadMessage(pipe1_, buffer, &buffer_size)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - ASSERT_EQ(123, buffer[0]); - ASSERT_EQ(456, buffer[1]); - - // Read from port 1. - buffer[0] = 123; - buffer[1] = 456; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - ASSERT_EQ(123456789, buffer[0]); - ASSERT_EQ(456, buffer[1]); - - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Read again from port 1. - buffer[0] = 123; - buffer[1] = 456; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - ASSERT_EQ(234567890, buffer[0]); - ASSERT_EQ(456, buffer[1]); - - // Read again from port 1 -- it should be empty. - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, ReadMessage(pipe1_, buffer, &buffer_size)); - - // Write from port 0 (to port 1). - buffer[0] = 345678901; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, sizeof(buffer[0]))); - - // Close port 0. - MojoClose(pipe0_); - pipe0_ = MOJO_HANDLE_INVALID; - - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &state)); - - // Try to write from port 1 (to port 0). - buffer[0] = 456789012; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - WriteMessage(pipe1_, buffer, sizeof(buffer[0]))); - - // Read from port 1; should still get message (even though port 0 was closed). - buffer[0] = 123; - buffer[1] = 456; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - ASSERT_EQ(345678901, buffer[0]); - ASSERT_EQ(456, buffer[1]); - - // Read again from port 1 -- it should be empty (and port 0 is closed). - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - ReadMessage(pipe1_, buffer, &buffer_size)); -} - -TEST_F(MessagePipeTest, CloseWithQueuedIncomingMessages) { - int32_t buffer[1]; - const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); - uint32_t buffer_size; - - // Write some messages from port 1 (to port 0). - for (int32_t i = 0; i < 5; i++) { - buffer[0] = i; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, kBufferSize)); - } - - MojoHandleSignalsState state; - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Port 0 shouldn't be empty. - buffer_size = 0; - ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, - ReadMessage(pipe0_, nullptr, &buffer_size)); - ASSERT_EQ(kBufferSize, buffer_size); - - // Close port 0 first, which should have outstanding (incoming) messages. - MojoClose(pipe0_); - MojoClose(pipe1_); - pipe0_ = pipe1_ = MOJO_HANDLE_INVALID; -} - -TEST_F(MessagePipeTest, DiscardMode) { - int32_t buffer[2]; - const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); - uint32_t buffer_size; - - // Write from port 1 (to port 0). - buffer[0] = 789012345; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0]))); - - MojoHandleSignalsState state; - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Read/discard from port 0 (no buffer); get size. - buffer_size = 0; - ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, - ReadMessage(pipe0_, nullptr, &buffer_size, true)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - - // Read again from port 0 -- it should be empty. - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, - ReadMessage(pipe0_, buffer, &buffer_size, true)); - - // Write from port 1 (to port 0). - buffer[0] = 890123456; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, - WriteMessage(pipe1_, buffer, sizeof(buffer[0]))); - - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Read from port 0 (buffer big enough). - buffer[0] = 123; - buffer[1] = 456; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe0_, buffer, &buffer_size, true)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - ASSERT_EQ(890123456, buffer[0]); - ASSERT_EQ(456, buffer[1]); - - // Read again from port 0 -- it should be empty. - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, - ReadMessage(pipe0_, buffer, &buffer_size, true)); - - // Write from port 1 (to port 0). - buffer[0] = 901234567; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0]))); - - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Read/discard from port 0 (buffer too small); get size. - buffer_size = 1; - ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, - ReadMessage(pipe0_, buffer, &buffer_size, true)); - ASSERT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size); - - // Read again from port 0 -- it should be empty. - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, - ReadMessage(pipe0_, buffer, &buffer_size, true)); - - // Write from port 1 (to port 0). - buffer[0] = 123456789; - buffer[1] = 0; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe1_, buffer, sizeof(buffer[0]))); - - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe0_, MOJO_HANDLE_SIGNAL_READABLE, &state)); - - // Discard from port 0. - buffer_size = 1; - ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, - ReadMessage(pipe0_, nullptr, 0, true)); - - // Read again from port 0 -- it should be empty. - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, - ReadMessage(pipe0_, buffer, &buffer_size, true)); -} - -TEST_F(MessagePipeTest, BasicWaiting) { - MojoHandleSignalsState hss; - - int32_t buffer[1]; - const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); - uint32_t buffer_size; - - // Always writable (until the other port is closed). Not yet readable. Peer - // not closed. - hss = GetSignalsState(pipe0_); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - ASSERT_EQ(kAllSignals, hss.satisfiable_signals); - hss = MojoHandleSignalsState(); - - // Write from port 0 (to port 1), to make port 1 readable. - buffer[0] = 123456789; - ASSERT_EQ(MOJO_RESULT_OK, WriteMessage(pipe0_, buffer, kBufferSize)); - - // Port 1 should already be readable now. - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, - hss.satisfied_signals); - ASSERT_EQ(kAllSignals, hss.satisfiable_signals); - // ... and still writable. - hss = MojoHandleSignalsState(); - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, - hss.satisfied_signals); - ASSERT_EQ(kAllSignals, hss.satisfiable_signals); - - // Close port 0. - MojoClose(pipe0_); - pipe0_ = MOJO_HANDLE_INVALID; - - // Port 1 should be signaled with peer closed. - hss = MojoHandleSignalsState(); - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfied_signals); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfiable_signals); - - // Port 1 should not be writable. - hss = MojoHandleSignalsState(); - - ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_WRITABLE, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfied_signals); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfiable_signals); - - // But it should still be readable. - hss = MojoHandleSignalsState(); - ASSERT_EQ(MOJO_RESULT_OK, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfied_signals); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, - hss.satisfiable_signals); - - // Read from port 1. - buffer[0] = 0; - buffer_size = kBufferSize; - ASSERT_EQ(MOJO_RESULT_OK, ReadMessage(pipe1_, buffer, &buffer_size)); - ASSERT_EQ(123456789, buffer[0]); - - // Now port 1 should no longer be readable. - hss = MojoHandleSignalsState(); - ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, - WaitForSignals(pipe1_, MOJO_HANDLE_SIGNAL_READABLE, &hss)); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals); - ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); -} - -TEST_F(MessagePipeTest, InvalidMessageObjects) { - // null message - ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - MojoFreeMessage(MOJO_MESSAGE_HANDLE_INVALID)); - - // null message - ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - MojoGetMessageBuffer(MOJO_MESSAGE_HANDLE_INVALID, nullptr)); - - // Non-zero num_handles with null handles array. - ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, - MojoAllocMessage(0, nullptr, 1, MOJO_ALLOC_MESSAGE_FLAG_NONE, - nullptr)); -} - -TEST_F(MessagePipeTest, AllocAndFreeMessage) { - const std::string kMessage = "Hello, world."; - MojoMessageHandle message = MOJO_MESSAGE_HANDLE_INVALID; - ASSERT_EQ(MOJO_RESULT_OK, - MojoAllocMessage(static_cast<uint32_t>(kMessage.size()), nullptr, 0, - MOJO_ALLOC_MESSAGE_FLAG_NONE, &message)); - ASSERT_NE(MOJO_MESSAGE_HANDLE_INVALID, message); - ASSERT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message)); -} - -TEST_F(MessagePipeTest, WriteAndReadMessageObject) { - const std::string kMessage = "Hello, world."; - MojoMessageHandle message = MOJO_MESSAGE_HANDLE_INVALID; - EXPECT_EQ(MOJO_RESULT_OK, - MojoAllocMessage(static_cast<uint32_t>(kMessage.size()), nullptr, 0, - MOJO_ALLOC_MESSAGE_FLAG_NONE, &message)); - ASSERT_NE(MOJO_MESSAGE_HANDLE_INVALID, message); - - void* buffer = nullptr; - EXPECT_EQ(MOJO_RESULT_OK, MojoGetMessageBuffer(message, &buffer)); - ASSERT_TRUE(buffer); - memcpy(buffer, kMessage.data(), kMessage.size()); - - MojoHandle a, b; - CreateMessagePipe(&a, &b); - EXPECT_EQ(MOJO_RESULT_OK, - MojoWriteMessageNew(a, message, MOJO_WRITE_MESSAGE_FLAG_NONE)); - - EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(b, MOJO_HANDLE_SIGNAL_READABLE)); - uint32_t num_bytes = 0; - uint32_t num_handles = 0; - EXPECT_EQ(MOJO_RESULT_OK, - MojoReadMessageNew(b, &message, &num_bytes, nullptr, &num_handles, - MOJO_READ_MESSAGE_FLAG_NONE)); - ASSERT_NE(MOJO_MESSAGE_HANDLE_INVALID, message); - EXPECT_EQ(static_cast<uint32_t>(kMessage.size()), num_bytes); - EXPECT_EQ(0u, num_handles); - - EXPECT_EQ(MOJO_RESULT_OK, MojoGetMessageBuffer(message, &buffer)); - ASSERT_TRUE(buffer); - - EXPECT_EQ(0, strncmp(static_cast<const char*>(buffer), kMessage.data(), - num_bytes)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoFreeMessage(message)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b)); -} - -#if !defined(OS_IOS) - -const size_t kPingPongHandlesPerIteration = 50; -const size_t kPingPongIterations = 500; - -DEFINE_TEST_CLIENT_TEST_WITH_PIPE(HandlePingPong, MessagePipeTest, h) { - // Waits for a handle to become readable and writes it back to the sender. - for (size_t i = 0; i < kPingPongIterations; i++) { - MojoHandle handles[kPingPongHandlesPerIteration]; - ReadMessageWithHandles(h, handles, kPingPongHandlesPerIteration); - WriteMessageWithHandles(h, "", handles, kPingPongHandlesPerIteration); - } - - EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(h, MOJO_HANDLE_SIGNAL_READABLE)); - char msg[4]; - uint32_t num_bytes = 4; - EXPECT_EQ(MOJO_RESULT_OK, ReadMessage(h, msg, &num_bytes)); -} - -// This test is flaky: http://crbug.com/585784 -TEST_F(MessagePipeTest, DISABLED_DataPipeConsumerHandlePingPong) { - MojoHandle p, c[kPingPongHandlesPerIteration]; - for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i) { - EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(nullptr, &p, &c[i])); - MojoClose(p); - } - - RUN_CHILD_ON_PIPE(HandlePingPong, h) - for (size_t i = 0; i < kPingPongIterations; i++) { - WriteMessageWithHandles(h, "", c, kPingPongHandlesPerIteration); - ReadMessageWithHandles(h, c, kPingPongHandlesPerIteration); - } - WriteMessage(h, "quit", 4); - END_CHILD() - for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i) - MojoClose(c[i]); -} - -// This test is flaky: http://crbug.com/585784 -TEST_F(MessagePipeTest, DISABLED_DataPipeProducerHandlePingPong) { - MojoHandle p[kPingPongHandlesPerIteration], c; - for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i) { - EXPECT_EQ(MOJO_RESULT_OK, MojoCreateDataPipe(nullptr, &p[i], &c)); - MojoClose(c); - } - - RUN_CHILD_ON_PIPE(HandlePingPong, h) - for (size_t i = 0; i < kPingPongIterations; i++) { - WriteMessageWithHandles(h, "", p, kPingPongHandlesPerIteration); - ReadMessageWithHandles(h, p, kPingPongHandlesPerIteration); - } - WriteMessage(h, "quit", 4); - END_CHILD() - for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i) - MojoClose(p[i]); -} - -TEST_F(MessagePipeTest, SharedBufferHandlePingPong) { - MojoHandle buffers[kPingPongHandlesPerIteration]; - for (size_t i = 0; i <kPingPongHandlesPerIteration; ++i) - EXPECT_EQ(MOJO_RESULT_OK, MojoCreateSharedBuffer(nullptr, 1, &buffers[i])); - - RUN_CHILD_ON_PIPE(HandlePingPong, h) - for (size_t i = 0; i < kPingPongIterations; i++) { - WriteMessageWithHandles(h, "", buffers, kPingPongHandlesPerIteration); - ReadMessageWithHandles(h, buffers, kPingPongHandlesPerIteration); - } - WriteMessage(h, "quit", 4); - END_CHILD() - for (size_t i = 0; i < kPingPongHandlesPerIteration; ++i) - MojoClose(buffers[i]); -} - -#endif // !defined(OS_IOS) - -TEST_F(FuseMessagePipeTest, Basic) { - // Test that we can fuse pipes and they still work. - - MojoHandle a, b, c, d; - CreateMessagePipe(&a, &b); - CreateMessagePipe(&c, &d); - - EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c)); - - // Handles b and c should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c)); - - const std::string kTestMessage1 = "Hello, world!"; - const std::string kTestMessage2 = "Goodbye, world!"; - - WriteMessage(a, kTestMessage1); - EXPECT_EQ(kTestMessage1, ReadMessage(d)); - - WriteMessage(d, kTestMessage2); - EXPECT_EQ(kTestMessage2, ReadMessage(a)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d)); -} - -TEST_F(FuseMessagePipeTest, FuseAfterPeerWrite) { - // Test that messages written before fusion are eventually delivered. - - MojoHandle a, b, c, d; - CreateMessagePipe(&a, &b); - CreateMessagePipe(&c, &d); - - const std::string kTestMessage1 = "Hello, world!"; - const std::string kTestMessage2 = "Goodbye, world!"; - WriteMessage(a, kTestMessage1); - WriteMessage(d, kTestMessage2); - - EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c)); - - // Handles b and c should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c)); - - EXPECT_EQ(kTestMessage1, ReadMessage(d)); - EXPECT_EQ(kTestMessage2, ReadMessage(a)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d)); -} - -TEST_F(FuseMessagePipeTest, NoFuseAfterWrite) { - // Test that a pipe endpoint which has been written to cannot be fused. - - MojoHandle a, b, c, d; - CreateMessagePipe(&a, &b); - CreateMessagePipe(&c, &d); - - WriteMessage(b, "shouldn't have done that!"); - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, MojoFuseMessagePipes(b, c)); - - // Handles b and c should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d)); -} - -TEST_F(FuseMessagePipeTest, NoFuseSelf) { - // Test that a pipe's own endpoints can't be fused together. - - MojoHandle a, b; - CreateMessagePipe(&a, &b); - - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, MojoFuseMessagePipes(a, b)); - - // Handles a and b should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(a)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b)); -} - -TEST_F(FuseMessagePipeTest, FuseInvalidArguments) { - MojoHandle a, b, c, d; - CreateMessagePipe(&a, &b); - CreateMessagePipe(&c, &d); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(b)); - - // Can't fuse an invalid handle. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoFuseMessagePipes(b, c)); - - // Handle c should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c)); - - // Can't fuse a non-message pipe handle. - MojoHandle e, f; - CreateDataPipe(&e, &f, 16); - - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoFuseMessagePipes(e, d)); - - // Handles d and e should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(d)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(e)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(f)); -} - -TEST_F(FuseMessagePipeTest, FuseAfterPeerClosure) { - // Test that peer closure prior to fusion can still be detected after fusion. - - MojoHandle a, b, c, d; - CreateMessagePipe(&a, &b); - CreateMessagePipe(&c, &d); - - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); - EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c)); - - // Handles b and c should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c)); - - EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d)); -} - -TEST_F(FuseMessagePipeTest, FuseAfterPeerWriteAndClosure) { - // Test that peer write and closure prior to fusion still results in the - // both message arrival and awareness of peer closure. - - MojoHandle a, b, c, d; - CreateMessagePipe(&a, &b); - CreateMessagePipe(&c, &d); - - const std::string kTestMessage = "ayyy lmao"; - WriteMessage(a, kTestMessage); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(a)); - - EXPECT_EQ(MOJO_RESULT_OK, MojoFuseMessagePipes(b, c)); - - // Handles b and c should be closed. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(b)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(c)); - - EXPECT_EQ(kTestMessage, ReadMessage(d)); - EXPECT_EQ(MOJO_RESULT_OK, WaitForSignals(d, MOJO_HANDLE_SIGNAL_PEER_CLOSED)); - EXPECT_EQ(MOJO_RESULT_OK, MojoClose(d)); -} - -TEST_F(MessagePipeTest, ClosePipesStressTest) { - // Stress test to exercise https://crbug.com/665869. - const size_t kNumPipes = 100000; - for (size_t i = 0; i < kNumPipes; ++i) { - MojoHandle a, b; - CreateMessagePipe(&a, &b); - MojoClose(a); - MojoClose(b); - } -} - -} // namespace -} // namespace edk -} // namespace mojo |