| Index: content/child/scheduler/worker_scheduler_impl_unittest.cc
|
| diff --git a/content/child/scheduler/worker_scheduler_impl_unittest.cc b/content/child/scheduler/worker_scheduler_impl_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3e0d63918e1180bb75aacf4033ef95bdec8f6594
|
| --- /dev/null
|
| +++ b/content/child/scheduler/worker_scheduler_impl_unittest.cc
|
| @@ -0,0 +1,229 @@
|
| +// Copyright 2015 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 "content/child/scheduler/worker_scheduler_impl.h"
|
| +
|
| +#include "base/callback.h"
|
| +#include "cc/test/ordered_simple_task_runner.h"
|
| +#include "content/child/scheduler/nestable_task_runner_for_test.h"
|
| +#include "content/child/scheduler/scheduler_message_loop_delegate.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +void NopTask() {
|
| +}
|
| +
|
| +void AppendToVectorTestTask(std::vector<std::string>* vector,
|
| + std::string value) {
|
| + vector->push_back(value);
|
| +}
|
| +
|
| +void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
|
| + std::string value,
|
| + base::TimeTicks deadline) {
|
| + AppendToVectorTestTask(vector, value);
|
| +}
|
| +
|
| +void IdleTestTask(base::TimeTicks* deadline_out, base::TimeTicks deadline) {
|
| + *deadline_out = deadline;
|
| +}
|
| +}; // namespace
|
| +
|
| +class WorkerSchedulerImplTest : public testing::Test {
|
| + public:
|
| + WorkerSchedulerImplTest()
|
| + : clock_(cc::TestNowSource::Create(5000)),
|
| + mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, true)),
|
| + nestable_task_runner_(
|
| + NestableTaskRunnerForTest::Create(mock_task_runner_)),
|
| + scheduler_(new WorkerSchedulerImpl(nestable_task_runner_)),
|
| + default_task_runner_(scheduler_->DefaultTaskRunner()),
|
| + idle_task_runner_(scheduler_->IdleTaskRunner()) {
|
| + scheduler_->SetTimeSourceForTesting(clock_);
|
| + }
|
| +
|
| + ~WorkerSchedulerImplTest() override {}
|
| +
|
| + void TearDown() override {
|
| + // Check that all tests stop posting tasks.
|
| + mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| + while (mock_task_runner_->RunUntilIdle()) {
|
| + }
|
| + }
|
| +
|
| + void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); }
|
| +
|
| + // Helper for posting several tasks of specific types. |task_descriptor| is a
|
| + // string with space delimited task identifiers. The first letter of each
|
| + // task identifier specifies the task type:
|
| + // - 'D': Default task
|
| + // - 'I': Idle task
|
| + void PostTestTasks(std::vector<std::string>* run_order,
|
| + const std::string& task_descriptor) {
|
| + std::istringstream stream(task_descriptor);
|
| + while (!stream.eof()) {
|
| + std::string task;
|
| + stream >> task;
|
| + switch (task[0]) {
|
| + case 'D':
|
| + default_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
|
| + break;
|
| + case 'I':
|
| + idle_task_runner_->PostIdleTask(
|
| + FROM_HERE,
|
| + base::Bind(&AppendToVectorIdleTestTask, run_order, task));
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| + }
|
| + }
|
| +
|
| + protected:
|
| + scoped_refptr<cc::TestNowSource> clock_;
|
| + // Only one of mock_task_runner_ or message_loop_ will be set.
|
| + scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
|
| +
|
| + scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
|
| + scoped_ptr<WorkerSchedulerImpl> scheduler_;
|
| + scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
|
| + scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerImplTest);
|
| +};
|
| +
|
| +TEST_F(WorkerSchedulerImplTest, TestPostDefaultTask) {
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "D1 D2 D3 D4");
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_THAT(run_order,
|
| + testing::ElementsAre(std::string("D1"), std::string("D2"),
|
| + std::string("D3"), std::string("D4")));
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest, TestPostIdleTask) {
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "I1");
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_THAT(run_order, testing::ElementsAre(std::string("I1")));
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest, TestPostDefaultAndIdleTasks) {
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "I1 D2 D3 D4");
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_THAT(run_order,
|
| + testing::ElementsAre(std::string("D2"), std::string("D3"),
|
| + std::string("D4"), std::string("I1")));
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest, TestPostIdleTaskWithWakeupNeeded_NoWakeup) {
|
| + RunUntilIdle();
|
| + // The delayed call to InitiateLongIdlePeriod happened and it posted a call to
|
| + // InitiateLongIdlePeriod on the after wakeup control queue.
|
| +
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "I1");
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_TRUE(run_order.empty());
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest, TestPostIdleTaskWithWakeupNeeded_Wakeup) {
|
| + RunUntilIdle();
|
| + // The delayed call to InitiateLongIdlePeriod happened and it posted a call to
|
| + // InitiateLongIdlePeriod on the after wakeup control queue.
|
| +
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "I1 D2");
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_THAT(run_order,
|
| + testing::ElementsAre(std::string("D2"), std::string("I1")));
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest, TestPostDefaultDelayedAndIdleTasks) {
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "I1 D2 D3 D4");
|
| +
|
| + default_task_runner_->PostDelayedTask(
|
| + FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "DELAYED"),
|
| + base::TimeDelta::FromMilliseconds(1000));
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_THAT(run_order,
|
| + testing::ElementsAre(std::string("D2"), std::string("D3"),
|
| + std::string("D4"), std::string("I1"),
|
| + std::string("DELAYED")));
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest, TestIdleDeadlineWithPendingDelayedTask) {
|
| + base::TimeDelta delay = base::TimeDelta::FromMilliseconds(140);
|
| + default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
|
| + base::TimeTicks deadline;
|
| + idle_task_runner_->PostIdleTask(FROM_HERE,
|
| + base::Bind(&IdleTestTask, &deadline));
|
| +
|
| + base::TimeTicks expected_deadline = clock_->Now() + delay;
|
| + clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_EQ(expected_deadline, deadline);
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest,
|
| + TestIdleDeadlineWithPendingDelayedTaskFarInTheFuture) {
|
| + base::TimeDelta delay = base::TimeDelta::FromMilliseconds(1000);
|
| + base::TimeTicks task_run_time = clock_->Now() + delay;
|
| + default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
|
| + base::TimeTicks deadline;
|
| + idle_task_runner_->PostIdleTask(FROM_HERE,
|
| + base::Bind(&IdleTestTask, &deadline));
|
| +
|
| + clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_LT(deadline, task_run_time);
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest,
|
| + TestPostIdleTaskAfterRunningUntilIdle_NoWakeUp) {
|
| + default_task_runner_->PostDelayedTask(
|
| + FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000));
|
| + RunUntilIdle();
|
| + // The delayed call to InitiateLongIdlePeriod happened and it posted a call to
|
| + // InitiateLongIdlePeriod on the after wakeup control queue.
|
| +
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "I1 I2");
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_TRUE(run_order.empty());
|
| +}
|
| +
|
| +TEST_F(WorkerSchedulerImplTest,
|
| + TestPostIdleTaskAfterRunningUntilIdle_WithWakeUp) {
|
| + default_task_runner_->PostDelayedTask(
|
| + FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000));
|
| + RunUntilIdle();
|
| + // The delayed call to InitiateLongIdlePeriod happened and it posted a call to
|
| + // InitiateLongIdlePeriod on the after wakeup control queue.
|
| +
|
| + std::vector<std::string> run_order;
|
| + PostTestTasks(&run_order, "I1 I2 D3");
|
| +
|
| + RunUntilIdle();
|
| + EXPECT_THAT(run_order,
|
| + testing::ElementsAre(std::string("D3"), std::string("I1"),
|
| + std::string("I2")));
|
| +}
|
| +
|
| +} // namespace content
|
|
|