blob: e0bf9f15424b88666c2641109348e5d817e461e8 [file] [log] [blame]
// Copyright 2015 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 "mojo/edk/system/channel_endpoint.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/test_timeouts.h"
#include "mojo/edk/system/channel_test_base.h"
#include "mojo/edk/system/message_in_transit_queue.h"
#include "mojo/edk/system/message_in_transit_test_utils.h"
#include "mojo/edk/system/test_channel_endpoint_client.h"
#include "mojo/public/cpp/system/macros.h"
namespace mojo {
namespace system {
namespace {
class ChannelEndpointTest : public test::ChannelTestBase {
public:
ChannelEndpointTest() {}
~ChannelEndpointTest() override {}
void SetUp() override {
test::ChannelTestBase::SetUp();
PostMethodToIOThreadAndWait(
FROM_HERE, &ChannelEndpointTest::CreateAndInitChannelOnIOThread, 0);
PostMethodToIOThreadAndWait(
FROM_HERE, &ChannelEndpointTest::CreateAndInitChannelOnIOThread, 1);
}
void TearDown() override {
PostMethodToIOThreadAndWait(
FROM_HERE, &ChannelEndpointTest::ShutdownChannelOnIOThread, 0);
PostMethodToIOThreadAndWait(
FROM_HERE, &ChannelEndpointTest::ShutdownChannelOnIOThread, 1);
test::ChannelTestBase::TearDown();
}
private:
MOJO_DISALLOW_COPY_AND_ASSIGN(ChannelEndpointTest);
};
TEST_F(ChannelEndpointTest, Basic) {
scoped_refptr<test::TestChannelEndpointClient> client0(
new test::TestChannelEndpointClient());
scoped_refptr<ChannelEndpoint> endpoint0(
new ChannelEndpoint(client0.get(), 0));
client0->Init(0, endpoint0.get());
channel(0)->SetBootstrapEndpoint(endpoint0);
scoped_refptr<test::TestChannelEndpointClient> client1(
new test::TestChannelEndpointClient());
scoped_refptr<ChannelEndpoint> endpoint1(
new ChannelEndpoint(client1.get(), 1));
client1->Init(1, endpoint1.get());
channel(1)->SetBootstrapEndpoint(endpoint1);
// We'll receive a message on channel/client 0.
base::WaitableEvent read_event(true, false);
client0->SetReadEvent(&read_event);
// Make a test message.
unsigned message_id = 0x12345678;
scoped_ptr<MessageInTransit> send_message = test::MakeTestMessage(message_id);
// Check that our test utility works (at least in one direction).
test::VerifyTestMessage(send_message.get(), message_id);
// Event shouldn't be signalled yet.
EXPECT_FALSE(read_event.IsSignaled());
// Send it through channel/endpoint 1.
EXPECT_TRUE(endpoint1->EnqueueMessage(send_message.Pass()));
// Wait to receive it.
EXPECT_TRUE(read_event.TimedWait(TestTimeouts::tiny_timeout()));
client0->SetReadEvent(nullptr);
// Check the received message.
ASSERT_EQ(1u, client0->NumMessages());
scoped_ptr<MessageInTransit> read_message = client0->PopMessage();
ASSERT_TRUE(read_message);
test::VerifyTestMessage(read_message.get(), message_id);
}
// Checks that prequeued messages and messages sent at various stages later on
// are all sent/received (and in the correct order). (Note: Due to the way
// bootstrap endpoints work, the receiving side has to be set up first.)
TEST_F(ChannelEndpointTest, Prequeued) {
scoped_refptr<test::TestChannelEndpointClient> client0(
new test::TestChannelEndpointClient());
scoped_refptr<ChannelEndpoint> endpoint0(
new ChannelEndpoint(client0.get(), 0));
client0->Init(0, endpoint0.get());
channel(0)->SetBootstrapEndpoint(endpoint0);
MessageInTransitQueue prequeued_messages;
prequeued_messages.AddMessage(test::MakeTestMessage(1));
prequeued_messages.AddMessage(test::MakeTestMessage(2));
scoped_refptr<test::TestChannelEndpointClient> client1(
new test::TestChannelEndpointClient());
scoped_refptr<ChannelEndpoint> endpoint1(
new ChannelEndpoint(client1.get(), 1, &prequeued_messages));
client1->Init(1, endpoint1.get());
EXPECT_TRUE(endpoint1->EnqueueMessage(test::MakeTestMessage(3)));
EXPECT_TRUE(endpoint1->EnqueueMessage(test::MakeTestMessage(4)));
channel(1)->SetBootstrapEndpoint(endpoint1);
EXPECT_TRUE(endpoint1->EnqueueMessage(test::MakeTestMessage(5)));
EXPECT_TRUE(endpoint1->EnqueueMessage(test::MakeTestMessage(6)));
// Wait for the messages.
base::WaitableEvent read_event(true, false);
client0->SetReadEvent(&read_event);
for (size_t i = 0; client0->NumMessages() < 6 && i < 6; i++) {
EXPECT_TRUE(read_event.TimedWait(TestTimeouts::tiny_timeout()));
read_event.Reset();
}
client0->SetReadEvent(nullptr);
// Check the received messages.
ASSERT_EQ(6u, client0->NumMessages());
for (unsigned message_id = 1; message_id <= 6; message_id++) {
scoped_ptr<MessageInTransit> read_message = client0->PopMessage();
ASSERT_TRUE(read_message);
test::VerifyTestMessage(read_message.get(), message_id);
}
}
} // namespace
} // namespace system
} // namespace mojo