Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/multi_process_notification.h" | 5 #include "chrome/browser/multi_process_notification.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/environment.h" | 9 #include "base/environment.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "base/test/multiprocess_test.h" | 12 #include "base/test/multiprocess_test.h" |
| 13 #include "base/test/test_timeouts.h" | 13 #include "base/test/test_timeouts.h" |
| 14 #include "base/threading/thread.h" | |
| 14 #include "base/time.h" | 15 #include "base/time.h" |
| 15 #include "chrome/browser/browser_thread.h" | |
| 16 #include "testing/multiprocess_func_list.h" | 16 #include "testing/multiprocess_func_list.h" |
| 17 | 17 |
| 18 #if defined(OS_MACOSX) | 18 #if defined(OS_MACOSX) |
| 19 // TODO(dmaclach): Remove defined(OS_MACOSX) once | 19 // TODO(dmaclach): Remove defined(OS_MACOSX) once |
| 20 // MultiProcessNotification is implemented on Win/Linux. | 20 // MultiProcessNotification is implemented on Win/Linux. |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 | 23 |
| 24 const char kStartedNotificationName[] = "MultiProcessTestStartedNotification"; | 24 const char kStartedNotificationName[] = "MultiProcessTestStartedNotification"; |
| 25 const char kQuitNotificationName[] = "MultiProcessTestQuitNotification"; | 25 const char kQuitNotificationName[] = "MultiProcessTestQuitNotification"; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 QuitterDelegate::~QuitterDelegate() { | 90 QuitterDelegate::~QuitterDelegate() { |
| 91 } | 91 } |
| 92 | 92 |
| 93 void QuitterDelegate::OnNotificationReceived( | 93 void QuitterDelegate::OnNotificationReceived( |
| 94 const std::string& name, multi_process_notification::Domain domain) { | 94 const std::string& name, multi_process_notification::Domain domain) { |
| 95 SimpleDelegate::OnNotificationReceived(name, domain); | 95 SimpleDelegate::OnNotificationReceived(name, domain); |
| 96 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 96 MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
| 97 } | 97 } |
| 98 | 98 |
| 99 int MultiProcessNotificationMain(multi_process_notification::Domain domain) { | 99 int MultiProcessNotificationMain(multi_process_notification::Domain domain) { |
| 100 BrowserThread browser_thread(BrowserThread::IO); | 100 base::Thread thread("MultiProcessNotificationMainIOThread"); |
| 101 base::Thread::Options options(MessageLoop::TYPE_IO, 0); | 101 base::Thread::Options options(MessageLoop::TYPE_IO, 0); |
| 102 EXPECT_TRUE(browser_thread.StartWithOptions(options)); | 102 EXPECT_TRUE(thread.StartWithOptions(options)); |
| 103 MessageLoop loop; | 103 MessageLoop loop; |
| 104 QuitterDelegate quitter; | 104 QuitterDelegate quitter; |
| 105 multi_process_notification::Listener listener( | 105 multi_process_notification::Listener listener( |
| 106 kQuitNotificationName, domain, &quitter); | 106 kQuitNotificationName, domain, &quitter); |
| 107 EXPECT_TRUE(listener.Start()); | 107 EXPECT_TRUE(listener.Start(thread.message_loop())); |
| 108 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 108 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 109 EXPECT_TRUE(quitter.WasStartedReceived()); | 109 EXPECT_TRUE(quitter.WasStartedReceived()); |
| 110 EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName, | 110 EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName, |
| 111 domain)); | 111 domain)); |
| 112 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 112 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 113 EXPECT_TRUE(quitter.WasNotificationReceived()); | 113 EXPECT_TRUE(quitter.WasNotificationReceived()); |
| 114 return 0; | 114 return 0; |
| 115 } | 115 } |
| 116 | 116 |
| 117 } // namespace | 117 } // namespace |
| 118 | 118 |
| 119 class MultiProcessNotificationTest : public base::MultiProcessTest { | 119 class MultiProcessNotificationTest : public base::MultiProcessTest { |
| 120 public: | 120 public: |
| 121 MultiProcessNotificationTest(); | 121 MultiProcessNotificationTest(); |
| 122 | 122 |
| 123 void PostNotificationTest(multi_process_notification::Domain domain); | 123 void PostNotificationTest(multi_process_notification::Domain domain); |
| 124 void CrossPostNotificationTest(multi_process_notification::Domain domain); | 124 void CrossPostNotificationTest(multi_process_notification::Domain domain); |
| 125 | 125 |
| 126 static void SetUpTestCase(); | 126 virtual void SetUp(); |
| 127 static void TearDownTestCase(); | 127 MessageLoop* IOMessageLoop() { return io_thread.message_loop(); }; |
| 128 | 128 |
| 129 private: | 129 private: |
| 130 MessageLoop loop_; | 130 MessageLoop loop_; |
| 131 static BrowserThread* g_io_thread; | 131 base::Thread io_thread; |
|
garykac
2011/01/19 22:49:40
io_thread_
dmac
2011/01/19 23:14:41
Done.
| |
| 132 }; | 132 }; |
| 133 | 133 |
| 134 MultiProcessNotificationTest::MultiProcessNotificationTest() { | 134 MultiProcessNotificationTest::MultiProcessNotificationTest() |
| 135 : io_thread("MultiProcessNotificationTestThread") { | |
| 135 } | 136 } |
| 136 | 137 |
| 137 BrowserThread* MultiProcessNotificationTest::g_io_thread = NULL; | |
| 138 | 138 |
| 139 void MultiProcessNotificationTest::SetUpTestCase() { | 139 void MultiProcessNotificationTest::SetUp() { |
| 140 g_io_thread = new BrowserThread(BrowserThread::IO); | |
| 141 base::Thread::Options options(MessageLoop::TYPE_IO, 0); | 140 base::Thread::Options options(MessageLoop::TYPE_IO, 0); |
| 142 ASSERT_TRUE(g_io_thread->StartWithOptions(options)); | 141 ASSERT_TRUE(io_thread.StartWithOptions(options)); |
| 143 } | |
| 144 | |
| 145 void MultiProcessNotificationTest::TearDownTestCase() { | |
| 146 delete g_io_thread; | |
| 147 } | 142 } |
| 148 | 143 |
| 149 void MultiProcessNotificationTest::PostNotificationTest( | 144 void MultiProcessNotificationTest::PostNotificationTest( |
| 150 multi_process_notification::Domain domain) { | 145 multi_process_notification::Domain domain) { |
| 151 QuitterDelegate process_started; | 146 QuitterDelegate process_started; |
| 152 multi_process_notification::Listener listener( | 147 multi_process_notification::Listener listener( |
| 153 kStartedNotificationName, domain, &process_started); | 148 kStartedNotificationName, domain, &process_started); |
| 154 ASSERT_TRUE(listener.Start()); | 149 ASSERT_TRUE(listener.Start(io_thread.message_loop())); |
| 155 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 150 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 156 ASSERT_TRUE(process_started.WasStartedReceived()); | 151 ASSERT_TRUE(process_started.WasStartedReceived()); |
| 157 std::string process_name; | 152 std::string process_name; |
| 158 switch (domain) { | 153 switch (domain) { |
| 159 case multi_process_notification::ProfileDomain: | 154 case multi_process_notification::ProfileDomain: |
| 160 process_name = "MultiProcessProfileNotificationMain"; | 155 process_name = "MultiProcessProfileNotificationMain"; |
| 161 break; | 156 break; |
| 162 | 157 |
| 163 case multi_process_notification::UserDomain: | 158 case multi_process_notification::UserDomain: |
| 164 process_name = "MultiProcessUserNotificationMain"; | 159 process_name = "MultiProcessUserNotificationMain"; |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 193 &profile_quitter); | 188 &profile_quitter); |
| 194 multi_process_notification::Listener user_listener( | 189 multi_process_notification::Listener user_listener( |
| 195 local_notification, multi_process_notification::UserDomain, | 190 local_notification, multi_process_notification::UserDomain, |
| 196 &user_quitter); | 191 &user_quitter); |
| 197 multi_process_notification::Listener system_listener( | 192 multi_process_notification::Listener system_listener( |
| 198 local_notification, multi_process_notification::SystemDomain, | 193 local_notification, multi_process_notification::SystemDomain, |
| 199 &system_quitter); | 194 &system_quitter); |
| 200 multi_process_notification::Listener final_listener( | 195 multi_process_notification::Listener final_listener( |
| 201 final_notification, multi_process_notification::UserDomain, | 196 final_notification, multi_process_notification::UserDomain, |
| 202 &final_quitter); | 197 &final_quitter); |
| 203 | 198 |
| 204 ASSERT_TRUE(profile_listener.Start()); | 199 MessageLoop* message_loop = io_thread.message_loop(); |
| 200 ASSERT_TRUE(profile_listener.Start(message_loop)); | |
| 205 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 201 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 206 ASSERT_TRUE(profile_quitter.WasStartedReceived()); | 202 ASSERT_TRUE(profile_quitter.WasStartedReceived()); |
| 207 ASSERT_TRUE(user_listener.Start()); | 203 ASSERT_TRUE(user_listener.Start(message_loop)); |
| 208 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 204 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 209 ASSERT_TRUE(user_quitter.WasStartedReceived()); | 205 ASSERT_TRUE(user_quitter.WasStartedReceived()); |
| 210 ASSERT_TRUE(system_listener.Start()); | 206 ASSERT_TRUE(system_listener.Start(message_loop)); |
| 211 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 207 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 212 ASSERT_TRUE(system_quitter.WasStartedReceived()); | 208 ASSERT_TRUE(system_quitter.WasStartedReceived()); |
| 213 | 209 |
| 214 ASSERT_TRUE(multi_process_notification::Post(local_notification, domain)); | 210 ASSERT_TRUE(multi_process_notification::Post(local_notification, domain)); |
| 215 SpinRunLoop(TestTimeouts::action_timeout_ms()); | 211 SpinRunLoop(TestTimeouts::action_timeout_ms()); |
| 216 | 212 |
| 217 // Now send out a final_notification to queue up a notification | 213 // Now send out a final_notification to queue up a notification |
| 218 // after the local_notification and make sure that all listeners have had a | 214 // after the local_notification and make sure that all listeners have had a |
| 219 // chance to process local_notification before we check to see if they | 215 // chance to process local_notification before we check to see if they |
| 220 // were called. | 216 // were called. |
| 221 ASSERT_TRUE(final_listener.Start()); | 217 ASSERT_TRUE(final_listener.Start(message_loop)); |
| 222 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 218 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 223 EXPECT_TRUE(final_quitter.WasStartedReceived()); | 219 EXPECT_TRUE(final_quitter.WasStartedReceived()); |
| 224 ASSERT_TRUE(multi_process_notification::Post( | 220 ASSERT_TRUE(multi_process_notification::Post( |
| 225 final_notification, multi_process_notification::UserDomain)); | 221 final_notification, multi_process_notification::UserDomain)); |
| 226 SpinRunLoop(TestTimeouts::action_timeout_ms()); | 222 SpinRunLoop(TestTimeouts::action_timeout_ms()); |
| 227 ASSERT_TRUE(final_quitter.WasNotificationReceived()); | 223 ASSERT_TRUE(final_quitter.WasNotificationReceived()); |
| 228 switch (domain) { | 224 switch (domain) { |
| 229 case multi_process_notification::ProfileDomain: | 225 case multi_process_notification::ProfileDomain: |
| 230 ASSERT_TRUE(profile_quitter.WasNotificationReceived()); | 226 ASSERT_TRUE(profile_quitter.WasNotificationReceived()); |
| 231 ASSERT_FALSE(user_quitter.WasNotificationReceived()); | 227 ASSERT_FALSE(user_quitter.WasNotificationReceived()); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 243 ASSERT_FALSE(user_quitter.WasNotificationReceived()); | 239 ASSERT_FALSE(user_quitter.WasNotificationReceived()); |
| 244 ASSERT_TRUE(system_quitter.WasNotificationReceived()); | 240 ASSERT_TRUE(system_quitter.WasNotificationReceived()); |
| 245 break; | 241 break; |
| 246 } | 242 } |
| 247 } | 243 } |
| 248 | 244 |
| 249 TEST_F(MultiProcessNotificationTest, BasicCreationTest) { | 245 TEST_F(MultiProcessNotificationTest, BasicCreationTest) { |
| 250 QuitterDelegate quitter; | 246 QuitterDelegate quitter; |
| 251 multi_process_notification::Listener local_listener( | 247 multi_process_notification::Listener local_listener( |
| 252 "BasicCreationTest", multi_process_notification::UserDomain, &quitter); | 248 "BasicCreationTest", multi_process_notification::UserDomain, &quitter); |
| 253 ASSERT_TRUE(local_listener.Start()); | 249 MessageLoop* message_loop = IOMessageLoop(); |
| 250 ASSERT_TRUE(local_listener.Start(message_loop)); | |
| 254 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 251 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 255 ASSERT_TRUE(quitter.WasStartedReceived()); | 252 ASSERT_TRUE(quitter.WasStartedReceived()); |
| 256 multi_process_notification::Listener system_listener( | 253 multi_process_notification::Listener system_listener( |
| 257 "BasicCreationTest", multi_process_notification::SystemDomain, &quitter); | 254 "BasicCreationTest", multi_process_notification::SystemDomain, &quitter); |
| 258 ASSERT_TRUE(system_listener.Start()); | 255 ASSERT_TRUE(system_listener.Start(message_loop)); |
| 259 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 256 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 260 ASSERT_TRUE(quitter.WasStartedReceived()); | 257 ASSERT_TRUE(quitter.WasStartedReceived()); |
| 258 | |
| 259 multi_process_notification::Listener local_listener2( | |
| 260 "BasicCreationTest", multi_process_notification::UserDomain, &quitter); | |
| 261 // Should fail because current message loop should not be an IOMessageLoop. | |
| 262 ASSERT_FALSE(local_listener2.Start(MessageLoop::current())); | |
| 261 } | 263 } |
| 262 | 264 |
| 263 TEST_F(MultiProcessNotificationTest, PostInProcessNotification) { | 265 TEST_F(MultiProcessNotificationTest, PostInProcessNotification) { |
| 264 std::string local_notification("QuitLocalNotification"); | 266 std::string local_notification("QuitLocalNotification"); |
| 265 QuitterDelegate quitter; | 267 QuitterDelegate quitter; |
| 266 multi_process_notification::Listener listener( | 268 multi_process_notification::Listener listener( |
| 267 local_notification, multi_process_notification::UserDomain, &quitter); | 269 local_notification, multi_process_notification::UserDomain, &quitter); |
| 268 | 270 MessageLoop* message_loop = IOMessageLoop(); |
| 269 ASSERT_TRUE(listener.Start()); | 271 ASSERT_TRUE(listener.Start(message_loop)); |
| 270 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 272 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 271 ASSERT_TRUE(quitter.WasStartedReceived()); | 273 ASSERT_TRUE(quitter.WasStartedReceived()); |
| 272 ASSERT_TRUE(multi_process_notification::Post( | 274 ASSERT_TRUE(multi_process_notification::Post( |
| 273 local_notification, multi_process_notification::UserDomain)); | 275 local_notification, multi_process_notification::UserDomain)); |
| 274 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 276 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 275 ASSERT_TRUE(quitter.WasNotificationReceived()); | 277 ASSERT_TRUE(quitter.WasNotificationReceived()); |
| 276 } | 278 } |
| 277 | 279 |
| 278 TEST_F(MultiProcessNotificationTest, MultiListener) { | 280 TEST_F(MultiProcessNotificationTest, MultiListener) { |
| 279 std::string local_notification("LocalNotification"); | 281 std::string local_notification("LocalNotification"); |
| 280 std::string quit_local_notification("QuitLocalNotification"); | 282 std::string quit_local_notification("QuitLocalNotification"); |
| 281 | 283 |
| 282 SimpleDelegate delegate1; | 284 SimpleDelegate delegate1; |
| 283 SimpleDelegate delegate2; | 285 SimpleDelegate delegate2; |
| 284 multi_process_notification::Listener local_listener1( | 286 multi_process_notification::Listener local_listener1( |
| 285 local_notification, multi_process_notification::UserDomain, | 287 local_notification, multi_process_notification::UserDomain, |
| 286 &delegate1); | 288 &delegate1); |
| 287 multi_process_notification::Listener local_listener2( | 289 multi_process_notification::Listener local_listener2( |
| 288 local_notification, multi_process_notification::UserDomain, | 290 local_notification, multi_process_notification::UserDomain, |
| 289 &delegate2); | 291 &delegate2); |
| 290 | 292 |
| 291 QuitterDelegate quitter; | 293 QuitterDelegate quitter; |
| 292 | 294 |
| 293 multi_process_notification::Listener quit_listener(quit_local_notification, | 295 multi_process_notification::Listener quit_listener(quit_local_notification, |
| 294 multi_process_notification::UserDomain, &quitter); | 296 multi_process_notification::UserDomain, &quitter); |
| 295 | 297 MessageLoop* message_loop = IOMessageLoop(); |
| 296 ASSERT_TRUE(local_listener1.Start()); | 298 ASSERT_TRUE(local_listener1.Start(message_loop)); |
| 297 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 299 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 298 ASSERT_TRUE(delegate1.WasStartedReceived()); | 300 ASSERT_TRUE(delegate1.WasStartedReceived()); |
| 299 ASSERT_TRUE(local_listener2.Start()); | 301 ASSERT_TRUE(local_listener2.Start(message_loop)); |
| 300 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 302 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 301 ASSERT_TRUE(delegate2.WasStartedReceived()); | 303 ASSERT_TRUE(delegate2.WasStartedReceived()); |
| 302 ASSERT_TRUE(quit_listener.Start()); | 304 ASSERT_TRUE(quit_listener.Start(message_loop)); |
| 303 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 305 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 304 ASSERT_TRUE(quitter.WasStartedReceived()); | 306 ASSERT_TRUE(quitter.WasStartedReceived()); |
| 305 ASSERT_TRUE(multi_process_notification::Post( | 307 ASSERT_TRUE(multi_process_notification::Post( |
| 306 local_notification, multi_process_notification::UserDomain)); | 308 local_notification, multi_process_notification::UserDomain)); |
| 307 ASSERT_TRUE(multi_process_notification::Post( | 309 ASSERT_TRUE(multi_process_notification::Post( |
| 308 quit_local_notification, multi_process_notification::UserDomain)); | 310 quit_local_notification, multi_process_notification::UserDomain)); |
| 309 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); | 311 SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| 310 ASSERT_TRUE(delegate1.WasNotificationReceived()); | 312 ASSERT_TRUE(delegate1.WasNotificationReceived()); |
| 311 ASSERT_TRUE(delegate2.WasNotificationReceived()); | 313 ASSERT_TRUE(delegate2.WasNotificationReceived()); |
| 312 ASSERT_TRUE(quitter.WasNotificationReceived()); | 314 ASSERT_TRUE(quitter.WasNotificationReceived()); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 343 | 345 |
| 344 MULTIPROCESS_TEST_MAIN(MultiProcessUserNotificationMain) { | 346 MULTIPROCESS_TEST_MAIN(MultiProcessUserNotificationMain) { |
| 345 return MultiProcessNotificationMain(multi_process_notification::UserDomain); | 347 return MultiProcessNotificationMain(multi_process_notification::UserDomain); |
| 346 } | 348 } |
| 347 | 349 |
| 348 MULTIPROCESS_TEST_MAIN(MultiProcessSystemNotificationMain) { | 350 MULTIPROCESS_TEST_MAIN(MultiProcessSystemNotificationMain) { |
| 349 return MultiProcessNotificationMain(multi_process_notification::SystemDomain); | 351 return MultiProcessNotificationMain(multi_process_notification::SystemDomain); |
| 350 } | 352 } |
| 351 | 353 |
| 352 #endif // defined(OS_MACOSX) | 354 #endif // defined(OS_MACOSX) |
| OLD | NEW |