Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Unified Diff: third_party/mojo/src/mojo/edk/system/local_data_pipe_impl_unittest.cc

Issue 975973002: Update mojo sdk to rev f68e697e389943cd9bf9652397312280e96b127a (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: shake fist at msvc Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/mojo/src/mojo/edk/system/local_data_pipe_impl_unittest.cc
diff --git a/third_party/mojo/src/mojo/edk/system/local_data_pipe_impl_unittest.cc b/third_party/mojo/src/mojo/edk/system/local_data_pipe_impl_unittest.cc
index 3b42e5705529160d0a61d5bfc1922bb620149921..7a0bb19b746dafc4aa5e6af9bddc38e44dd3e5be 100644
--- a/third_party/mojo/src/mojo/edk/system/local_data_pipe_impl_unittest.cc
+++ b/third_party/mojo/src/mojo/edk/system/local_data_pipe_impl_unittest.cc
@@ -63,28 +63,13 @@ TEST(LocalDataPipeImplTest, Creation) {
dp->ProducerClose();
dp->ConsumerClose();
}
- {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
- 7, // |element_num_bytes|.
- 7000000 // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK,
- DataPipe::ValidateCreateOptions(MakeUserPointer(&options),
- &validated_options));
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- dp->ProducerClose();
- dp->ConsumerClose();
- }
// Default capacity.
{
const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
- 100, // |element_num_bytes|.
- 0 // |capacity_num_bytes|.
+ kSizeOfOptions, // |struct_size|.
+ MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
+ 100, // |element_num_bytes|.
+ 0 // |capacity_num_bytes|.
};
MojoCreateDataPipeOptions validated_options = {0};
EXPECT_EQ(MOJO_RESULT_OK,
@@ -96,1491 +81,6 @@ TEST(LocalDataPipeImplTest, Creation) {
}
}
-TEST(LocalDataPipeImplTest, SimpleReadWrite) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 1000 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
-
- int32_t elements[10] = {0};
- uint32_t num_bytes = 0;
-
- // Try reading; nothing there yet.
- num_bytes = static_cast<uint32_t>(arraysize(elements) * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), false, false));
-
- // Query; nothing there yet.
- num_bytes = 0;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(0u, num_bytes);
-
- // Discard; nothing there yet.
- num_bytes = static_cast<uint32_t>(5u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), false));
-
- // Read with invalid |num_bytes|.
- num_bytes = sizeof(elements[0]) + 1;
- EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), false, false));
-
- // Write two elements.
- elements[0] = 123;
- elements[1] = 456;
- num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), false));
- // It should have written everything (even without "all or none").
- EXPECT_EQ(2u * sizeof(elements[0]), num_bytes);
-
- // Query.
- num_bytes = 0;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(2 * sizeof(elements[0]), num_bytes);
-
- // Read one element.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), false, false));
- EXPECT_EQ(1u * sizeof(elements[0]), num_bytes);
- EXPECT_EQ(123, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Query.
- num_bytes = 0;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(1 * sizeof(elements[0]), num_bytes);
-
- // Peek one element.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), false, true));
- EXPECT_EQ(1u * sizeof(elements[0]), num_bytes);
- EXPECT_EQ(456, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Query. Still has 1 element remaining.
- num_bytes = 0;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(1 * sizeof(elements[0]), num_bytes);
-
- // Try to read two elements, with "all or none".
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), true, false));
- EXPECT_EQ(-1, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Try to read two elements, without "all or none".
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), false, false));
- EXPECT_EQ(456, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Query.
- num_bytes = 0;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(0u, num_bytes);
-
- dp->ProducerClose();
- dp->ConsumerClose();
-}
-
-// Note: The "basic" waiting tests test that the "wait states" are correct in
-// various situations; they don't test that waiters are properly awoken on state
-// changes. (For that, we need to use multiple threads.)
-TEST(LocalDataPipeImplTest, BasicProducerWaiting) {
- // Note: We take advantage of the fact that for |LocalDataPipeImpl|,
- // capacities are strict maximums. This is not guaranteed by the API.
-
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 2 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- Waiter waiter;
- uint32_t context = 0;
- HandleSignalsState hss;
-
- // Never readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_FAILED_PRECONDITION,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 12, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Already writable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 34, &hss));
-
- // Write two elements.
- int32_t elements[2] = {123, 456};
- uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
-
- // Adding a waiter should now succeed.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 56,
- nullptr));
- // And it shouldn't be writable yet.
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ProducerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Peek one element.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), true, true));
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
- EXPECT_EQ(123, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Add a waiter.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 56,
- nullptr));
- // And it still shouldn't be writable yet.
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ProducerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Do it again.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 78,
- nullptr));
-
- // Read one element.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), true, false));
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
- EXPECT_EQ(123, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Waiting should now succeed.
- EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
- EXPECT_EQ(78u, context);
- hss = HandleSignalsState();
- dp->ProducerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Try writing, using a two-phase write.
- void* buffer = nullptr;
- num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&buffer),
- MakeUserPointer(&num_bytes), false));
- EXPECT_TRUE(buffer);
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
-
- static_cast<int32_t*>(buffer)[0] = 789;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(static_cast<uint32_t>(
- 1u * sizeof(elements[0]))));
-
- // Add a waiter.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 90,
- nullptr));
-
- // Read one element, using a two-phase read.
- const void* read_buffer = nullptr;
- num_bytes = 0u;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
- MakeUserPointer(&num_bytes), false));
- EXPECT_TRUE(read_buffer);
- // Since we only read one element (after having written three in all), the
- // two-phase read should only allow us to read one. This checks an
- // implementation detail!
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
- EXPECT_EQ(456, static_cast<const int32_t*>(read_buffer)[0]);
- EXPECT_EQ(
- MOJO_RESULT_OK,
- dp->ConsumerEndReadData(static_cast<uint32_t>(1u * sizeof(elements[0]))));
-
- // Waiting should succeed.
- EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
- EXPECT_EQ(90u, context);
- hss = HandleSignalsState();
- dp->ProducerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Write one element.
- elements[0] = 123;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
-
- // Add a waiter.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 12,
- nullptr));
-
- // Close the consumer.
- dp->ConsumerClose();
-
- // It should now be never-writable.
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000, &context));
- EXPECT_EQ(12u, context);
- hss = HandleSignalsState();
- dp->ProducerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
-
- dp->ProducerClose();
-}
-
-TEST(LocalDataPipeImplTest, PeerClosedWaiting) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 2 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- Waiter waiter;
- HandleSignalsState hss;
-
- // Check MOJO_HANDLE_SIGNAL_PEER_CLOSED on producer.
- {
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- // Add a waiter.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- 12, nullptr));
-
- // Close the consumer.
- dp->ConsumerClose();
-
- // It should be signaled.
- uint32_t context = 0;
- EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
- EXPECT_EQ(12u, context);
- hss = HandleSignalsState();
- dp->ProducerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
-
- dp->ProducerClose();
- }
-
- // Check MOJO_HANDLE_SIGNAL_PEER_CLOSED on consumer.
- {
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- // Add a waiter.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- 12, nullptr));
-
- // Close the producer.
- dp->ProducerClose();
-
- // It should be signaled.
- uint32_t context = 0;
- EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
- EXPECT_EQ(12u, context);
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
-
- dp->ConsumerClose();
- }
-}
-
-TEST(LocalDataPipeImplTest, BasicConsumerWaiting) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 1000 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- {
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- Waiter waiter;
- uint32_t context = 0;
- HandleSignalsState hss;
-
- // Never writable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 12,
- &hss));
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Not yet readable.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 34,
- nullptr));
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Write two elements.
- int32_t elements[2] = {123, 456};
- uint32_t num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), true));
-
- // Should already be readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 56,
- &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Discard one element.
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
-
- // Should still be readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 78,
- &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Peek one element.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), true, true));
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
- EXPECT_EQ(456, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Should still be readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 78,
- &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Read one element.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), true, false));
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
- EXPECT_EQ(456, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Adding a waiter should now succeed.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 90,
- nullptr));
-
- // Write one element.
- elements[0] = 789;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), true));
-
- // Waiting should now succeed.
- EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(1000, &context));
- EXPECT_EQ(90u, context);
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Close the producer.
- dp->ProducerClose();
-
- // Should still be readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 12,
- &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Read one element.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = static_cast<uint32_t>(1u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(elements),
- MakeUserPointer(&num_bytes), true, false));
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
- EXPECT_EQ(789, elements[0]);
- EXPECT_EQ(-1, elements[1]);
-
- // Should be never-readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 34,
- &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
-
- dp->ConsumerClose();
- }
-
- // Test with two-phase APIs and closing the producer with an active consumer
- // waiter.
- {
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- Waiter waiter;
- uint32_t context = 0;
- HandleSignalsState hss;
-
- // Write two elements.
- int32_t* elements = nullptr;
- void* buffer = nullptr;
- // Request room for three (but we'll only write two).
- uint32_t num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_TRUE(buffer);
- EXPECT_GE(num_bytes, static_cast<uint32_t>(3u * sizeof(elements[0])));
- elements = static_cast<int32_t*>(buffer);
- elements[0] = 123;
- elements[1] = 456;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(static_cast<uint32_t>(
- 2u * sizeof(elements[0]))));
-
- // Should already be readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 12,
- &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Read one element.
- // Request two in all-or-none mode, but only read one.
- const void* read_buffer = nullptr;
- num_bytes = static_cast<uint32_t>(2u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_TRUE(read_buffer);
- EXPECT_EQ(static_cast<uint32_t>(2u * sizeof(elements[0])), num_bytes);
- const int32_t* read_elements = static_cast<const int32_t*>(read_buffer);
- EXPECT_EQ(123, read_elements[0]);
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(static_cast<uint32_t>(
- 1u * sizeof(elements[0]))));
-
- // Should still be readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 34,
- &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Read one element.
- // Request three, but not in all-or-none mode.
- read_buffer = nullptr;
- num_bytes = static_cast<uint32_t>(3u * sizeof(elements[0]));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_buffer),
- MakeUserPointer(&num_bytes), false));
- EXPECT_TRUE(read_buffer);
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(elements[0])), num_bytes);
- read_elements = static_cast<const int32_t*>(read_buffer);
- EXPECT_EQ(456, read_elements[0]);
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(static_cast<uint32_t>(
- 1u * sizeof(elements[0]))));
-
- // Adding a waiter should now succeed.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 56,
- nullptr));
-
- // Close the producer.
- dp->ProducerClose();
-
- // Should be never-readable.
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, waiter.Wait(1000, &context));
- EXPECT_EQ(56u, context);
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
-
- dp->ConsumerClose();
- }
-}
-
-// Tests that data pipes aren't writable/readable during two-phase writes/reads.
-TEST(LocalDataPipeImplTest, BasicTwoPhaseWaiting) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 1000 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- Waiter waiter;
- HandleSignalsState hss;
-
- // It should be writable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- uint32_t num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
- void* write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), false));
- EXPECT_TRUE(write_ptr);
- EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
-
- // At this point, it shouldn't be writable.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 1,
- nullptr));
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ProducerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // It shouldn't be readable yet either.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 2,
- nullptr));
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- static_cast<int32_t*>(write_ptr)[0] = 123;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(
- static_cast<uint32_t>(1u * sizeof(int32_t))));
-
- // It should be writable again.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 3, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // And readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 4, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Start another two-phase write and check that it's readable even in the
- // middle of it.
- num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), false));
- EXPECT_TRUE(write_ptr);
- EXPECT_GE(num_bytes, static_cast<uint32_t>(1u * sizeof(int32_t)));
-
- // It should be readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 5, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // End the two-phase write without writing anything.
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(0u));
-
- // Start a two-phase read.
- num_bytes = static_cast<uint32_t>(1u * sizeof(int32_t));
- const void* read_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), false));
- EXPECT_TRUE(read_ptr);
- EXPECT_EQ(static_cast<uint32_t>(1u * sizeof(int32_t)), num_bytes);
-
- // At this point, it should still be writable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 6, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // But not readable.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 7,
- nullptr));
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // End the two-phase read without reading anything.
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(0u));
-
- // It should be readable again.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 8, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- dp->ProducerClose();
- dp->ConsumerClose();
-}
-
-// Test that a "may discard" data pipe is writable even when it's full.
-TEST(LocalDataPipeImplTest, BasicMayDiscardWaiting) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 1 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
- Waiter waiter;
- HandleSignalsState hss;
-
- // Writable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Not readable.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 1,
- nullptr));
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- uint32_t num_bytes = static_cast<uint32_t>(sizeof(int32_t));
- int32_t element = 123;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(&element),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
-
- // Still writable (even though it's full).
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 2, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Now readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 3, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Overwrite that element.
- num_bytes = static_cast<uint32_t>(sizeof(int32_t));
- element = 456;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(&element),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
-
- // Still writable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 4, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // And still readable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 5, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // Read that element.
- num_bytes = static_cast<uint32_t>(sizeof(int32_t));
- element = 0;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(&element),
- MakeUserPointer(&num_bytes), false, false));
- EXPECT_EQ(static_cast<uint32_t>(sizeof(int32_t)), num_bytes);
- EXPECT_EQ(456, element);
-
- // Still writable.
- waiter.Init();
- hss = HandleSignalsState();
- EXPECT_EQ(
- MOJO_RESULT_ALREADY_EXISTS,
- dp->ProducerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 6, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- // No longer readable.
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- dp->ConsumerAddAwakable(&waiter, MOJO_HANDLE_SIGNAL_READABLE, 7,
- nullptr));
- EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
- hss = HandleSignalsState();
- dp->ConsumerRemoveAwakable(&waiter, &hss);
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss.satisfiable_signals);
-
- dp->ProducerClose();
- dp->ConsumerClose();
-}
-
-void Seq(int32_t start, size_t count, int32_t* out) {
- for (size_t i = 0; i < count; i++)
- out[i] = start + static_cast<int32_t>(i);
-}
-
-TEST(LocalDataPipeImplTest, MayDiscard) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 10 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
-
- int32_t buffer[100] = {0};
- uint32_t num_bytes = 0;
-
- num_bytes = 20u * sizeof(int32_t);
- Seq(0, arraysize(buffer), buffer);
- // Try writing more than capacity. (This test relies on the implementation
- // enforcing the capacity strictly.)
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
-
- // Read half of what we wrote.
- num_bytes = 5u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), false, false));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
- int32_t expected_buffer[100];
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- Seq(0, 5u, expected_buffer);
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
- // Internally, a circular buffer would now look like:
- // -, -, -, -, -, 5, 6, 7, 8, 9
-
- // Write a bit more than the space that's available.
- num_bytes = 8u * sizeof(int32_t);
- Seq(100, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
- // Internally, a circular buffer would now look like:
- // 100, 101, 102, 103, 104, 105, 106, 107, 8, 9
-
- // Read half of what's available.
- num_bytes = 5u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), false, false));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- expected_buffer[0] = 8;
- expected_buffer[1] = 9;
- expected_buffer[2] = 100;
- expected_buffer[3] = 101;
- expected_buffer[4] = 102;
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
- // Internally, a circular buffer would now look like:
- // -, -, -, 103, 104, 105, 106, 107, -, -
-
- // Write one integer.
- num_bytes = 1u * sizeof(int32_t);
- Seq(200, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
- // Internally, a circular buffer would now look like:
- // -, -, -, 103, 104, 105, 106, 107, 200, -
-
- // Write five more.
- num_bytes = 5u * sizeof(int32_t);
- Seq(300, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
- // Internally, a circular buffer would now look like:
- // 301, 302, 303, 304, 104, 105, 106, 107, 200, 300
-
- // Read it all.
- num_bytes = sizeof(buffer);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), false, false));
- EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- expected_buffer[0] = 104;
- expected_buffer[1] = 105;
- expected_buffer[2] = 106;
- expected_buffer[3] = 107;
- expected_buffer[4] = 200;
- expected_buffer[5] = 300;
- expected_buffer[6] = 301;
- expected_buffer[7] = 302;
- expected_buffer[8] = 303;
- expected_buffer[9] = 304;
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Test two-phase writes, including in all-or-none mode.
- // Note: Again, the following depends on an implementation detail -- namely
- // that the write pointer will point at the 5th element of the buffer (and the
- // buffer has exactly the capacity requested).
-
- num_bytes = 0u;
- void* write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), false));
- EXPECT_TRUE(write_ptr);
- EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
- Seq(400, 6, static_cast<int32_t*>(write_ptr));
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(6u * sizeof(int32_t)));
- // Internally, a circular buffer would now look like:
- // -, -, -, -, 400, 401, 402, 403, 404, 405
-
- // |ProducerBeginWriteData()| ignores |*num_bytes| except in "all-or-none"
- // mode.
- num_bytes = 6u * sizeof(int32_t);
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
- static_cast<int32_t*>(write_ptr)[0] = 500;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(1u * sizeof(int32_t)));
- // Internally, a circular buffer would now look like:
- // 500, -, -, -, 400, 401, 402, 403, 404, 405
-
- // Requesting a 10-element buffer in all-or-none mode fails at this point.
- num_bytes = 10u * sizeof(int32_t);
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), true));
-
- // But requesting, say, a 5-element (up to 9, really) buffer should be okay.
- // It will discard two elements.
- num_bytes = 5u * sizeof(int32_t);
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
- // Only write 4 elements though.
- Seq(600, 4, static_cast<int32_t*>(write_ptr));
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(4u * sizeof(int32_t)));
- // Internally, a circular buffer would now look like:
- // 500, 600, 601, 602, 603, -, 402, 403, 404, 405
-
- // Do this again. Make sure we can get a buffer all the way out to the end of
- // the internal buffer.
- num_bytes = 5u * sizeof(int32_t);
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
- // Only write 3 elements though.
- Seq(700, 3, static_cast<int32_t*>(write_ptr));
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(3u * sizeof(int32_t)));
- // Internally, a circular buffer would now look like:
- // 500, 600, 601, 602, 603, 700, 701, 702, -, -
-
- // Read everything.
- num_bytes = sizeof(buffer);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), false, false));
- EXPECT_EQ(8u * sizeof(int32_t), num_bytes);
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- expected_buffer[0] = 500;
- expected_buffer[1] = 600;
- expected_buffer[2] = 601;
- expected_buffer[3] = 602;
- expected_buffer[4] = 603;
- expected_buffer[5] = 700;
- expected_buffer[6] = 701;
- expected_buffer[7] = 702;
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- dp->ProducerClose();
- dp->ConsumerClose();
-}
-
-TEST(LocalDataPipeImplTest, AllOrNone) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 10 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
-
- // Try writing way too much.
- uint32_t num_bytes = 20u * sizeof(int32_t);
- int32_t buffer[100];
- Seq(0, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
-
- // Should still be empty.
- num_bytes = ~0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(0u, num_bytes);
-
- // Write some data.
- num_bytes = 5u * sizeof(int32_t);
- Seq(100, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
-
- // Half full.
- num_bytes = 0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
-
- // Too much.
- num_bytes = 6u * sizeof(int32_t);
- Seq(200, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
-
- // Try reading too much.
- num_bytes = 11u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- int32_t expected_buffer[100];
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Try discarding too much.
- num_bytes = 11u * sizeof(int32_t);
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
-
- // Just a little.
- num_bytes = 2u * sizeof(int32_t);
- Seq(300, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
-
- // Just right.
- num_bytes = 3u * sizeof(int32_t);
- Seq(400, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(3u * sizeof(int32_t), num_bytes);
-
- // Exactly full.
- num_bytes = 0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
-
- // Read half.
- num_bytes = 5u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- Seq(100, 5, expected_buffer);
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Try reading too much again.
- num_bytes = 6u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Try discarding too much again.
- num_bytes = 6u * sizeof(int32_t);
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
-
- // Discard a little.
- num_bytes = 2u * sizeof(int32_t);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
-
- // Three left.
- num_bytes = 0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(3u * sizeof(int32_t), num_bytes);
-
- // Close the producer, then test producer-closed cases.
- dp->ProducerClose();
-
- // Try reading too much; "failed precondition" since the producer is closed.
- num_bytes = 4u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Try discarding too much; "failed precondition" again.
- num_bytes = 4u * sizeof(int32_t);
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
-
- // Read a little.
- num_bytes = 2u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- EXPECT_EQ(2u * sizeof(int32_t), num_bytes);
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- Seq(400, 2, expected_buffer);
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Discard the remaining element.
- num_bytes = 1u * sizeof(int32_t);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
-
- // Empty again.
- num_bytes = ~0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(0u, num_bytes);
-
- dp->ConsumerClose();
-}
-
-TEST(LocalDataPipeImplTest, AllOrNoneMayDiscard) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 10 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
-
- // Try writing way too much.
- uint32_t num_bytes = 20u * sizeof(int32_t);
- int32_t buffer[100];
- Seq(0, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
-
- // Write some stuff.
- num_bytes = 5u * sizeof(int32_t);
- Seq(100, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
-
- // Write lots of stuff (discarding all but "104").
- num_bytes = 9u * sizeof(int32_t);
- Seq(200, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(9u * sizeof(int32_t), num_bytes);
-
- // Read one.
- num_bytes = 1u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- EXPECT_EQ(1u * sizeof(int32_t), num_bytes);
- int32_t expected_buffer[100];
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- expected_buffer[0] = 104;
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Try reading too many.
- num_bytes = 10u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Try discarding too many.
- num_bytes = 10u * sizeof(int32_t);
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
-
- // Discard a bunch.
- num_bytes = 4u * sizeof(int32_t);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerDiscardData(MakeUserPointer(&num_bytes), true));
-
- // Half full.
- num_bytes = 0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(5u * sizeof(int32_t), num_bytes);
-
- // Write as much as possible.
- num_bytes = 10u * sizeof(int32_t);
- Seq(300, arraysize(buffer), buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
-
- // Read everything.
- num_bytes = 10u * sizeof(int32_t);
- memset(buffer, 0xab, sizeof(buffer));
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerReadData(UserPointer<void>(buffer),
- MakeUserPointer(&num_bytes), true, false));
- memset(expected_buffer, 0xab, sizeof(expected_buffer));
- EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
- Seq(300, 10, expected_buffer);
- EXPECT_EQ(0, memcmp(buffer, expected_buffer, sizeof(buffer)));
-
- // Note: All-or-none two-phase writes on a "may discard" data pipe are tested
- // in LocalDataPipeImplTest.MayDiscard.
-
- dp->ProducerClose();
- dp->ConsumerClose();
-}
-
-TEST(LocalDataPipeImplTest, TwoPhaseAllOrNone) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, // |flags|.
- static_cast<uint32_t>(sizeof(int32_t)), // |element_num_bytes|.
- 10 * sizeof(int32_t) // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
-
- // Try writing way too much (two-phase).
- uint32_t num_bytes = 20u * sizeof(int32_t);
- void* write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), true));
-
- // Try writing an amount which isn't a multiple of the element size
- // (two-phase).
- static_assert(sizeof(int32_t) > 1u, "Wow! int32_t's have size 1");
- num_bytes = 1u;
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), true));
-
- // Try reading way too much (two-phase).
- num_bytes = 20u * sizeof(int32_t);
- const void* read_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), true));
-
- // Write half (two-phase).
- num_bytes = 5u * sizeof(int32_t);
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), true));
- // May provide more space than requested.
- EXPECT_GE(num_bytes, 5u * sizeof(int32_t));
- EXPECT_TRUE(write_ptr);
- Seq(0, 5, static_cast<int32_t*>(write_ptr));
- EXPECT_EQ(MOJO_RESULT_OK, dp->ProducerEndWriteData(5u * sizeof(int32_t)));
-
- // Try reading an amount which isn't a multiple of the element size
- // (two-phase).
- num_bytes = 1u;
- read_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), true));
-
- // Read one (two-phase).
- num_bytes = 1u * sizeof(int32_t);
- read_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), true));
- EXPECT_GE(num_bytes, 1u * sizeof(int32_t));
- EXPECT_EQ(0, static_cast<const int32_t*>(read_ptr)[0]);
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(1u * sizeof(int32_t)));
-
- // We should have four left, leaving room for six.
- num_bytes = 0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(4u * sizeof(int32_t), num_bytes);
-
- // Assuming a tight circular buffer of the specified capacity, we can't do a
- // two-phase write of six now.
- num_bytes = 6u * sizeof(int32_t);
- write_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ProducerBeginWriteData(MakeUserPointer(&write_ptr),
- MakeUserPointer(&num_bytes), true));
-
- // Write six elements (simple), filling the buffer.
- num_bytes = 6u * sizeof(int32_t);
- int32_t buffer[100];
- Seq(100, 6, buffer);
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(buffer),
- MakeUserPointer(&num_bytes), true));
- EXPECT_EQ(6u * sizeof(int32_t), num_bytes);
-
- // We have ten.
- num_bytes = 0u;
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerQueryData(MakeUserPointer(&num_bytes)));
- EXPECT_EQ(10u * sizeof(int32_t), num_bytes);
-
- // But a two-phase read of ten should fail.
- num_bytes = 10u * sizeof(int32_t);
- read_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), true));
-
- // Close the producer.
- dp->ProducerClose();
-
- // A two-phase read of nine should work.
- num_bytes = 9u * sizeof(int32_t);
- read_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), true));
- EXPECT_GE(num_bytes, 9u * sizeof(int32_t));
- EXPECT_EQ(1, static_cast<const int32_t*>(read_ptr)[0]);
- EXPECT_EQ(2, static_cast<const int32_t*>(read_ptr)[1]);
- EXPECT_EQ(3, static_cast<const int32_t*>(read_ptr)[2]);
- EXPECT_EQ(4, static_cast<const int32_t*>(read_ptr)[3]);
- EXPECT_EQ(100, static_cast<const int32_t*>(read_ptr)[4]);
- EXPECT_EQ(101, static_cast<const int32_t*>(read_ptr)[5]);
- EXPECT_EQ(102, static_cast<const int32_t*>(read_ptr)[6]);
- EXPECT_EQ(103, static_cast<const int32_t*>(read_ptr)[7]);
- EXPECT_EQ(104, static_cast<const int32_t*>(read_ptr)[8]);
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(9u * sizeof(int32_t)));
-
- // A two-phase read of two should fail, with "failed precondition".
- num_bytes = 2u * sizeof(int32_t);
- read_ptr = nullptr;
- EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), true));
-
- dp->ConsumerClose();
-}
-
// Tests that |ProducerWriteData()| and |ConsumerReadData()| writes and reads,
// respectively, as much as possible, even if it has to "wrap around" the
// internal circular buffer. (Note that the two-phase write and read do not do
@@ -1986,86 +486,6 @@ TEST(LocalDataPipeImplTest, TwoPhaseMoreInvalidArguments) {
dp->ConsumerClose();
}
-// Tests that even with "may discard", the data won't change under a two-phase
-// read.
-// TODO(vtl): crbug.com/348644: We currently don't pass this. (There are two
-// related issues: First, we don't recognize that the data given to
-// |ConsumerBeginReadData()| isn't discardable until |ConsumerEndReadData()|,
-// and thus we erroneously allow |ProducerWriteData()| to succeed. Second, the
-// |ProducerWriteData()| then changes the data underneath the two-phase read.)
-TEST(LocalDataPipeImplTest, DISABLED_MayDiscardTwoPhaseConsistent) {
- const MojoCreateDataPipeOptions options = {
- kSizeOfOptions, // |struct_size|.
- MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD, // |flags|.
- 1, // |element_num_bytes|.
- 2 // |capacity_num_bytes|.
- };
- MojoCreateDataPipeOptions validated_options = {0};
- EXPECT_EQ(MOJO_RESULT_OK, DataPipe::ValidateCreateOptions(
- MakeUserPointer(&options), &validated_options));
-
- scoped_refptr<DataPipe> dp(DataPipe::CreateLocal(validated_options));
-
- // Write some elements.
- char elements[2] = {'a', 'b'};
- uint32_t num_bytes = 2u;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(2u, num_bytes);
-
- // Begin reading.
- const void* read_ptr = nullptr;
- num_bytes = 2u;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(2u, num_bytes);
- EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
- EXPECT_EQ('b', static_cast<const char*>(read_ptr)[1]);
-
- // Try to write some more. But nothing should be discardable right now.
- elements[0] = 'x';
- elements[1] = 'y';
- num_bytes = 2u;
- // TODO(vtl): This should be:
- // EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
- // dp->ProducerWriteData(elements, &num_bytes, false));
- // but we incorrectly think that the bytes being read are discardable. Letting
- // this through reveals the significant consequence.
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), false));
-
- // Check that our read buffer hasn't changed underneath us.
- EXPECT_EQ('a', static_cast<const char*>(read_ptr)[0]);
- EXPECT_EQ('b', static_cast<const char*>(read_ptr)[1]);
-
- // End reading.
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(2u));
-
- // Now writing should succeed.
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ProducerWriteData(UserPointer<const void>(elements),
- MakeUserPointer(&num_bytes), false));
-
- // And if we read, we should get the new values.
- read_ptr = nullptr;
- num_bytes = 2u;
- EXPECT_EQ(MOJO_RESULT_OK,
- dp->ConsumerBeginReadData(MakeUserPointer(&read_ptr),
- MakeUserPointer(&num_bytes), false));
- EXPECT_EQ(2u, num_bytes);
- EXPECT_EQ('x', static_cast<const char*>(read_ptr)[0]);
- EXPECT_EQ('y', static_cast<const char*>(read_ptr)[1]);
-
- // End reading.
- EXPECT_EQ(MOJO_RESULT_OK, dp->ConsumerEndReadData(2u));
-
- dp->ProducerClose();
- dp->ConsumerClose();
-}
-
} // namespace
} // namespace system
} // namespace mojo

Powered by Google App Engine
This is Rietveld 408576698