1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/child/scheduler/scheduler_helper.h"
7 #include "base/callback.h"
8 #include "cc/test/ordered_simple_task_runner.h"
9 #include "content/child/scheduler/nestable_task_runner_for_test.h"
10 #include "content/child/scheduler/scheduler_message_loop_delegate.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
15 using testing::Invoke
;
16 using testing::Return
;
21 void AppendToVectorTestTask(std::vector
<std::string
>* vector
,
23 vector
->push_back(value
);
26 void AppendToVectorIdleTestTask(std::vector
<std::string
>* vector
,
28 base::TimeTicks deadline
) {
29 AppendToVectorTestTask(vector
, value
);
35 void AppendToVectorReentrantTask(
36 base::SingleThreadTaskRunner
* task_runner
,
37 std::vector
<int>* vector
,
39 int max_reentrant_count
) {
40 vector
->push_back((*reentrant_count
)++);
41 if (*reentrant_count
< max_reentrant_count
) {
42 task_runner
->PostTask(
43 FROM_HERE
, base::Bind(AppendToVectorReentrantTask
,
44 base::Unretained(task_runner
), vector
,
45 reentrant_count
, max_reentrant_count
));
49 void NullIdleTask(base::TimeTicks
) {
52 void IdleTestTask(int* run_count
,
53 base::TimeTicks
* deadline_out
,
54 base::TimeTicks deadline
) {
56 *deadline_out
= deadline
;
59 int max_idle_task_reposts
= 2;
61 void RepostingIdleTestTask(
62 SingleThreadIdleTaskRunner
* idle_task_runner
,
64 base::TimeTicks deadline
) {
65 if ((*run_count
+ 1) < max_idle_task_reposts
) {
66 idle_task_runner
->PostIdleTask(
68 base::Bind(&RepostingIdleTestTask
,
69 base::Unretained(idle_task_runner
), run_count
));
74 void UpdateClockToDeadlineIdleTestTask(
75 scoped_refptr
<cc::TestNowSource
> clock
,
76 base::SingleThreadTaskRunner
* task_runner
,
78 base::TimeTicks deadline
) {
79 clock
->SetNow(deadline
);
80 // Due to the way in which OrderedSimpleTestRunner orders tasks and the fact
81 // that we updated the time within a task, the delayed pending task to call
82 // EndIdlePeriod will not happen until after a TaskQueueManager DoWork, so
83 // post a normal task here to ensure it runs before the next idle task.
84 task_runner
->PostTask(FROM_HERE
, base::Bind(NullTask
));
91 class SchedulerHelperForTest
: public SchedulerHelper
,
92 public SchedulerHelper::SchedulerHelperDelegate
{
94 explicit SchedulerHelperForTest(
95 scoped_refptr
<NestableSingleThreadTaskRunner
> main_task_runner
)
96 : SchedulerHelper(main_task_runner
,
99 TRACE_DISABLED_BY_DEFAULT("test.scheduler"),
102 ~SchedulerHelperForTest() override
{}
104 using SchedulerHelper::CanExceedIdleDeadlineIfRequired
;
105 using SchedulerHelper::EndIdlePeriod
;
106 using SchedulerHelper::StartIdlePeriod
;
107 using SchedulerHelper::InitiateLongIdlePeriod
;
109 // SchedulerHelperDelegate implementation:
110 MOCK_METHOD2(CanEnterLongIdlePeriod
,
111 bool(base::TimeTicks now
,
112 base::TimeDelta
* next_long_idle_period_delay_out
));
115 class SchedulerHelperTest
: public testing::Test
{
117 SchedulerHelperTest()
118 : clock_(cc::TestNowSource::Create(5000)),
119 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_
, false)),
120 nestable_task_runner_(
121 NestableTaskRunnerForTest::Create(mock_task_runner_
)),
122 scheduler_helper_(new SchedulerHelperForTest(nestable_task_runner_
)),
123 default_task_runner_(scheduler_helper_
->DefaultTaskRunner()),
124 idle_task_runner_(scheduler_helper_
->IdleTaskRunner()) {
125 scheduler_helper_
->SetTimeSourceForTesting(clock_
);
128 SchedulerHelperTest(base::MessageLoop
* message_loop
)
129 : clock_(cc::TestNowSource::Create(5000)),
130 message_loop_(message_loop
),
131 nestable_task_runner_(
132 SchedulerMessageLoopDelegate::Create(message_loop
)),
133 scheduler_helper_(new SchedulerHelperForTest(nestable_task_runner_
)),
134 default_task_runner_(scheduler_helper_
->DefaultTaskRunner()),
135 idle_task_runner_(scheduler_helper_
->IdleTaskRunner()) {
136 scheduler_helper_
->SetTimeSourceForTesting(clock_
);
138 ~SchedulerHelperTest() override
{}
140 void TearDown() override
{
141 DCHECK(!mock_task_runner_
.get() || !message_loop_
.get());
142 if (mock_task_runner_
.get()) {
143 // Check that all tests stop posting tasks.
144 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
145 while (mock_task_runner_
->RunUntilIdle()) {
148 message_loop_
->RunUntilIdle();
152 void RunUntilIdle() {
153 // Only one of mock_task_runner_ or message_loop_ should be set.
154 DCHECK(!mock_task_runner_
.get() || !message_loop_
.get());
155 if (mock_task_runner_
.get())
156 mock_task_runner_
->RunUntilIdle();
158 message_loop_
->RunUntilIdle();
161 // Helper for posting several tasks of specific types. |task_descriptor| is a
162 // string with space delimited task identifiers. The first letter of each
163 // task identifier specifies the task type:
164 // - 'D': Default task
166 void PostTestTasks(std::vector
<std::string
>* run_order
,
167 const std::string
& task_descriptor
) {
168 std::istringstream
stream(task_descriptor
);
169 while (!stream
.eof()) {
174 default_task_runner_
->PostTask(
175 FROM_HERE
, base::Bind(&AppendToVectorTestTask
, run_order
, task
));
178 idle_task_runner_
->PostIdleTask(
180 base::Bind(&AppendToVectorIdleTestTask
, run_order
, task
));
189 static base::TimeDelta
maximum_idle_period_duration() {
190 return base::TimeDelta::FromMilliseconds(
191 SchedulerHelper::kMaximumIdlePeriodMillis
);
194 base::TimeTicks
CurrentIdleTaskDeadlineForTesting() {
195 base::TimeTicks deadline
;
196 scheduler_helper_
->CurrentIdleTaskDeadlineCallback(&deadline
);
200 scoped_refptr
<cc::TestNowSource
> clock_
;
201 // Only one of mock_task_runner_ or message_loop_ will be set.
202 scoped_refptr
<cc::OrderedSimpleTaskRunner
> mock_task_runner_
;
203 scoped_ptr
<base::MessageLoop
> message_loop_
;
205 scoped_refptr
<NestableSingleThreadTaskRunner
> nestable_task_runner_
;
206 scoped_ptr
<SchedulerHelperForTest
> scheduler_helper_
;
207 scoped_refptr
<base::SingleThreadTaskRunner
> default_task_runner_
;
208 scoped_refptr
<SingleThreadIdleTaskRunner
> idle_task_runner_
;
210 DISALLOW_COPY_AND_ASSIGN(SchedulerHelperTest
);
213 TEST_F(SchedulerHelperTest
, TestPostDefaultTask
) {
214 std::vector
<std::string
> run_order
;
215 PostTestTasks(&run_order
, "D1 D2 D3 D4");
218 EXPECT_THAT(run_order
,
219 testing::ElementsAre(std::string("D1"), std::string("D2"),
220 std::string("D3"), std::string("D4")));
223 TEST_F(SchedulerHelperTest
, TestRentrantTask
) {
225 std::vector
<int> run_order
;
226 default_task_runner_
->PostTask(
227 FROM_HERE
, base::Bind(AppendToVectorReentrantTask
, default_task_runner_
,
228 &run_order
, &count
, 5));
231 EXPECT_THAT(run_order
, testing::ElementsAre(0, 1, 2, 3, 4));
234 TEST_F(SchedulerHelperTest
, TestPostIdleTask
) {
236 base::TimeTicks expected_deadline
=
237 clock_
->Now() + base::TimeDelta::FromMilliseconds(2300);
238 base::TimeTicks deadline_in_task
;
240 clock_
->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
241 idle_task_runner_
->PostIdleTask(
242 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
245 EXPECT_EQ(0, run_count
);
247 scheduler_helper_
->StartIdlePeriod(
248 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
253 EXPECT_EQ(1, run_count
);
254 EXPECT_EQ(expected_deadline
, deadline_in_task
);
257 TEST_F(SchedulerHelperTest
, TestPostIdleTask_EndIdlePeriod
) {
259 base::TimeTicks deadline_in_task
;
261 clock_
->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
262 idle_task_runner_
->PostIdleTask(
263 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
266 EXPECT_EQ(0, run_count
);
268 scheduler_helper_
->StartIdlePeriod(
269 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
271 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
273 scheduler_helper_
->EndIdlePeriod();
275 EXPECT_EQ(0, run_count
);
278 TEST_F(SchedulerHelperTest
, TestRepostingIdleTask
) {
281 max_idle_task_reposts
= 2;
282 idle_task_runner_
->PostIdleTask(
284 base::Bind(&RepostingIdleTestTask
, idle_task_runner_
, &run_count
));
285 scheduler_helper_
->StartIdlePeriod(
286 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
288 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
291 EXPECT_EQ(1, run_count
);
293 // Reposted tasks shouldn't run until next idle period.
295 EXPECT_EQ(1, run_count
);
297 scheduler_helper_
->StartIdlePeriod(
298 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
300 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
303 EXPECT_EQ(2, run_count
);
306 TEST_F(SchedulerHelperTest
, TestIdleTaskExceedsDeadline
) {
309 // Post two UpdateClockToDeadlineIdleTestTask tasks.
310 idle_task_runner_
->PostIdleTask(
311 FROM_HERE
, base::Bind(&UpdateClockToDeadlineIdleTestTask
, clock_
,
312 default_task_runner_
, &run_count
));
313 idle_task_runner_
->PostIdleTask(
314 FROM_HERE
, base::Bind(&UpdateClockToDeadlineIdleTestTask
, clock_
,
315 default_task_runner_
, &run_count
));
317 scheduler_helper_
->StartIdlePeriod(
318 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
320 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
323 // Only the first idle task should execute since it's used up the deadline.
324 EXPECT_EQ(1, run_count
);
326 scheduler_helper_
->EndIdlePeriod();
327 scheduler_helper_
->StartIdlePeriod(
328 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
330 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
333 // Second task should be run on the next idle period.
334 EXPECT_EQ(2, run_count
);
337 TEST_F(SchedulerHelperTest
, TestPostIdleTaskAfterWakeup
) {
338 base::TimeTicks deadline_in_task
;
341 idle_task_runner_
->PostIdleTaskAfterWakeup(
342 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
344 scheduler_helper_
->StartIdlePeriod(
345 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
347 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
350 // Shouldn't run yet as no other task woke up the scheduler.
351 EXPECT_EQ(0, run_count
);
353 idle_task_runner_
->PostIdleTaskAfterWakeup(
354 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
356 scheduler_helper_
->StartIdlePeriod(
357 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
359 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
362 // Another after wakeup idle task shouldn't wake the scheduler.
363 EXPECT_EQ(0, run_count
);
365 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(&NullTask
));
368 // Must start a new idle period before idle task runs.
369 scheduler_helper_
->StartIdlePeriod(
370 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
372 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
375 // Execution of default task queue task should trigger execution of idle task.
376 EXPECT_EQ(2, run_count
);
379 TEST_F(SchedulerHelperTest
, TestPostIdleTaskAfterWakeupWhileAwake
) {
380 base::TimeTicks deadline_in_task
;
383 idle_task_runner_
->PostIdleTaskAfterWakeup(
384 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
385 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(&NullTask
));
388 // Must start a new idle period before idle task runs.
389 scheduler_helper_
->StartIdlePeriod(
390 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
392 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
395 // Should run as the scheduler was already awakened by the normal task.
396 EXPECT_EQ(1, run_count
);
399 TEST_F(SchedulerHelperTest
, TestPostIdleTaskWakesAfterWakeupIdleTask
) {
400 base::TimeTicks deadline_in_task
;
403 idle_task_runner_
->PostIdleTaskAfterWakeup(
404 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
405 idle_task_runner_
->PostIdleTask(
406 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
408 scheduler_helper_
->StartIdlePeriod(
409 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
411 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
414 // Must start a new idle period before after-wakeup idle task runs.
415 scheduler_helper_
->StartIdlePeriod(
416 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
418 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
421 // Normal idle task should wake up after-wakeup idle task.
422 EXPECT_EQ(2, run_count
);
425 TEST_F(SchedulerHelperTest
, TestDelayedEndIdlePeriod
) {
426 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
427 TaskQueueManager
* task_queue_manager
=
428 scheduler_helper_
->SchedulerTaskQueueManager();
430 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
432 .WillRepeatedly(Return(true));
434 // We need an idle task posted or InitiateLongIdlePeriod will use the
435 // control_task_after_wakeup_runner_ instead of the control_task_runner_.
436 idle_task_runner_
->PostIdleTask(FROM_HERE
, base::Bind(&NullIdleTask
));
437 scheduler_helper_
->InitiateLongIdlePeriod();
439 // Check there is a pending delayed task.
441 task_queue_manager
->NextPendingDelayedTaskRunTime(), base::TimeTicks());
445 // If the delayed task ran, it will an InitiateLongIdlePeriod on the control
446 // task after wake up queue.
447 EXPECT_FALSE(task_queue_manager
->IsQueueEmpty(
448 SchedulerHelper::CONTROL_TASK_AFTER_WAKEUP_QUEUE
));
451 TEST_F(SchedulerHelperTest
, TestDelayedEndIdlePeriodCanceled
) {
452 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
453 TaskQueueManager
* task_queue_manager
=
454 scheduler_helper_
->SchedulerTaskQueueManager();
456 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
458 .WillRepeatedly(Return(true));
460 // We need an idle task posted or InitiateLongIdlePeriod will use the
461 // control_task_after_wakeup_runner_ instead of the control_task_runner_.
462 idle_task_runner_
->PostIdleTask(FROM_HERE
, base::Bind(&NullIdleTask
));
463 scheduler_helper_
->InitiateLongIdlePeriod();
465 // Check there is a pending delayed task.
467 task_queue_manager
->NextPendingDelayedTaskRunTime(), base::TimeTicks());
469 scheduler_helper_
->EndIdlePeriod();
472 // If the delayed task didn't run, there will be nothing on the control task
473 // after wake up queue.
474 EXPECT_TRUE(task_queue_manager
->IsQueueEmpty(
475 SchedulerHelper::CONTROL_TASK_AFTER_WAKEUP_QUEUE
));
478 class SchedulerHelperWithMessageLoopTest
: public SchedulerHelperTest
{
480 SchedulerHelperWithMessageLoopTest()
481 : SchedulerHelperTest(new base::MessageLoop()) {}
482 ~SchedulerHelperWithMessageLoopTest() override
{}
484 void PostFromNestedRunloop(std::vector
<
485 std::pair
<SingleThreadIdleTaskRunner::IdleTask
, bool>>* tasks
) {
486 base::MessageLoop::ScopedNestableTaskAllower
allow(message_loop_
.get());
487 for (std::pair
<SingleThreadIdleTaskRunner::IdleTask
, bool>& pair
: *tasks
) {
489 idle_task_runner_
->PostIdleTask(FROM_HERE
, pair
.first
);
491 idle_task_runner_
->PostNonNestableIdleTask(FROM_HERE
, pair
.first
);
494 scheduler_helper_
->StartIdlePeriod(
495 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
497 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
499 message_loop_
->RunUntilIdle();
503 DISALLOW_COPY_AND_ASSIGN(SchedulerHelperWithMessageLoopTest
);
506 TEST_F(SchedulerHelperWithMessageLoopTest
,
507 NonNestableIdleTaskDoesntExecuteInNestedLoop
) {
508 std::vector
<std::string
> order
;
509 idle_task_runner_
->PostIdleTask(
511 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("1")));
512 idle_task_runner_
->PostIdleTask(
514 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("2")));
516 std::vector
<std::pair
<SingleThreadIdleTaskRunner::IdleTask
, bool>>
517 tasks_to_post_from_nested_loop
;
518 tasks_to_post_from_nested_loop
.push_back(std::make_pair(
519 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("3")),
521 tasks_to_post_from_nested_loop
.push_back(std::make_pair(
522 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("4")), true));
523 tasks_to_post_from_nested_loop
.push_back(std::make_pair(
524 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("5")), true));
526 default_task_runner_
->PostTask(
528 base::Bind(&SchedulerHelperWithMessageLoopTest::PostFromNestedRunloop
,
529 base::Unretained(this),
530 base::Unretained(&tasks_to_post_from_nested_loop
)));
532 scheduler_helper_
->StartIdlePeriod(
533 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
535 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
538 // Note we expect task 3 to run last because it's non-nestable.
539 EXPECT_THAT(order
, testing::ElementsAre(std::string("1"), std::string("2"),
540 std::string("4"), std::string("5"),
544 TEST_F(SchedulerHelperTest
, TestLongIdlePeriod
) {
545 base::TimeTicks expected_deadline
=
546 clock_
->Now() + maximum_idle_period_duration();
547 base::TimeTicks deadline_in_task
;
550 idle_task_runner_
->PostIdleTask(
551 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
553 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
555 .WillRepeatedly(Return(true));
558 EXPECT_EQ(0, run_count
); // Shouldn't run yet as no idle period.
560 scheduler_helper_
->InitiateLongIdlePeriod();
562 EXPECT_EQ(1, run_count
); // Should have run in a long idle time.
563 EXPECT_EQ(expected_deadline
, deadline_in_task
);
566 TEST_F(SchedulerHelperTest
, TestLongIdlePeriodWithPendingDelayedTask
) {
567 base::TimeDelta pending_task_delay
= base::TimeDelta::FromMilliseconds(30);
568 base::TimeTicks expected_deadline
= clock_
->Now() + pending_task_delay
;
569 base::TimeTicks deadline_in_task
;
572 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
574 .WillRepeatedly(Return(true));
576 idle_task_runner_
->PostIdleTask(
577 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
578 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
581 scheduler_helper_
->InitiateLongIdlePeriod();
583 EXPECT_EQ(1, run_count
); // Should have run in a long idle time.
584 EXPECT_EQ(expected_deadline
, deadline_in_task
);
587 TEST_F(SchedulerHelperTest
, TestLongIdlePeriodWithLatePendingDelayedTask
) {
588 base::TimeDelta pending_task_delay
= base::TimeDelta::FromMilliseconds(10);
589 base::TimeTicks deadline_in_task
;
592 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
594 .WillRepeatedly(Return(true));
596 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
599 // Advance clock until after delayed task was meant to be run.
600 clock_
->AdvanceNow(base::TimeDelta::FromMilliseconds(20));
602 // Post an idle task and then InitiateLongIdlePeriod. Since there is a late
603 // pending delayed task this shouldn't actually start an idle period.
604 idle_task_runner_
->PostIdleTask(
605 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
606 scheduler_helper_
->InitiateLongIdlePeriod();
608 EXPECT_EQ(0, run_count
);
610 // After the delayed task has been run we should trigger an idle period.
611 clock_
->AdvanceNow(maximum_idle_period_duration());
613 EXPECT_EQ(1, run_count
);
616 TEST_F(SchedulerHelperTest
, TestLongIdlePeriodRepeating
) {
619 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
621 .WillRepeatedly(Return(true));
623 max_idle_task_reposts
= 3;
624 idle_task_runner_
->PostIdleTask(
626 base::Bind(&RepostingIdleTestTask
, idle_task_runner_
, &run_count
));
628 scheduler_helper_
->InitiateLongIdlePeriod();
630 EXPECT_EQ(1, run_count
); // Should only run once per idle period.
632 // Advance time to start of next long idle period and check task reposted task
634 clock_
->AdvanceNow(maximum_idle_period_duration());
636 EXPECT_EQ(2, run_count
);
638 // Advance time to start of next long idle period then end the idle period and
639 // check the task doesn't get run.
640 clock_
->AdvanceNow(maximum_idle_period_duration());
641 scheduler_helper_
->EndIdlePeriod();
643 EXPECT_EQ(2, run_count
);
646 TEST_F(SchedulerHelperTest
, TestLongIdlePeriodDoesNotWakeScheduler
) {
647 base::TimeTicks deadline_in_task
;
650 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
652 .WillRepeatedly(Return(true));
654 // Start a long idle period and get the time it should end.
655 scheduler_helper_
->InitiateLongIdlePeriod();
656 // The scheduler should not run the initiate_next_long_idle_period task if
657 // there are no idle tasks and no other task woke up the scheduler, thus
658 // the idle period deadline shouldn't update at the end of the current long
660 base::TimeTicks idle_period_deadline
= CurrentIdleTaskDeadlineForTesting();
661 clock_
->AdvanceNow(maximum_idle_period_duration());
664 base::TimeTicks new_idle_period_deadline
=
665 CurrentIdleTaskDeadlineForTesting();
666 EXPECT_EQ(idle_period_deadline
, new_idle_period_deadline
);
668 // Posting a after-wakeup idle task also shouldn't wake the scheduler or
669 // initiate the next long idle period.
670 idle_task_runner_
->PostIdleTaskAfterWakeup(
671 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
673 new_idle_period_deadline
= CurrentIdleTaskDeadlineForTesting();
674 EXPECT_EQ(idle_period_deadline
, new_idle_period_deadline
);
675 EXPECT_EQ(0, run_count
);
677 // Running a normal task should initiate a new long idle period though.
678 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(&NullTask
));
680 new_idle_period_deadline
= CurrentIdleTaskDeadlineForTesting();
681 EXPECT_EQ(idle_period_deadline
+ maximum_idle_period_duration(),
682 new_idle_period_deadline
);
684 EXPECT_EQ(1, run_count
);
687 TEST_F(SchedulerHelperTest
, TestLongIdlePeriodWhenNotCanEnterLongIdlePeriod
) {
688 base::TimeDelta delay
= base::TimeDelta::FromMilliseconds(1000);
689 base::TimeDelta halfDelay
= base::TimeDelta::FromMilliseconds(500);
690 base::TimeTicks delayOver
= clock_
->Now() + delay
;
691 base::TimeTicks deadline_in_task
;
694 ON_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
695 .WillByDefault(Invoke([delay
, delayOver
](
697 base::TimeDelta
* next_long_idle_period_delay_out
) {
698 if (now
>= delayOver
)
700 *next_long_idle_period_delay_out
= delay
;
704 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
)).Times(3);
706 idle_task_runner_
->PostIdleTask(
707 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
709 // Make sure Idle tasks don't run until the delay has occured.
710 scheduler_helper_
->InitiateLongIdlePeriod();
712 EXPECT_EQ(0, run_count
);
714 clock_
->AdvanceNow(halfDelay
);
716 EXPECT_EQ(0, run_count
);
718 // Delay is finished, idle task should run.
719 clock_
->AdvanceNow(halfDelay
);
721 EXPECT_EQ(1, run_count
);
724 void TestCanExceedIdleDeadlineIfRequiredTask(SchedulerHelperForTest
* scheduler
,
725 bool* can_exceed_idle_deadline_out
,
727 base::TimeTicks deadline
) {
728 *can_exceed_idle_deadline_out
= scheduler
->CanExceedIdleDeadlineIfRequired();
732 TEST_F(SchedulerHelperTest
, CanExceedIdleDeadlineIfRequired
) {
734 bool can_exceed_idle_deadline
= false;
736 EXPECT_CALL(*scheduler_helper_
, CanEnterLongIdlePeriod(_
, _
))
738 .WillRepeatedly(Return(true));
740 // Should return false if not in an idle period.
741 EXPECT_FALSE(scheduler_helper_
->CanExceedIdleDeadlineIfRequired());
743 // Should return false for short idle periods.
744 idle_task_runner_
->PostIdleTask(
745 FROM_HERE
, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask
,
746 scheduler_helper_
.get(), &can_exceed_idle_deadline
,
748 scheduler_helper_
->StartIdlePeriod(
749 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
,
751 clock_
->Now() + base::TimeDelta::FromMilliseconds(10),
754 EXPECT_EQ(1, run_count
);
755 EXPECT_FALSE(can_exceed_idle_deadline
);
757 // Should return false for a long idle period which is shortened due to a
758 // pending delayed task.
759 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
760 base::TimeDelta::FromMilliseconds(10));
761 idle_task_runner_
->PostIdleTask(
762 FROM_HERE
, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask
,
763 scheduler_helper_
.get(), &can_exceed_idle_deadline
,
765 scheduler_helper_
->InitiateLongIdlePeriod();
767 EXPECT_EQ(2, run_count
);
768 EXPECT_FALSE(can_exceed_idle_deadline
);
770 // Next long idle period will be for the maximum time, so
771 // CanExceedIdleDeadlineIfRequired should return true.
772 clock_
->AdvanceNow(maximum_idle_period_duration());
773 idle_task_runner_
->PostIdleTask(
774 FROM_HERE
, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask
,
775 scheduler_helper_
.get(), &can_exceed_idle_deadline
,
778 EXPECT_EQ(3, run_count
);
779 EXPECT_TRUE(can_exceed_idle_deadline
);
782 TEST_F(SchedulerHelperTest
, IsShutdown
) {
783 EXPECT_FALSE(scheduler_helper_
->IsShutdown());
785 scheduler_helper_
->Shutdown();
786 EXPECT_TRUE(scheduler_helper_
->IsShutdown());
789 } // namespace content