blob: cbcd5dc5189cafa9a2410922e9b1216e72ada5bd [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 "build/build_config.h"
#include <set>
#include "ipc/attachment_broker.h"
#include "ipc/brokerable_attachment.h"
#include "ipc/ipc_channel_reader.h"
#include "testing/gtest/include/gtest/gtest.h"
#if USE_ATTACHMENT_BROKER
namespace IPC {
namespace internal {
namespace {
class MockAttachment : public BrokerableAttachment {
public:
MockAttachment(int internal_state) : internal_state_(internal_state) {}
MockAttachment(BrokerableAttachment::AttachmentId id)
: BrokerableAttachment(id, true), internal_state_(-1) {}
void PopulateWithAttachment(const BrokerableAttachment* attachment) override {
const MockAttachment* mock_attachment =
static_cast<const MockAttachment*>(attachment);
internal_state_ = mock_attachment->internal_state_;
}
#if defined(OS_POSIX)
base::PlatformFile TakePlatformFile() override {
return base::PlatformFile();
}
#endif // OS_POSIX
BrokerableType GetBrokerableType() const override { return WIN_HANDLE; }
private:
~MockAttachment() override {}
// Internal state differentiates MockAttachments.
int internal_state_;
};
class MockAttachmentBroker : public AttachmentBroker {
public:
typedef std::set<scoped_refptr<BrokerableAttachment>> AttachmentSet;
bool SendAttachmentToProcess(const BrokerableAttachment* attachment,
base::ProcessId destination_process) override {
return false;
}
bool OnMessageReceived(const Message& message) override { return false; }
void AddAttachment(scoped_refptr<BrokerableAttachment> attachment) {
get_attachments()->push_back(attachment);
NotifyObservers(attachment->GetIdentifier());
}
};
class MockChannelReader : public ChannelReader {
public:
MockChannelReader()
: ChannelReader(nullptr), last_dispatched_message_(nullptr) {}
ReadState ReadData(char* buffer, int buffer_len, int* bytes_read) override {
return READ_FAILED;
}
bool ShouldDispatchInputMessage(Message* msg) override { return true; }
bool GetNonBrokeredAttachments(Message* msg) override { return true; }
bool DidEmptyInputBuffers() override { return true; }
void HandleInternalMessage(const Message& msg) override {}
void DispatchMessage(Message* m) override { last_dispatched_message_ = m; }
base::ProcessId GetSenderPID() override { return base::kNullProcessId; }
bool IsAttachmentBrokerEndpoint() override { return false; }
AttachmentBroker* GetAttachmentBroker() override { return broker_; }
// This instance takes ownership of |m|.
void AddMessageForDispatch(Message* m) {
get_queued_messages()->push_back(m);
}
Message* get_last_dispatched_message() { return last_dispatched_message_; }
void set_broker(AttachmentBroker* broker) { broker_ = broker; }
private:
Message* last_dispatched_message_;
AttachmentBroker* broker_;
};
} // namespace
TEST(ChannelReaderTest, AttachmentAlreadyBrokered) {
MockAttachmentBroker broker;
MockChannelReader reader;
reader.set_broker(&broker);
scoped_refptr<MockAttachment> attachment(new MockAttachment(5));
broker.AddAttachment(attachment);
Message* m = new Message;
MockAttachment* needs_brokering_attachment =
new MockAttachment(attachment->GetIdentifier());
EXPECT_TRUE(m->WriteAttachment(needs_brokering_attachment));
reader.AddMessageForDispatch(m);
EXPECT_EQ(ChannelReader::DISPATCH_FINISHED, reader.DispatchMessages());
EXPECT_EQ(m, reader.get_last_dispatched_message());
}
TEST(ChannelReaderTest, AttachmentNotYetBrokered) {
MockAttachmentBroker broker;
MockChannelReader reader;
reader.set_broker(&broker);
scoped_refptr<MockAttachment> attachment(new MockAttachment(5));
Message* m = new Message;
MockAttachment* needs_brokering_attachment =
new MockAttachment(attachment->GetIdentifier());
EXPECT_TRUE(m->WriteAttachment(needs_brokering_attachment));
reader.AddMessageForDispatch(m);
EXPECT_EQ(ChannelReader::DISPATCH_WAITING_ON_BROKER,
reader.DispatchMessages());
EXPECT_EQ(nullptr, reader.get_last_dispatched_message());
broker.AddAttachment(attachment);
EXPECT_EQ(m, reader.get_last_dispatched_message());
}
} // namespace internal
} // namespace IPC
#endif // USE_ATTACHMENT_BROKER