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 #include "chrome/browser/process_singleton.h" | 5 #include "chrome/browser/process_singleton.h" |
| 6 | 6 |
| 7 #include <signal.h> | 7 #include <signal.h> |
| 8 #include <sys/types.h> | 8 #include <sys/types.h> |
| 9 #include <sys/wait.h> | 9 #include <sys/wait.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 | 32 |
| 33 namespace { | 33 namespace { |
| 34 | 34 |
| 35 bool NotificationCallback(const CommandLine& command_line, | 35 bool NotificationCallback(const CommandLine& command_line, |
| 36 const FilePath& current_directory) { | 36 const FilePath& current_directory) { |
| 37 return true; | 37 return true; |
| 38 } | 38 } |
| 39 | 39 |
| 40 class ProcessSingletonLinuxTest : public testing::Test { | 40 class ProcessSingletonLinuxTest : public testing::Test { |
| 41 public: | 41 public: |
| 42 // A MockPocessSingleton to test protected methods of ProcessSingleton. | |
| 43 class MockProcessSingleton : ProcessSingleton { | |
| 44 public: | |
| 45 virtual NotifyResult NotifyOtherProcess() OVERRIDE { | |
| 46 ProcessSingleton::NotifyOtherProcess(); | |
| 47 } | |
| 48 virtual bool Create( | |
| 49 const NotificationCallback& notification_callback) OVERRIDE { | |
| 50 ProcessSingleton::Create(); | |
| 51 } | |
| 52 virtual NotifyResult NotifyOtherProcessWithTimeout( | |
| 53 const CommandLine& command_line, | |
| 54 int timeout_seconds, | |
| 55 bool kill_unresponsive) OVERRIDE { | |
| 56 ProcessSingleton::NotifyOtherProcessWithTimeout(); | |
|
robertshield
2012/11/30 21:21:52
might not build?
gab
2012/11/30 21:35:36
Never heard of implicit parameter passing ;)?!
| |
| 57 } | |
| 58 virtual NotifyResult NotifyOtherProcessWithTimeoutOrCreate( | |
| 59 const CommandLine& command_line, | |
| 60 const NotificationCallback& notification_callback, | |
| 61 int timeout_seconds) OVERRIDE { | |
| 62 ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate(); | |
| 63 } | |
| 64 virtual void OverrideCurrentPidForTesting(base::ProcessId pid) OVERRIDE { | |
| 65 ProcessSingleton::OverrideCurrentPidForTesting(); | |
| 66 } | |
| 67 virtual void OverrideKillCallbackForTesting( | |
| 68 const base::Callback<void(int)>& callback) OVERRIDE { | |
| 69 ProcessSingleton::OverrideKillCallbackForTesting(); | |
| 70 } | |
| 71 }; | |
| 72 | |
| 42 ProcessSingletonLinuxTest() | 73 ProcessSingletonLinuxTest() |
| 43 : kill_callbacks_(0), | 74 : kill_callbacks_(0), |
| 44 io_thread_(BrowserThread::IO), | 75 io_thread_(BrowserThread::IO), |
| 45 wait_event_(true, false), | 76 wait_event_(true, false), |
| 46 signal_event_(true, false), | 77 signal_event_(true, false), |
| 47 process_singleton_on_thread_(NULL) { | 78 process_singleton_on_thread_(NULL) { |
| 48 io_thread_.StartIOThread(); | 79 io_thread_.StartIOThread(); |
| 49 } | 80 } |
| 50 | 81 |
| 51 virtual void SetUp() { | 82 virtual void SetUp() { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 base::Bind(&ProcessSingletonLinuxTest:: | 123 base::Bind(&ProcessSingletonLinuxTest:: |
| 93 CreateProcessSingletonInternal, | 124 CreateProcessSingletonInternal, |
| 94 base::Unretained(this))); | 125 base::Unretained(this))); |
| 95 | 126 |
| 96 scoped_refptr<base::ThreadTestHelper> helper( | 127 scoped_refptr<base::ThreadTestHelper> helper( |
| 97 new base::ThreadTestHelper( | 128 new base::ThreadTestHelper( |
| 98 worker_thread_->message_loop_proxy())); | 129 worker_thread_->message_loop_proxy())); |
| 99 ASSERT_TRUE(helper->Run()); | 130 ASSERT_TRUE(helper->Run()); |
| 100 } | 131 } |
| 101 | 132 |
| 102 ProcessSingleton* CreateProcessSingleton() { | 133 MockProcessSingleton* CreateProcessSingleton() { |
| 103 return new ProcessSingleton(temp_dir_.path()); | 134 return new MockProcessSingleton(temp_dir_.path()); |
| 104 } | 135 } |
| 105 | 136 |
| 106 ProcessSingleton::NotifyResult NotifyOtherProcess( | 137 ProcessSingleton::NotifyResult NotifyOtherProcess( |
| 107 bool override_kill, | 138 bool override_kill, |
| 108 base::TimeDelta timeout) { | 139 base::TimeDelta timeout) { |
| 109 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); | 140 scoped_ptr<MockProcessSingleton> process_singleton( |
| 141 CreateProcessSingleton()); | |
| 110 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); | 142 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); |
| 111 command_line.AppendArg("about:blank"); | 143 command_line.AppendArg("about:blank"); |
| 112 if (override_kill) { | 144 if (override_kill) { |
| 113 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); | 145 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); |
| 114 process_singleton->OverrideKillCallbackForTesting( | 146 process_singleton->OverrideKillCallbackForTesting( |
| 115 base::Bind(&ProcessSingletonLinuxTest::KillCallback, | 147 base::Bind(&ProcessSingletonLinuxTest::KillCallback, |
| 116 base::Unretained(this))); | 148 base::Unretained(this))); |
| 117 } | 149 } |
| 118 | 150 |
| 119 return process_singleton->NotifyOtherProcessWithTimeout( | 151 return process_singleton->NotifyOtherProcessWithTimeout( |
| 120 command_line, timeout.InSeconds(), true); | 152 command_line, timeout.InSeconds(), true); |
| 121 } | 153 } |
| 122 | 154 |
| 123 // A helper method to call ProcessSingleton::NotifyOtherProcessOrCreate(). | 155 // A helper method to call ProcessSingleton::NotifyOtherProcessOrCreate(). |
| 124 ProcessSingleton::NotifyResult NotifyOtherProcessOrCreate( | 156 ProcessSingleton::NotifyResult NotifyOtherProcessOrCreate( |
| 125 const std::string& url, | 157 const std::string& url, |
| 126 base::TimeDelta timeout) { | 158 base::TimeDelta timeout) { |
| 127 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); | 159 scoped_ptr<MockProcessSingleton> process_singleton( |
| 160 CreateProcessSingleton()); | |
| 128 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); | 161 CommandLine command_line(CommandLine::ForCurrentProcess()->GetProgram()); |
| 129 command_line.AppendArg(url); | 162 command_line.AppendArg(url); |
| 130 return process_singleton->NotifyOtherProcessWithTimeoutOrCreate( | 163 return process_singleton->NotifyOtherProcessWithTimeoutOrCreate( |
| 131 command_line, base::Bind(&NotificationCallback), timeout.InSeconds()); | 164 command_line, base::Bind(&NotificationCallback), timeout.InSeconds()); |
| 132 } | 165 } |
| 133 | 166 |
| 134 void CheckNotified() { | 167 void CheckNotified() { |
| 135 ASSERT_EQ(1u, callback_command_lines_.size()); | 168 ASSERT_EQ(1u, callback_command_lines_.size()); |
| 136 bool found = false; | 169 bool found = false; |
| 137 for (size_t i = 0; i < callback_command_lines_[0].size(); ++i) { | 170 for (size_t i = 0; i < callback_command_lines_[0].size(); ++i) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 void KillCallback(int pid) { | 223 void KillCallback(int pid) { |
| 191 kill_callbacks_++; | 224 kill_callbacks_++; |
| 192 } | 225 } |
| 193 | 226 |
| 194 content::TestBrowserThread io_thread_; | 227 content::TestBrowserThread io_thread_; |
| 195 base::ScopedTempDir temp_dir_; | 228 base::ScopedTempDir temp_dir_; |
| 196 base::WaitableEvent wait_event_; | 229 base::WaitableEvent wait_event_; |
| 197 base::WaitableEvent signal_event_; | 230 base::WaitableEvent signal_event_; |
| 198 | 231 |
| 199 scoped_ptr<base::Thread> worker_thread_; | 232 scoped_ptr<base::Thread> worker_thread_; |
| 200 ProcessSingleton* process_singleton_on_thread_; | 233 MockProcessSingleton* process_singleton_on_thread_; |
| 201 | 234 |
| 202 std::vector<CommandLine::StringVector> callback_command_lines_; | 235 std::vector<CommandLine::StringVector> callback_command_lines_; |
| 203 }; | 236 }; |
| 204 | 237 |
| 205 } // namespace | 238 } // namespace |
| 206 | 239 |
| 207 // Test if the socket file and symbol link created by ProcessSingletonLinux | 240 // Test if the socket file and symbol link created by ProcessSingletonLinux |
| 208 // are valid. | 241 // are valid. |
| 209 // If this test flakes, use http://crbug.com/74554. | 242 // If this test flakes, use http://crbug.com/74554. |
| 210 TEST_F(ProcessSingletonLinuxTest, CheckSocketFile) { | 243 TEST_F(ProcessSingletonLinuxTest, CheckSocketFile) { |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 | 358 |
| 326 ASSERT_EQ(0, unlink(lock_path_.value().c_str())); | 359 ASSERT_EQ(0, unlink(lock_path_.value().c_str())); |
| 327 | 360 |
| 328 UnblockWorkerThread(); | 361 UnblockWorkerThread(); |
| 329 } | 362 } |
| 330 | 363 |
| 331 // Test that Create fails when another browser is using the profile directory. | 364 // Test that Create fails when another browser is using the profile directory. |
| 332 TEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) { | 365 TEST_F(ProcessSingletonLinuxTest, CreateFailsWithExistingBrowser) { |
| 333 CreateProcessSingletonOnThread(); | 366 CreateProcessSingletonOnThread(); |
| 334 | 367 |
| 335 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); | 368 scoped_ptr<MockProcessSingleton> process_singleton(CreateProcessSingleton()); |
| 336 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); | 369 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); |
| 337 EXPECT_FALSE(process_singleton->Create( | 370 EXPECT_FALSE(process_singleton->Create( |
| 338 base::Bind(&NotificationCallback))); | 371 base::Bind(&NotificationCallback))); |
| 339 } | 372 } |
| 340 | 373 |
| 341 // Test that Create fails when another browser is using the profile directory | 374 // Test that Create fails when another browser is using the profile directory |
| 342 // but with the old socket location. | 375 // but with the old socket location. |
| 343 TEST_F(ProcessSingletonLinuxTest, CreateChecksCompatibilitySocket) { | 376 TEST_F(ProcessSingletonLinuxTest, CreateChecksCompatibilitySocket) { |
| 344 CreateProcessSingletonOnThread(); | 377 CreateProcessSingletonOnThread(); |
| 345 scoped_ptr<ProcessSingleton> process_singleton(CreateProcessSingleton()); | 378 scoped_ptr<MockProcessSingleton> process_singleton(CreateProcessSingleton()); |
| 346 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); | 379 process_singleton->OverrideCurrentPidForTesting(base::GetCurrentProcId() + 1); |
| 347 | 380 |
| 348 // Do some surgery so as to look like the old configuration. | 381 // Do some surgery so as to look like the old configuration. |
| 349 char buf[PATH_MAX]; | 382 char buf[PATH_MAX]; |
| 350 ssize_t len = readlink(socket_path_.value().c_str(), buf, sizeof(buf)); | 383 ssize_t len = readlink(socket_path_.value().c_str(), buf, sizeof(buf)); |
| 351 ASSERT_GT(len, 0); | 384 ASSERT_GT(len, 0); |
| 352 FilePath socket_target_path = FilePath(std::string(buf, len)); | 385 FilePath socket_target_path = FilePath(std::string(buf, len)); |
| 353 ASSERT_EQ(0, unlink(socket_path_.value().c_str())); | 386 ASSERT_EQ(0, unlink(socket_path_.value().c_str())); |
| 354 ASSERT_EQ(0, rename(socket_target_path.value().c_str(), | 387 ASSERT_EQ(0, rename(socket_target_path.value().c_str(), |
| 355 socket_path_.value().c_str())); | 388 socket_path_.value().c_str())); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 368 | 401 |
| 369 // Also change the hostname, so the remote does not retry. | 402 // Also change the hostname, so the remote does not retry. |
| 370 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); | 403 EXPECT_EQ(0, unlink(lock_path_.value().c_str())); |
| 371 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); | 404 EXPECT_EQ(0, symlink("FAKEFOOHOST-1234", lock_path_.value().c_str())); |
| 372 | 405 |
| 373 std::string url("about:blank"); | 406 std::string url("about:blank"); |
| 374 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, | 407 EXPECT_EQ(ProcessSingleton::PROFILE_IN_USE, |
| 375 NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout())); | 408 NotifyOtherProcessOrCreate(url, TestTimeouts::action_timeout())); |
| 376 } | 409 } |
| 377 | 410 |
| OLD | NEW |