Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // These tests are POSIX only. | 5 // These tests are POSIX only. |
| 6 | 6 |
| 7 #include "ipc/ipc_channel_posix.h" | 7 #include "ipc/ipc_channel_posix.h" |
| 8 | 8 |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 enum STATUS { | 34 enum STATUS { |
| 35 DISCONNECTED, | 35 DISCONNECTED, |
| 36 MESSAGE_RECEIVED, | 36 MESSAGE_RECEIVED, |
| 37 CHANNEL_ERROR, | 37 CHANNEL_ERROR, |
| 38 CONNECTED, | 38 CONNECTED, |
| 39 DENIED, | 39 DENIED, |
| 40 LISTEN_ERROR | 40 LISTEN_ERROR |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 IPCChannelPosixTestListener(bool quit_only_on_message) | 43 IPCChannelPosixTestListener(bool quit_only_on_message) |
| 44 : status_(DISCONNECTED), quit_only_on_message_(quit_only_on_message) {} | 44 : status_(DISCONNECTED), |
| 45 quit_only_on_message_(quit_only_on_message) { | |
| 46 } | |
| 45 | 47 |
| 46 virtual ~IPCChannelPosixTestListener() {} | 48 virtual ~IPCChannelPosixTestListener() {} |
| 47 | 49 |
| 48 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 50 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
| 49 EXPECT_EQ(message.type(), kQuitMessage); | 51 EXPECT_EQ(message.type(), kQuitMessage); |
| 50 status_ = MESSAGE_RECEIVED; | 52 status_ = MESSAGE_RECEIVED; |
| 51 QuitRunLoop(); | 53 QuitRunLoop(); |
| 52 return true; | 54 return true; |
| 53 } | 55 } |
| 54 | 56 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 76 virtual void OnChannelListenError() OVERRIDE { | 78 virtual void OnChannelListenError() OVERRIDE { |
| 77 status_ = LISTEN_ERROR; | 79 status_ = LISTEN_ERROR; |
| 78 if (!quit_only_on_message_) { | 80 if (!quit_only_on_message_) { |
| 79 QuitRunLoop(); | 81 QuitRunLoop(); |
| 80 } | 82 } |
| 81 } | 83 } |
| 82 | 84 |
| 83 STATUS status() { return status_; } | 85 STATUS status() { return status_; } |
| 84 | 86 |
| 85 void QuitRunLoop() { | 87 void QuitRunLoop() { |
| 86 base::MessageLoopForIO::current()->QuitNow(); | 88 base::MessageLoopForIO* loop = base::MessageLoopForIO::current(); |
| 89 if (loop->is_running()) { | |
| 90 loop->QuitNow(); | |
| 91 } else { | |
| 92 // Die as soon as Run is called. | |
| 93 loop->PostTask(FROM_HERE, loop->QuitClosure()); | |
| 94 } | |
| 87 } | 95 } |
| 88 | 96 |
| 89 private: | 97 private: |
| 90 // The current status of the listener. | 98 // The current status of the listener. |
| 91 STATUS status_; | 99 STATUS status_; |
| 92 // If |quit_only_on_message_| then the listener will only break out of | 100 // If |quit_only_on_message_| then the listener will only break out of |
| 93 // the run loop when kQuitMessage is received. | 101 // the run loop when kQuitMessage is received. |
| 94 bool quit_only_on_message_; | 102 bool quit_only_on_message_; |
| 95 }; | 103 }; |
| 96 | 104 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 } | 187 } |
| 180 handle->socket.fd = socket_fd; | 188 handle->socket.fd = socket_fd; |
| 181 } | 189 } |
| 182 | 190 |
| 183 void IPCChannelPosixTest::SpinRunLoop(base::TimeDelta delay) { | 191 void IPCChannelPosixTest::SpinRunLoop(base::TimeDelta delay) { |
| 184 base::MessageLoopForIO* loop = base::MessageLoopForIO::current(); | 192 base::MessageLoopForIO* loop = base::MessageLoopForIO::current(); |
| 185 // Post a quit task so that this loop eventually ends and we don't hang | 193 // Post a quit task so that this loop eventually ends and we don't hang |
| 186 // in the case of a bad test. Usually, the run loop will quit sooner than | 194 // in the case of a bad test. Usually, the run loop will quit sooner than |
| 187 // that because all tests use a IPCChannelPosixTestListener which quits the | 195 // that because all tests use a IPCChannelPosixTestListener which quits the |
| 188 // current run loop on any channel activity. | 196 // current run loop on any channel activity. |
| 189 loop->PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), delay); | 197 loop->PostDelayedTask(FROM_HERE, loop->QuitClosure(), delay); |
| 190 loop->Run(); | 198 loop->Run(); |
| 191 } | 199 } |
| 192 | 200 |
| 193 TEST_F(IPCChannelPosixTest, BasicListen) { | 201 TEST_F(IPCChannelPosixTest, BasicListen) { |
| 194 const std::string kChannelName = | 202 const std::string kChannelName = |
| 195 GetChannelDirName() + "/IPCChannelPosixTest_BasicListen"; | 203 GetChannelDirName() + "/IPCChannelPosixTest_BasicListen"; |
| 196 | 204 |
| 197 // Test creating a socket that is listening. | 205 // Test creating a socket that is listening. |
| 198 IPC::ChannelHandle handle(kChannelName); | 206 IPC::ChannelHandle handle(kChannelName); |
| 199 SetUpSocket(&handle, IPC::Channel::MODE_NAMED_SERVER); | 207 SetUpSocket(&handle, IPC::Channel::MODE_NAMED_SERVER); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 221 channel.Close(); | 229 channel.Close(); |
| 222 ASSERT_TRUE(HANDLE_EINTR(close(pipe_fds[1])) == 0); | 230 ASSERT_TRUE(HANDLE_EINTR(close(pipe_fds[1])) == 0); |
| 223 | 231 |
| 224 // Make sure that we can use the socket that is created for us by | 232 // Make sure that we can use the socket that is created for us by |
| 225 // a standard channel. | 233 // a standard channel. |
| 226 IPC::Channel channel2(socket_name, IPC::Channel::MODE_SERVER, NULL); | 234 IPC::Channel channel2(socket_name, IPC::Channel::MODE_SERVER, NULL); |
| 227 ASSERT_TRUE(channel2.Connect()); | 235 ASSERT_TRUE(channel2.Connect()); |
| 228 ASSERT_FALSE(channel2.AcceptsConnections()); | 236 ASSERT_FALSE(channel2.AcceptsConnections()); |
| 229 } | 237 } |
| 230 | 238 |
| 239 // If a connection closes right before a Send() call, we may end up closing | |
| 240 // the connection without notifying the listener, which can cause hangs in | |
| 241 // sync_message_filter and others. Make sure the listener is notified. | |
| 242 TEST_F(IPCChannelPosixTest, SendHangTest) { | |
| 243 IPCChannelPosixTestListener out_listener(true); | |
| 244 IPCChannelPosixTestListener in_listener(true); | |
| 245 IPC::ChannelHandle in_handle("IN"); | |
| 246 IPC::Channel in_chan(in_handle, IPC::Channel::MODE_SERVER, &in_listener); | |
| 247 base::FileDescriptor out_fd(in_chan.TakeClientFileDescriptor(), false); | |
| 248 IPC::ChannelHandle out_handle("OUT", out_fd); | |
| 249 IPC::Channel out_chan(out_handle, IPC::Channel::MODE_CLIENT, &out_listener); | |
| 250 ASSERT_TRUE(in_chan.Connect()); | |
| 251 ASSERT_TRUE(out_chan.Connect()); | |
| 252 in_chan.Close(); // simulate remote process dying at an unforunate time. | |
|
Scott Hess - ex-Googler
2013/11/13 21:33:22
sp "unfortunate".
hubbe
2013/11/20 20:21:22
Done.
| |
| 253 // Send will fail, because it cannot write the message. | |
| 254 ASSERT_FALSE(out_chan.Send(new IPC::Message( | |
| 255 0, // routing_id | |
| 256 kQuitMessage, // message type | |
| 257 IPC::Message::PRIORITY_NORMAL))); | |
| 258 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, out_listener.status()); | |
| 259 } | |
| 260 | |
| 261 // If a connection closes right before an Connect() call, | |
|
Scott Hess - ex-Googler
2013/11/13 21:33:22
"a Connect() call". Also paragraph formatting loo
hubbe
2013/11/20 20:21:22
Done.
| |
| 262 // we may end up closing the connection without notifying the listener, | |
| 263 // which can cause hangs in sync_message_filter and others. Make sure the | |
| 264 // listener is notified. | |
| 265 TEST_F(IPCChannelPosixTest, AcceptHangTest) { | |
| 266 IPCChannelPosixTestListener out_listener(true); | |
| 267 IPCChannelPosixTestListener in_listener(true); | |
| 268 IPC::ChannelHandle in_handle("IN"); | |
| 269 IPC::Channel in_chan(in_handle, IPC::Channel::MODE_SERVER, &in_listener); | |
| 270 base::FileDescriptor out_fd(in_chan.TakeClientFileDescriptor(), false); | |
| 271 IPC::ChannelHandle out_handle("OUT", out_fd); | |
| 272 IPC::Channel out_chan(out_handle, IPC::Channel::MODE_CLIENT, &out_listener); | |
| 273 ASSERT_TRUE(in_chan.Connect()); | |
| 274 in_chan.Close(); // simulate remote process dying at an unforunate time. | |
| 275 ASSERT_FALSE(out_chan.Connect()); | |
| 276 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, out_listener.status()); | |
| 277 } | |
| 278 | |
| 231 TEST_F(IPCChannelPosixTest, AdvancedConnected) { | 279 TEST_F(IPCChannelPosixTest, AdvancedConnected) { |
| 232 // Test creating a connection to an external process. | 280 // Test creating a connection to an external process. |
| 233 IPCChannelPosixTestListener listener(false); | 281 IPCChannelPosixTestListener listener(false); |
| 234 IPC::ChannelHandle chan_handle(GetConnectionSocketName()); | 282 IPC::ChannelHandle chan_handle(GetConnectionSocketName()); |
| 235 SetUpSocket(&chan_handle, IPC::Channel::MODE_NAMED_SERVER); | 283 SetUpSocket(&chan_handle, IPC::Channel::MODE_NAMED_SERVER); |
| 236 IPC::Channel channel(chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener); | 284 IPC::Channel channel(chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener); |
| 237 ASSERT_TRUE(channel.Connect()); | 285 ASSERT_TRUE(channel.Connect()); |
| 238 ASSERT_TRUE(channel.AcceptsConnections()); | 286 ASSERT_TRUE(channel.AcceptsConnections()); |
| 239 ASSERT_FALSE(channel.HasAcceptedConnection()); | 287 ASSERT_FALSE(channel.HasAcceptedConnection()); |
| 240 | 288 |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 417 if (connected) { | 465 if (connected) { |
| 418 IPCChannelPosixTest::SpinRunLoop(TestTimeouts::action_max_timeout()); | 466 IPCChannelPosixTest::SpinRunLoop(TestTimeouts::action_max_timeout()); |
| 419 EXPECT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); | 467 EXPECT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); |
| 420 } else { | 468 } else { |
| 421 EXPECT_EQ(IPCChannelPosixTestListener::DISCONNECTED, listener.status()); | 469 EXPECT_EQ(IPCChannelPosixTestListener::DISCONNECTED, listener.status()); |
| 422 } | 470 } |
| 423 return 0; | 471 return 0; |
| 424 } | 472 } |
| 425 | 473 |
| 426 } // namespace | 474 } // namespace |
| OLD | NEW |