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