Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Unified Diff: components/scheduler/child/idle_helper_unittest.cc

Issue 1151353003: [scheduler]: Avoid waking up the scheduler to end long idle periods. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@end_idle_sync_2
Patch Set: Fix Win for realz hopefully... Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/scheduler/child/idle_helper_unittest.cc
diff --git a/components/scheduler/child/idle_helper_unittest.cc b/components/scheduler/child/idle_helper_unittest.cc
index ad8ea26b0d5fe71dd5e36fa1ebb7668f2f4a05ed..721ec65691489b633a3794164862ee51bfe6f129 100644
--- a/components/scheduler/child/idle_helper_unittest.cc
+++ b/components/scheduler/child/idle_helper_unittest.cc
@@ -37,6 +37,9 @@ void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
void NullTask() {
}
+void NullIdleTask(base::TimeTicks deadline) {
+}
+
void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner,
std::vector<int>* vector,
int* reentrant_count,
@@ -50,9 +53,6 @@ void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner,
}
}
-void NullIdleTask(base::TimeTicks) {
-}
-
void IdleTestTask(int* run_count,
base::TimeTicks* deadline_out,
base::TimeTicks deadline) {
@@ -64,13 +64,34 @@ int max_idle_task_reposts = 2;
void RepostingIdleTestTask(SingleThreadIdleTaskRunner* idle_task_runner,
int* run_count,
+ base::TimeTicks* deadline_out,
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));
+ FROM_HERE,
+ base::Bind(&RepostingIdleTestTask, base::Unretained(idle_task_runner),
+ run_count, deadline_out));
+ }
+ *deadline_out = deadline;
+ (*run_count)++;
+}
+
+void RepostingUpdateClockIdleTestTask(
+ SingleThreadIdleTaskRunner* idle_task_runner,
+ int* run_count,
+ scoped_refptr<cc::TestNowSource> clock,
+ base::TimeDelta advance_time,
+ std::vector<base::TimeTicks>* deadlines,
+ base::TimeTicks deadline) {
+ if ((*run_count + 1) < max_idle_task_reposts) {
+ idle_task_runner->PostIdleTask(
+ FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask,
+ base::Unretained(idle_task_runner), run_count,
+ clock, advance_time, deadlines));
}
+ deadlines->push_back(deadline);
(*run_count)++;
+ clock->AdvanceNow(advance_time);
}
void RepeatingTask(base::SingleThreadTaskRunner* task_runner,
@@ -84,20 +105,24 @@ void RepeatingTask(base::SingleThreadTaskRunner* task_runner,
}
}
-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));
+void UpdateClockIdleTestTask(scoped_refptr<cc::TestNowSource> clock,
+ int* run_count,
+ base::TimeTicks set_time,
+ base::TimeTicks deadline) {
+ clock->SetNow(set_time);
(*run_count)++;
}
+void UpdateClockToDeadlineIdleTestTask(scoped_refptr<cc::TestNowSource> clock,
+ int* run_count,
+ base::TimeTicks deadline) {
+ UpdateClockIdleTestTask(clock, run_count, deadline, deadline);
+}
+
+void EndIdlePeriodIdleTask(IdleHelper* idle_helper, base::TimeTicks deadline) {
+ idle_helper->EndIdlePeriod();
+}
+
scoped_refptr<NestableSingleThreadTaskRunner>
CreateNestableSingleThreadTaskRunner(
base::MessageLoop* message_loop,
@@ -208,10 +233,18 @@ class BaseIdleHelperTest : public testing::Test {
IdleHelper::kMaximumIdlePeriodMillis);
}
- base::TimeTicks CurrentIdleTaskDeadlineForTesting() {
- base::TimeTicks deadline;
- idle_helper_->CurrentIdleTaskDeadlineCallback(&deadline);
- return deadline;
+ static base::TimeDelta retry_enable_long_idle_period_delay() {
+ return base::TimeDelta::FromMilliseconds(
+ IdleHelper::kRetryEnableLongIdlePeriodDelayMillis);
+ }
+
+ base::TimeTicks CurrentIdleTaskDeadline() {
+ return idle_helper_->CurrentIdleTaskDeadline();
+ }
+
+ void CheckIdlePeriodStateIs(const char* expected) {
+ EXPECT_STREQ(expected, IdleHelper::IdlePeriodStateToString(
+ idle_helper_->SchedulerIdlePeriodState()));
}
scoped_refptr<cc::TestNowSource> clock_;
@@ -257,7 +290,7 @@ TEST_F(IdleHelperTest, TestPostIdleTask) {
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- expected_deadline, true);
+ expected_deadline);
RunUntilIdle();
EXPECT_EQ(1, run_count);
EXPECT_EQ(expected_deadline, deadline_in_task);
@@ -276,22 +309,23 @@ TEST_F(IdleHelperTest, TestPostIdleTask_EndIdlePeriod) {
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
idle_helper_->EndIdlePeriod();
RunUntilIdle();
EXPECT_EQ(0, run_count);
}
TEST_F(IdleHelperTest, TestRepostingIdleTask) {
+ base::TimeTicks actual_deadline;
int run_count = 0;
max_idle_task_reposts = 2;
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
+ FROM_HERE, base::Bind(&RepostingIdleTestTask, idle_task_runner_,
+ &run_count, &actual_deadline));
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
EXPECT_EQ(1, run_count);
@@ -301,7 +335,7 @@ TEST_F(IdleHelperTest, TestRepostingIdleTask) {
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
EXPECT_EQ(2, run_count);
}
@@ -311,15 +345,15 @@ TEST_F(IdleHelperTest, TestIdleTaskExceedsDeadline) {
// Post two UpdateClockToDeadlineIdleTestTask tasks.
idle_task_runner_->PostIdleTask(
- FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
- default_task_runner_, &run_count));
+ FROM_HERE,
+ base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, &run_count));
idle_task_runner_->PostIdleTask(
- FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
- default_task_runner_, &run_count));
+ FROM_HERE,
+ base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, &run_count));
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Only the first idle task should execute since it's used up the deadline.
EXPECT_EQ(1, run_count);
@@ -327,7 +361,7 @@ TEST_F(IdleHelperTest, TestIdleTaskExceedsDeadline) {
idle_helper_->EndIdlePeriod();
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Second task should be run on the next idle period.
EXPECT_EQ(2, run_count);
@@ -342,7 +376,7 @@ TEST_F(IdleHelperTest, TestPostIdleTaskAfterWakeup) {
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Shouldn't run yet as no other task woke up the scheduler.
EXPECT_EQ(0, run_count);
@@ -352,7 +386,7 @@ TEST_F(IdleHelperTest, TestPostIdleTaskAfterWakeup) {
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Another after wakeup idle task shouldn't wake the scheduler.
EXPECT_EQ(0, run_count);
@@ -363,7 +397,7 @@ TEST_F(IdleHelperTest, TestPostIdleTaskAfterWakeup) {
// Must start a new idle period before idle task runs.
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Execution of default task queue task should trigger execution of idle task.
EXPECT_EQ(2, run_count);
@@ -381,7 +415,7 @@ TEST_F(IdleHelperTest, TestPostIdleTaskAfterWakeupWhileAwake) {
// Must start a new idle period before idle task runs.
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Should run as the scheduler was already awakened by the normal task.
EXPECT_EQ(1, run_count);
@@ -398,66 +432,17 @@ TEST_F(IdleHelperTest, TestPostIdleTaskWakesAfterWakeupIdleTask) {
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Must start a new idle period before after-wakeup idle task runs.
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
// Normal idle task should wake up after-wakeup idle task.
EXPECT_EQ(2, run_count);
}
-TEST_F(IdleHelperTest, TestDelayedEndIdlePeriod) {
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
- EXPECT_CALL(*idle_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));
- idle_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(IdleHelperTest, TestDelayedEndIdlePeriodCanceled) {
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
- EXPECT_CALL(*idle_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));
- idle_helper_->EnableLongIdlePeriod();
-
- // Check there is a pending delayed task.
- EXPECT_GT(task_queue_manager()->NextPendingDelayedTaskRunTime(),
- base::TimeTicks());
-
- idle_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 IdleHelperWithMessageLoopTest : public BaseIdleHelperTest {
public:
IdleHelperWithMessageLoopTest()
@@ -476,7 +461,7 @@ class IdleHelperWithMessageLoopTest : public BaseIdleHelperTest {
}
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
message_loop_->RunUntilIdle();
}
@@ -512,7 +497,7 @@ TEST_F(IdleHelperWithMessageLoopTest,
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
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"),
@@ -530,7 +515,7 @@ TEST_F(IdleHelperTest, TestLongIdlePeriod) {
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
- .Times(2)
+ .Times(1)
.WillRepeatedly(Return(true));
RunUntilIdle();
@@ -549,7 +534,7 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodWithPendingDelayedTask) {
int run_count = 0;
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
- .Times(2)
+ .Times(1)
.WillRepeatedly(Return(true));
idle_task_runner_->PostIdleTask(
@@ -569,7 +554,7 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodWithLatePendingDelayedTask) {
int run_count = 0;
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
- .Times(3)
+ .Times(2)
.WillRepeatedly(Return(true));
default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
@@ -593,33 +578,46 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodWithLatePendingDelayedTask) {
}
TEST_F(IdleHelperTest, TestLongIdlePeriodRepeating) {
+ mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
+ std::vector<base::TimeTicks> actual_deadlines;
int run_count = 0;
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
- .Times(2)
+ .Times(4)
.WillRepeatedly(Return(true));
max_idle_task_reposts = 3;
+ base::TimeTicks clock_before(clock_->Now());
+ base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
idle_task_runner_->PostIdleTask(
FROM_HERE,
- base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
+ base::Bind(&RepostingUpdateClockIdleTestTask, idle_task_runner_,
+ &run_count, clock_, idle_task_runtime, &actual_deadlines));
+ // Check each idle task runs in their own idle period.
idle_helper_->EnableLongIdlePeriod();
RunUntilIdle();
- EXPECT_EQ(1, run_count); // Should only run once per idle period.
+ EXPECT_EQ(3, run_count);
+ EXPECT_THAT(
+ actual_deadlines,
+ testing::ElementsAre(
+ clock_before + maximum_idle_period_duration(),
+ clock_before + idle_task_runtime + maximum_idle_period_duration(),
+ clock_before + (2 * idle_task_runtime) +
+ maximum_idle_period_duration()));
+
+ max_idle_task_reposts = 5;
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE,
+ base::Bind(&RepostingUpdateClockIdleTestTask, idle_task_runner_,
+ &run_count, clock_, idle_task_runtime, &actual_deadlines));
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE,
+ base::Bind(&EndIdlePeriodIdleTask, base::Unretained(idle_helper_.get())));
- // Advance time to start of next long idle period and check task reposted task
- // gets run.
- clock_->AdvanceNow(maximum_idle_period_duration());
+ // Ensure that reposting tasks stop after EndIdlePeriod is called.
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());
- idle_helper_->EndIdlePeriod();
- RunUntilIdle();
- EXPECT_EQ(2, run_count);
+ EXPECT_EQ(4, run_count);
}
TEST_F(IdleHelperTest, TestLongIdlePeriodDoesNotWakeScheduler) {
@@ -627,21 +625,20 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodDoesNotWakeScheduler) {
int run_count = 0;
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
- .Times(3)
+ .Times(2)
.WillRepeatedly(Return(true));
// Start a long idle period and get the time it should end.
idle_helper_->EnableLongIdlePeriod();
- // The scheduler should not run the initiate_next_long_idle_period task if
+ // The scheduler should not run the enable_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();
+ base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadline();
clock_->AdvanceNow(maximum_idle_period_duration());
RunUntilIdle();
- base::TimeTicks new_idle_period_deadline =
- CurrentIdleTaskDeadlineForTesting();
+ base::TimeTicks new_idle_period_deadline = CurrentIdleTaskDeadline();
EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
// Posting a after-wakeup idle task also shouldn't wake the scheduler or
@@ -649,14 +646,14 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodDoesNotWakeScheduler) {
idle_task_runner_->PostIdleTaskAfterWakeup(
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
RunUntilIdle();
- new_idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
+ new_idle_period_deadline = CurrentIdleTaskDeadline();
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();
+ new_idle_period_deadline = CurrentIdleTaskDeadline();
EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(),
new_idle_period_deadline);
@@ -680,12 +677,12 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodWhenNotCanEnterLongIdlePeriod) {
return false;
}));
- EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _)).Times(3);
+ EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _)).Times(2);
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.
+ // Make sure Idle tasks don't run until the delay has occurred.
idle_helper_->EnableLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(0, run_count);
@@ -700,6 +697,138 @@ TEST_F(IdleHelperTest, TestLongIdlePeriodWhenNotCanEnterLongIdlePeriod) {
EXPECT_EQ(1, run_count);
}
+TEST_F(IdleHelperTest, TestLongIdlePeriodImmediatelyRestartsIfMaxDeadline) {
+ base::TimeTicks actual_deadline;
+ int run_count = 0;
+
+ EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(2)
+ .WillRepeatedly(Return(true));
+
+ base::TimeDelta idle_task_duration(base::TimeDelta::FromMilliseconds(10));
+ base::TimeTicks expected_deadline_1(clock_->Now() +
+ maximum_idle_period_duration());
+ base::TimeTicks expected_deadline_2(clock_->Now() + idle_task_duration +
+ maximum_idle_period_duration());
+
+ // The second idle period should happen immediately after the first the
+ // they have max deadlines.
+ max_idle_task_reposts = 2;
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE, base::Bind(&RepostingIdleTestTask, idle_task_runner_,
+ &run_count, &actual_deadline));
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE, base::Bind(UpdateClockIdleTestTask, clock_, &run_count,
+ clock_->Now() + idle_task_duration));
+
+ idle_helper_->EnableLongIdlePeriod();
+ RunUntilIdle();
+ EXPECT_EQ(2, run_count);
+ EXPECT_EQ(expected_deadline_1, actual_deadline);
+
+ RunUntilIdle();
+ EXPECT_EQ(3, run_count);
+ EXPECT_EQ(expected_deadline_2, actual_deadline);
+}
+
+TEST_F(IdleHelperTest, TestLongIdlePeriodRestartWaitsIfNotMaxDeadline) {
+ base::TimeTicks actual_deadline;
+ int run_count = 0;
+
+ EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(3)
+ .WillRepeatedly(Return(true));
+
+ base::TimeDelta pending_task_delay(base::TimeDelta::FromMilliseconds(20));
+ base::TimeDelta idle_task_duration(base::TimeDelta::FromMilliseconds(10));
+ base::TimeTicks expected_deadline(clock_->Now() + pending_task_delay +
+ maximum_idle_period_duration() +
+ retry_enable_long_idle_period_delay());
+
+ // Post delayed task to ensure idle period doesn't have a max deadline.
+ default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
+ pending_task_delay);
+
+ max_idle_task_reposts = 2;
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE, base::Bind(&RepostingIdleTestTask, idle_task_runner_,
+ &run_count, &actual_deadline));
+ idle_helper_->EnableLongIdlePeriod();
+ RunUntilIdle();
+ EXPECT_EQ(1, run_count);
+ clock_->AdvanceNow(idle_task_duration);
+
+ // Next idle period shouldn't happen until the pending task has been run.
+ RunUntilIdle();
+ EXPECT_EQ(1, run_count);
+
+ // Once the pending task is run the new idle period should start.
+ clock_->AdvanceNow(pending_task_delay - idle_task_duration);
+ RunUntilIdle();
+ // Since the idle period tried to start before the pending task ran we have to
+ // wait for the idle helper to retry starting the long idle period.
+ clock_->AdvanceNow(retry_enable_long_idle_period_delay());
+ RunUntilIdle();
+
+ EXPECT_EQ(2, run_count);
+ EXPECT_EQ(expected_deadline, actual_deadline);
+}
+
+TEST_F(IdleHelperTest, TestLongIdlePeriodPaused) {
+ mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
+ std::vector<base::TimeTicks> actual_deadlines;
+ int run_count = 0;
+ EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(3)
+ .WillRepeatedly(Return(true));
+
+ // If there are no idle tasks posted we should start in the paused state.
+ idle_helper_->EnableLongIdlePeriod();
+ CheckIdlePeriodStateIs("in_long_idle_period_paused");
+ // There shouldn't be any delayed tasks posted by the idle helper when paused.
+ EXPECT_EQ(base::TimeTicks(),
+ scheduler_helper_->NextPendingDelayedTaskRunTime());
+
+ // Posting a task should transition us to the an active state.
+ max_idle_task_reposts = 2;
+ base::TimeTicks clock_before(clock_->Now());
+ base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE,
+ base::Bind(&RepostingUpdateClockIdleTestTask, idle_task_runner_,
+ &run_count, clock_, idle_task_runtime, &actual_deadlines));
+ RunUntilIdle();
+ EXPECT_EQ(2, run_count);
+ EXPECT_THAT(
+ actual_deadlines,
+ testing::ElementsAre(
+ clock_before + maximum_idle_period_duration(),
+ clock_before + idle_task_runtime + maximum_idle_period_duration()));
+
+ // Once all task have been run we should go back to the paused state.
+ CheckIdlePeriodStateIs("in_long_idle_period_paused");
+ EXPECT_EQ(base::TimeTicks(),
+ scheduler_helper_->NextPendingDelayedTaskRunTime());
+
+ idle_helper_->EndIdlePeriod();
+ CheckIdlePeriodStateIs("not_in_idle_period");
+}
+
+TEST_F(IdleHelperTest, TestLongIdlePeriodWhenShutdown) {
+ base::TimeTicks deadline_in_task;
+ int run_count = 0;
+
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
+ scheduler_helper_->Shutdown();
+
+ // We shouldn't be able to enter a long idle period when shutdown
+ idle_helper_->EnableLongIdlePeriod();
+ RunUntilIdle();
+ CheckIdlePeriodStateIs("not_in_idle_period");
+ EXPECT_EQ(0, run_count);
+}
+
void TestCanExceedIdleDeadlineIfRequiredTask(IdleHelperForTest* idle_helper,
bool* can_exceed_idle_deadline_out,
int* run_count,
@@ -714,7 +843,7 @@ TEST_F(IdleHelperTest, CanExceedIdleDeadlineIfRequired) {
bool can_exceed_idle_deadline = false;
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
- .Times(3)
+ .Times(2)
.WillRepeatedly(Return(true));
// Should return false if not in an idle period.
@@ -727,7 +856,7 @@ TEST_F(IdleHelperTest, CanExceedIdleDeadlineIfRequired) {
&can_exceed_idle_deadline, &run_count));
idle_helper_->StartIdlePeriod(
IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD, clock_->Now(),
- clock_->Now() + base::TimeDelta::FromMilliseconds(10), true);
+ clock_->Now() + base::TimeDelta::FromMilliseconds(10));
RunUntilIdle();
EXPECT_EQ(1, run_count);
EXPECT_FALSE(can_exceed_idle_deadline);
@@ -784,14 +913,15 @@ class IdleHelperWithQuiescencePeriodTest : public BaseIdleHelperTest {
TEST_F(IdleHelperWithQuiescencePeriodTest,
LongIdlePeriodStartsImmediatelyIfQuiescent) {
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _))
- .Times(2)
+ .Times(1)
.WillRepeatedly(Return(true));
+ base::TimeTicks actual_deadline;
int run_count = 0;
max_idle_task_reposts = 1;
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
+ FROM_HERE, base::Bind(&RepostingIdleTestTask, idle_task_runner_,
+ &run_count, &actual_deadline));
idle_helper_->EnableLongIdlePeriod();
RunUntilIdle();
@@ -804,11 +934,12 @@ TEST_F(IdleHelperWithQuiescencePeriodTest,
MakeNonQuiescent();
EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _)).Times(0);
+ base::TimeTicks actual_deadline;
int run_count = 0;
max_idle_task_reposts = 1;
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
+ FROM_HERE, base::Bind(&RepostingIdleTestTask, idle_task_runner_,
+ &run_count, &actual_deadline));
idle_helper_->EnableLongIdlePeriod();
RunUntilIdle();
@@ -859,22 +990,20 @@ TEST_F(IdleHelperWithQuiescencePeriodTest,
idle_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));
+ // Post a normal task to make the scheduler non-quiescent.
+ default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
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.
+ // Post an idle task. The idle task won't run initially because the system is
+ // not judged to be quiescent, but should be run after the quiescence delay.
+ int run_count = 0;
+ base::TimeTicks deadline_in_task;
base::TimeTicks expected_deadline =
clock_->Now() +
base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs + kLongIdlePeriodMs);
- default_task_runner_->PostTask(FROM_HERE, base::Bind(NullTask));
+ idle_task_runner_->PostIdleTask(
+ FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
+ idle_helper_->EnableLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(1, run_count);
« no previous file with comments | « components/scheduler/child/idle_helper.cc ('k') | components/scheduler/child/nestable_task_runner_for_test.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698