Chromium Code Reviews| 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 |