Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1404)

Unified Diff: chrome/browser/multi_process_notification_unittest.cc

Issue 5970015: Add multi-process notification class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed up bad tabs Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/multi_process_notification_mac.mm ('k') | chrome/browser/multi_process_notification_win.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/multi_process_notification_unittest.cc
diff --git a/chrome/browser/multi_process_notification_unittest.cc b/chrome/browser/multi_process_notification_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8c42fcb5387b4d3374f2cc230aa03d048547f96f
--- /dev/null
+++ b/chrome/browser/multi_process_notification_unittest.cc
@@ -0,0 +1,352 @@
+// 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/browser/multi_process_notification.h"
+
+#include "base/basictypes.h"
+#include "base/compiler_specific.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 "chrome/browser/browser_thread.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) {
+ MessageLoop *loop = MessageLoop::current();
+
+ // Post a quit task so that this loop eventually ends and we don't hang
+ // 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();
+}
+
+class SimpleDelegate
+ : public multi_process_notification::Listener::Delegate {
+ public:
+ SimpleDelegate()
+ : notification_received_(false), started_received_(false) { }
+ virtual ~SimpleDelegate();
+
+ virtual void OnNotificationReceived(
+ const std::string& name,
+ multi_process_notification::Domain domain) OVERRIDE;
+ virtual void OnListenerStarted(
+ const std::string& name, multi_process_notification::Domain domain,
+ bool success) OVERRIDE;
+
+ bool WasNotificationReceived() { return notification_received_; }
+ bool WasStartedReceived() { return started_received_; }
+
+ private:
+ bool notification_received_;
+ bool started_received_;
+ DISALLOW_COPY_AND_ASSIGN(SimpleDelegate);
+};
+
+SimpleDelegate::~SimpleDelegate() {
+}
+
+void SimpleDelegate::OnNotificationReceived(
+ const std::string& name, multi_process_notification::Domain domain) {
+ notification_received_ = true;
+}
+
+void SimpleDelegate::OnListenerStarted(
+ const std::string& name, multi_process_notification::Domain domain,
+ bool success) {
+ ASSERT_TRUE(success);
+ started_received_ = true;
+ MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+}
+
+class QuitterDelegate : public SimpleDelegate {
+ public:
+ QuitterDelegate() : SimpleDelegate() { }
+ virtual ~QuitterDelegate();
+
+ virtual void OnNotificationReceived(
+ const std::string& name,
+ multi_process_notification::Domain domain) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QuitterDelegate);
+};
+
+QuitterDelegate::~QuitterDelegate() {
+}
+
+void QuitterDelegate::OnNotificationReceived(
+ const std::string& name, multi_process_notification::Domain domain) {
+ SimpleDelegate::OnNotificationReceived(name, domain);
+ MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
+}
+
+int MultiProcessNotificationMain(multi_process_notification::Domain domain) {
+ BrowserThread browser_thread(BrowserThread::IO);
+ base::Thread::Options options(MessageLoop::TYPE_IO, 0);
+ EXPECT_TRUE(browser_thread.StartWithOptions(options));
+ MessageLoop loop;
+ QuitterDelegate quitter;
+ multi_process_notification::Listener listener(
+ kQuitNotificationName, domain, &quitter);
+ EXPECT_TRUE(listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ EXPECT_TRUE(quitter.WasStartedReceived());
+ EXPECT_TRUE(multi_process_notification::Post(kStartedNotificationName,
+ domain));
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ EXPECT_TRUE(quitter.WasNotificationReceived());
+ return 0;
+}
+
+} // namespace
+
+class MultiProcessNotificationTest : public base::MultiProcessTest {
+ public:
+ MultiProcessNotificationTest();
+
+ void PostNotificationTest(multi_process_notification::Domain domain);
+ void CrossPostNotificationTest(multi_process_notification::Domain domain);
+
+ static void SetUpTestCase();
+ static void TearDownTestCase();
+
+ private:
+ MessageLoop loop_;
+ static BrowserThread* g_io_thread;
+};
+
+MultiProcessNotificationTest::MultiProcessNotificationTest() {
+}
+
+BrowserThread* MultiProcessNotificationTest::g_io_thread = NULL;
+
+void MultiProcessNotificationTest::SetUpTestCase() {
+ g_io_thread = new BrowserThread(BrowserThread::IO);
+ base::Thread::Options options(MessageLoop::TYPE_IO, 0);
+ ASSERT_TRUE(g_io_thread->StartWithOptions(options));
+}
+
+void MultiProcessNotificationTest::TearDownTestCase() {
+ delete g_io_thread;
+}
+
+void MultiProcessNotificationTest::PostNotificationTest(
+ multi_process_notification::Domain domain) {
+ QuitterDelegate process_started;
+ multi_process_notification::Listener listener(
+ kStartedNotificationName, domain, &process_started);
+ ASSERT_TRUE(listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(process_started.WasStartedReceived());
+ 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.WasNotificationReceived());
+ 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");
+ QuitterDelegate profile_quitter;
+ QuitterDelegate user_quitter;
+ QuitterDelegate system_quitter;
+ QuitterDelegate final_quitter;
+ 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());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(profile_quitter.WasStartedReceived());
+ ASSERT_TRUE(user_listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(user_quitter.WasStartedReceived());
+ ASSERT_TRUE(system_listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(system_quitter.WasStartedReceived());
+
+ 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());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ EXPECT_TRUE(final_quitter.WasStartedReceived());
+ ASSERT_TRUE(multi_process_notification::Post(
+ final_notification, multi_process_notification::UserDomain));
+ SpinRunLoop(TestTimeouts::action_timeout_ms());
+ ASSERT_TRUE(final_quitter.WasNotificationReceived());
+ switch (domain) {
+ case multi_process_notification::ProfileDomain:
+ ASSERT_TRUE(profile_quitter.WasNotificationReceived());
+ ASSERT_FALSE(user_quitter.WasNotificationReceived());
+ ASSERT_FALSE(system_quitter.WasNotificationReceived());
+ break;
+
+ case multi_process_notification::UserDomain:
+ ASSERT_FALSE(profile_quitter.WasNotificationReceived());
+ ASSERT_TRUE(user_quitter.WasNotificationReceived());
+ ASSERT_FALSE(system_quitter.WasNotificationReceived());
+ break;
+
+ case multi_process_notification::SystemDomain:
+ ASSERT_FALSE(profile_quitter.WasNotificationReceived());
+ ASSERT_FALSE(user_quitter.WasNotificationReceived());
+ ASSERT_TRUE(system_quitter.WasNotificationReceived());
+ break;
+ }
+}
+
+TEST_F(MultiProcessNotificationTest, BasicCreationTest) {
+ QuitterDelegate quitter;
+ multi_process_notification::Listener local_listener(
+ "BasicCreationTest", multi_process_notification::UserDomain, &quitter);
+ ASSERT_TRUE(local_listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(quitter.WasStartedReceived());
+ multi_process_notification::Listener system_listener(
+ "BasicCreationTest", multi_process_notification::SystemDomain, &quitter);
+ ASSERT_TRUE(system_listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(quitter.WasStartedReceived());
+}
+
+TEST_F(MultiProcessNotificationTest, PostInProcessNotification) {
+ std::string local_notification("QuitLocalNotification");
+ QuitterDelegate quitter;
+ multi_process_notification::Listener listener(
+ local_notification, multi_process_notification::UserDomain, &quitter);
+
+ ASSERT_TRUE(listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(quitter.WasStartedReceived());
+ ASSERT_TRUE(multi_process_notification::Post(
+ local_notification, multi_process_notification::UserDomain));
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(quitter.WasNotificationReceived());
+}
+
+TEST_F(MultiProcessNotificationTest, MultiListener) {
+ std::string local_notification("LocalNotification");
+ std::string quit_local_notification("QuitLocalNotification");
+
+ SimpleDelegate delegate1;
+ SimpleDelegate delegate2;
+ multi_process_notification::Listener local_listener1(
+ local_notification, multi_process_notification::UserDomain,
+ &delegate1);
+ multi_process_notification::Listener local_listener2(
+ local_notification, multi_process_notification::UserDomain,
+ &delegate2);
+
+ QuitterDelegate quitter;
+
+ multi_process_notification::Listener quit_listener(quit_local_notification,
+ multi_process_notification::UserDomain, &quitter);
+
+ ASSERT_TRUE(local_listener1.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(delegate1.WasStartedReceived());
+ ASSERT_TRUE(local_listener2.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(delegate2.WasStartedReceived());
+ ASSERT_TRUE(quit_listener.Start());
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(quitter.WasStartedReceived());
+ ASSERT_TRUE(multi_process_notification::Post(
+ local_notification, multi_process_notification::UserDomain));
+ ASSERT_TRUE(multi_process_notification::Post(
+ quit_local_notification, multi_process_notification::UserDomain));
+ SpinRunLoop(TestTimeouts::action_max_timeout_ms());
+ ASSERT_TRUE(delegate1.WasNotificationReceived());
+ ASSERT_TRUE(delegate2.WasNotificationReceived());
+ ASSERT_TRUE(quitter.WasNotificationReceived());
+}
+
+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)
« no previous file with comments | « chrome/browser/multi_process_notification_mac.mm ('k') | chrome/browser/multi_process_notification_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698