| Index: content/child/scheduler/scheduler_helper_unittest.cc
|
| diff --git a/content/child/scheduler/scheduler_helper_unittest.cc b/content/child/scheduler/scheduler_helper_unittest.cc
|
| deleted file mode 100644
|
| index d3e9bda3e669aa6fc4881e1ebb8dcd050ffa68ad..0000000000000000000000000000000000000000
|
| --- a/content/child/scheduler/scheduler_helper_unittest.cc
|
| +++ /dev/null
|
| @@ -1,948 +0,0 @@
|
| -// Copyright 2014 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/scheduler_helper.h"
|
| -
|
| -#include "base/callback.h"
|
| -#include "cc/test/ordered_simple_task_runner.h"
|
| -#include "cc/test/test_now_source.h"
|
| -#include "content/child/scheduler/nestable_task_runner_for_test.h"
|
| -#include "content/child/scheduler/scheduler_message_loop_delegate.h"
|
| -#include "content/child/scheduler/task_queue_manager.h"
|
| -#include "content/test/test_time_source.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using testing::_;
|
| -using testing::AnyNumber;
|
| -using testing::Invoke;
|
| -using testing::Return;
|
| -
|
| -namespace content {
|
| -
|
| -namespace {
|
| -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 NullTask() {
|
| -}
|
| -
|
| -void AppendToVectorReentrantTask(
|
| - base::SingleThreadTaskRunner* task_runner,
|
| - std::vector<int>* vector,
|
| - int* reentrant_count,
|
| - int max_reentrant_count) {
|
| - vector->push_back((*reentrant_count)++);
|
| - if (*reentrant_count < max_reentrant_count) {
|
| - task_runner->PostTask(
|
| - FROM_HERE, base::Bind(AppendToVectorReentrantTask,
|
| - base::Unretained(task_runner), vector,
|
| - reentrant_count, max_reentrant_count));
|
| - }
|
| -}
|
| -
|
| -void NullIdleTask(base::TimeTicks) {
|
| -}
|
| -
|
| -void IdleTestTask(int* run_count,
|
| - base::TimeTicks* deadline_out,
|
| - base::TimeTicks deadline) {
|
| - (*run_count)++;
|
| - *deadline_out = deadline;
|
| -}
|
| -
|
| -int max_idle_task_reposts = 2;
|
| -
|
| -void RepostingIdleTestTask(
|
| - SingleThreadIdleTaskRunner* idle_task_runner,
|
| - int* run_count,
|
| - base::TimeTicks deadline) {
|
| - if ((*run_count + 1) < max_idle_task_reposts) {
|
| - idle_task_runner->PostIdleTask(
|
| - FROM_HERE,
|
| - base::Bind(&RepostingIdleTestTask,
|
| - base::Unretained(idle_task_runner), run_count));
|
| - }
|
| - (*run_count)++;
|
| -}
|
| -
|
| -void UpdateClockToDeadlineIdleTestTask(
|
| - scoped_refptr<cc::TestNowSource> clock,
|
| - base::SingleThreadTaskRunner* task_runner,
|
| - int* run_count,
|
| - base::TimeTicks deadline) {
|
| - clock->SetNow(deadline);
|
| - // Due to the way in which OrderedSimpleTestRunner orders tasks and the fact
|
| - // that we updated the time within a task, the delayed pending task to call
|
| - // EndIdlePeriod will not happen until after a TaskQueueManager DoWork, so
|
| - // post a normal task here to ensure it runs before the next idle task.
|
| - task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
|
| - (*run_count)++;
|
| -}
|
| -
|
| -void RepeatingTask(base::SingleThreadTaskRunner* task_runner,
|
| - int num_repeats,
|
| - base::TimeDelta delay) {
|
| - if (num_repeats > 1) {
|
| - task_runner->PostDelayedTask(
|
| - FROM_HERE, base::Bind(&RepeatingTask, base::Unretained(task_runner),
|
| - num_repeats - 1, delay),
|
| - delay);
|
| - }
|
| -}
|
| -
|
| -scoped_refptr<NestableSingleThreadTaskRunner>
|
| -CreateNestableSingleThreadTaskRunner(
|
| - base::MessageLoop* message_loop,
|
| - scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner) {
|
| - if (message_loop)
|
| - return SchedulerMessageLoopDelegate::Create(message_loop);
|
| -
|
| - return NestableTaskRunnerForTest::Create(mock_task_runner);
|
| -}
|
| -
|
| -}; // namespace
|
| -
|
| -class SchedulerHelperForTest : public SchedulerHelper,
|
| - public SchedulerHelper::SchedulerHelperDelegate {
|
| - public:
|
| - explicit SchedulerHelperForTest(
|
| - scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner,
|
| - base::TimeDelta required_quiescence_duration_before_long_idle_period)
|
| - : SchedulerHelper(main_task_runner,
|
| - this,
|
| - "test.scheduler",
|
| - TRACE_DISABLED_BY_DEFAULT("test.scheduler"),
|
| - "TestSchedulerIdlePeriod",
|
| - TASK_QUEUE_COUNT,
|
| - required_quiescence_duration_before_long_idle_period) {}
|
| -
|
| - ~SchedulerHelperForTest() override {}
|
| -
|
| - // SchedulerHelperDelegate implementation:
|
| - MOCK_METHOD2(CanEnterLongIdlePeriod,
|
| - bool(base::TimeTicks now,
|
| - base::TimeDelta* next_long_idle_period_delay_out));
|
| -
|
| - MOCK_METHOD0(IsNotQuiescent, void());
|
| -};
|
| -
|
| -class BaseSchedulerHelperTest : public testing::Test {
|
| - public:
|
| - BaseSchedulerHelperTest(
|
| - base::MessageLoop* message_loop,
|
| - base::TimeDelta required_quiescence_duration_before_long_idle_period)
|
| - : clock_(cc::TestNowSource::Create(5000)),
|
| - mock_task_runner_(message_loop
|
| - ? nullptr
|
| - : new cc::OrderedSimpleTaskRunner(clock_, false)),
|
| - message_loop_(message_loop),
|
| - nestable_task_runner_(
|
| - CreateNestableSingleThreadTaskRunner(message_loop,
|
| - mock_task_runner_)),
|
| - scheduler_helper_(new SchedulerHelperForTest(
|
| - nestable_task_runner_,
|
| - required_quiescence_duration_before_long_idle_period)),
|
| - default_task_runner_(scheduler_helper_->DefaultTaskRunner()),
|
| - idle_task_runner_(scheduler_helper_->IdleTaskRunner()) {
|
| - scheduler_helper_->SetTimeSourceForTesting(
|
| - make_scoped_ptr(new TestTimeSource(clock_)));
|
| - scheduler_helper_->GetTaskQueueManagerForTesting()->SetTimeSourceForTesting(
|
| - make_scoped_ptr(new TestTimeSource(clock_)));
|
| - }
|
| -
|
| - ~BaseSchedulerHelperTest() override {}
|
| -
|
| - void TearDown() override {
|
| - DCHECK(!mock_task_runner_.get() || !message_loop_.get());
|
| - if (mock_task_runner_.get()) {
|
| - // Check that all tests stop posting tasks.
|
| - mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| - while (mock_task_runner_->RunUntilIdle()) {
|
| - }
|
| - } else {
|
| - message_loop_->RunUntilIdle();
|
| - }
|
| - }
|
| -
|
| - void RunUntilIdle() {
|
| - // Only one of mock_task_runner_ or message_loop_ should be set.
|
| - DCHECK(!mock_task_runner_.get() || !message_loop_.get());
|
| - if (mock_task_runner_.get())
|
| - mock_task_runner_->RunUntilIdle();
|
| - else
|
| - message_loop_->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:
|
| - static base::TimeDelta maximum_idle_period_duration() {
|
| - return base::TimeDelta::FromMilliseconds(
|
| - SchedulerHelper::kMaximumIdlePeriodMillis);
|
| - }
|
| -
|
| - base::TimeTicks CurrentIdleTaskDeadlineForTesting() {
|
| - base::TimeTicks deadline;
|
| - scheduler_helper_->CurrentIdleTaskDeadlineCallback(&deadline);
|
| - return deadline;
|
| - }
|
| -
|
| - 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_ptr<base::MessageLoop> message_loop_;
|
| -
|
| - scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
|
| - scoped_ptr<SchedulerHelperForTest> scheduler_helper_;
|
| - scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
|
| - scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(BaseSchedulerHelperTest);
|
| -};
|
| -
|
| -class SchedulerHelperTest : public BaseSchedulerHelperTest {
|
| - public:
|
| - SchedulerHelperTest() : BaseSchedulerHelperTest(nullptr, base::TimeDelta()) {}
|
| -
|
| - ~SchedulerHelperTest() override {}
|
| -
|
| - TaskQueueManager* task_queue_manager() const {
|
| - return scheduler_helper_->task_queue_manager_.get();
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(SchedulerHelperTest);
|
| -};
|
| -
|
| -TEST_F(SchedulerHelperTest, 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(SchedulerHelperTest, TestRentrantTask) {
|
| - int count = 0;
|
| - std::vector<int> run_order;
|
| - default_task_runner_->PostTask(
|
| - FROM_HERE, base::Bind(AppendToVectorReentrantTask, default_task_runner_,
|
| - &run_order, &count, 5));
|
| - RunUntilIdle();
|
| -
|
| - EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4));
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestPostIdleTask) {
|
| - int run_count = 0;
|
| - base::TimeTicks expected_deadline =
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(2300);
|
| - base::TimeTicks deadline_in_task;
|
| -
|
| - clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - expected_deadline,
|
| - true);
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count);
|
| - EXPECT_EQ(expected_deadline, deadline_in_task);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestPostIdleTask_EndIdlePeriod) {
|
| - int run_count = 0;
|
| - base::TimeTicks deadline_in_task;
|
| -
|
| - clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - scheduler_helper_->EndIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestRepostingIdleTask) {
|
| - int run_count = 0;
|
| -
|
| - max_idle_task_reposts = 2;
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE,
|
| - base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count);
|
| -
|
| - // Reposted tasks shouldn't run until next idle period.
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count);
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - EXPECT_EQ(2, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestIdleTaskExceedsDeadline) {
|
| - int run_count = 0;
|
| -
|
| - // Post two UpdateClockToDeadlineIdleTestTask tasks.
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
|
| - default_task_runner_, &run_count));
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
|
| - default_task_runner_, &run_count));
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Only the first idle task should execute since it's used up the deadline.
|
| - EXPECT_EQ(1, run_count);
|
| -
|
| - scheduler_helper_->EndIdlePeriod();
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Second task should be run on the next idle period.
|
| - EXPECT_EQ(2, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestPostIdleTaskAfterWakeup) {
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - idle_task_runner_->PostIdleTaskAfterWakeup(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Shouldn't run yet as no other task woke up the scheduler.
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - idle_task_runner_->PostIdleTaskAfterWakeup(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Another after wakeup idle task shouldn't wake the scheduler.
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
|
| -
|
| - RunUntilIdle();
|
| - // Must start a new idle period before idle task runs.
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Execution of default task queue task should trigger execution of idle task.
|
| - EXPECT_EQ(2, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestPostIdleTaskAfterWakeupWhileAwake) {
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - idle_task_runner_->PostIdleTaskAfterWakeup(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| - default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
|
| -
|
| - RunUntilIdle();
|
| - // Must start a new idle period before idle task runs.
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Should run as the scheduler was already awakened by the normal task.
|
| - EXPECT_EQ(1, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestPostIdleTaskWakesAfterWakeupIdleTask) {
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - idle_task_runner_->PostIdleTaskAfterWakeup(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Must start a new idle period before after-wakeup idle task runs.
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Normal idle task should wake up after-wakeup idle task.
|
| - EXPECT_EQ(2, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestDelayedEndIdlePeriod) {
|
| - mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(2)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - // We need an idle task posted or EnableLongIdlePeriod will use the
|
| - // control_task_after_wakeup_runner_ instead of the control_task_runner_.
|
| - idle_task_runner_->PostIdleTask(FROM_HERE, base::Bind(&NullIdleTask));
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| -
|
| - // Check there is a pending delayed task.
|
| - EXPECT_GT(task_queue_manager()->NextPendingDelayedTaskRunTime(),
|
| - base::TimeTicks());
|
| -
|
| - RunUntilIdle();
|
| -
|
| - // If the delayed task ran, it will an EnableLongIdlePeriod on the control
|
| - // task after wake up queue.
|
| - EXPECT_FALSE(task_queue_manager()->IsQueueEmpty(
|
| - SchedulerHelper::CONTROL_TASK_AFTER_WAKEUP_QUEUE));
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestDelayedEndIdlePeriodCanceled) {
|
| - mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(1)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - // We need an idle task posted or EnableLongIdlePeriod will use the
|
| - // control_task_after_wakeup_runner_ instead of the control_task_runner_.
|
| - idle_task_runner_->PostIdleTask(FROM_HERE, base::Bind(&NullIdleTask));
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| -
|
| - // Check there is a pending delayed task.
|
| - EXPECT_GT(task_queue_manager()->NextPendingDelayedTaskRunTime(),
|
| - base::TimeTicks());
|
| -
|
| - scheduler_helper_->EndIdlePeriod();
|
| - RunUntilIdle();
|
| -
|
| - // If the delayed task didn't run, there will be nothing on the control task
|
| - // after wake up queue.
|
| - EXPECT_TRUE(scheduler_helper_->IsQueueEmpty(
|
| - SchedulerHelper::CONTROL_TASK_AFTER_WAKEUP_QUEUE));
|
| -}
|
| -
|
| -class SchedulerHelperWithMessageLoopTest : public BaseSchedulerHelperTest {
|
| - public:
|
| - SchedulerHelperWithMessageLoopTest()
|
| - : BaseSchedulerHelperTest(new base::MessageLoop(), base::TimeDelta()) {}
|
| - ~SchedulerHelperWithMessageLoopTest() override {}
|
| -
|
| - void PostFromNestedRunloop(std::vector<
|
| - std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) {
|
| - base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get());
|
| - for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) {
|
| - if (pair.second) {
|
| - idle_task_runner_->PostIdleTask(FROM_HERE, pair.first);
|
| - } else {
|
| - idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first);
|
| - }
|
| - }
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - message_loop_->RunUntilIdle();
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(SchedulerHelperWithMessageLoopTest);
|
| -};
|
| -
|
| -TEST_F(SchedulerHelperWithMessageLoopTest,
|
| - NonNestableIdleTaskDoesntExecuteInNestedLoop) {
|
| - std::vector<std::string> order;
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE,
|
| - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1")));
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE,
|
| - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("2")));
|
| -
|
| - std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>
|
| - tasks_to_post_from_nested_loop;
|
| - tasks_to_post_from_nested_loop.push_back(std::make_pair(
|
| - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("3")),
|
| - false));
|
| - tasks_to_post_from_nested_loop.push_back(std::make_pair(
|
| - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("4")), true));
|
| - tasks_to_post_from_nested_loop.push_back(std::make_pair(
|
| - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("5")), true));
|
| -
|
| - default_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&SchedulerHelperWithMessageLoopTest::PostFromNestedRunloop,
|
| - base::Unretained(this),
|
| - base::Unretained(&tasks_to_post_from_nested_loop)));
|
| -
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - // Note we expect task 3 to run last because it's non-nestable.
|
| - EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"),
|
| - std::string("4"), std::string("5"),
|
| - std::string("3")));
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestLongIdlePeriod) {
|
| - base::TimeTicks expected_deadline =
|
| - clock_->Now() + maximum_idle_period_duration();
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(2)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period.
|
| -
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count); // Should have run in a long idle time.
|
| - EXPECT_EQ(expected_deadline, deadline_in_task);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestLongIdlePeriodWithPendingDelayedTask) {
|
| - base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
|
| - base::TimeTicks expected_deadline = clock_->Now() + pending_task_delay;
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(2)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
|
| - pending_task_delay);
|
| -
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count); // Should have run in a long idle time.
|
| - EXPECT_EQ(expected_deadline, deadline_in_task);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestLongIdlePeriodWithLatePendingDelayedTask) {
|
| - base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10);
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(3)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
|
| - pending_task_delay);
|
| -
|
| - // Advance clock until after delayed task was meant to be run.
|
| - clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20));
|
| -
|
| - // Post an idle task and then EnableLongIdlePeriod. Since there is a late
|
| - // pending delayed task this shouldn't actually start an idle period.
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - // After the delayed task has been run we should trigger an idle period.
|
| - clock_->AdvanceNow(maximum_idle_period_duration());
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestLongIdlePeriodRepeating) {
|
| - int run_count = 0;
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(2)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - max_idle_task_reposts = 3;
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE,
|
| - base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
|
| -
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count); // Should only run once per idle period.
|
| -
|
| - // Advance time to start of next long idle period and check task reposted task
|
| - // gets run.
|
| - clock_->AdvanceNow(maximum_idle_period_duration());
|
| - RunUntilIdle();
|
| - EXPECT_EQ(2, run_count);
|
| -
|
| - // Advance time to start of next long idle period then end the idle period and
|
| - // check the task doesn't get run.
|
| - clock_->AdvanceNow(maximum_idle_period_duration());
|
| - scheduler_helper_->EndIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(2, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestLongIdlePeriodDoesNotWakeScheduler) {
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(3)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - // Start a long idle period and get the time it should end.
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - // The scheduler should not run the initiate_next_long_idle_period task if
|
| - // there are no idle tasks and no other task woke up the scheduler, thus
|
| - // the idle period deadline shouldn't update at the end of the current long
|
| - // idle period.
|
| - base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
|
| - clock_->AdvanceNow(maximum_idle_period_duration());
|
| - RunUntilIdle();
|
| -
|
| - base::TimeTicks new_idle_period_deadline =
|
| - CurrentIdleTaskDeadlineForTesting();
|
| - EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
|
| -
|
| - // Posting a after-wakeup idle task also shouldn't wake the scheduler or
|
| - // initiate the next long idle period.
|
| - idle_task_runner_->PostIdleTaskAfterWakeup(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| - RunUntilIdle();
|
| - new_idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
|
| - EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - // Running a normal task should initiate a new long idle period though.
|
| - default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
|
| - RunUntilIdle();
|
| - new_idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
|
| - EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(),
|
| - new_idle_period_deadline);
|
| -
|
| - EXPECT_EQ(1, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, TestLongIdlePeriodWhenNotCanEnterLongIdlePeriod) {
|
| - base::TimeDelta delay = base::TimeDelta::FromMilliseconds(1000);
|
| - base::TimeDelta halfDelay = base::TimeDelta::FromMilliseconds(500);
|
| - base::TimeTicks delayOver = clock_->Now() + delay;
|
| - base::TimeTicks deadline_in_task;
|
| - int run_count = 0;
|
| -
|
| - ON_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .WillByDefault(Invoke([delay, delayOver](
|
| - base::TimeTicks now,
|
| - base::TimeDelta* next_long_idle_period_delay_out) {
|
| - if (now >= delayOver)
|
| - return true;
|
| - *next_long_idle_period_delay_out = delay;
|
| - return false;
|
| - }));
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)).Times(3);
|
| -
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - // Make sure Idle tasks don't run until the delay has occured.
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - clock_->AdvanceNow(halfDelay);
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - // Delay is finished, idle task should run.
|
| - clock_->AdvanceNow(halfDelay);
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count);
|
| -}
|
| -
|
| -void TestCanExceedIdleDeadlineIfRequiredTask(SchedulerHelperForTest* scheduler,
|
| - bool* can_exceed_idle_deadline_out,
|
| - int* run_count,
|
| - base::TimeTicks deadline) {
|
| - *can_exceed_idle_deadline_out = scheduler->CanExceedIdleDeadlineIfRequired();
|
| - (*run_count)++;
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, CanExceedIdleDeadlineIfRequired) {
|
| - int run_count = 0;
|
| - bool can_exceed_idle_deadline = false;
|
| -
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(3)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - // Should return false if not in an idle period.
|
| - EXPECT_FALSE(scheduler_helper_->CanExceedIdleDeadlineIfRequired());
|
| -
|
| - // Should return false for short idle periods.
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask,
|
| - scheduler_helper_.get(), &can_exceed_idle_deadline,
|
| - &run_count));
|
| - scheduler_helper_->StartIdlePeriod(
|
| - SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
|
| - clock_->Now(),
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(10),
|
| - true);
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count);
|
| - EXPECT_FALSE(can_exceed_idle_deadline);
|
| -
|
| - // Should return false for a long idle period which is shortened due to a
|
| - // pending delayed task.
|
| - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
|
| - base::TimeDelta::FromMilliseconds(10));
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask,
|
| - scheduler_helper_.get(), &can_exceed_idle_deadline,
|
| - &run_count));
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(2, run_count);
|
| - EXPECT_FALSE(can_exceed_idle_deadline);
|
| -
|
| - // Next long idle period will be for the maximum time, so
|
| - // CanExceedIdleDeadlineIfRequired should return true.
|
| - clock_->AdvanceNow(maximum_idle_period_duration());
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask,
|
| - scheduler_helper_.get(), &can_exceed_idle_deadline,
|
| - &run_count));
|
| - RunUntilIdle();
|
| - EXPECT_EQ(3, run_count);
|
| - EXPECT_TRUE(can_exceed_idle_deadline);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperTest, IsShutdown) {
|
| - EXPECT_FALSE(scheduler_helper_->IsShutdown());
|
| -
|
| - scheduler_helper_->Shutdown();
|
| - EXPECT_TRUE(scheduler_helper_->IsShutdown());
|
| -}
|
| -
|
| -class SchedulerHelperWithQuiescencePeriodTest : public BaseSchedulerHelperTest {
|
| - public:
|
| - enum {
|
| - kQuiescenceDelayMs = 100,
|
| - kLongIdlePeriodMs = 50,
|
| - };
|
| -
|
| - SchedulerHelperWithQuiescencePeriodTest()
|
| - : BaseSchedulerHelperTest(
|
| - nullptr,
|
| - base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs)) {}
|
| -
|
| - ~SchedulerHelperWithQuiescencePeriodTest() override {}
|
| -
|
| - void MakeNonQuiescent() {
|
| - // Run an arbitrary task so we're deemed to be not quiescent.
|
| - default_task_runner_->PostTask(FROM_HERE, base::Bind(NullTask));
|
| - RunUntilIdle();
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(SchedulerHelperWithQuiescencePeriodTest);
|
| -};
|
| -
|
| -TEST_F(SchedulerHelperWithQuiescencePeriodTest,
|
| - LongIdlePeriodStartsImmediatelyIfQuiescent) {
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(2)
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - int run_count = 0;
|
| - max_idle_task_reposts = 1;
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE,
|
| - base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
|
| -
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| -
|
| - EXPECT_EQ(1, run_count);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperWithQuiescencePeriodTest,
|
| - LongIdlePeriodDoesNotStartsImmediatelyIfBusy) {
|
| - MakeNonQuiescent();
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)).Times(0);
|
| -
|
| - int run_count = 0;
|
| - max_idle_task_reposts = 1;
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE,
|
| - base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
|
| -
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| -
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - scheduler_helper_->Shutdown();
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperWithQuiescencePeriodTest,
|
| - LongIdlePeriodStartsAfterQuiescence) {
|
| - MakeNonQuiescent();
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(AnyNumber())
|
| - .WillRepeatedly(Return(true));
|
| - mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| -
|
| - // Run a repeating task so we're deemed to be busy for the next 400ms.
|
| - default_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&RepeatingTask, base::Unretained(default_task_runner_.get()),
|
| - 10, base::TimeDelta::FromMilliseconds(40)));
|
| -
|
| - int run_count = 0;
|
| - // In this scenario EnableLongIdlePeriod deems us not to be quiescent 5x in
|
| - // a row.
|
| - base::TimeTicks expected_deadline =
|
| - clock_->Now() + base::TimeDelta::FromMilliseconds(5 * kQuiescenceDelayMs +
|
| - kLongIdlePeriodMs);
|
| - base::TimeTicks deadline_in_task;
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| -
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| - EXPECT_EQ(1, run_count);
|
| - EXPECT_EQ(expected_deadline, deadline_in_task);
|
| -}
|
| -
|
| -TEST_F(SchedulerHelperWithQuiescencePeriodTest,
|
| - QuescienceCheckedForAfterLongIdlePeriodEnds) {
|
| - EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
|
| - .Times(AnyNumber())
|
| - .WillRepeatedly(Return(true));
|
| - mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
|
| -
|
| - idle_task_runner_->PostIdleTask(FROM_HERE, base::Bind(&NullIdleTask));
|
| - scheduler_helper_->EnableLongIdlePeriod();
|
| - RunUntilIdle();
|
| -
|
| - int run_count = 0;
|
| - base::TimeTicks deadline_in_task;
|
| - // Post an idle task, it won't run initially because the
|
| - // EnableLongIdlePeriod task was posted on an after wakeup runner.
|
| - idle_task_runner_->PostIdleTask(
|
| - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
|
| - RunUntilIdle();
|
| - EXPECT_EQ(0, run_count);
|
| -
|
| - // Post a normal task to wake the system up. The idle task won't run
|
| - // immediately because the system isn't judged to be quiescent until the
|
| - // second time EnableLongIdlePeriod is run.
|
| - base::TimeTicks expected_deadline =
|
| - clock_->Now() +
|
| - base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs + kLongIdlePeriodMs);
|
| - default_task_runner_->PostTask(FROM_HERE, base::Bind(NullTask));
|
| - RunUntilIdle();
|
| -
|
| - EXPECT_EQ(1, run_count);
|
| - EXPECT_EQ(expected_deadline, deadline_in_task);
|
| -}
|
| -
|
| -} // namespace content
|
|
|