| 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..2a71036f54ed848af370ed7f5e24f7110e09a5de
|
| --- /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 internal {
|
| +
|
| +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 becomes
|
| +// 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.GetNextDelayedRunTime());
|
| +
|
| + manager.IncrementTime(delay);
|
| +
|
| + manager.PostReadyTasks();
|
| + EXPECT_EQ(TimeTicks(), manager.GetNextDelayedRunTime());
|
| + 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 becomes
|
| +// 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.GetNextDelayedRunTime());
|
| +
|
| + // Increment the time more than the task's delay.
|
| + manager.IncrementTime(TimeDelta::FromSeconds(10));
|
| +
|
| + manager.PostReadyTasks();
|
| + EXPECT_EQ(TimeTicks(), manager.GetNextDelayedRunTime());
|
| + 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.GetNextDelayedRunTime());
|
| +
|
| + manager.AddDelayedTask(std::move(task_b), sequence, &priority_queue);
|
| + testing::Mock::VerifyAndClear(&manager);
|
| + EXPECT_EQ(TimeTicks() + delay_a, manager.GetNextDelayedRunTime());
|
| +
|
| + EXPECT_CALL(manager, OnDelayedTaskReadyTimeChanged());
|
| + manager.AddDelayedTask(std::move(task_c), sequence, &priority_queue);
|
| + testing::Mock::VerifyAndClear(&manager);
|
| + EXPECT_EQ(TimeTicks() + delay_c, manager.GetNextDelayedRunTime());
|
| +
|
| + 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.GetNextDelayedRunTime());
|
| +
|
| + 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.GetNextDelayedRunTime());
|
| +}
|
| +
|
| +} // namespace internal
|
| +} // namespace base
|
|
|