| 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);
|
|
|
|
|