blob: b9d0723d434f5306ca939b36d5651aea74851ba8 [file] [log] [blame]
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +09001// Copyright (c) 2012 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.
4
5#include "build/build_config.h"
6
7#if defined(OS_WIN)
8#include <windows.h>
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +09009#endif
10
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090011#include <string>
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090012
avi@chromium.orga29af562013-07-18 08:00:30 +090013#include "base/message_loop/message_loop.h"
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090014#include "base/pickle.h"
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090015#include "base/threading/thread.h"
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090016#include "ipc/ipc_message.h"
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090017#include "ipc/ipc_test_base.h"
morrita@chromium.org15996aa2014-08-05 08:44:17 +090018#include "ipc/ipc_test_channel_listener.h"
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090019
viettrungluu@chromium.org7ca19132013-01-12 05:56:22 +090020namespace {
21
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090022class IPCChannelTest : public IPCTestBase {
23};
24
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090025// TODO(viettrungluu): Move to a separate IPCMessageTest.
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090026TEST_F(IPCChannelTest, BasicMessageTest) {
27 int v1 = 10;
28 std::string v2("foobar");
29 std::wstring v3(L"hello world");
30
bbudge@chromium.orgab4c6bc2013-11-05 07:28:12 +090031 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090032 EXPECT_TRUE(m.WriteInt(v1));
33 EXPECT_TRUE(m.WriteString(v2));
34 EXPECT_TRUE(m.WriteWString(v3));
35
36 PickleIterator iter(m);
37
38 int vi;
39 std::string vs;
40 std::wstring vw;
41
42 EXPECT_TRUE(m.ReadInt(&iter, &vi));
43 EXPECT_EQ(v1, vi);
44
45 EXPECT_TRUE(m.ReadString(&iter, &vs));
46 EXPECT_EQ(v2, vs);
47
48 EXPECT_TRUE(m.ReadWString(&iter, &vw));
49 EXPECT_EQ(v3, vw);
50
51 // should fail
52 EXPECT_FALSE(m.ReadInt(&iter, &vi));
53 EXPECT_FALSE(m.ReadString(&iter, &vs));
54 EXPECT_FALSE(m.ReadWString(&iter, &vw));
55}
56
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090057TEST_F(IPCChannelTest, ChannelTest) {
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090058 Init("GenericClient");
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090059
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090060 // Set up IPC channel and start client.
morrita@chromium.org15996aa2014-08-05 08:44:17 +090061 IPC::TestChannelListener listener;
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090062 CreateChannel(&listener);
63 listener.Init(sender());
64 ASSERT_TRUE(ConnectChannel());
65 ASSERT_TRUE(StartClient());
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090066
morrita@chromium.org15996aa2014-08-05 08:44:17 +090067 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090068
69 // Run message loop.
xhwang@chromium.org0b2c2a52013-05-01 05:55:03 +090070 base::MessageLoop::current()->Run();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090071
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090072 // Close the channel so the client's OnChannelError() gets fired.
73 channel()->Close();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090074
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090075 EXPECT_TRUE(WaitForClientShutdown());
76 DestroyChannel();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090077}
78
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090079// TODO(viettrungluu): Move to a separate IPCChannelWinTest.
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090080#if defined(OS_WIN)
81TEST_F(IPCChannelTest, ChannelTestExistingPipe) {
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090082 Init("GenericClient");
83
84 // Create pipe manually using the standard Chromium name and set up IPC
85 // channel.
morrita@chromium.org15996aa2014-08-05 08:44:17 +090086 IPC::TestChannelListener listener;
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090087 std::string name("\\\\.\\pipe\\chrome.");
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090088 name.append(GetChannelName("GenericClient"));
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090089 HANDLE pipe = CreateNamedPipeA(name.c_str(),
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090090 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
91 FILE_FLAG_FIRST_PIPE_INSTANCE,
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +090092 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
93 1,
94 4096,
95 4096,
96 5000,
97 NULL);
viettrungluu@chromium.org00155942013-01-26 06:51:35 +090098 CreateChannelFromChannelHandle(IPC::ChannelHandle(pipe), &listener);
99 CloseHandle(pipe); // The channel duplicates the handle.
100 listener.Init(sender());
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900101
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900102 // Connect to channel and start client.
103 ASSERT_TRUE(ConnectChannel());
104 ASSERT_TRUE(StartClient());
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900105
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900106 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900107
108 // Run message loop.
xhwang@chromium.org0b2c2a52013-05-01 05:55:03 +0900109 base::MessageLoop::current()->Run();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900110
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900111 // Close the channel so the client's OnChannelError() gets fired.
112 channel()->Close();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900113
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900114 EXPECT_TRUE(WaitForClientShutdown());
115 DestroyChannel();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900116}
117#endif // defined (OS_WIN)
118
119TEST_F(IPCChannelTest, ChannelProxyTest) {
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900120 Init("GenericClient");
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900121
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900122 base::Thread thread("ChannelProxyTestServer");
123 base::Thread::Options options;
xhwang@chromium.org0b2c2a52013-05-01 05:55:03 +0900124 options.message_loop_type = base::MessageLoop::TYPE_IO;
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900125 thread.StartWithOptions(options);
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900126
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900127 // Set up IPC channel proxy.
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900128 IPC::TestChannelListener listener;
rsleevi@chromium.org64293f12013-06-12 01:46:36 +0900129 CreateChannelProxy(&listener, thread.message_loop_proxy().get());
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900130 listener.Init(sender());
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900131
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900132 ASSERT_TRUE(StartClient());
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900133
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900134 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900135
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900136 // Run message loop.
xhwang@chromium.org0b2c2a52013-05-01 05:55:03 +0900137 base::MessageLoop::current()->Run();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900138
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900139 EXPECT_TRUE(WaitForClientShutdown());
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900140
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900141 // Destroy the channel proxy before shutting down the thread.
142 DestroyChannelProxy();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900143 thread.Stop();
144}
145
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900146class ChannelListenerWithOnConnectedSend : public IPC::TestChannelListener {
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900147 public:
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900148 ChannelListenerWithOnConnectedSend() {}
149 virtual ~ChannelListenerWithOnConnectedSend() {}
150
mostynbd41cdbb2014-10-07 16:17:16 +0900151 virtual void OnChannelConnected(int32 peer_pid) override {
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900152 SendNextMessage();
153 }
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900154};
155
156#if defined(OS_WIN)
157// Acting flakey in Windows. http://crbug.com/129595
158#define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnected
159#else
160#define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected
161#endif
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900162// This tests the case of a listener sending back an event in its
163// OnChannelConnected handler.
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900164TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) {
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900165 Init("GenericClient");
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900166
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900167 // Set up IPC channel and start client.
168 ChannelListenerWithOnConnectedSend listener;
169 CreateChannel(&listener);
170 listener.Init(sender());
171 ASSERT_TRUE(ConnectChannel());
172 ASSERT_TRUE(StartClient());
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900173
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900174 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent");
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900175
176 // Run message loop.
xhwang@chromium.org0b2c2a52013-05-01 05:55:03 +0900177 base::MessageLoop::current()->Run();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900178
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900179 // Close the channel so the client's OnChannelError() gets fired.
180 channel()->Close();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900181
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900182 EXPECT_TRUE(WaitForClientShutdown());
183 DestroyChannel();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900184}
185
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900186MULTIPROCESS_IPC_TEST_CLIENT_MAIN(GenericClient) {
xhwang@chromium.org0b2c2a52013-05-01 05:55:03 +0900187 base::MessageLoopForIO main_message_loop;
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900188 IPC::TestChannelListener listener;
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900189
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900190 // Set up IPC channel.
morrita@chromium.org2ced0042014-05-30 12:58:59 +0900191 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient(
192 IPCTestBase::GetChannelName("GenericClient"),
193 &listener));
194 CHECK(channel->Connect());
195 listener.Init(channel.get());
morrita@chromium.org15996aa2014-08-05 08:44:17 +0900196 IPC::TestChannelListener::SendOneMessage(channel.get(), "hello from child");
viettrungluu@chromium.org00155942013-01-26 06:51:35 +0900197
xhwang@chromium.org0b2c2a52013-05-01 05:55:03 +0900198 base::MessageLoop::current()->Run();
viettrungluu@chromium.org7d86af22013-01-12 00:13:37 +0900199 return 0;
200}
viettrungluu@chromium.org7ca19132013-01-12 05:56:22 +0900201
202} // namespace