Add details (where missing) for histograms and remove a few that are not worth provid...
[chromium-blink-merge.git] / ipc / ipc_channel_unittest.cc
blobeea432a15e73c22aa3077fef06edc005463e2acc
1 // 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.
5 #include "build/build_config.h"
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #endif
11 #include <string>
13 #include "base/message_loop/message_loop.h"
14 #include "base/pickle.h"
15 #include "base/threading/thread.h"
16 #include "ipc/ipc_message.h"
17 #include "ipc/ipc_test_base.h"
19 namespace {
21 const size_t kLongMessageStringNumBytes = 50000;
23 static void Send(IPC::Sender* sender, const char* text) {
24 static int message_index = 0;
26 IPC::Message* message = new IPC::Message(0,
28 IPC::Message::PRIORITY_NORMAL);
29 message->WriteInt(message_index++);
30 message->WriteString(std::string(text));
32 // Make sure we can handle large messages.
33 char junk[kLongMessageStringNumBytes];
34 memset(junk, 'a', sizeof(junk)-1);
35 junk[sizeof(junk)-1] = 0;
36 message->WriteString(std::string(junk));
38 // DEBUG: printf("[%u] sending message [%s]\n", GetCurrentProcessId(), text);
39 sender->Send(message);
42 // A generic listener that expects messages of a certain type (see
43 // OnMessageReceived()), and either sends a generic response or quits after the
44 // 50th message (or on channel error).
45 class GenericChannelListener : public IPC::Listener {
46 public:
47 GenericChannelListener() : sender_(NULL), messages_left_(50) {}
48 virtual ~GenericChannelListener() {}
50 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
51 PickleIterator iter(message);
53 int ignored;
54 EXPECT_TRUE(iter.ReadInt(&ignored));
55 std::string data;
56 EXPECT_TRUE(iter.ReadString(&data));
57 std::string big_string;
58 EXPECT_TRUE(iter.ReadString(&big_string));
59 EXPECT_EQ(kLongMessageStringNumBytes - 1, big_string.length());
61 SendNextMessage();
62 return true;
65 virtual void OnChannelError() OVERRIDE {
66 // There is a race when closing the channel so the last message may be lost.
67 EXPECT_LE(messages_left_, 1);
68 base::MessageLoop::current()->Quit();
71 void Init(IPC::Sender* s) {
72 sender_ = s;
75 protected:
76 void SendNextMessage() {
77 if (--messages_left_ <= 0)
78 base::MessageLoop::current()->Quit();
79 else
80 Send(sender_, "Foo");
83 private:
84 IPC::Sender* sender_;
85 int messages_left_;
88 class IPCChannelTest : public IPCTestBase {
91 // TODO(viettrungluu): Move to a separate IPCMessageTest.
92 TEST_F(IPCChannelTest, BasicMessageTest) {
93 int v1 = 10;
94 std::string v2("foobar");
95 std::wstring v3(L"hello world");
97 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
98 EXPECT_TRUE(m.WriteInt(v1));
99 EXPECT_TRUE(m.WriteString(v2));
100 EXPECT_TRUE(m.WriteWString(v3));
102 PickleIterator iter(m);
104 int vi;
105 std::string vs;
106 std::wstring vw;
108 EXPECT_TRUE(m.ReadInt(&iter, &vi));
109 EXPECT_EQ(v1, vi);
111 EXPECT_TRUE(m.ReadString(&iter, &vs));
112 EXPECT_EQ(v2, vs);
114 EXPECT_TRUE(m.ReadWString(&iter, &vw));
115 EXPECT_EQ(v3, vw);
117 // should fail
118 EXPECT_FALSE(m.ReadInt(&iter, &vi));
119 EXPECT_FALSE(m.ReadString(&iter, &vs));
120 EXPECT_FALSE(m.ReadWString(&iter, &vw));
123 TEST_F(IPCChannelTest, ChannelTest) {
124 Init("GenericClient");
126 // Set up IPC channel and start client.
127 GenericChannelListener listener;
128 CreateChannel(&listener);
129 listener.Init(sender());
130 ASSERT_TRUE(ConnectChannel());
131 ASSERT_TRUE(StartClient());
133 Send(sender(), "hello from parent");
135 // Run message loop.
136 base::MessageLoop::current()->Run();
138 // Close the channel so the client's OnChannelError() gets fired.
139 channel()->Close();
141 EXPECT_TRUE(WaitForClientShutdown());
142 DestroyChannel();
145 // TODO(viettrungluu): Move to a separate IPCChannelWinTest.
146 #if defined(OS_WIN)
147 TEST_F(IPCChannelTest, ChannelTestExistingPipe) {
148 Init("GenericClient");
150 // Create pipe manually using the standard Chromium name and set up IPC
151 // channel.
152 GenericChannelListener listener;
153 std::string name("\\\\.\\pipe\\chrome.");
154 name.append(GetChannelName("GenericClient"));
155 HANDLE pipe = CreateNamedPipeA(name.c_str(),
156 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
157 FILE_FLAG_FIRST_PIPE_INSTANCE,
158 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
160 4096,
161 4096,
162 5000,
163 NULL);
164 CreateChannelFromChannelHandle(IPC::ChannelHandle(pipe), &listener);
165 CloseHandle(pipe); // The channel duplicates the handle.
166 listener.Init(sender());
168 // Connect to channel and start client.
169 ASSERT_TRUE(ConnectChannel());
170 ASSERT_TRUE(StartClient());
172 Send(sender(), "hello from parent");
174 // Run message loop.
175 base::MessageLoop::current()->Run();
177 // Close the channel so the client's OnChannelError() gets fired.
178 channel()->Close();
180 EXPECT_TRUE(WaitForClientShutdown());
181 DestroyChannel();
183 #endif // defined (OS_WIN)
185 TEST_F(IPCChannelTest, ChannelProxyTest) {
186 Init("GenericClient");
188 base::Thread thread("ChannelProxyTestServer");
189 base::Thread::Options options;
190 options.message_loop_type = base::MessageLoop::TYPE_IO;
191 thread.StartWithOptions(options);
193 // Set up IPC channel proxy.
194 GenericChannelListener listener;
195 CreateChannelProxy(&listener, thread.message_loop_proxy().get());
196 listener.Init(sender());
198 ASSERT_TRUE(StartClient());
200 Send(sender(), "hello from parent");
202 // Run message loop.
203 base::MessageLoop::current()->Run();
205 EXPECT_TRUE(WaitForClientShutdown());
207 // Destroy the channel proxy before shutting down the thread.
208 DestroyChannelProxy();
209 thread.Stop();
212 class ChannelListenerWithOnConnectedSend : public GenericChannelListener {
213 public:
214 ChannelListenerWithOnConnectedSend() {}
215 virtual ~ChannelListenerWithOnConnectedSend() {}
217 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE {
218 SendNextMessage();
222 #if defined(OS_WIN)
223 // Acting flakey in Windows. http://crbug.com/129595
224 #define MAYBE_SendMessageInChannelConnected DISABLED_SendMessageInChannelConnected
225 #else
226 #define MAYBE_SendMessageInChannelConnected SendMessageInChannelConnected
227 #endif
228 // This tests the case of a listener sending back an event in its
229 // OnChannelConnected handler.
230 TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) {
231 Init("GenericClient");
233 // Set up IPC channel and start client.
234 ChannelListenerWithOnConnectedSend listener;
235 CreateChannel(&listener);
236 listener.Init(sender());
237 ASSERT_TRUE(ConnectChannel());
238 ASSERT_TRUE(StartClient());
240 Send(sender(), "hello from parent");
242 // Run message loop.
243 base::MessageLoop::current()->Run();
245 // Close the channel so the client's OnChannelError() gets fired.
246 channel()->Close();
248 EXPECT_TRUE(WaitForClientShutdown());
249 DestroyChannel();
252 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(GenericClient) {
253 base::MessageLoopForIO main_message_loop;
254 GenericChannelListener listener;
256 // Set up IPC channel.
257 IPC::Channel channel(IPCTestBase::GetChannelName("GenericClient"),
258 IPC::Channel::MODE_CLIENT,
259 &listener);
260 CHECK(channel.Connect());
261 listener.Init(&channel);
262 Send(&channel, "hello from child");
264 base::MessageLoop::current()->Run();
265 return 0;
268 } // namespace