Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ipc / mojo / ipc_channel_mojo_unittest.cc
blob31578370399034a094fc188bc1bbe165181e7e1c
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/mojo/ipc_channel_mojo.h"
7 #include "base/base_paths.h"
8 #include "base/files/file.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/path_service.h"
11 #include "base/pickle.h"
12 #include "base/threading/thread.h"
13 #include "ipc/ipc_message.h"
14 #include "ipc/ipc_test_base.h"
15 #include "ipc/ipc_test_channel_listener.h"
17 #if defined(OS_POSIX)
18 #include "base/file_descriptor_posix.h"
19 #endif
21 namespace {
23 class ListenerThatExpectsOK : public IPC::Listener {
24 public:
25 ListenerThatExpectsOK()
26 : received_ok_(false) {}
28 virtual ~ListenerThatExpectsOK() {}
30 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
31 PickleIterator iter(message);
32 std::string should_be_ok;
33 EXPECT_TRUE(iter.ReadString(&should_be_ok));
34 EXPECT_EQ(should_be_ok, "OK");
35 received_ok_ = true;
36 base::MessageLoop::current()->Quit();
37 return true;
40 virtual void OnChannelError() OVERRIDE {
41 // The connection should be healthy while the listener is waiting
42 // message. An error can occur after that because the peer
43 // process dies.
44 DCHECK(received_ok_);
47 static void SendOK(IPC::Sender* sender) {
48 IPC::Message* message = new IPC::Message(
49 0, 2, IPC::Message::PRIORITY_NORMAL);
50 message->WriteString(std::string("OK"));
51 ASSERT_TRUE(sender->Send(message));
54 private:
55 bool received_ok_;
58 class ListenerThatShouldBeNeverCalled : public IPC::Listener {
59 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
60 NOTREACHED();
61 return true;
64 virtual void OnChannelError() OVERRIDE {
65 NOTREACHED();
68 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE {
69 NOTREACHED();
72 virtual void OnBadMessageReceived(const IPC::Message& message) OVERRIDE {
73 NOTREACHED();
77 class ChannelClient {
78 public:
79 explicit ChannelClient(IPC::Listener* listener, const char* name) {
80 scoped_ptr<IPC::Channel> bootstrap(IPC::Channel::CreateClient(
81 IPCTestBase::GetChannelName(name),
82 &never_called_));
83 channel_ = IPC::ChannelMojo::Create(
84 bootstrap.Pass(), IPC::Channel::MODE_CLIENT, listener,
85 main_message_loop_.message_loop_proxy());
88 void Connect() {
89 CHECK(channel_->Connect());
92 IPC::ChannelMojo* channel() const { return channel_.get(); }
94 private:
95 scoped_ptr<IPC::ChannelMojo> channel_;
96 ListenerThatShouldBeNeverCalled never_called_;
97 base::MessageLoopForIO main_message_loop_;
100 class IPCChannelMojoTest : public IPCTestBase {
101 public:
102 void CreateMojoChannel(IPC::Listener* listener);
104 protected:
105 virtual void SetUp() OVERRIDE {
106 IPCTestBase::SetUp();
109 ListenerThatShouldBeNeverCalled never_called_;
113 void IPCChannelMojoTest::CreateMojoChannel(IPC::Listener* listener) {
114 CreateChannel(&never_called_);
115 scoped_ptr<IPC::Channel> mojo_channel = IPC::ChannelMojo::Create(
116 ReleaseChannel(), IPC::Channel::MODE_SERVER, listener,
117 io_thread_task_runner()).PassAs<IPC::Channel>();
118 SetChannel(mojo_channel.PassAs<IPC::Channel>());
121 class TestChannelListenerWithExtraExpectations
122 : public IPC::TestChannelListener {
123 public:
124 TestChannelListenerWithExtraExpectations()
125 : is_connected_called_(false) {
128 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE {
129 IPC::TestChannelListener::OnChannelConnected(peer_pid);
130 EXPECT_TRUE(base::kNullProcessId != peer_pid);
131 is_connected_called_ = true;
134 bool is_connected_called() const { return is_connected_called_; }
136 private:
137 bool is_connected_called_;
140 TEST_F(IPCChannelMojoTest, ConnectedFromClient) {
141 Init("IPCChannelMojoTestClient");
143 // Set up IPC channel and start client.
144 TestChannelListenerWithExtraExpectations listener;
145 CreateMojoChannel(&listener);
146 listener.Init(sender());
147 ASSERT_TRUE(ConnectChannel());
148 ASSERT_TRUE(StartClient());
150 IPC::TestChannelListener::SendOneMessage(
151 sender(), "hello from parent");
153 base::MessageLoop::current()->Run();
154 EXPECT_TRUE(base::kNullProcessId != this->channel()->GetPeerPID());
156 this->channel()->Close();
158 EXPECT_TRUE(WaitForClientShutdown());
159 EXPECT_TRUE(listener.is_connected_called());
160 EXPECT_TRUE(listener.HasSentAll());
162 DestroyChannel();
165 // A long running process that connects to us
166 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestClient) {
167 TestChannelListenerWithExtraExpectations listener;
168 ChannelClient client(&listener, "IPCChannelMojoTestClient");
169 client.Connect();
170 listener.Init(client.channel());
172 IPC::TestChannelListener::SendOneMessage(
173 client.channel(), "hello from child");
174 base::MessageLoop::current()->Run();
175 EXPECT_TRUE(listener.is_connected_called());
176 EXPECT_TRUE(listener.HasSentAll());
178 return 0;
181 #if defined(OS_POSIX)
182 class ListenerThatExpectsFile : public IPC::Listener {
183 public:
184 ListenerThatExpectsFile()
185 : sender_(NULL) {}
187 virtual ~ListenerThatExpectsFile() {}
189 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
190 PickleIterator iter(message);
191 base::FileDescriptor desc;
192 EXPECT_TRUE(message.ReadFileDescriptor(&iter, &desc));
193 std::string content(GetSendingFileContent().size(), ' ');
194 base::File file(desc.fd);
195 file.Read(0, &content[0], content.size());
196 EXPECT_EQ(content, GetSendingFileContent());
197 base::MessageLoop::current()->Quit();
198 ListenerThatExpectsOK::SendOK(sender_);
199 return true;
202 virtual void OnChannelError() OVERRIDE {
203 NOTREACHED();
206 static std::string GetSendingFileContent() {
207 return "Hello";
210 static base::FilePath GetSendingFilePath() {
211 base::FilePath path;
212 bool ok = PathService::Get(base::DIR_CACHE, &path);
213 EXPECT_TRUE(ok);
214 return path.Append("ListenerThatExpectsFile.txt");
217 static void WriteAndSendFile(IPC::Sender* sender, base::File& file) {
218 std::string content = GetSendingFileContent();
219 file.WriteAtCurrentPos(content.data(), content.size());
220 file.Flush();
221 IPC::Message* message = new IPC::Message(
222 0, 2, IPC::Message::PRIORITY_NORMAL);
223 message->WriteFileDescriptor(
224 base::FileDescriptor(file.TakePlatformFile(), false));
225 ASSERT_TRUE(sender->Send(message));
228 void set_sender(IPC::Sender* sender) { sender_ = sender; }
230 private:
231 IPC::Sender* sender_;
235 TEST_F(IPCChannelMojoTest, SendPlatformHandle) {
236 Init("IPCChannelMojoTestSendPlatformHandleClient");
238 ListenerThatExpectsOK listener;
239 CreateMojoChannel(&listener);
240 ASSERT_TRUE(ConnectChannel());
241 ASSERT_TRUE(StartClient());
243 base::File file(ListenerThatExpectsFile::GetSendingFilePath(),
244 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
245 base::File::FLAG_READ);
246 ListenerThatExpectsFile::WriteAndSendFile(channel(), file);
247 base::MessageLoop::current()->Run();
249 this->channel()->Close();
251 EXPECT_TRUE(WaitForClientShutdown());
252 DestroyChannel();
255 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(IPCChannelMojoTestSendPlatformHandleClient) {
256 ListenerThatExpectsFile listener;
257 ChannelClient client(
258 &listener, "IPCChannelMojoTestSendPlatformHandleClient");
259 client.Connect();
260 listener.set_sender(client.channel());
262 base::MessageLoop::current()->Run();
264 return 0;
266 #endif
268 } // namespace