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. 4 5#include "build/build_config.h" 6 7#if defined(OS_WIN) 8#include <windows.h> 9#endif 10 11#include <string> 12 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" 18#include "ipc/ipc_test_channel_listener.h" 19 20namespace { 21 22class IPCChannelTest : public IPCTestBase { 23}; 24 25// TODO(viettrungluu): Move to a separate IPCMessageTest. 26TEST_F(IPCChannelTest, BasicMessageTest) { 27 int v1 = 10; 28 std::string v2("foobar"); 29 std::wstring v3(L"hello world"); 30 31 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL); 32 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 57TEST_F(IPCChannelTest, ChannelTest) { 58 Init("GenericClient"); 59 60 // Set up IPC channel and start client. 61 IPC::TestChannelListener listener; 62 CreateChannel(&listener); 63 listener.Init(sender()); 64 ASSERT_TRUE(ConnectChannel()); 65 ASSERT_TRUE(StartClient()); 66 67 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent"); 68 69 // Run message loop. 70 base::MessageLoop::current()->Run(); 71 72 // Close the channel so the client's OnChannelError() gets fired. 73 channel()->Close(); 74 75 EXPECT_TRUE(WaitForClientShutdown()); 76 DestroyChannel(); 77} 78 79// TODO(viettrungluu): Move to a separate IPCChannelWinTest. 80#if defined(OS_WIN) 81TEST_F(IPCChannelTest, ChannelTestExistingPipe) { 82 Init("GenericClient"); 83 84 // Create pipe manually using the standard Chromium name and set up IPC 85 // channel. 86 IPC::TestChannelListener listener; 87 std::string name("\\\\.\\pipe\\chrome."); 88 name.append(GetChannelName("GenericClient")); 89 HANDLE pipe = CreateNamedPipeA(name.c_str(), 90 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | 91 FILE_FLAG_FIRST_PIPE_INSTANCE, 92 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 93 1, 94 4096, 95 4096, 96 5000, 97 NULL); 98 CreateChannelFromChannelHandle(IPC::ChannelHandle(pipe), &listener); 99 CloseHandle(pipe); // The channel duplicates the handle. 100 listener.Init(sender()); 101 102 // Connect to channel and start client. 103 ASSERT_TRUE(ConnectChannel()); 104 ASSERT_TRUE(StartClient()); 105 106 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent"); 107 108 // Run message loop. 109 base::MessageLoop::current()->Run(); 110 111 // Close the channel so the client's OnChannelError() gets fired. 112 channel()->Close(); 113 114 EXPECT_TRUE(WaitForClientShutdown()); 115 DestroyChannel(); 116} 117#endif // defined (OS_WIN) 118 119TEST_F(IPCChannelTest, ChannelProxyTest) { 120 Init("GenericClient"); 121 122 base::Thread thread("ChannelProxyTestServer"); 123 base::Thread::Options options; 124 options.message_loop_type = base::MessageLoop::TYPE_IO; 125 thread.StartWithOptions(options); 126 127 // Set up IPC channel proxy. 128 IPC::TestChannelListener listener; 129 CreateChannelProxy(&listener, thread.message_loop_proxy().get()); 130 listener.Init(sender()); 131 132 ASSERT_TRUE(StartClient()); 133 134 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent"); 135 136 // Run message loop. 137 base::MessageLoop::current()->Run(); 138 139 EXPECT_TRUE(WaitForClientShutdown()); 140 141 // Destroy the channel proxy before shutting down the thread. 142 DestroyChannelProxy(); 143 thread.Stop(); 144} 145 146class ChannelListenerWithOnConnectedSend : public IPC::TestChannelListener { 147 public: 148 ChannelListenerWithOnConnectedSend() {} 149 virtual ~ChannelListenerWithOnConnectedSend() {} 150 151 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { 152 SendNextMessage(); 153 } 154}; 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 162// This tests the case of a listener sending back an event in its 163// OnChannelConnected handler. 164TEST_F(IPCChannelTest, MAYBE_SendMessageInChannelConnected) { 165 Init("GenericClient"); 166 167 // 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()); 173 174 IPC::TestChannelListener::SendOneMessage(sender(), "hello from parent"); 175 176 // Run message loop. 177 base::MessageLoop::current()->Run(); 178 179 // Close the channel so the client's OnChannelError() gets fired. 180 channel()->Close(); 181 182 EXPECT_TRUE(WaitForClientShutdown()); 183 DestroyChannel(); 184} 185 186MULTIPROCESS_IPC_TEST_CLIENT_MAIN(GenericClient) { 187 base::MessageLoopForIO main_message_loop; 188 IPC::TestChannelListener listener; 189 190 // Set up IPC channel. 191 scoped_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( 192 IPCTestBase::GetChannelName("GenericClient"), 193 &listener)); 194 CHECK(channel->Connect()); 195 listener.Init(channel.get()); 196 IPC::TestChannelListener::SendOneMessage(channel.get(), "hello from child"); 197 198 base::MessageLoop::current()->Run(); 199 return 0; 200} 201 202} // namespace 203