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 |