| 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 #include "chrome/browser/process_singleton.h" | 5 #include "chrome/browser/process_singleton.h" |
| 6 | 6 |
| 7 #include <sys/types.h> | 7 #include <sys/types.h> |
| 8 #include <sys/wait.h> | 8 #include <sys/wait.h> |
| 9 #include <signal.h> | 9 #include <signal.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 worker_thread_->message_loop_proxy())); | 97 worker_thread_->message_loop_proxy())); |
| 98 ASSERT_TRUE(helper->Run()); | 98 ASSERT_TRUE(helper->Run()); |
| 99 } | 99 } |
| 100 | 100 |
| 101 ProcessSingleton* CreateProcessSingleton() { | 101 ProcessSingleton* CreateProcessSingleton() { |
| 102 return new ProcessSingleton(temp_dir_.path()); | 102 return new ProcessSingleton(temp_dir_.path()); |
| 103 } | 103 } |
| 104 | 104 |
| 105 ProcessSingleton::NotifyResult NotifyOtherProcess( | 105 ProcessSingleton::NotifyResult NotifyOtherProcess( |
| 106 bool override_kill, | 106 bool override_kill, |
| 107 int timeout_ms) { | 107 base::TimeDelta timeout) { |
| 108 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); | 108 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); |
| 109 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); | 109 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); |
| 110 command_line.AppendArg("about:blank"); | 110 command_line.AppendArg("about:blank"); |
| 111 if (override_kill) { | 111 if (override_kill) { |
| 112 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() +
1); | 112 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() +
1); |
| 113 process_singleton->OverrideKillCallbackForTesting( | 113 process_singleton->OverrideKillCallbackForTesting( |
| 114 base::Bind(&ProcessSingletonLinuxTest::KillCallback, | 114 base::Bind(&ProcessSingletonLinuxTest::KillCallback, |
| 115 base::Unretained(this))); | 115 base::Unretained(this))); |
| 116 } | 116 } |
| 117 | 117 |
| 118 return process_singleton->NotifyOtherProcessWithTimeout( | 118 return process_singleton->NotifyOtherProcessWithTimeout( |
| 119 command_line, timeout_ms / 1000, true); | 119 command_line, timeout.InSeconds(), true); |
| 120 } | 120 } |
| 121 | 121 |
| 122 // A helper method to call ProcessSingleton::NotifyOtherProcessOrCreate(). | 122 // A helper method to call ProcessSingleton::NotifyOtherProcessOrCreate(). |
| 123 ProcessSingleton::NotifyResult NotifyOtherProcessOrCreate( | 123 ProcessSingleton::NotifyResult NotifyOtherProcessOrCreate( |
| 124 const std::string& url, | 124 const std::string& url, |
| 125 int timeout_ms) { | 125 base::TimeDelta timeout) { |
| 126 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); | 126 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); |
| 127 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); | 127 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); |
| 128 command_line.AppendArg(url); | 128 command_line.AppendArg(url); |
| 129 return process_singleton->NotifyOtherProcessWithTimeoutOrCreate( | 129 return process_singleton->NotifyOtherProcessWithTimeoutOrCreate( |
| 130 command_line, base::Bind(&NotificationCallback), timeout_ms / 1000); | 130 command_line, base::Bind(&NotificationCallback), timeout.InSeconds()); |
| 131 } | 131 } |
| 132 | 132 |
| 133 void CheckNotified() { | 133 void CheckNotified() { |
| 134 ASSERT_EQ(1u, callback_command_lines_.size()); | 134 ASSERT_EQ(1u, callback_command_lines_.size()); |
| 135 bool found = false; | 135 bool found = false; |
| 136 for (size_t i = 0; i < callback_command_lines_[0].size(); ++i) { | 136 for (size_t i = 0; i < callback_command_lines_[0].size(); ++i) { |
| 137 if (callback_command_lines_[0][i] == "about:blank") { | 137 if (callback_command_lines_[0][i] == "about:blank") { |
| 138 found = true; | 138 found = true; |
| 139 break; | 139 break; |
| 140 } | 140 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 len = readlink(remote_cookie_path.value().c_str(), buf, PATH_MAX); | 234 len = readlink(remote_cookie_path.value().c_str(), buf, PATH_MAX); |
| 235 ASSERT_GT(len, 0); | 235 ASSERT_GT(len, 0); |
| 236 EXPECT_EQ(cookie, std::string(buf, len)); | 236 EXPECT_EQ(cookie, std::string(buf, len)); |
| 237 } | 237 } |
| 238 | 238 |
| 239 // TODO(james.su@gmail.com): port following tests to Windows. | 239 // TODO(james.su@gmail.com): port following tests to Windows. |
| 240 // Test success case of NotifyOtherProcess(). | 240 // Test success case of NotifyOtherProcess(). |
| 241 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) { | 241 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessSuccess) { |
| 242 CreateProcessSingletonOnThread(); | 242 CreateProcessSingletonOnThread(); |
| 243 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, | 243 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, |
| 244 NotifyOtherProcess(true, TestTimeouts::action_timeout_ms())); | 244 NotifyOtherProcess(true, TestTimeouts::action_timeout())); |
| 245 CheckNotified(); | 245 CheckNotified(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 // Test failure case of NotifyOtherProcess(). | 248 // Test failure case of NotifyOtherProcess(). |
| 249 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) { | 249 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessFailure) { |
| 250 CreateProcessSingletonOnThread(); | 250 CreateProcessSingletonOnThread(); |
| 251 | 251 |
| 252 BlockWorkerThread(); | 252 BlockWorkerThread(); |
| 253 EXPECT_EQ(ProcessSingleton::PROCESS_NONE, | 253 EXPECT_EQ(ProcessSingleton::PROCESS_NONE, |
| 254 NotifyOtherProcess(true, TestTimeouts::action_timeout_ms())); | 254 NotifyOtherProcess(true, TestTimeouts::action_timeout())); |
| 255 | 255 |
| 256 ASSERT_EQ(1, kill_callbacks_); | 256 ASSERT_EQ(1, kill_callbacks_); |
| 257 UnblockWorkerThread(); | 257 UnblockWorkerThread(); |
| 258 } | 258 } |
| 259 | 259 |
| 260 // Test that we don't kill ourselves by accident if a lockfile with the same pid | 260 // Test that we don't kill ourselves by accident if a lockfile with the same pid |
| 261 // happens to exist. | 261 // happens to exist. |
| 262 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessNoSuicide) { | 262 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessNoSuicide) { |
| 263 CreateProcessSingletonOnThread(); | 263 CreateProcessSingletonOnThread(); |
| 264 // Replace lockfile with one containing our own pid. | 264 // Replace lockfile with one containing our own pid. |
| 265 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); | 265 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
| 266 std::string symlink_content = base::StringPrintf( | 266 std::string symlink_content = base::StringPrintf( |
| 267 "%s%c%u", | 267 "%s%c%u", |
| 268 net::GetHostName().c_str(), | 268 net::GetHostName().c_str(), |
| 269 '-', | 269 '-', |
| 270 base::GetCurrentProcId()); | 270 base::GetCurrentProcId()); |
| 271 EXPECT_EQ(0, symlink(symlink_content.c_str(), lock_path_.value().c_str())); | 271 EXPECT_EQ(0, symlink(symlink_content.c_str(), lock_path_.value().c_str())); |
| 272 | 272 |
| 273 // Remove socket so that we will not be able to notify the existing browser. | 273 // Remove socket so that we will not be able to notify the existing browser. |
| 274 EXPECT_EQ(0, unlink(socket_path_.value().c_str())); | 274 EXPECT_EQ(0, unlink(socket_path_.value().c_str())); |
| 275 | 275 |
| 276 EXPECT_EQ(ProcessSingleton::PROCESS_NONE, | 276 EXPECT_EQ(ProcessSingleton::PROCESS_NONE, |
| 277 NotifyOtherProcess(false, TestTimeouts::action_timeout_ms())); | 277 NotifyOtherProcess(false, TestTimeouts::action_timeout())); |
| 278 // If we've gotten to this point without killing ourself, the test succeeded. | 278 // If we've gotten to this point without killing ourself, the test succeeded. |
| 279 } | 279 } |
| 280 | 280 |
| 281 // Test that we can still notify a process on the same host even after the | 281 // Test that we can still notify a process on the same host even after the |
| 282 // hostname changed. | 282 // hostname changed. |
| 283 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) { | 283 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessHostChanged) { |
| 284 CreateProcessSingletonOnThread(); | 284 CreateProcessSingletonOnThread(); |
| 285 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); | 285 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
| 286 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); | 286 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); |
| 287 | 287 |
| 288 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, | 288 EXPECT_EQ(ProcessSingleton::PROCESS_NOTIFIED, |
| 289 NotifyOtherProcess(false, TestTimeouts::action_timeout_ms())); | 289 NotifyOtherProcess(false, TestTimeouts::action_timeout())); |
| 290 CheckNotified(); | 290 CheckNotified(); |
| 291 } | 291 } |
| 292 | 292 |
| 293 // Test that we fail when lock says process is on another host and we can't | 293 // Test that we fail when lock says process is on another host and we can't |
| 294 // notify it over the socket. | 294 // notify it over the socket. |
| 295 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessDifferingHost) { | 295 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessDifferingHost) { |
| 296 CreateProcessSingletonOnThread(); | 296 CreateProcessSingletonOnThread(); |
| 297 | 297 |
| 298 BlockWorkerThread(); | 298 BlockWorkerThread(); |
| 299 | 299 |
| 300 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); | 300 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
| 301 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); | 301 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); |
| 302 | 302 |
| 303 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, | 303 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, |
| 304 NotifyOtherProcess(false, TestTimeouts::action_timeout_ms())); | 304 NotifyOtherProcess(false, TestTimeouts::action_timeout())); |
| 305 | 305 |
| 306 ASSERT_EQ(0, unlink(lock_path_.value().c_str())); | 306 ASSERT_EQ(0, unlink(lock_path_.value().c_str())); |
| 307 | 307 |
| 308 UnblockWorkerThread(); | 308 UnblockWorkerThread(); |
| 309 } | 309 } |
| 310 | 310 |
| 311 // Test that we fail when lock says process is on another host and we can't | 311 // Test that we fail when lock says process is on another host and we can't |
| 312 // notify it over the socket. | 312 // notify it over the socket. |
| 313 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_DifferingHost) { | 313 TEST_F(ProcessSingletonLinuxTest, NotifyOtherProcessOrCreate_DifferingHost) { |
| 314 CreateProcessSingletonOnThread(); | 314 CreateProcessSingletonOnThread(); |
| 315 | 315 |
| 316 BlockWorkerThread(); | 316 BlockWorkerThread(); |
| 317 | 317 |
| 318 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); | 318 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
| 319 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); | 319 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); |
| 320 | 320 |
| 321 std::string url("about:blank"); | 321 std::string url("about:blank"); |
| 322 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, | 322 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, |
| 323 NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout_ms())); | 323 NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout())); |
| 324 | 324 |
| 325 ASSERT_EQ(0, unlink(lock_path_.value().c_str())); | 325 ASSERT_EQ(0, unlink(lock_path_.value().c_str())); |
| 326 | 326 |
| 327 UnblockWorkerThread(); | 327 UnblockWorkerThread(); |
| 328 } | 328 } |
| 329 | 329 |
| 330 // Test that Create fails when another browser is using the profile directory. | 330 // Test that Create fails when another browser is using the profile directory. |
| 331 TEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) { | 331 TEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) { |
| 332 CreateProcessSingletonOnThread(); | 332 CreateProcessSingletonOnThread(); |
| 333 | 333 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 364 // Change the cookie. | 364 // Change the cookie. |
| 365 EXPECT_EQ(0, unlink(cookie_path_.value().c_str())); | 365 EXPECT_EQ(0, unlink(cookie_path_.value().c_str())); |
| 366 EXPECT_EQ(0, symlink("INCORRECTCOOKIE", cookie_path_.value().c_str())); | 366 EXPECT_EQ(0, symlink("INCORRECTCOOKIE", cookie_path_.value().c_str())); |
| 367 | 367 |
| 368 // Also change the hostname, so the remote does not retry. | 368 // Also change the hostname, so the remote does not retry. |
| 369 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); | 369 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
| 370 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); | 370 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); |
| 371 | 371 |
| 372 std::string url("about:blank"); | 372 std::string url("about:blank"); |
| 373 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, | 373 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, |
| 374 NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout_ms())); | 374 NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout())); |
| 375 } | 375 } |
| 376 | 376 |
| OLD | NEW |