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), | 44 : status_(DISCONNECTED), quit_only_on_message_(quit_only_on_message) {} |
45 quit_only_on_message_(quit_only_on_message) { | |
46 } | |
47 | 45 |
48 virtual ~IPCChannelPosixTestListener() {} | 46 virtual ~IPCChannelPosixTestListener() {} |
49 | 47 |
50 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 48 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
51 EXPECT_EQ(message.type(), kQuitMessage); | 49 EXPECT_EQ(message.type(), kQuitMessage); |
52 status_ = MESSAGE_RECEIVED; | 50 status_ = MESSAGE_RECEIVED; |
53 QuitRunLoop(); | 51 QuitRunLoop(); |
54 return true; | 52 return true; |
55 } | 53 } |
56 | 54 |
(...skipping 21 matching lines...) Expand all Loading... |
78 virtual void OnChannelListenError() OVERRIDE { | 76 virtual void OnChannelListenError() OVERRIDE { |
79 status_ = LISTEN_ERROR; | 77 status_ = LISTEN_ERROR; |
80 if (!quit_only_on_message_) { | 78 if (!quit_only_on_message_) { |
81 QuitRunLoop(); | 79 QuitRunLoop(); |
82 } | 80 } |
83 } | 81 } |
84 | 82 |
85 STATUS status() { return status_; } | 83 STATUS status() { return status_; } |
86 | 84 |
87 void QuitRunLoop() { | 85 void QuitRunLoop() { |
88 base::MessageLoopForIO* loop = base::MessageLoopForIO::current(); | 86 base::MessageLoopForIO::current()->QuitNow(); |
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 } | |
95 } | 87 } |
96 | 88 |
97 private: | 89 private: |
98 // The current status of the listener. | 90 // The current status of the listener. |
99 STATUS status_; | 91 STATUS status_; |
100 // If |quit_only_on_message_| then the listener will only break out of | 92 // If |quit_only_on_message_| then the listener will only break out of |
101 // the run loop when kQuitMessage is received. | 93 // the run loop when kQuitMessage is received. |
102 bool quit_only_on_message_; | 94 bool quit_only_on_message_; |
103 }; | 95 }; |
104 | 96 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 } | 179 } |
188 handle->socket.fd = socket_fd; | 180 handle->socket.fd = socket_fd; |
189 } | 181 } |
190 | 182 |
191 void IPCChannelPosixTest::SpinRunLoop(base::TimeDelta delay) { | 183 void IPCChannelPosixTest::SpinRunLoop(base::TimeDelta delay) { |
192 base::MessageLoopForIO* loop = base::MessageLoopForIO::current(); | 184 base::MessageLoopForIO* loop = base::MessageLoopForIO::current(); |
193 // Post a quit task so that this loop eventually ends and we don't hang | 185 // Post a quit task so that this loop eventually ends and we don't hang |
194 // in the case of a bad test. Usually, the run loop will quit sooner than | 186 // in the case of a bad test. Usually, the run loop will quit sooner than |
195 // that because all tests use a IPCChannelPosixTestListener which quits the | 187 // that because all tests use a IPCChannelPosixTestListener which quits the |
196 // current run loop on any channel activity. | 188 // current run loop on any channel activity. |
197 loop->PostDelayedTask(FROM_HERE, loop->QuitClosure(), delay); | 189 loop->PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(), delay); |
198 loop->Run(); | 190 loop->Run(); |
199 } | 191 } |
200 | 192 |
201 TEST_F(IPCChannelPosixTest, BasicListen) { | 193 TEST_F(IPCChannelPosixTest, BasicListen) { |
202 const std::string kChannelName = | 194 const std::string kChannelName = |
203 GetChannelDirName() + "/IPCChannelPosixTest_BasicListen"; | 195 GetChannelDirName() + "/IPCChannelPosixTest_BasicListen"; |
204 | 196 |
205 // Test creating a socket that is listening. | 197 // Test creating a socket that is listening. |
206 IPC::ChannelHandle handle(kChannelName); | 198 IPC::ChannelHandle handle(kChannelName); |
207 SetUpSocket(&handle, IPC::Channel::MODE_NAMED_SERVER); | 199 SetUpSocket(&handle, IPC::Channel::MODE_NAMED_SERVER); |
(...skipping 21 matching lines...) Expand all Loading... |
229 channel.Close(); | 221 channel.Close(); |
230 ASSERT_TRUE(IGNORE_EINTR(close(pipe_fds[1])) == 0); | 222 ASSERT_TRUE(IGNORE_EINTR(close(pipe_fds[1])) == 0); |
231 | 223 |
232 // Make sure that we can use the socket that is created for us by | 224 // Make sure that we can use the socket that is created for us by |
233 // a standard channel. | 225 // a standard channel. |
234 IPC::Channel channel2(socket_name, IPC::Channel::MODE_SERVER, NULL); | 226 IPC::Channel channel2(socket_name, IPC::Channel::MODE_SERVER, NULL); |
235 ASSERT_TRUE(channel2.Connect()); | 227 ASSERT_TRUE(channel2.Connect()); |
236 ASSERT_FALSE(channel2.AcceptsConnections()); | 228 ASSERT_FALSE(channel2.AcceptsConnections()); |
237 } | 229 } |
238 | 230 |
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 unfortunate time. | |
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 a Connect() call, we may end up closing | |
262 // the connection without notifying the listener, which can cause hangs in | |
263 // sync_message_filter and others. Make sure the listener is notified. | |
264 TEST_F(IPCChannelPosixTest, AcceptHangTest) { | |
265 IPCChannelPosixTestListener out_listener(true); | |
266 IPCChannelPosixTestListener in_listener(true); | |
267 IPC::ChannelHandle in_handle("IN"); | |
268 IPC::Channel in_chan(in_handle, IPC::Channel::MODE_SERVER, &in_listener); | |
269 base::FileDescriptor out_fd(in_chan.TakeClientFileDescriptor(), false); | |
270 IPC::ChannelHandle out_handle("OUT", out_fd); | |
271 IPC::Channel out_chan(out_handle, IPC::Channel::MODE_CLIENT, &out_listener); | |
272 ASSERT_TRUE(in_chan.Connect()); | |
273 in_chan.Close(); // simulate remote process dying at an unfortunate time. | |
274 ASSERT_FALSE(out_chan.Connect()); | |
275 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, out_listener.status()); | |
276 } | |
277 | |
278 TEST_F(IPCChannelPosixTest, AdvancedConnected) { | 231 TEST_F(IPCChannelPosixTest, AdvancedConnected) { |
279 // Test creating a connection to an external process. | 232 // Test creating a connection to an external process. |
280 IPCChannelPosixTestListener listener(false); | 233 IPCChannelPosixTestListener listener(false); |
281 IPC::ChannelHandle chan_handle(GetConnectionSocketName()); | 234 IPC::ChannelHandle chan_handle(GetConnectionSocketName()); |
282 SetUpSocket(&chan_handle, IPC::Channel::MODE_NAMED_SERVER); | 235 SetUpSocket(&chan_handle, IPC::Channel::MODE_NAMED_SERVER); |
283 IPC::Channel channel(chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener); | 236 IPC::Channel channel(chan_handle, IPC::Channel::MODE_NAMED_SERVER, &listener); |
284 ASSERT_TRUE(channel.Connect()); | 237 ASSERT_TRUE(channel.Connect()); |
285 ASSERT_TRUE(channel.AcceptsConnections()); | 238 ASSERT_TRUE(channel.AcceptsConnections()); |
286 ASSERT_FALSE(channel.HasAcceptedConnection()); | 239 ASSERT_FALSE(channel.HasAcceptedConnection()); |
287 | 240 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 if (connected) { | 417 if (connected) { |
465 IPCChannelPosixTest::SpinRunLoop(TestTimeouts::action_max_timeout()); | 418 IPCChannelPosixTest::SpinRunLoop(TestTimeouts::action_max_timeout()); |
466 EXPECT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); | 419 EXPECT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); |
467 } else { | 420 } else { |
468 EXPECT_EQ(IPCChannelPosixTestListener::DISCONNECTED, listener.status()); | 421 EXPECT_EQ(IPCChannelPosixTestListener::DISCONNECTED, listener.status()); |
469 } | 422 } |
470 return 0; | 423 return 0; |
471 } | 424 } |
472 | 425 |
473 } // namespace | 426 } // namespace |
OLD | NEW |