Index: base/task_scheduler/shutdown_manager_unittest.cc |
diff --git a/base/task_scheduler/shutdown_manager_unittest.cc b/base/task_scheduler/shutdown_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f51c40f5c78b95d152e287efc96027390ccf9d74 |
--- /dev/null |
+++ b/base/task_scheduler/shutdown_manager_unittest.cc |
@@ -0,0 +1,239 @@ |
+// Copyright 2016 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/task_scheduler/shutdown_manager.h" |
+ |
+#include "base/macros.h" |
+#include "base/threading/platform_thread.h" |
+#include "base/threading/simple_thread.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace base { |
+namespace internal { |
+ |
+namespace { |
+ |
+class ThreadCallingShutdown : public SimpleThread { |
+ public: |
+ explicit ThreadCallingShutdown(ShutdownManager* manager) |
+ : SimpleThread("ThreadCallingShutdown"), |
+ manager_(manager), |
+ has_exited_(false) {} |
+ |
+ // Waits until manager_->Shutdown() has been called. |
+ void WaitUntilShutdownCalled() { |
+ while (!manager_->is_shutting_down_for_testing()) |
+ PlatformThread::Sleep(TimeDelta::FromMilliseconds(5)); |
gab
2016/02/23 22:28:23
5 seems arbitrary. How about PlatformThread::Yield
fdoray
2016/02/26 15:53:28
Done.
|
+ } |
+ |
+ // Returns true once the thread has exited. |
+ bool has_exited() const { return has_exited_; } |
+ |
+ private: |
+ void Run() override { |
+ manager_->Shutdown(); |
+ has_exited_ = true; |
+ } |
+ |
+ ShutdownManager* manager_; |
+ bool has_exited_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ThreadCallingShutdown); |
+}; |
+ |
+} // namespace |
+ |
+TEST(TaskSchedulerShutdownManagerTest, ShouldPostTaskBeforeShutdown) { |
+ ShutdownManager manager; |
+ EXPECT_TRUE( |
+ manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, ShouldPostTaskAfterShutdownCompleted) { |
+ ShutdownManager manager; |
+ manager.Shutdown(); |
+ EXPECT_FALSE( |
+ manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_FALSE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ EXPECT_FALSE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, ShouldScheduleTaskBeforeShutdown) { |
+ ShutdownManager manager; |
+ EXPECT_TRUE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_TRUE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, |
+ ShouldScheduleTaskAfterShutdownCompleted) { |
+ ShutdownManager manager; |
+ manager.Shutdown(); |
+ EXPECT_FALSE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_FALSE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ EXPECT_FALSE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, |
+ ShouldPostAndScheduleTaskDuringShutdown) { |
+ ShutdownManager manager; |
+ |
+ // Inform the manager that a BLOCK_SHUTDOWN task has been posted, to block |
+ // shutdown. |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ |
+ // Call manager.Shutdown() on another thread. |
+ ThreadCallingShutdown thread(&manager); |
+ thread.Start(); |
+ thread.WaitUntilShutdownCalled(); |
+ EXPECT_FALSE(thread.has_exited()); |
+ |
+ // Check that only a BLOCK_SHUTDOWN task can be posted. |
+ EXPECT_FALSE( |
+ manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ EXPECT_FALSE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ |
+ // Check that only a BLOCK_SHUTDOWN task can be scheduled. |
+ EXPECT_FALSE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ EXPECT_FALSE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ |
+ // Unblock Shutdown(). |
+ manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); |
+ EXPECT_FALSE(thread.has_exited()); |
+ EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); |
+ |
+ // Wait until the thread calling manager.Shutdown() exits. |
+ thread.Join(); |
+ EXPECT_TRUE(thread.has_exited()); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, |
+ ShutdownWithQueuedSkipAndContinueOnShutdownTasks) { |
+ ShutdownManager manager; |
+ |
+ // Inform |manager| that a CONTINUE_ON_SHUTDOWN task and a SKIP_ON_SHUTDOWN |
+ // task have been posted. |
+ EXPECT_TRUE( |
+ manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ |
+ // Call manager.Shutdown(). This call shouldn't block. |
+ manager.Shutdown(); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, |
+ ShutdownScheduledContinueOnShutdownTasks) { |
+ ShutdownManager manager; |
+ |
+ // Inform |manager| that a SKIP_ON_SHUTDOWN task has been posted and |
+ // scheduled. |
+ EXPECT_TRUE( |
+ manager.ShouldPostTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ EXPECT_TRUE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
+ |
+ // Call manager.Shutdown() on another thread. This call shouldn't block. |
+ manager.Shutdown(); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, ShutdownScheduledSkipOnShutdownTasks) { |
+ ShutdownManager manager; |
+ |
+ // Inform |manager| that a SKIP_ON_SHUTDOWN task has been posted and |
+ // scheduled. |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ EXPECT_TRUE( |
+ manager.ShouldScheduleTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
+ |
+ // Call manager.Shutdown() on another thread. This call should block until the |
+ // SKIP_ON_SHUTDOWN task has been executed. |
+ ThreadCallingShutdown thread(&manager); |
+ thread.Start(); |
+ thread.WaitUntilShutdownCalled(); |
+ EXPECT_FALSE(thread.has_exited()); |
+ |
+ // Inform |manager| that a SKIP_ON_SHUTDOWN task has been executed. |
+ manager.DidExecuteTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN); |
+ |
+ // Wait until the thread calling manager.Shutdown() exits. |
+ thread.Join(); |
+ EXPECT_TRUE(thread.has_exited()); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, ShutdownWithQueuedBlockShutdownTasks) { |
gab
2016/02/23 22:28:23
I think ShouldPostAndScheduleTaskDuringShutdown al
fdoray
2016/02/26 15:53:28
I completely refactored the unit tests :)
|
+ ShutdownManager manager; |
+ |
+ // Inform |manager| that 2 BLOCK_SHUTDOWN task have been posted. |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ |
+ // Call manager.Shutdown() on another thread. This call should block until |
+ // both BLOCK_SHUTDOWN tasks have been executed. |
+ ThreadCallingShutdown thread(&manager); |
+ thread.Start(); |
+ thread.WaitUntilShutdownCalled(); |
+ EXPECT_FALSE(thread.has_exited()); |
+ |
+ // Inform |manager| that the first BLOCK_SHUTDOWN task has been scheduled and |
+ // executed. |
+ EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); |
+ EXPECT_FALSE(thread.has_exited()); |
+ |
+ // Inform |manager| that the second BLOCK_SHUTDOWN task has been scheduled and |
+ // executed.. |
+ EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ EXPECT_FALSE(thread.has_exited()); |
+ manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); |
+ |
+ // Wait until the thread calling manager.Shutdown() exits. |
+ thread.Join(); |
+ EXPECT_TRUE(thread.has_exited()); |
+} |
+ |
+TEST(TaskSchedulerShutdownManagerTest, |
+ ShutdownWithScheduledBlockShutdownTasks) { |
+ ShutdownManager manager; |
+ |
+ // Inform |manager| that a BLOCK_SHUTDOWN task have been posted and scheduled. |
+ EXPECT_TRUE(manager.ShouldPostTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ EXPECT_TRUE(manager.ShouldScheduleTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
+ |
+ // Call manager.Shutdown() on another thread. This call should block until the |
+ // BLOCK_SHUTDOWN task has been executed. |
+ ThreadCallingShutdown thread(&manager); |
+ thread.Start(); |
+ thread.WaitUntilShutdownCalled(); |
+ EXPECT_FALSE(thread.has_exited()); |
+ |
+ // Inform |manager| that a BLOCK_SHUTDOWN task has been executed. |
+ manager.DidExecuteTask(TaskShutdownBehavior::BLOCK_SHUTDOWN); |
+ |
+ // Wait until the thread calling manager.Shutdown() exits. |
+ thread.Join(); |
+ EXPECT_TRUE(thread.has_exited()); |
+} |
+ |
+} // namespace internal |
+} // namespace base |