Chromium Code Reviews| Index: chrome/common/multi_process_notification_unittest.cc |
| diff --git a/chrome/common/multi_process_notification_unittest.cc b/chrome/common/multi_process_notification_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..debee923e50f194f4ddf24e7d93a65e249cd2e38 |
| --- /dev/null |
| +++ b/chrome/common/multi_process_notification_unittest.cc |
| @@ -0,0 +1,221 @@ |
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/common/multi_process_notification.h" |
| + |
| +#include "base/basictypes.h" |
| +#include "base/environment.h" |
| +#include "base/logging.h" |
| +#include "base/message_loop.h" |
| +#include "base/test/multiprocess_test.h" |
| +#include "base/test/test_timeouts.h" |
| +#include "base/time.h" |
| +#include "testing/multiprocess_func_list.h" |
| + |
| +#if defined(OS_MACOSX) |
| +// TODO(dmaclach): Remove defined(OS_MACOSX) once |
| +// MultiProcessNotification is implemented on Win/Linux. |
| + |
| +namespace { |
| + |
| +const char kStartedNotificationName[] = "MultiProcessTestStartedNotification"; |
| +const char kQuitNotificationName[] = "MultiProcessTestQuitNotification"; |
| + |
| +void SpinRunLoop(int milliseconds) { |
| + MessageLoopForIO *loop = MessageLoopForIO::current(); |
| + // Post a quit task so that this loop eventually ends and we don't hang |
|
Mark Mentovai
2011/01/06 17:59:09
What’s with this indentation? Bring it back to be
dmac
2011/01/06 18:22:37
Stupid Xcode.
|
| + // in the case of a bad test. Usually, the run loop will quit sooner than |
| + // that because all tests use a MultiProcessNotificationTestQuit which quits |
| + // the current run loop when it gets a notification. |
| + loop->PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), milliseconds); |
| + loop->Run(); |
| +} |
| + |
| +int MultiProcessNotificationMain(multi_process_notification::Domain domain) { |
| + MessageLoop io_loop(MessageLoop::TYPE_IO); |
| + multi_process_notification::PerformTaskOnNotification quitter( |
| + new MessageLoop::QuitTask()); |
| + multi_process_notification::Listener listener( |
| + kQuitNotificationName, domain, &quitter); |
| + EXPECT_TRUE(listener.Start()); |
| + EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName, |
| + domain)); |
| + SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| + EXPECT_TRUE(quitter.WasNotificationCalled()); |
| + return 0; |
| +} |
| + |
| +} // namespace |
| + |
| +class MultiProcessNotificationTest : public base::MultiProcessTest { |
| + public: |
| + MultiProcessNotificationTest(); |
| + |
| + void PostNotificationTest(multi_process_notification::Domain domain); |
| + void CrossPostNotificationTest(multi_process_notification::Domain domain); |
| + |
| + private: |
| + MessageLoop io_loop_; |
| +}; |
| + |
| +MultiProcessNotificationTest::MultiProcessNotificationTest() |
| + : io_loop_(MessageLoop::TYPE_IO) { |
| +} |
| + |
| +void MultiProcessNotificationTest::PostNotificationTest( |
| + multi_process_notification::Domain domain) { |
| + multi_process_notification::PerformTaskOnNotification process_started( |
| + new MessageLoop::QuitTask()); |
| + multi_process_notification::Listener listener(kStartedNotificationName, |
| + domain, |
| + &process_started); |
| + ASSERT_TRUE(listener.Start()); |
| + std::string process_name; |
| + switch (domain) { |
| + case multi_process_notification::ProfileDomain: |
| + process_name = "MultiProcessProfileNotificationMain"; |
| + break; |
| + |
| + case multi_process_notification::UserDomain: |
| + process_name = "MultiProcessUserNotificationMain"; |
| + break; |
| + |
| + case multi_process_notification::SystemDomain: |
| + process_name = "MultiProcessSystemNotificationMain"; |
| + break; |
| + } |
| + base::ProcessHandle handle = SpawnChild(process_name, false); |
| + ASSERT_TRUE(handle); |
| + SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| + ASSERT_TRUE(process_started.WasNotificationCalled()); |
| + ASSERT_TRUE(multi_process_notification::Post(kQuitNotificationName, domain)); |
| + int exit_code = 0; |
| + EXPECT_TRUE(base::WaitForExitCodeWithTimeout( |
| + handle, &exit_code, TestTimeouts::action_max_timeout_ms())); |
| +} |
| + |
| +void MultiProcessNotificationTest::CrossPostNotificationTest( |
| + multi_process_notification::Domain domain) { |
| + // Check to make sure notifications sent to user domain aren't picked up |
| + // by system domain listeners and vice versa. |
| + std::string local_notification("QuitLocalNotification"); |
| + std::string final_notification("FinalQuitLocalNotification"); |
| + multi_process_notification::PerformTaskOnNotification profile_quitter( |
| + new MessageLoop::QuitTask()); |
| + multi_process_notification::PerformTaskOnNotification user_quitter( |
| + new MessageLoop::QuitTask()); |
| + multi_process_notification::PerformTaskOnNotification system_quitter( |
| + new MessageLoop::QuitTask()); |
| + multi_process_notification::PerformTaskOnNotification final_quitter( |
| + new MessageLoop::QuitTask()); |
| + multi_process_notification::Listener profile_listener( |
| + local_notification, multi_process_notification::ProfileDomain, |
| + &profile_quitter); |
| + multi_process_notification::Listener user_listener( |
| + local_notification, multi_process_notification::UserDomain, |
| + &user_quitter); |
| + multi_process_notification::Listener system_listener( |
| + local_notification, multi_process_notification::SystemDomain, |
| + &system_quitter); |
| + multi_process_notification::Listener final_listener( |
| + final_notification, multi_process_notification::UserDomain, |
| + &final_quitter); |
| + |
| + ASSERT_TRUE(profile_listener.Start()); |
| + ASSERT_TRUE(user_listener.Start()); |
| + ASSERT_TRUE(system_listener.Start()); |
| + ASSERT_TRUE(multi_process_notification::Post(local_notification, domain)); |
| + SpinRunLoop(TestTimeouts::action_timeout_ms()); |
| + |
| + // Now send out a final_notification to queue up a notification |
| + // after the local_notification and make sure that all listeners have had a |
| + // chance to process local_notification before we check to see if they |
| + // were called. |
| + ASSERT_TRUE(final_listener.Start()); |
| + ASSERT_TRUE(multi_process_notification::Post( |
| + final_notification, multi_process_notification::UserDomain)); |
| + SpinRunLoop(TestTimeouts::action_timeout_ms()); |
| + ASSERT_TRUE(final_quitter.WasNotificationCalled()); |
| + switch (domain) { |
| + case multi_process_notification::ProfileDomain: |
| + ASSERT_TRUE(profile_quitter.WasNotificationCalled()); |
| + ASSERT_FALSE(user_quitter.WasNotificationCalled()); |
| + ASSERT_FALSE(system_quitter.WasNotificationCalled()); |
| + break; |
| + |
| + case multi_process_notification::UserDomain: |
| + ASSERT_FALSE(profile_quitter.WasNotificationCalled()); |
| + ASSERT_TRUE(user_quitter.WasNotificationCalled()); |
| + ASSERT_FALSE(system_quitter.WasNotificationCalled()); |
| + break; |
| + |
| + case multi_process_notification::SystemDomain: |
| + ASSERT_FALSE(profile_quitter.WasNotificationCalled()); |
| + ASSERT_FALSE(user_quitter.WasNotificationCalled()); |
| + ASSERT_TRUE(system_quitter.WasNotificationCalled()); |
| + break; |
| + } |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, BasicCreationTest) { |
| + multi_process_notification::Listener local_listener( |
| + "BasicCreationTest", multi_process_notification::UserDomain, NULL); |
| + ASSERT_TRUE(local_listener.Start()); |
| + multi_process_notification::Listener system_listener( |
| + "BasicCreationTest", multi_process_notification::SystemDomain, NULL); |
| + ASSERT_TRUE(system_listener.Start()); |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, PostInProcessNotification) { |
| + std::string local_notification("QuitLocalNotification"); |
| + multi_process_notification::PerformTaskOnNotification quitter( |
| + new MessageLoop::QuitTask()); |
| + multi_process_notification::Listener listener( |
| + local_notification, multi_process_notification::UserDomain, &quitter); |
| + |
| + ASSERT_TRUE(listener.Start()); |
| + ASSERT_TRUE(multi_process_notification::Post( |
| + local_notification, multi_process_notification::UserDomain)); |
| + SpinRunLoop(TestTimeouts::action_max_timeout_ms()); |
| + ASSERT_TRUE(quitter.WasNotificationCalled()); |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, PostProfileNotification) { |
| + PostNotificationTest(multi_process_notification::ProfileDomain); |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, PostUserNotification) { |
| + PostNotificationTest(multi_process_notification::UserDomain); |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, PostSystemNotification) { |
| + PostNotificationTest(multi_process_notification::SystemDomain); |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, ProfileCrossDomainPosting) { |
| + CrossPostNotificationTest(multi_process_notification::ProfileDomain); |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, UserCrossDomainPosting) { |
| + CrossPostNotificationTest(multi_process_notification::UserDomain); |
| +} |
| + |
| +TEST_F(MultiProcessNotificationTest, SystemCrossDomainPosting) { |
| + CrossPostNotificationTest(multi_process_notification::SystemDomain); |
| +} |
| + |
| +MULTIPROCESS_TEST_MAIN(MultiProcessProfileNotificationMain) { |
| + return MultiProcessNotificationMain( |
| + multi_process_notification::ProfileDomain); |
| +} |
| + |
| +MULTIPROCESS_TEST_MAIN(MultiProcessUserNotificationMain) { |
| + return MultiProcessNotificationMain(multi_process_notification::UserDomain); |
| +} |
| + |
| +MULTIPROCESS_TEST_MAIN(MultiProcessSystemNotificationMain) { |
| + return MultiProcessNotificationMain(multi_process_notification::SystemDomain); |
| +} |
| + |
| +#endif // defined(OS_MACOSX) |