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

Unified Diff: mojo/edk/system/data_pipe_impl_unittest.cc

Issue 973513004: Allow data pipe producer/consumer handles to be re-sent. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: review comments 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
« no previous file with comments | « mojo/edk/system/data_pipe_impl.cc ('k') | mojo/edk/system/local_data_pipe_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: mojo/edk/system/data_pipe_impl_unittest.cc
diff --git a/mojo/edk/system/data_pipe_impl_unittest.cc b/mojo/edk/system/data_pipe_impl_unittest.cc
index 2c7e53f107309a9b67df58c30a97434d95f53cda..b14d3af4c4c7d2c78c3873b3bb6f082bc7e468e7 100644
--- a/mojo/edk/system/data_pipe_impl_unittest.cc
+++ b/mojo/edk/system/data_pipe_impl_unittest.cc
@@ -164,10 +164,64 @@ class RemoteDataPipeImplTestHelper : public DataPipeImplTestHelper {
}
protected:
+ void SendDispatcher(size_t source_i,
+ scoped_refptr<Dispatcher> to_send,
+ scoped_refptr<Dispatcher>* to_receive) {
+ DCHECK(source_i == 0 || source_i == 1);
+ size_t dest_i = source_i ^ 1;
+
+ // Write the dispatcher to MP |source_i| (port 0). Wait and receive on MP
+ // |dest_i| (port 0). (Add the waiter first, to avoid any handling the case
+ // where it's already readable.)
+ Waiter waiter;
+ waiter.Init();
+ ASSERT_EQ(MOJO_RESULT_OK,
+ message_pipe(dest_i)->AddAwakable(
+ 0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 987, nullptr));
+ {
+ DispatcherTransport transport(
+ test::DispatcherTryStartTransport(to_send.get()));
+ ASSERT_TRUE(transport.is_valid());
+
+ std::vector<DispatcherTransport> transports;
+ transports.push_back(transport);
+ ASSERT_EQ(MOJO_RESULT_OK, message_pipe(source_i)->WriteMessage(
+ 0, NullUserPointer(), 0, &transports,
+ MOJO_WRITE_MESSAGE_FLAG_NONE));
+ transport.End();
+ }
+ uint32_t context = 0;
+ ASSERT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), &context));
+ EXPECT_EQ(987u, context);
+ HandleSignalsState hss = HandleSignalsState();
+ message_pipe(dest_i)->RemoveAwakable(0, &waiter, &hss);
+ EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
+ hss.satisfied_signals);
+ EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
+ char read_buffer[100] = {};
+ uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
+ DispatcherVector read_dispatchers;
+ uint32_t read_num_dispatchers = 10; // Maximum to get.
+ ASSERT_EQ(MOJO_RESULT_OK,
+ message_pipe(dest_i)->ReadMessage(
+ 0, UserPointer<void>(read_buffer),
+ MakeUserPointer(&read_buffer_size), &read_dispatchers,
+ &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
+ EXPECT_EQ(0u, static_cast<size_t>(read_buffer_size));
+ ASSERT_EQ(1u, read_dispatchers.size());
+ ASSERT_EQ(1u, read_num_dispatchers);
+ ASSERT_TRUE(read_dispatchers[0]);
+ EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
+
+ *to_receive = read_dispatchers[0];
+ }
+
scoped_refptr<MessagePipe> message_pipe(size_t i) {
return message_pipes_[i];
}
+ scoped_refptr<DataPipe> dp() { return dp_; }
+ private:
void EnsureMessagePipeClosed(size_t i) {
if (!message_pipes_[i])
return;
@@ -213,6 +267,9 @@ class RemoteDataPipeImplTestHelper : public DataPipeImplTestHelper {
// RemoteProducerDataPipeImplTestHelper ----------------------------------------
+// Note about naming confusion: This class is named after the "local" class,
+// i.e., |dp_| will have a |RemoteProducerDataPipeImpl|. The remote side, of
+// course, will have a |RemoteConsumerDataPipeImpl|.
class RemoteProducerDataPipeImplTestHelper
: public RemoteDataPipeImplTestHelper {
public:
@@ -220,87 +277,49 @@ class RemoteProducerDataPipeImplTestHelper
~RemoteProducerDataPipeImplTestHelper() override {}
void DoTransfer() override {
- // Write the producer to MP 0 (port 0). Wait and receive on MP 1 (port 0).
- // (Add the waiter first, to avoid any handling the case where it's already
- // readable.)
- Waiter waiter;
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- message_pipe(1)->AddAwakable(
- 0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 987, nullptr));
- {
- // This is the producer dispatcher we'll send.
- scoped_refptr<DataPipeProducerDispatcher> to_send =
- new DataPipeProducerDispatcher();
- to_send->Init(dp_);
-
- DispatcherTransport transport(
- test::DispatcherTryStartTransport(to_send.get()));
- ASSERT_TRUE(transport.is_valid());
-
- std::vector<DispatcherTransport> transports;
- transports.push_back(transport);
- ASSERT_EQ(MOJO_RESULT_OK, message_pipe(0)->WriteMessage(
- 0, NullUserPointer(), 0, &transports,
- MOJO_WRITE_MESSAGE_FLAG_NONE));
- transport.End();
-
- // |to_send| should have been closed. This is |DCHECK()|ed when it is
- // destroyed.
- EXPECT_TRUE(to_send->HasOneRef());
- }
- uint32_t context = 0;
- ASSERT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), &context));
- EXPECT_EQ(987u, context);
- HandleSignalsState hss = HandleSignalsState();
- message_pipe(1)->RemoveAwakable(0, &waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
- hss.satisfied_signals);
- EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
- char read_buffer[100] = {};
- uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
- DispatcherVector read_dispatchers;
- uint32_t read_num_dispatchers = 10; // Maximum to get.
- ASSERT_EQ(MOJO_RESULT_OK,
- message_pipe(1)->ReadMessage(
- 0, UserPointer<void>(read_buffer),
- MakeUserPointer(&read_buffer_size), &read_dispatchers,
- &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
- EXPECT_EQ(0u, static_cast<size_t>(read_buffer_size));
- ASSERT_EQ(1u, read_dispatchers.size());
- ASSERT_EQ(1u, read_num_dispatchers);
- ASSERT_TRUE(read_dispatchers[0]);
- EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
-
- ASSERT_EQ(Dispatcher::kTypeDataPipeProducer,
- read_dispatchers[0]->GetType());
+ // This is the producer dispatcher we'll send.
+ scoped_refptr<DataPipeProducerDispatcher> to_send =
+ new DataPipeProducerDispatcher();
+ to_send->Init(dp());
+ scoped_refptr<Dispatcher> to_receive;
+ SendDispatcher(0, to_send, &to_receive);
+ // |to_send| should have been closed. This is |DCHECK()|ed when it is
+ // destroyed.
+ EXPECT_TRUE(to_send->HasOneRef());
+ to_send = nullptr;
+
+ ASSERT_EQ(Dispatcher::kTypeDataPipeProducer, to_receive->GetType());
producer_dispatcher_ =
- static_cast<DataPipeProducerDispatcher*>(read_dispatchers[0].get());
+ static_cast<DataPipeProducerDispatcher*>(to_receive.get());
}
DataPipe* dpp() override {
if (producer_dispatcher_)
return producer_dispatcher_->GetDataPipeForTest();
- return dp_.get();
+ return dp().get();
}
- DataPipe* dpc() override { return dp_.get(); }
+ DataPipe* dpc() override { return dp().get(); }
void ProducerClose() override {
if (producer_dispatcher_)
ASSERT_EQ(MOJO_RESULT_OK, producer_dispatcher_->Close());
else
- dp_->ProducerClose();
+ dp()->ProducerClose();
}
- void ConsumerClose() override { dp_->ConsumerClose(); }
+ void ConsumerClose() override { dp()->ConsumerClose(); }
- private:
+ protected:
scoped_refptr<DataPipeProducerDispatcher> producer_dispatcher_;
+ private:
DISALLOW_COPY_AND_ASSIGN(RemoteProducerDataPipeImplTestHelper);
};
// RemoteConsumerDataPipeImplTestHelper ----------------------------------------
+// Note about naming confusion: This class is named after the "local" class,
+// i.e., |dp_| will have a |RemoteConsumerDataPipeImpl|. The remote side, of
+// course, will have a |RemoteProducerDataPipeImpl|.
class RemoteConsumerDataPipeImplTestHelper
: public RemoteDataPipeImplTestHelper {
public:
@@ -308,90 +327,145 @@ class RemoteConsumerDataPipeImplTestHelper
~RemoteConsumerDataPipeImplTestHelper() override {}
void DoTransfer() override {
- // Write the consumer to MP 0 (port 0). Wait and receive on MP 1 (port 0).
- // (Add the waiter first, to avoid any handling the case where it's already
- // readable.)
- Waiter waiter;
- waiter.Init();
- ASSERT_EQ(MOJO_RESULT_OK,
- message_pipe(1)->AddAwakable(
- 0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 987, nullptr));
- {
- // This is the consumer dispatcher we'll send.
- scoped_refptr<DataPipeConsumerDispatcher> to_send =
- new DataPipeConsumerDispatcher();
- to_send->Init(dp_);
-
- DispatcherTransport transport(
- test::DispatcherTryStartTransport(to_send.get()));
- ASSERT_TRUE(transport.is_valid());
-
- std::vector<DispatcherTransport> transports;
- transports.push_back(transport);
- ASSERT_EQ(MOJO_RESULT_OK, message_pipe(0)->WriteMessage(
- 0, NullUserPointer(), 0, &transports,
- MOJO_WRITE_MESSAGE_FLAG_NONE));
- transport.End();
-
- // |to_send| should have been closed. This is |DCHECK()|ed when it is
- // destroyed.
- EXPECT_TRUE(to_send->HasOneRef());
- }
- uint32_t context = 0;
- ASSERT_EQ(MOJO_RESULT_OK, waiter.Wait(test::ActionDeadline(), &context));
- EXPECT_EQ(987u, context);
- HandleSignalsState hss = HandleSignalsState();
- message_pipe(1)->RemoveAwakable(0, &waiter, &hss);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
- hss.satisfied_signals);
- EXPECT_EQ(kAllSignals, hss.satisfiable_signals);
- char read_buffer[100] = {};
- uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
- DispatcherVector read_dispatchers;
- uint32_t read_num_dispatchers = 10; // Maximum to get.
- ASSERT_EQ(MOJO_RESULT_OK,
- message_pipe(1)->ReadMessage(
- 0, UserPointer<void>(read_buffer),
- MakeUserPointer(&read_buffer_size), &read_dispatchers,
- &read_num_dispatchers, MOJO_READ_MESSAGE_FLAG_NONE));
- EXPECT_EQ(0u, static_cast<size_t>(read_buffer_size));
- ASSERT_EQ(1u, read_dispatchers.size());
- ASSERT_EQ(1u, read_num_dispatchers);
- ASSERT_TRUE(read_dispatchers[0]);
- EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
-
- ASSERT_EQ(Dispatcher::kTypeDataPipeConsumer,
- read_dispatchers[0]->GetType());
+ // This is the consumer dispatcher we'll send.
+ scoped_refptr<DataPipeConsumerDispatcher> to_send =
+ new DataPipeConsumerDispatcher();
+ to_send->Init(dp());
+ scoped_refptr<Dispatcher> to_receive;
+ SendDispatcher(0, to_send, &to_receive);
+ // |to_send| should have been closed. This is |DCHECK()|ed when it is
+ // destroyed.
+ EXPECT_TRUE(to_send->HasOneRef());
+ to_send = nullptr;
+
+ ASSERT_EQ(Dispatcher::kTypeDataPipeConsumer, to_receive->GetType());
consumer_dispatcher_ =
- static_cast<DataPipeConsumerDispatcher*>(read_dispatchers[0].get());
+ static_cast<DataPipeConsumerDispatcher*>(to_receive.get());
}
- DataPipe* dpp() override { return dp_.get(); }
+ DataPipe* dpp() override { return dp().get(); }
DataPipe* dpc() override {
if (consumer_dispatcher_)
return consumer_dispatcher_->GetDataPipeForTest();
- return dp_.get();
+ return dp().get();
}
- void ProducerClose() override { dp_->ProducerClose(); }
+ void ProducerClose() override { dp()->ProducerClose(); }
void ConsumerClose() override {
if (consumer_dispatcher_)
ASSERT_EQ(MOJO_RESULT_OK, consumer_dispatcher_->Close());
else
- dp_->ConsumerClose();
+ dp()->ConsumerClose();
}
- private:
+ protected:
scoped_refptr<DataPipeConsumerDispatcher> consumer_dispatcher_;
+ private:
DISALLOW_COPY_AND_ASSIGN(RemoteConsumerDataPipeImplTestHelper);
};
+// RemoteProducerDataPipeImplTestHelper2 ---------------------------------------
+
+// This is like |RemoteProducerDataPipeImplTestHelper|, but |DoTransfer()| does
+// a second transfer. This thus tests passing a producer handle twice, and in
+// particular tests (some of) |RemoteConsumerDataPipeImpl|'s
+// |ProducerEndSerialize()| (instead of |LocalDataPipeImpl|'s).
+//
+// Note about naming confusion: This class is named after the "local" class,
+// i.e., |dp_| will have a |RemoteProducerDataPipeImpl|. The remote side, of
+// course, will have a |RemoteConsumerDataPipeImpl|.
+class RemoteProducerDataPipeImplTestHelper2
+ : public RemoteProducerDataPipeImplTestHelper {
+ public:
+ RemoteProducerDataPipeImplTestHelper2() {}
+ ~RemoteProducerDataPipeImplTestHelper2() override {}
+
+ void DoTransfer() override {
+ // This is the producer dispatcher we'll send.
+ scoped_refptr<DataPipeProducerDispatcher> to_send =
+ new DataPipeProducerDispatcher();
+ to_send->Init(dp());
+ scoped_refptr<Dispatcher> to_receive;
+ SendDispatcher(0, to_send, &to_receive);
+ // |to_send| should have been closed. This is |DCHECK()|ed when it is
+ // destroyed.
+ EXPECT_TRUE(to_send->HasOneRef());
+ to_send = nullptr;
+ ASSERT_EQ(Dispatcher::kTypeDataPipeProducer, to_receive->GetType());
+ to_send = static_cast<DataPipeProducerDispatcher*>(to_receive.get());
+ to_receive = nullptr;
+
+ // Now send it back the other way.
+ SendDispatcher(1, to_send, &to_receive);
+ // |producer_dispatcher_| should have been closed. This is |DCHECK()|ed when
+ // it is destroyed.
+ EXPECT_TRUE(to_send->HasOneRef());
+ to_send = nullptr;
+
+ ASSERT_EQ(Dispatcher::kTypeDataPipeProducer, to_receive->GetType());
+ producer_dispatcher_ =
+ static_cast<DataPipeProducerDispatcher*>(to_receive.get());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RemoteProducerDataPipeImplTestHelper2);
+};
+
+// RemoteConsumerDataPipeImplTestHelper2 ---------------------------------------
+
+// This is like |RemoteConsumerDataPipeImplTestHelper|, but |DoTransfer()| does
+// a second transfer. This thus tests passing a consumer handle twice, and in
+// particular tests (some of) |RemoteProducerDataPipeImpl|'s
+// |ConsumerEndSerialize()| (instead of |LocalDataPipeImpl|'s).
+//
+// Note about naming confusion: This class is named after the "local" class,
+// i.e., |dp_| will have a |RemoteConsumerDataPipeImpl|. The remote side, of
+// course, will have a |RemoteProducerDataPipeImpl|.
+class RemoteConsumerDataPipeImplTestHelper2
+ : public RemoteConsumerDataPipeImplTestHelper {
+ public:
+ RemoteConsumerDataPipeImplTestHelper2() {}
+ ~RemoteConsumerDataPipeImplTestHelper2() override {}
+
+ void DoTransfer() override {
+ // This is the consumer dispatcher we'll send.
+ scoped_refptr<DataPipeConsumerDispatcher> to_send =
+ new DataPipeConsumerDispatcher();
+ to_send->Init(dp());
+ scoped_refptr<Dispatcher> to_receive;
+ SendDispatcher(0, to_send, &to_receive);
+ // |to_send| should have been closed. This is |DCHECK()|ed when it is
+ // destroyed.
+ EXPECT_TRUE(to_send->HasOneRef());
+ to_send = nullptr;
+ ASSERT_EQ(Dispatcher::kTypeDataPipeConsumer, to_receive->GetType());
+ to_send = static_cast<DataPipeConsumerDispatcher*>(to_receive.get());
+ to_receive = nullptr;
+
+ // Now send it back the other way.
+ SendDispatcher(1, to_send, &to_receive);
+ // |consumer_dispatcher_| should have been closed. This is |DCHECK()|ed when
+ // it is destroyed.
+ EXPECT_TRUE(to_send->HasOneRef());
+ to_send = nullptr;
+
+ ASSERT_EQ(Dispatcher::kTypeDataPipeConsumer, to_receive->GetType());
+ consumer_dispatcher_ =
+ static_cast<DataPipeConsumerDispatcher*>(to_receive.get());
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RemoteConsumerDataPipeImplTestHelper2);
+};
+
// Test case instantiation -----------------------------------------------------
typedef testing::Types<LocalDataPipeImplTestHelper,
RemoteProducerDataPipeImplTestHelper,
- RemoteConsumerDataPipeImplTestHelper> HelperTypes;
+ RemoteConsumerDataPipeImplTestHelper,
+ RemoteProducerDataPipeImplTestHelper2,
+ RemoteConsumerDataPipeImplTestHelper2> HelperTypes;
TYPED_TEST_CASE(DataPipeImplTest, HelperTypes);
« no previous file with comments | « mojo/edk/system/data_pipe_impl.cc ('k') | mojo/edk/system/local_data_pipe_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698