Index: base/task_scheduler/delayed_task_manager_unittest.cc |
diff --git a/base/task_scheduler/delayed_task_manager_unittest.cc b/base/task_scheduler/delayed_task_manager_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..edac738dd53ea3f12db7cf1f7f04e3b7019bbe4f |
--- /dev/null |
+++ b/base/task_scheduler/delayed_task_manager_unittest.cc |
@@ -0,0 +1,159 @@ |
+// 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/delayed_task_manager.h" |
+ |
+#include <utility> |
+ |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/logging.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/task_scheduler/priority_queue.h" |
+#include "base/task_scheduler/sequence.h" |
+#include "base/task_scheduler/shutdown_manager.h" |
+#include "base/task_scheduler/task.h" |
+#include "base/time/time.h" |
+#include "testing/gmock/include/gmock/gmock.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace base { |
+ |
+// Required by gmock. |
+bool operator==(const Closure& closure, const Closure& other_closure) { |
+ return closure.Equals(other_closure); |
+} |
+ |
+namespace task_scheduler { |
+ |
+namespace { |
+ |
+class TestDelayedTaskManager : public DelayedTaskManager { |
+ public: |
+ TestDelayedTaskManager() |
+ : DelayedTaskManager( |
+ Bind(&TestDelayedTaskManager::OnDelayedTaskReadyTimeChanged, |
+ Unretained(this)), |
+ &shutdown_manager_) {} |
+ |
+ void IncrementTime(TimeDelta delta) { now_ += delta; } |
+ MOCK_METHOD0(OnDelayedTaskReadyTimeChanged, void()); |
+ TimeTicks Now() override { return now_; } |
+ |
+ private: |
+ TimeTicks now_; |
+ ShutdownManager shutdown_manager_; |
+}; |
+ |
+} // namespace |
+ |
+// Check that a task added to a DelayedTaskManager is added to the proper |
+// sequence and priority queue by PostReadyTasks() when the current time is |
fdoray
2016/02/11 17:30:33
current time *becomes
fdoray
2016/02/12 04:16:19
Done.
|
+// equal to the task delayed run time. |
+TEST(TaskSchedulerDelayedTaskManagerTest, AddAndPostTask) { |
+ TestDelayedTaskManager manager; |
+ |
+ Task task(FROM_HERE, Bind(&DoNothing), TaskTraits(), TimeTicks()); |
+ const auto delay = TimeDelta::FromSeconds(1); |
+ task.delayed_run_time = TimeTicks() + delay; |
+ |
+ scoped_refptr<Sequence> sequence(new Sequence); |
+ PriorityQueue priority_queue(Bind(&DoNothing)); |
+ |
+ EXPECT_CALL(manager, OnDelayedTaskReadyTimeChanged()); |
+ manager.AddDelayedTask(task, sequence, &priority_queue); |
+ testing::Mock::VerifyAndClear(&manager); |
+ EXPECT_EQ(TimeTicks() + delay, manager.GetNextDelayedTaskReadyTime()); |
+ |
+ manager.IncrementTime(delay); |
+ |
+ manager.PostReadyTasks(); |
+ EXPECT_EQ(TimeTicks(), manager.GetNextDelayedTaskReadyTime()); |
+ EXPECT_EQ(task.posted_from, sequence->PeekTask()->posted_from); |
+ SequenceSortKey sort_key; |
+ EXPECT_EQ(sequence.get(), |
+ priority_queue.BeginTransaction()->PeekSequence(&sort_key).get()); |
+} |
+ |
+// Check that a task added to a DelayedTaskManager is added to the proper |
+// sequence and priority queue by PostReadyTasks() when the current time is |
fdoray
2016/02/11 17:30:32
current time *becomes
fdoray
2016/02/12 04:16:19
Done.
|
+// greater than the task delayed run time. |
+TEST(TaskSchedulerDelayedTaskManagerTest, AddAndPostTaskLate) { |
+ TestDelayedTaskManager manager; |
+ |
+ Task task(FROM_HERE, Bind(&DoNothing), TaskTraits(), TimeTicks()); |
+ const auto delay = TimeDelta::FromSeconds(1); |
+ task.delayed_run_time = TimeTicks() + delay; |
+ |
+ scoped_refptr<Sequence> sequence(new Sequence); |
+ PriorityQueue priority_queue(Bind(&DoNothing)); |
+ |
+ EXPECT_CALL(manager, OnDelayedTaskReadyTimeChanged()); |
+ manager.AddDelayedTask(task, sequence, &priority_queue); |
+ testing::Mock::VerifyAndClear(&manager); |
+ EXPECT_EQ(TimeTicks() + delay, manager.GetNextDelayedTaskReadyTime()); |
+ |
+ // Increment the time more than the task's delay. |
+ manager.IncrementTime(TimeDelta::FromSeconds(10)); |
+ |
+ manager.PostReadyTasks(); |
+ EXPECT_EQ(TimeTicks(), manager.GetNextDelayedTaskReadyTime()); |
+ EXPECT_EQ(task.posted_from, sequence->PeekTask()->posted_from); |
+} |
+ |
+// Check that when multiple tasks are added to a DelayedTaskManager, they are |
+// all inserted in their respective sequence and priority queue when they become |
+// ripe for execution. |
+TEST(TaskSchedulerDelayedTaskManagerTest, AddAndPostTasks) { |
+ TestDelayedTaskManager manager; |
+ size_t new_num_tasks = 0; |
+ |
+ scoped_refptr<Sequence> sequence(new Sequence); |
+ PriorityQueue priority_queue(Bind(&DoNothing)); |
+ |
+ Task task_a(FROM_HERE, Bind(&DoNothing), TaskTraits(), TimeTicks()); |
+ const auto delay_a = TimeDelta::FromSeconds(2); |
+ task_a.delayed_run_time = TimeTicks() + delay_a; |
+ |
+ Task task_b(FROM_HERE, Bind(&DoNothing), TaskTraits(), TimeTicks()); |
+ const auto delay_b = TimeDelta::FromSeconds(2); |
+ task_b.delayed_run_time = TimeTicks() + delay_b; |
+ |
+ Task task_c(FROM_HERE, Bind(&DoNothing), TaskTraits(), TimeTicks()); |
+ const auto delay_c = TimeDelta::FromSeconds(1); |
+ task_c.delayed_run_time = TimeTicks() + delay_c; |
+ |
+ EXPECT_CALL(manager, OnDelayedTaskReadyTimeChanged()); |
+ manager.AddDelayedTask(std::move(task_a), sequence, &priority_queue); |
+ testing::Mock::VerifyAndClear(&manager); |
+ EXPECT_EQ(TimeTicks() + delay_a, manager.GetNextDelayedTaskReadyTime()); |
+ |
+ manager.AddDelayedTask(std::move(task_b), sequence, &priority_queue); |
+ testing::Mock::VerifyAndClear(&manager); |
+ EXPECT_EQ(TimeTicks() + delay_a, manager.GetNextDelayedTaskReadyTime()); |
+ |
+ EXPECT_CALL(manager, OnDelayedTaskReadyTimeChanged()); |
+ manager.AddDelayedTask(std::move(task_c), sequence, &priority_queue); |
+ testing::Mock::VerifyAndClear(&manager); |
+ EXPECT_EQ(TimeTicks() + delay_c, manager.GetNextDelayedTaskReadyTime()); |
+ |
+ manager.IncrementTime(delay_c); |
+ |
+ manager.PostReadyTasks(); |
+ EXPECT_EQ(task_c.posted_from, sequence->PeekTask()->posted_from); |
+ sequence->PopTask(&new_num_tasks); |
+ EXPECT_EQ(TimeTicks() + delay_a, manager.GetNextDelayedTaskReadyTime()); |
+ |
+ manager.IncrementTime(delay_a - delay_c); |
+ |
+ manager.PostReadyTasks(); |
+ EXPECT_EQ(task_a.posted_from, sequence->PeekTask()->posted_from); |
+ sequence->PopTask(&new_num_tasks); |
+ EXPECT_EQ(task_b.posted_from, sequence->PeekTask()->posted_from); |
+ sequence->PopTask(&new_num_tasks); |
+ EXPECT_EQ(TimeTicks(), manager.GetNextDelayedTaskReadyTime()); |
+} |
+ |
+} // namespace task_scheduler |
+} // namespace base |