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 20 namespace { 21 22 class IPCChannelTest : public IPCTestBase { 23 }; 24 25 // TODO(viettrungluu): Move to a separate IPCMessageTest. 26 TEST_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 57 TEST_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) 81 TEST_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 119 TEST_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 146 class 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. 164 TEST_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 186 MULTIPROCESS_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