| 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 // This test validates that the ProcessSingleton class properly makes sure | 5 // This test validates that the ProcessSingleton class properly makes sure |
| 6 // that there is only one main browser process. | 6 // that there is only one main browser process. |
| 7 // | 7 // |
| 8 // It is currently compiled and run on Windows and Posix(non-Mac) platforms. | 8 // It is currently compiled and run on Windows and Posix(non-Mac) platforms. |
| 9 // Mac uses system services and ProcessSingletonMac is a noop. (Maybe it still | 9 // Mac uses system services and ProcessSingletonMac is a noop. (Maybe it still |
| 10 // makes sense to test that the system services are giving the behavior we | 10 // makes sense to test that the system services are giving the behavior we |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "chrome/test/base/in_process_browser_test.h" | 28 #include "chrome/test/base/in_process_browser_test.h" |
| 29 | 29 |
| 30 namespace { | 30 namespace { |
| 31 | 31 |
| 32 // This is for the code that is to be ran in multiple threads at once, | 32 // This is for the code that is to be ran in multiple threads at once, |
| 33 // to stress a race condition on first process start. | 33 // to stress a race condition on first process start. |
| 34 // We use the thread safe ref counted base class so that we can use the | 34 // We use the thread safe ref counted base class so that we can use the |
| 35 // base::Bind to run the StartChrome methods in many threads. | 35 // base::Bind to run the StartChrome methods in many threads. |
| 36 class ChromeStarter : public base::RefCountedThreadSafe<ChromeStarter> { | 36 class ChromeStarter : public base::RefCountedThreadSafe<ChromeStarter> { |
| 37 public: | 37 public: |
| 38 ChromeStarter(int timeout_ms, const FilePath& user_data_dir) | 38 ChromeStarter(base::TimeDelta timeout, const FilePath& user_data_dir) |
| 39 : ready_event_(false /* manual */, false /* signaled */), | 39 : ready_event_(false /* manual */, false /* signaled */), |
| 40 done_event_(false /* manual */, false /* signaled */), | 40 done_event_(false /* manual */, false /* signaled */), |
| 41 process_handle_(base::kNullProcessHandle), | 41 process_handle_(base::kNullProcessHandle), |
| 42 process_terminated_(false), | 42 process_terminated_(false), |
| 43 timeout_ms_(timeout_ms), | 43 timeout_(timeout), |
| 44 user_data_dir_(user_data_dir) { | 44 user_data_dir_(user_data_dir) { |
| 45 } | 45 } |
| 46 | 46 |
| 47 // We must reset some data members since we reuse the same ChromeStarter | 47 // We must reset some data members since we reuse the same ChromeStarter |
| 48 // object and start/stop it a few times. We must start fresh! :-) | 48 // object and start/stop it a few times. We must start fresh! :-) |
| 49 void Reset() { | 49 void Reset() { |
| 50 ready_event_.Reset(); | 50 ready_event_.Reset(); |
| 51 done_event_.Reset(); | 51 done_event_.Reset(); |
| 52 if (process_handle_ != base::kNullProcessHandle) | 52 if (process_handle_ != base::kNullProcessHandle) |
| 53 base::CloseProcessHandle(process_handle_); | 53 base::CloseProcessHandle(process_handle_); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 // Here we don't wait for the app to be terminated because one of the | 94 // Here we don't wait for the app to be terminated because one of the |
| 95 // process will stay alive while the others will be restarted. If we would | 95 // process will stay alive while the others will be restarted. If we would |
| 96 // wait here, we would never get a handle to the main process... | 96 // wait here, we would never get a handle to the main process... |
| 97 base::LaunchProcess(command_line, base::LaunchOptions(), &process_handle_); | 97 base::LaunchProcess(command_line, base::LaunchOptions(), &process_handle_); |
| 98 ASSERT_NE(base::kNullProcessHandle, process_handle_); | 98 ASSERT_NE(base::kNullProcessHandle, process_handle_); |
| 99 | 99 |
| 100 // We can wait on the handle here, we should get stuck on one and only | 100 // We can wait on the handle here, we should get stuck on one and only |
| 101 // one process. The test below will take care of killing that process | 101 // one process. The test below will take care of killing that process |
| 102 // to unstuck us once it confirms there is only one. | 102 // to unstuck us once it confirms there is only one. |
| 103 process_terminated_ = base::WaitForSingleProcess(process_handle_, | 103 process_terminated_ = base::WaitForSingleProcess(process_handle_, |
| 104 timeout_ms_); | 104 timeout_); |
| 105 // Let the test know we are done. | 105 // Let the test know we are done. |
| 106 done_event_.Signal(); | 106 done_event_.Signal(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 // Public access to simplify the test code using them. | 109 // Public access to simplify the test code using them. |
| 110 base::WaitableEvent ready_event_; | 110 base::WaitableEvent ready_event_; |
| 111 base::WaitableEvent done_event_; | 111 base::WaitableEvent done_event_; |
| 112 base::ProcessHandle process_handle_; | 112 base::ProcessHandle process_handle_; |
| 113 bool process_terminated_; | 113 bool process_terminated_; |
| 114 | 114 |
| 115 private: | 115 private: |
| 116 friend class base::RefCountedThreadSafe<ChromeStarter>; | 116 friend class base::RefCountedThreadSafe<ChromeStarter>; |
| 117 | 117 |
| 118 ~ChromeStarter() { | 118 ~ChromeStarter() { |
| 119 if (process_handle_ != base::kNullProcessHandle) | 119 if (process_handle_ != base::kNullProcessHandle) |
| 120 base::CloseProcessHandle(process_handle_); | 120 base::CloseProcessHandle(process_handle_); |
| 121 } | 121 } |
| 122 | 122 |
| 123 int timeout_ms_; | 123 base::TimeDelta timeout_; |
| 124 FilePath user_data_dir_; | 124 FilePath user_data_dir_; |
| 125 | 125 |
| 126 DISALLOW_COPY_AND_ASSIGN(ChromeStarter); | 126 DISALLOW_COPY_AND_ASSIGN(ChromeStarter); |
| 127 }; | 127 }; |
| 128 | 128 |
| 129 } // namespace | 129 } // namespace |
| 130 | 130 |
| 131 // Our test fixture that initializes and holds onto a few global vars. | 131 // Our test fixture that initializes and holds onto a few global vars. |
| 132 class ProcessSingletonTest : public InProcessBrowserTest { | 132 class ProcessSingletonTest : public InProcessBrowserTest { |
| 133 public: | 133 public: |
| 134 ProcessSingletonTest() | 134 ProcessSingletonTest() |
| 135 // We use a manual reset so that all threads wake up at once when signaled | 135 // We use a manual reset so that all threads wake up at once when signaled |
| 136 // and thus we must manually reset it for each attempt. | 136 // and thus we must manually reset it for each attempt. |
| 137 : threads_waker_(true /* manual */, false /* signaled */) { | 137 : threads_waker_(true /* manual */, false /* signaled */) { |
| 138 EXPECT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); | 138 EXPECT_TRUE(temp_profile_dir_.CreateUniqueTempDir()); |
| 139 } | 139 } |
| 140 | 140 |
| 141 void SetUp() { | 141 void SetUp() { |
| 142 // Start the threads and create the starters. | 142 // Start the threads and create the starters. |
| 143 for (size_t i = 0; i < kNbThreads; ++i) { | 143 for (size_t i = 0; i < kNbThreads; ++i) { |
| 144 chrome_starter_threads_[i].reset(new base::Thread("ChromeStarter")); | 144 chrome_starter_threads_[i].reset(new base::Thread("ChromeStarter")); |
| 145 ASSERT_TRUE(chrome_starter_threads_[i]->Start()); | 145 ASSERT_TRUE(chrome_starter_threads_[i]->Start()); |
| 146 chrome_starters_[i] = new ChromeStarter( | 146 chrome_starters_[i] = new ChromeStarter( |
| 147 TestTimeouts::action_max_timeout_ms(), temp_profile_dir_.path()); | 147 TestTimeouts::action_max_timeout(), temp_profile_dir_.path()); |
| 148 } | 148 } |
| 149 } | 149 } |
| 150 | 150 |
| 151 void TearDown() { | 151 void TearDown() { |
| 152 // Stop the threads. | 152 // Stop the threads. |
| 153 for (size_t i = 0; i < kNbThreads; ++i) | 153 for (size_t i = 0; i < kNbThreads; ++i) |
| 154 chrome_starter_threads_[i]->Stop(); | 154 chrome_starter_threads_[i]->Stop(); |
| 155 } | 155 } |
| 156 | 156 |
| 157 // This method is used to make sure we kill the main browser process after | 157 // This method is used to make sure we kill the main browser process after |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 316 ASSERT_EQ(static_cast<size_t>(1), pending_starters.size()); | 316 ASSERT_EQ(static_cast<size_t>(1), pending_starters.size()); |
| 317 size_t last_index = pending_starters.front(); | 317 size_t last_index = pending_starters.front(); |
| 318 pending_starters.clear(); | 318 pending_starters.clear(); |
| 319 if (chrome_starters_[last_index]->process_handle_ != | 319 if (chrome_starters_[last_index]->process_handle_ != |
| 320 base::kNullProcessHandle) { | 320 base::kNullProcessHandle) { |
| 321 KillProcessTree(chrome_starters_[last_index]->process_handle_); | 321 KillProcessTree(chrome_starters_[last_index]->process_handle_); |
| 322 chrome_starters_[last_index]->done_event_.Wait(); | 322 chrome_starters_[last_index]->done_event_.Wait(); |
| 323 } | 323 } |
| 324 } | 324 } |
| 325 } | 325 } |
| OLD | NEW |