OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 ran on the windows platform only but has been | 8 // It is currently compiled and ran on the windows platform only but has been |
9 // written in a platform independent way (using the process/threads/sync | 9 // written in a platform independent way (using the process/threads/sync |
10 // routines from base). So it does compile fine on Mac and Linux but fails to | 10 // routines from base). So it does compile fine on Mac and Linux but fails to |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 // This is for the code that is to be ran in multiple threads at once, | 30 // This is for the code that is to be ran in multiple threads at once, |
31 // to stress a race condition on first process start. | 31 // to stress a race condition on first process start. |
32 // We use the thread safe ref counted base class so that we can use the | 32 // We use the thread safe ref counted base class so that we can use the |
33 // NewRunnableMethod class to run the StartChrome methods in many threads. | 33 // NewRunnableMethod class to run the StartChrome methods in many threads. |
34 class ChromeStarter : public base::RefCountedThreadSafe<ChromeStarter> { | 34 class ChromeStarter : public base::RefCountedThreadSafe<ChromeStarter> { |
35 public: | 35 public: |
36 ChromeStarter() | 36 explicit ChromeStarter(int timeout_ms) |
37 : ready_event_(false /* manual */, false /* signaled */), | 37 : ready_event_(false /* manual */, false /* signaled */), |
38 done_event_(false /* manual */, false /* signaled */), | 38 done_event_(false /* manual */, false /* signaled */), |
39 process_handle_(NULL), | 39 process_handle_(NULL), |
40 process_terminated_(false) { | 40 process_terminated_(false), |
| 41 timeout_ms_(timeout_ms) { |
41 } | 42 } |
42 | 43 |
43 // We must reset some data members since we reuse the same ChromeStarter | 44 // We must reset some data members since we reuse the same ChromeStarter |
44 // object and start/stop it a few times. We must start fresh! :-) | 45 // object and start/stop it a few times. We must start fresh! :-) |
45 void Reset() { | 46 void Reset() { |
46 ready_event_.Reset(); | 47 ready_event_.Reset(); |
47 done_event_.Reset(); | 48 done_event_.Reset(); |
48 if (process_handle_ != NULL) | 49 if (process_handle_ != NULL) |
49 base::CloseProcessHandle(process_handle_); | 50 base::CloseProcessHandle(process_handle_); |
50 process_handle_ = NULL; | 51 process_handle_ = NULL; |
(...skipping 17 matching lines...) Expand all Loading... |
68 // Here we don't wait for the app to be terminated because one of the | 69 // Here we don't wait for the app to be terminated because one of the |
69 // process will stay alive while the others will be restarted. If we would | 70 // process will stay alive while the others will be restarted. If we would |
70 // wait here, we would never get a handle to the main process... | 71 // wait here, we would never get a handle to the main process... |
71 base::LaunchApp(command_line, false /* wait */, | 72 base::LaunchApp(command_line, false /* wait */, |
72 false /* hidden */, &process_handle_); | 73 false /* hidden */, &process_handle_); |
73 ASSERT_NE(static_cast<base::ProcessHandle>(NULL), process_handle_); | 74 ASSERT_NE(static_cast<base::ProcessHandle>(NULL), process_handle_); |
74 | 75 |
75 // We can wait on the handle here, we should get stuck on one and only | 76 // We can wait on the handle here, we should get stuck on one and only |
76 // one process. The test below will take care of killing that process | 77 // one process. The test below will take care of killing that process |
77 // to unstuck us once it confirms there is only one. | 78 // to unstuck us once it confirms there is only one. |
78 static const int64 kWaitForProcessDeath = 5000; | |
79 process_terminated_ = base::WaitForSingleProcess(process_handle_, | 79 process_terminated_ = base::WaitForSingleProcess(process_handle_, |
80 kWaitForProcessDeath); | 80 timeout_ms_); |
81 // Let the test know we are done. | 81 // Let the test know we are done. |
82 done_event_.Signal(); | 82 done_event_.Signal(); |
83 } | 83 } |
84 | 84 |
85 // Public access to simplify the test code using them. | 85 // Public access to simplify the test code using them. |
86 base::WaitableEvent ready_event_; | 86 base::WaitableEvent ready_event_; |
87 base::WaitableEvent done_event_; | 87 base::WaitableEvent done_event_; |
88 base::ProcessHandle process_handle_; | 88 base::ProcessHandle process_handle_; |
89 bool process_terminated_; | 89 bool process_terminated_; |
90 | 90 |
91 private: | 91 private: |
92 friend class base::RefCountedThreadSafe<ChromeStarter>; | 92 friend class base::RefCountedThreadSafe<ChromeStarter>; |
| 93 |
93 ~ChromeStarter() { | 94 ~ChromeStarter() { |
94 if (process_handle_ != NULL) | 95 if (process_handle_ != NULL) |
95 base::CloseProcessHandle(process_handle_); | 96 base::CloseProcessHandle(process_handle_); |
96 } | 97 } |
| 98 |
| 99 int timeout_ms_; |
| 100 |
97 DISALLOW_COPY_AND_ASSIGN(ChromeStarter); | 101 DISALLOW_COPY_AND_ASSIGN(ChromeStarter); |
98 }; | 102 }; |
99 | 103 |
100 // Our test fixture that initializes and holds onto a few global vars. | 104 // Our test fixture that initializes and holds onto a few global vars. |
101 class ProcessSingletonWinTest : public UITest { | 105 class ProcessSingletonWinTest : public UITest { |
102 public: | 106 public: |
103 ProcessSingletonWinTest() | 107 ProcessSingletonWinTest() |
104 // We use a manual reset so that all threads wake up at once when signaled | 108 // We use a manual reset so that all threads wake up at once when signaled |
105 // and thus we must manually reset it for each attempt. | 109 // and thus we must manually reset it for each attempt. |
106 : threads_waker_(true /* manual */, false /* signaled */) { | 110 : threads_waker_(true /* manual */, false /* signaled */) { |
107 } | 111 } |
108 | 112 |
109 void SetUp() { | 113 void SetUp() { |
110 // Start the threads and create the starters. | 114 // Start the threads and create the starters. |
111 for (size_t i = 0; i < kNbThreads; ++i) { | 115 for (size_t i = 0; i < kNbThreads; ++i) { |
112 chrome_starter_threads_[i].reset(new base::Thread("ChromeStarter")); | 116 chrome_starter_threads_[i].reset(new base::Thread("ChromeStarter")); |
113 ASSERT_TRUE(chrome_starter_threads_[i]->Start()); | 117 ASSERT_TRUE(chrome_starter_threads_[i]->Start()); |
114 chrome_starters_[i] = new ChromeStarter; | 118 chrome_starters_[i] = new ChromeStarter(action_max_timeout_ms()); |
115 } | 119 } |
116 } | 120 } |
117 | 121 |
118 void TearDown() { | 122 void TearDown() { |
119 // Stop the threads. | 123 // Stop the threads. |
120 for (size_t i = 0; i < kNbThreads; ++i) | 124 for (size_t i = 0; i < kNbThreads; ++i) |
121 chrome_starter_threads_[i]->Stop(); | 125 chrome_starter_threads_[i]->Stop(); |
122 } | 126 } |
123 | 127 |
124 // This method is used to make sure we kill the main browser process after | 128 // This method is used to make sure we kill the main browser process after |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 size_t last_index = pending_starters.front(); | 262 size_t last_index = pending_starters.front(); |
259 pending_starters.empty(); | 263 pending_starters.empty(); |
260 if (chrome_starters_[last_index]->process_handle_ != NULL) { | 264 if (chrome_starters_[last_index]->process_handle_ != NULL) { |
261 KillProcessTree(chrome_starters_[last_index]->process_handle_); | 265 KillProcessTree(chrome_starters_[last_index]->process_handle_); |
262 chrome_starters_[last_index]->done_event_.Wait(); | 266 chrome_starters_[last_index]->done_event_.Wait(); |
263 } | 267 } |
264 } | 268 } |
265 } | 269 } |
266 | 270 |
267 } // namespace | 271 } // namespace |
OLD | NEW |