Index: base/waitable_event_watcher_unittest.cc |
diff --git a/base/waitable_event_watcher_unittest.cc b/base/waitable_event_watcher_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c50807fd86697764a6b58778ea8c105dbd5ea013 |
--- /dev/null |
+++ b/base/waitable_event_watcher_unittest.cc |
@@ -0,0 +1,136 @@ |
+// Copyright (c) 2006-2008 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 "base/message_loop.h" |
+#include "base/platform_thread.h" |
+#include "base/waitable_event.h" |
+#include "base/waitable_event_watcher.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using base::WaitableEvent; |
+using base::WaitableEventWatcher; |
+ |
+namespace { |
+ |
+class QuitDelegate : public WaitableEventWatcher::Delegate { |
+ public: |
+ virtual void OnWaitableEventSignaled(WaitableEvent* event) { |
+ MessageLoop::current()->Quit(); |
+ } |
+}; |
+ |
+class DecrementCountDelegate : public WaitableEventWatcher::Delegate { |
+ public: |
+ DecrementCountDelegate(int* counter) : counter_(counter) { |
+ } |
+ virtual void OnWaitableEventSignaled(WaitableEvent* object) { |
+ --(*counter_); |
+ } |
+ private: |
+ int* counter_; |
+}; |
+ |
+} // namespace |
+ |
+void RunTest_BasicSignal(MessageLoop::Type message_loop_type) { |
+ MessageLoop message_loop(message_loop_type); |
+ |
+ // A manual-reset event that is not yet signaled. |
+ WaitableEvent event(true, false); |
+ |
+ WaitableEventWatcher watcher; |
+ EXPECT_EQ(NULL, watcher.GetWatchedObject()); |
+ |
+ QuitDelegate delegate; |
+ watcher.StartWatching(&event, &delegate); |
+ EXPECT_EQ(&event, watcher.GetWatchedObject()); |
+ |
+ event.Signal(); |
+ |
+ MessageLoop::current()->Run(); |
+ |
+ EXPECT_EQ(NULL, watcher.GetWatchedObject()); |
+} |
+ |
+void RunTest_BasicCancel(MessageLoop::Type message_loop_type) { |
+ MessageLoop message_loop(message_loop_type); |
+ |
+ // A manual-reset event that is not yet signaled. |
+ WaitableEvent event(true, false); |
+ |
+ WaitableEventWatcher watcher; |
+ |
+ QuitDelegate delegate; |
+ watcher.StartWatching(&event, &delegate); |
+ |
+ watcher.StopWatching(); |
+} |
+ |
+void RunTest_CancelAfterSet(MessageLoop::Type message_loop_type) { |
+ MessageLoop message_loop(message_loop_type); |
+ |
+ // A manual-reset event that is not yet signaled. |
+ WaitableEvent event(true, false); |
+ |
+ WaitableEventWatcher watcher; |
+ |
+ int counter = 1; |
+ DecrementCountDelegate delegate(&counter); |
+ |
+ watcher.StartWatching(&event, &delegate); |
+ |
+ event.Signal(); |
+ |
+ // Let the background thread do its business |
+ PlatformThread::Sleep(30); |
+ |
+ watcher.StopWatching(); |
+ |
+ MessageLoop::current()->RunAllPending(); |
+ |
+ // Our delegate should not have fired. |
+ EXPECT_EQ(1, counter); |
+} |
+ |
+void RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type) { |
+ // Simulate a MessageLoop that dies before an WaitableEventWatcher. This |
+ // ordinarily doesn't happen when people use the Thread class, but it can |
+ // happen when people use the Singleton pattern or atexit. |
+ WaitableEvent event(true, false); |
+ { |
+ WaitableEventWatcher watcher; |
+ { |
+ MessageLoop message_loop(message_loop_type); |
+ |
+ QuitDelegate delegate; |
+ watcher.StartWatching(&event, &delegate); |
+ } |
+ } |
+} |
+ |
+//----------------------------------------------------------------------------- |
+ |
+TEST(ObjectWatcherTest, BasicSignal) { |
+ RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT); |
+ RunTest_BasicSignal(MessageLoop::TYPE_IO); |
+ RunTest_BasicSignal(MessageLoop::TYPE_UI); |
+} |
+ |
+TEST(ObjectWatcherTest, BasicCancel) { |
+ RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT); |
+ RunTest_BasicCancel(MessageLoop::TYPE_IO); |
+ RunTest_BasicCancel(MessageLoop::TYPE_UI); |
+} |
+ |
+TEST(ObjectWatcherTest, CancelAfterSet) { |
+ RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT); |
+ RunTest_CancelAfterSet(MessageLoop::TYPE_IO); |
+ RunTest_CancelAfterSet(MessageLoop::TYPE_UI); |
+} |
+ |
+TEST(ObjectWatcherTest, OutlivesMessageLoop) { |
+ RunTest_OutlivesMessageLoop(MessageLoop::TYPE_DEFAULT); |
+ RunTest_OutlivesMessageLoop(MessageLoop::TYPE_IO); |
+ RunTest_OutlivesMessageLoop(MessageLoop::TYPE_UI); |
+} |