| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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> |
| 11 #include <sys/un.h> | 11 #include <sys/un.h> |
| 12 #include <unistd.h> | 12 #include <unistd.h> |
| 13 | 13 |
| 14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 15 #include "base/eintr_wrapper.h" | 15 #include "base/eintr_wrapper.h" |
| 16 #include "base/file_path.h" | 16 #include "base/file_path.h" |
| 17 #include "base/file_util.h" | 17 #include "base/file_util.h" |
| 18 #include "base/memory/scoped_ptr.h" | 18 #include "base/memory/scoped_ptr.h" |
| 19 #include "base/message_loop.h" | 19 #include "base/message_loop.h" |
| 20 #include "base/test/multiprocess_test.h" | 20 #include "base/test/multiprocess_test.h" |
| 21 #include "base/test/test_timeouts.h" | 21 #include "base/test/test_timeouts.h" |
| 22 #include "testing/multiprocess_func_list.h" | 22 #include "testing/multiprocess_func_list.h" |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 enum { | 26 static const uint32 kQuitMessage = 47; |
| 27 QUIT_MESSAGE = 47 | |
| 28 }; | |
| 29 | 27 |
| 30 class IPCChannelPosixTestListener : public IPC::Channel::Listener { | 28 class IPCChannelPosixTestListener : public IPC::Channel::Listener { |
| 31 public: | 29 public: |
| 32 enum STATUS { | 30 enum STATUS { |
| 33 DISCONNECTED, | 31 DISCONNECTED, |
| 34 MESSAGE_RECEIVED, | 32 MESSAGE_RECEIVED, |
| 35 CHANNEL_ERROR, | 33 CHANNEL_ERROR, |
| 36 CONNECTED, | 34 CONNECTED, |
| 37 DENIED, | 35 DENIED, |
| 38 LISTEN_ERROR | 36 LISTEN_ERROR |
| 39 }; | 37 }; |
| 40 | 38 |
| 41 IPCChannelPosixTestListener(bool quit_only_on_message) | 39 IPCChannelPosixTestListener(bool quit_only_on_message) |
| 42 : status_(DISCONNECTED), quit_only_on_message_(quit_only_on_message) {} | 40 : status_(DISCONNECTED), quit_only_on_message_(quit_only_on_message) {} |
| 43 | 41 |
| 44 virtual ~IPCChannelPosixTestListener() {} | 42 virtual ~IPCChannelPosixTestListener() {} |
| 45 | 43 |
| 46 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { | 44 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { |
| 47 EXPECT_EQ(message.type(), QUIT_MESSAGE); | 45 EXPECT_EQ(message.type(), kQuitMessage); |
| 48 status_ = MESSAGE_RECEIVED; | 46 status_ = MESSAGE_RECEIVED; |
| 49 QuitRunLoop(); | 47 QuitRunLoop(); |
| 50 return true; | 48 return true; |
| 51 } | 49 } |
| 52 | 50 |
| 53 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { | 51 virtual void OnChannelConnected(int32 peer_pid) OVERRIDE { |
| 54 status_ = CONNECTED; | 52 status_ = CONNECTED; |
| 55 if (!quit_only_on_message_) { | 53 if (!quit_only_on_message_) { |
| 56 QuitRunLoop(); | 54 QuitRunLoop(); |
| 57 } | 55 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 81 STATUS status() { return status_; } | 79 STATUS status() { return status_; } |
| 82 | 80 |
| 83 void QuitRunLoop() { | 81 void QuitRunLoop() { |
| 84 MessageLoopForIO::current()->QuitNow(); | 82 MessageLoopForIO::current()->QuitNow(); |
| 85 } | 83 } |
| 86 | 84 |
| 87 private: | 85 private: |
| 88 // The current status of the listener. | 86 // The current status of the listener. |
| 89 STATUS status_; | 87 STATUS status_; |
| 90 // If |quit_only_on_message_| then the listener will only break out of | 88 // If |quit_only_on_message_| then the listener will only break out of |
| 91 // the run loop when the QUIT_MESSAGE is received. | 89 // the run loop when kQuitMessage is received. |
| 92 bool quit_only_on_message_; | 90 bool quit_only_on_message_; |
| 93 }; | 91 }; |
| 94 | 92 |
| 95 } // namespace | 93 } // namespace |
| 96 | 94 |
| 97 class IPCChannelPosixTest : public base::MultiProcessTest { | 95 class IPCChannelPosixTest : public base::MultiProcessTest { |
| 98 public: | 96 public: |
| 99 static const char kConnectionSocketTestName[]; | 97 static const char kConnectionSocketTestName[]; |
| 100 static void SetUpSocket(IPC::ChannelHandle *handle, | 98 static void SetUpSocket(IPC::ChannelHandle *handle, |
| 101 IPC::Channel::Mode mode); | 99 IPC::Channel::Mode mode); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 server_address.sun_family = AF_UNIX; | 135 server_address.sun_family = AF_UNIX; |
| 138 int path_len = snprintf(server_address.sun_path, IPC::kMaxPipeNameLength, | 136 int path_len = snprintf(server_address.sun_path, IPC::kMaxPipeNameLength, |
| 139 "%s", name.c_str()); | 137 "%s", name.c_str()); |
| 140 DCHECK_EQ(static_cast<int>(name.length()), path_len); | 138 DCHECK_EQ(static_cast<int>(name.length()), path_len); |
| 141 size_t server_address_len = offsetof(struct sockaddr_un, | 139 size_t server_address_len = offsetof(struct sockaddr_un, |
| 142 sun_path) + path_len + 1; | 140 sun_path) + path_len + 1; |
| 143 | 141 |
| 144 if (mode == IPC::Channel::MODE_NAMED_SERVER) { | 142 if (mode == IPC::Channel::MODE_NAMED_SERVER) { |
| 145 // Only one server at a time. Cleanup garbage if it exists. | 143 // Only one server at a time. Cleanup garbage if it exists. |
| 146 unlink(name.c_str()); | 144 unlink(name.c_str()); |
| 147 // Make sure the path we need exists. | 145 // Make sure the path we need exists. |
| 148 FilePath path(name); | 146 FilePath path(name); |
| 149 FilePath dir_path = path.DirName(); | 147 FilePath dir_path = path.DirName(); |
| 150 ASSERT_TRUE(file_util::CreateDirectory(dir_path)); | 148 ASSERT_TRUE(file_util::CreateDirectory(dir_path)); |
| 151 ASSERT_GE(bind(socket_fd, | 149 ASSERT_GE(bind(socket_fd, |
| 152 reinterpret_cast<struct sockaddr *>(&server_address), | 150 reinterpret_cast<struct sockaddr *>(&server_address), |
| 153 server_address_len), 0) << server_address.sun_path | 151 server_address_len), 0) << server_address.sun_path |
| 154 << ": " << strerror(errno) | 152 << ": " << strerror(errno) |
| 155 << "(" << errno << ")"; | 153 << "(" << errno << ")"; |
| 156 ASSERT_GE(listen(socket_fd, SOMAXCONN), 0) << server_address.sun_path | 154 ASSERT_GE(listen(socket_fd, SOMAXCONN), 0) << server_address.sun_path |
| 157 << ": " << strerror(errno) | 155 << ": " << strerror(errno) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 ASSERT_TRUE(channel.Connect()); | 220 ASSERT_TRUE(channel.Connect()); |
| 223 ASSERT_TRUE(channel.AcceptsConnections()); | 221 ASSERT_TRUE(channel.AcceptsConnections()); |
| 224 ASSERT_FALSE(channel.HasAcceptedConnection()); | 222 ASSERT_FALSE(channel.HasAcceptedConnection()); |
| 225 | 223 |
| 226 base::ProcessHandle handle = SpawnChild("IPCChannelPosixTestConnectionProc", | 224 base::ProcessHandle handle = SpawnChild("IPCChannelPosixTestConnectionProc", |
| 227 false); | 225 false); |
| 228 ASSERT_TRUE(handle); | 226 ASSERT_TRUE(handle); |
| 229 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 227 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 230 ASSERT_EQ(IPCChannelPosixTestListener::CONNECTED, listener.status()); | 228 ASSERT_EQ(IPCChannelPosixTestListener::CONNECTED, listener.status()); |
| 231 ASSERT_TRUE(channel.HasAcceptedConnection()); | 229 ASSERT_TRUE(channel.HasAcceptedConnection()); |
| 232 IPC::Message* message = new IPC::Message(0, // routing_id | 230 IPC::Message* message = new IPC::Message(0, // routing_id |
| 233 QUIT_MESSAGE, // message type | 231 kQuitMessage, // message type |
| 234 IPC::Message::PRIORITY_NORMAL); | 232 IPC::Message::PRIORITY_NORMAL); |
| 235 channel.Send(message); | 233 channel.Send(message); |
| 236 SpinRunLoop(TestTimeouts::action_timeout_ms()); | 234 SpinRunLoop(TestTimeouts::action_timeout_ms()); |
| 237 int exit_code = 0; | 235 int exit_code = 0; |
| 238 EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code)); | 236 EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code)); |
| 239 EXPECT_EQ(0, exit_code); | 237 EXPECT_EQ(0, exit_code); |
| 240 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); | 238 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); |
| 241 ASSERT_FALSE(channel.HasAcceptedConnection()); | 239 ASSERT_FALSE(channel.HasAcceptedConnection()); |
| 242 } | 240 } |
| 243 | 241 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 261 ASSERT_TRUE(channel.HasAcceptedConnection()); | 259 ASSERT_TRUE(channel.HasAcceptedConnection()); |
| 262 channel.ResetToAcceptingConnectionState(); | 260 channel.ResetToAcceptingConnectionState(); |
| 263 ASSERT_FALSE(channel.HasAcceptedConnection()); | 261 ASSERT_FALSE(channel.HasAcceptedConnection()); |
| 264 | 262 |
| 265 base::ProcessHandle handle2 = SpawnChild("IPCChannelPosixTestConnectionProc", | 263 base::ProcessHandle handle2 = SpawnChild("IPCChannelPosixTestConnectionProc", |
| 266 false); | 264 false); |
| 267 ASSERT_TRUE(handle2); | 265 ASSERT_TRUE(handle2); |
| 268 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 266 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 269 ASSERT_EQ(IPCChannelPosixTestListener::CONNECTED, listener.status()); | 267 ASSERT_EQ(IPCChannelPosixTestListener::CONNECTED, listener.status()); |
| 270 ASSERT_TRUE(channel.HasAcceptedConnection()); | 268 ASSERT_TRUE(channel.HasAcceptedConnection()); |
| 271 IPC::Message* message = new IPC::Message(0, // routing_id | 269 IPC::Message* message = new IPC::Message(0, // routing_id |
| 272 QUIT_MESSAGE, // message type | 270 kQuitMessage, // message type |
| 273 IPC::Message::PRIORITY_NORMAL); | 271 IPC::Message::PRIORITY_NORMAL); |
| 274 channel.Send(message); | 272 channel.Send(message); |
| 275 SpinRunLoop(TestTimeouts::action_timeout_ms()); | 273 SpinRunLoop(TestTimeouts::action_timeout_ms()); |
| 276 EXPECT_TRUE(base::KillProcess(handle, 0, false)); | 274 EXPECT_TRUE(base::KillProcess(handle, 0, false)); |
| 277 int exit_code = 0; | 275 int exit_code = 0; |
| 278 EXPECT_TRUE(base::WaitForExitCode(handle2, &exit_code)); | 276 EXPECT_TRUE(base::WaitForExitCode(handle2, &exit_code)); |
| 279 EXPECT_EQ(0, exit_code); | 277 EXPECT_EQ(0, exit_code); |
| 280 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); | 278 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); |
| 281 ASSERT_FALSE(channel.HasAcceptedConnection()); | 279 ASSERT_FALSE(channel.HasAcceptedConnection()); |
| 282 } | 280 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 ASSERT_TRUE(channel.HasAcceptedConnection()); | 318 ASSERT_TRUE(channel.HasAcceptedConnection()); |
| 321 base::ProcessHandle handle2 = SpawnChild("IPCChannelPosixFailConnectionProc", | 319 base::ProcessHandle handle2 = SpawnChild("IPCChannelPosixFailConnectionProc", |
| 322 false); | 320 false); |
| 323 ASSERT_TRUE(handle2); | 321 ASSERT_TRUE(handle2); |
| 324 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 322 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 325 int exit_code = 0; | 323 int exit_code = 0; |
| 326 EXPECT_TRUE(base::WaitForExitCode(handle2, &exit_code)); | 324 EXPECT_TRUE(base::WaitForExitCode(handle2, &exit_code)); |
| 327 EXPECT_EQ(exit_code, 0); | 325 EXPECT_EQ(exit_code, 0); |
| 328 ASSERT_EQ(IPCChannelPosixTestListener::DENIED, listener.status()); | 326 ASSERT_EQ(IPCChannelPosixTestListener::DENIED, listener.status()); |
| 329 ASSERT_TRUE(channel.HasAcceptedConnection()); | 327 ASSERT_TRUE(channel.HasAcceptedConnection()); |
| 330 IPC::Message* message = new IPC::Message(0, // routing_id | 328 IPC::Message* message = new IPC::Message(0, // routing_id |
| 331 QUIT_MESSAGE, // message type | 329 kQuitMessage, // message type |
| 332 IPC::Message::PRIORITY_NORMAL); | 330 IPC::Message::PRIORITY_NORMAL); |
| 333 channel.Send(message); | 331 channel.Send(message); |
| 334 SpinRunLoop(TestTimeouts::action_timeout_ms()); | 332 SpinRunLoop(TestTimeouts::action_timeout_ms()); |
| 335 EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code)); | 333 EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code)); |
| 336 EXPECT_EQ(exit_code, 0); | 334 EXPECT_EQ(exit_code, 0); |
| 337 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); | 335 ASSERT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); |
| 338 ASSERT_FALSE(channel.HasAcceptedConnection()); | 336 ASSERT_FALSE(channel.HasAcceptedConnection()); |
| 339 } | 337 } |
| 340 | 338 |
| 341 TEST_F(IPCChannelPosixTest, DoubleServer) { | 339 TEST_F(IPCChannelPosixTest, DoubleServer) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 bool connected = channel.Connect(); | 398 bool connected = channel.Connect(); |
| 401 if (connected) { | 399 if (connected) { |
| 402 IPCChannelPosixTest::SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 400 IPCChannelPosixTest::SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 403 EXPECT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); | 401 EXPECT_EQ(IPCChannelPosixTestListener::CHANNEL_ERROR, listener.status()); |
| 404 } else { | 402 } else { |
| 405 EXPECT_EQ(IPCChannelPosixTestListener::DISCONNECTED, listener.status()); | 403 EXPECT_EQ(IPCChannelPosixTestListener::DISCONNECTED, listener.status()); |
| 406 } | 404 } |
| 407 return 0; | 405 return 0; |
| 408 } | 406 } |
| 409 | 407 |
| OLD | NEW |