1 // Copyright 2015 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 "components/scheduler/child/idle_helper.h"
7 #include "base/callback.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "cc/test/ordered_simple_task_runner.h"
10 #include "components/scheduler/child/scheduler_helper.h"
11 #include "components/scheduler/child/scheduler_task_runner_delegate_for_test.h"
12 #include "components/scheduler/child/scheduler_task_runner_delegate_impl.h"
13 #include "components/scheduler/child/task_queue.h"
14 #include "components/scheduler/child/task_queue_manager.h"
15 #include "components/scheduler/child/test_time_source.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
20 using testing::AnyNumber
;
21 using testing::AtLeast
;
22 using testing::Exactly
;
23 using testing::Invoke
;
24 using testing::Return
;
29 void AppendToVectorTestTask(std::vector
<std::string
>* vector
,
31 vector
->push_back(value
);
34 void AppendToVectorIdleTestTask(std::vector
<std::string
>* vector
,
36 base::TimeTicks deadline
) {
37 AppendToVectorTestTask(vector
, value
);
43 void NullIdleTask(base::TimeTicks deadline
) {
46 void AppendToVectorReentrantTask(base::SingleThreadTaskRunner
* task_runner
,
47 std::vector
<int>* vector
,
49 int max_reentrant_count
) {
50 vector
->push_back((*reentrant_count
)++);
51 if (*reentrant_count
< max_reentrant_count
) {
52 task_runner
->PostTask(
54 base::Bind(AppendToVectorReentrantTask
, base::Unretained(task_runner
),
55 vector
, reentrant_count
, max_reentrant_count
));
59 void IdleTestTask(int* run_count
,
60 base::TimeTicks
* deadline_out
,
61 base::TimeTicks deadline
) {
63 *deadline_out
= deadline
;
66 int max_idle_task_reposts
= 2;
68 void RepostingIdleTestTask(SingleThreadIdleTaskRunner
* idle_task_runner
,
70 base::TimeTicks
* deadline_out
,
71 base::TimeTicks deadline
) {
72 if ((*run_count
+ 1) < max_idle_task_reposts
) {
73 idle_task_runner
->PostIdleTask(
75 base::Bind(&RepostingIdleTestTask
, base::Unretained(idle_task_runner
),
76 run_count
, deadline_out
));
78 *deadline_out
= deadline
;
82 void RepostingUpdateClockIdleTestTask(
83 SingleThreadIdleTaskRunner
* idle_task_runner
,
85 base::SimpleTestTickClock
* clock
,
86 base::TimeDelta advance_time
,
87 std::vector
<base::TimeTicks
>* deadlines
,
88 base::TimeTicks deadline
) {
89 if ((*run_count
+ 1) < max_idle_task_reposts
) {
90 idle_task_runner
->PostIdleTask(
91 FROM_HERE
, base::Bind(&RepostingUpdateClockIdleTestTask
,
92 base::Unretained(idle_task_runner
), run_count
,
93 clock
, advance_time
, deadlines
));
95 deadlines
->push_back(deadline
);
97 clock
->Advance(advance_time
);
100 void RepeatingTask(base::SingleThreadTaskRunner
* task_runner
,
102 base::TimeDelta delay
) {
103 if (num_repeats
> 1) {
104 task_runner
->PostDelayedTask(
105 FROM_HERE
, base::Bind(&RepeatingTask
, base::Unretained(task_runner
),
106 num_repeats
- 1, delay
),
111 void UpdateClockIdleTestTask(base::SimpleTestTickClock
* clock
,
113 base::TimeTicks set_time
,
114 base::TimeTicks deadline
) {
115 clock
->Advance(set_time
- clock
->NowTicks());
119 void UpdateClockToDeadlineIdleTestTask(base::SimpleTestTickClock
* clock
,
121 base::TimeTicks deadline
) {
122 UpdateClockIdleTestTask(clock
, run_count
, deadline
, deadline
);
125 void EndIdlePeriodIdleTask(IdleHelper
* idle_helper
, base::TimeTicks deadline
) {
126 idle_helper
->EndIdlePeriod();
129 scoped_refptr
<SchedulerTaskRunnerDelegate
> CreateTaskRunnerDelegate(
130 base::MessageLoop
* message_loop
,
131 scoped_refptr
<cc::OrderedSimpleTaskRunner
> mock_task_runner
) {
133 return SchedulerTaskRunnerDelegateImpl::Create(message_loop
);
135 return SchedulerTaskRunnerDelegateForTest::Create(mock_task_runner
);
140 class IdleHelperForTest
: public IdleHelper
, public IdleHelper::Delegate
{
142 explicit IdleHelperForTest(
143 SchedulerHelper
* scheduler_helper
,
144 base::TimeDelta required_quiescence_duration_before_long_idle_period
)
145 : IdleHelper(scheduler_helper
,
148 TRACE_DISABLED_BY_DEFAULT("test.idle"),
149 "TestSchedulerIdlePeriod",
150 required_quiescence_duration_before_long_idle_period
) {}
152 ~IdleHelperForTest() override
{}
154 // SchedulerHelperDelegate implementation:
155 MOCK_METHOD2(CanEnterLongIdlePeriod
,
156 bool(base::TimeTicks now
,
157 base::TimeDelta
* next_long_idle_period_delay_out
));
159 MOCK_METHOD0(IsNotQuiescent
, void());
160 MOCK_METHOD0(OnIdlePeriodStarted
, void());
161 MOCK_METHOD0(OnIdlePeriodEnded
, void());
164 class BaseIdleHelperTest
: public testing::Test
{
167 base::MessageLoop
* message_loop
,
168 base::TimeDelta required_quiescence_duration_before_long_idle_period
)
169 : clock_(new base::SimpleTestTickClock()),
173 : new cc::OrderedSimpleTaskRunner(clock_
.get(), false)),
174 message_loop_(message_loop
),
176 CreateTaskRunnerDelegate(message_loop
, mock_task_runner_
)),
178 new SchedulerHelper(main_task_runner_
,
180 TRACE_DISABLED_BY_DEFAULT("test.idle"),
181 TRACE_DISABLED_BY_DEFAULT("test.idle.debug"))),
182 idle_helper_(new IdleHelperForTest(
183 scheduler_helper_
.get(),
184 required_quiescence_duration_before_long_idle_period
)),
185 default_task_runner_(scheduler_helper_
->DefaultTaskRunner()),
186 idle_task_runner_(idle_helper_
->IdleTaskRunner()) {
187 clock_
->Advance(base::TimeDelta::FromMicroseconds(5000));
188 scheduler_helper_
->SetTimeSourceForTesting(
189 make_scoped_ptr(new TestTimeSource(clock_
.get())));
190 scheduler_helper_
->GetTaskQueueManagerForTesting()->SetTimeSourceForTesting(
191 make_scoped_ptr(new TestTimeSource(clock_
.get())));
194 ~BaseIdleHelperTest() override
{}
196 void SetUp() override
{
197 EXPECT_CALL(*idle_helper_
, OnIdlePeriodStarted()).Times(AnyNumber());
198 EXPECT_CALL(*idle_helper_
, OnIdlePeriodEnded()).Times(AnyNumber());
199 EXPECT_CALL(*idle_helper_
, CanEnterLongIdlePeriod(_
, _
))
201 .WillRepeatedly(Return(true));
204 void TearDown() override
{
205 DCHECK(!mock_task_runner_
.get() || !message_loop_
.get());
206 if (mock_task_runner_
.get()) {
207 // Check that all tests stop posting tasks.
208 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
209 while (mock_task_runner_
->RunUntilIdle()) {
212 message_loop_
->RunUntilIdle();
216 void RunUntilIdle() {
217 // Only one of mock_task_runner_ or message_loop_ should be set.
218 DCHECK(!mock_task_runner_
.get() || !message_loop_
.get());
219 if (mock_task_runner_
.get())
220 mock_task_runner_
->RunUntilIdle();
222 message_loop_
->RunUntilIdle();
225 template <typename E
>
226 static void CallForEachEnumValue(E first
,
228 const char* (*function
)(E
)) {
229 for (E val
= first
; val
< last
;
230 val
= static_cast<E
>(static_cast<int>(val
) + 1)) {
235 static void CheckAllTaskQueueIdToString() {
236 CallForEachEnumValue
<IdleHelper::IdlePeriodState
>(
237 IdleHelper::IdlePeriodState::FIRST_IDLE_PERIOD_STATE
,
238 IdleHelper::IdlePeriodState::IDLE_PERIOD_STATE_COUNT
,
239 &IdleHelper::IdlePeriodStateToString
);
242 bool IsInIdlePeriod() const {
243 return idle_helper_
->IsInIdlePeriod(
244 idle_helper_
->SchedulerIdlePeriodState());
248 static base::TimeDelta
maximum_idle_period_duration() {
249 return base::TimeDelta::FromMilliseconds(
250 IdleHelper::kMaximumIdlePeriodMillis
);
253 static base::TimeDelta
retry_enable_long_idle_period_delay() {
254 return base::TimeDelta::FromMilliseconds(
255 IdleHelper::kRetryEnableLongIdlePeriodDelayMillis
);
258 static base::TimeDelta
minimum_idle_period_duration() {
259 return base::TimeDelta::FromMilliseconds(
260 IdleHelper::kMinimumIdlePeriodDurationMillis
);
263 base::TimeTicks
CurrentIdleTaskDeadline() {
264 return idle_helper_
->CurrentIdleTaskDeadline();
267 void CheckIdlePeriodStateIs(const char* expected
) {
268 EXPECT_STREQ(expected
, IdleHelper::IdlePeriodStateToString(
269 idle_helper_
->SchedulerIdlePeriodState()));
272 scoped_ptr
<base::SimpleTestTickClock
> clock_
;
273 // Only one of mock_task_runner_ or message_loop_ will be set.
274 scoped_refptr
<cc::OrderedSimpleTaskRunner
> mock_task_runner_
;
275 scoped_ptr
<base::MessageLoop
> message_loop_
;
277 scoped_refptr
<SchedulerTaskRunnerDelegate
> main_task_runner_
;
278 scoped_ptr
<SchedulerHelper
> scheduler_helper_
;
279 scoped_ptr
<IdleHelperForTest
> idle_helper_
;
280 scoped_refptr
<base::SingleThreadTaskRunner
> default_task_runner_
;
281 scoped_refptr
<SingleThreadIdleTaskRunner
> idle_task_runner_
;
283 DISALLOW_COPY_AND_ASSIGN(BaseIdleHelperTest
);
286 class IdleHelperTest
: public BaseIdleHelperTest
{
288 IdleHelperTest() : BaseIdleHelperTest(nullptr, base::TimeDelta()) {}
290 ~IdleHelperTest() override
{}
292 TaskQueueManager
* task_queue_manager() const {
293 return scheduler_helper_
->GetTaskQueueManagerForTesting();
297 DISALLOW_COPY_AND_ASSIGN(IdleHelperTest
);
300 TEST_F(IdleHelperTest
, TestPostIdleTask
) {
302 base::TimeTicks expected_deadline
=
303 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
304 base::TimeTicks deadline_in_task
;
306 clock_
->Advance(base::TimeDelta::FromMilliseconds(100));
307 idle_task_runner_
->PostIdleTask(
308 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
311 EXPECT_EQ(0, run_count
);
313 idle_helper_
->StartIdlePeriod(
314 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
317 EXPECT_EQ(1, run_count
);
318 EXPECT_EQ(expected_deadline
, deadline_in_task
);
321 TEST_F(IdleHelperTest
, TestPostIdleTask_EndIdlePeriod
) {
323 base::TimeTicks deadline_in_task
;
325 clock_
->Advance(base::TimeDelta::FromMilliseconds(100));
326 idle_task_runner_
->PostIdleTask(
327 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
330 EXPECT_EQ(0, run_count
);
332 idle_helper_
->StartIdlePeriod(
333 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
334 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
335 idle_helper_
->EndIdlePeriod();
337 EXPECT_EQ(0, run_count
);
340 TEST_F(IdleHelperTest
, TestRepostingIdleTask
) {
341 base::TimeTicks actual_deadline
;
344 max_idle_task_reposts
= 2;
345 idle_task_runner_
->PostIdleTask(
346 FROM_HERE
, base::Bind(&RepostingIdleTestTask
, idle_task_runner_
,
347 &run_count
, &actual_deadline
));
348 idle_helper_
->StartIdlePeriod(
349 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
350 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
352 EXPECT_EQ(1, run_count
);
354 // Reposted tasks shouldn't run until next idle period.
356 EXPECT_EQ(1, run_count
);
358 idle_helper_
->StartIdlePeriod(
359 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
360 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
362 EXPECT_EQ(2, run_count
);
365 TEST_F(IdleHelperTest
, TestIdleTaskExceedsDeadline
) {
368 // Post two UpdateClockToDeadlineIdleTestTask tasks.
369 idle_task_runner_
->PostIdleTask(
371 base::Bind(&UpdateClockToDeadlineIdleTestTask
, clock_
.get(), &run_count
));
372 idle_task_runner_
->PostIdleTask(
374 base::Bind(&UpdateClockToDeadlineIdleTestTask
, clock_
.get(), &run_count
));
376 idle_helper_
->StartIdlePeriod(
377 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
378 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
380 // Only the first idle task should execute since it's used up the deadline.
381 EXPECT_EQ(1, run_count
);
383 idle_helper_
->EndIdlePeriod();
384 idle_helper_
->StartIdlePeriod(
385 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
386 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
388 // Second task should be run on the next idle period.
389 EXPECT_EQ(2, run_count
);
392 TEST_F(IdleHelperTest
, TestPostIdleTaskAfterWakeup
) {
393 base::TimeTicks deadline_in_task
;
396 idle_task_runner_
->PostIdleTaskAfterWakeup(
397 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
399 idle_helper_
->StartIdlePeriod(
400 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
401 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
403 // Shouldn't run yet as no other task woke up the scheduler.
404 EXPECT_EQ(0, run_count
);
406 // Must start a new idle period before idle task runs.
407 idle_task_runner_
->PostIdleTaskAfterWakeup(
408 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
410 idle_helper_
->StartIdlePeriod(
411 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
412 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
414 // Another after wakeup idle task shouldn't wake the scheduler.
415 EXPECT_EQ(0, run_count
);
417 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(&NullTask
));
420 idle_helper_
->StartIdlePeriod(
421 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
422 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
424 // Execution of default task queue task should trigger execution of idle task.
425 EXPECT_EQ(2, run_count
);
428 TEST_F(IdleHelperTest
, TestPostIdleTaskAfterWakeupWhileAwake
) {
429 base::TimeTicks deadline_in_task
;
432 idle_task_runner_
->PostIdleTaskAfterWakeup(
433 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
434 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(&NullTask
));
437 // Must start a new idle period before idle task runs.
438 idle_helper_
->StartIdlePeriod(
439 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
440 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
442 // Should run as the scheduler was already awakened by the normal task.
443 EXPECT_EQ(1, run_count
);
446 TEST_F(IdleHelperTest
, TestPostIdleTaskWakesAfterWakeupIdleTask
) {
447 base::TimeTicks deadline_in_task
;
450 idle_task_runner_
->PostIdleTaskAfterWakeup(
451 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
452 idle_task_runner_
->PostIdleTask(
453 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
455 idle_helper_
->StartIdlePeriod(
456 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
457 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
459 // Must start a new idle period before after-wakeup idle task runs.
460 idle_helper_
->StartIdlePeriod(
461 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
462 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
464 // Normal idle task should wake up after-wakeup idle task.
465 EXPECT_EQ(2, run_count
);
468 class IdleHelperTestWithIdlePeriodObserver
: public BaseIdleHelperTest
{
470 IdleHelperTestWithIdlePeriodObserver()
471 : BaseIdleHelperTest(nullptr, base::TimeDelta()) {}
473 ~IdleHelperTestWithIdlePeriodObserver() override
{}
475 void SetUp() override
{
476 // Don't set expectations on IdleHelper::Delegate.
479 TaskQueueManager
* task_queue_manager() const {
480 return scheduler_helper_
->GetTaskQueueManagerForTesting();
483 void ExpectIdlePeriodStartsButNeverEnds() {
484 EXPECT_CALL(*idle_helper_
, OnIdlePeriodStarted()).Times(1);
485 EXPECT_CALL(*idle_helper_
, OnIdlePeriodEnded()).Times(0);
488 void ExpectIdlePeriodStartsAndEnds(const testing::Cardinality
& cardinality
) {
489 EXPECT_CALL(*idle_helper_
, OnIdlePeriodStarted()).Times(cardinality
);
490 EXPECT_CALL(*idle_helper_
, OnIdlePeriodEnded()).Times(cardinality
);
494 DISALLOW_COPY_AND_ASSIGN(IdleHelperTestWithIdlePeriodObserver
);
497 TEST_F(IdleHelperTestWithIdlePeriodObserver
, TestEnterButNotExitIdlePeriod
) {
498 ExpectIdlePeriodStartsButNeverEnds();
500 idle_helper_
->StartIdlePeriod(
501 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
502 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
505 TEST_F(IdleHelperTestWithIdlePeriodObserver
, TestEnterAndExitIdlePeriod
) {
506 BaseIdleHelperTest
* fixture
= this;
507 ON_CALL(*idle_helper_
, OnIdlePeriodStarted())
509 Invoke([fixture
]() { EXPECT_TRUE(fixture
->IsInIdlePeriod()); }));
510 ON_CALL(*idle_helper_
, OnIdlePeriodEnded())
512 Invoke([fixture
]() { EXPECT_FALSE(fixture
->IsInIdlePeriod()); }));
514 ExpectIdlePeriodStartsAndEnds(Exactly(1));
516 idle_helper_
->StartIdlePeriod(
517 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
518 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
519 idle_helper_
->EndIdlePeriod();
522 class IdleHelperWithMessageLoopTest
: public BaseIdleHelperTest
{
524 IdleHelperWithMessageLoopTest()
525 : BaseIdleHelperTest(new base::MessageLoop(), base::TimeDelta()) {}
526 ~IdleHelperWithMessageLoopTest() override
{}
528 void PostFromNestedRunloop(std::vector
<
529 std::pair
<SingleThreadIdleTaskRunner::IdleTask
, bool>>* tasks
) {
530 base::MessageLoop::ScopedNestableTaskAllower
allow(message_loop_
.get());
531 for (std::pair
<SingleThreadIdleTaskRunner::IdleTask
, bool>& pair
: *tasks
) {
533 idle_task_runner_
->PostIdleTask(FROM_HERE
, pair
.first
);
535 idle_task_runner_
->PostNonNestableIdleTask(FROM_HERE
, pair
.first
);
538 idle_helper_
->StartIdlePeriod(
539 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
540 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
541 message_loop_
->RunUntilIdle();
544 void SetUp() override
{
545 EXPECT_CALL(*idle_helper_
, OnIdlePeriodStarted()).Times(AnyNumber());
546 EXPECT_CALL(*idle_helper_
, OnIdlePeriodEnded()).Times(AnyNumber());
550 DISALLOW_COPY_AND_ASSIGN(IdleHelperWithMessageLoopTest
);
553 TEST_F(IdleHelperWithMessageLoopTest
,
554 NonNestableIdleTaskDoesntExecuteInNestedLoop
) {
555 std::vector
<std::string
> order
;
556 idle_task_runner_
->PostIdleTask(
558 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("1")));
559 idle_task_runner_
->PostIdleTask(
561 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("2")));
563 std::vector
<std::pair
<SingleThreadIdleTaskRunner::IdleTask
, bool>>
564 tasks_to_post_from_nested_loop
;
565 tasks_to_post_from_nested_loop
.push_back(std::make_pair(
566 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("3")),
568 tasks_to_post_from_nested_loop
.push_back(std::make_pair(
569 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("4")), true));
570 tasks_to_post_from_nested_loop
.push_back(std::make_pair(
571 base::Bind(&AppendToVectorIdleTestTask
, &order
, std::string("5")), true));
573 default_task_runner_
->PostTask(
575 base::Bind(&IdleHelperWithMessageLoopTest::PostFromNestedRunloop
,
576 base::Unretained(this),
577 base::Unretained(&tasks_to_post_from_nested_loop
)));
579 idle_helper_
->StartIdlePeriod(
580 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
581 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
583 // Note we expect task 3 to run last because it's non-nestable.
584 EXPECT_THAT(order
, testing::ElementsAre(std::string("1"), std::string("2"),
585 std::string("4"), std::string("5"),
589 TEST_F(IdleHelperTestWithIdlePeriodObserver
, TestLongIdlePeriod
) {
590 base::TimeTicks expected_deadline
=
591 clock_
->NowTicks() + maximum_idle_period_duration();
592 base::TimeTicks deadline_in_task
;
595 idle_task_runner_
->PostIdleTask(
596 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
598 EXPECT_CALL(*idle_helper_
, CanEnterLongIdlePeriod(_
, _
))
600 .WillRepeatedly(Return(true));
601 ExpectIdlePeriodStartsButNeverEnds();
604 EXPECT_EQ(0, run_count
); // Shouldn't run yet as no idle period.
606 idle_helper_
->EnableLongIdlePeriod();
608 EXPECT_EQ(1, run_count
); // Should have run in a long idle time.
609 EXPECT_EQ(expected_deadline
, deadline_in_task
);
612 TEST_F(IdleHelperTest
, TestLongIdlePeriodWithPendingDelayedTask
) {
613 base::TimeDelta pending_task_delay
= base::TimeDelta::FromMilliseconds(30);
614 base::TimeTicks expected_deadline
= clock_
->NowTicks() + pending_task_delay
;
615 base::TimeTicks deadline_in_task
;
618 idle_task_runner_
->PostIdleTask(
619 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
620 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
623 idle_helper_
->EnableLongIdlePeriod();
625 EXPECT_EQ(1, run_count
); // Should have run in a long idle time.
626 EXPECT_EQ(expected_deadline
, deadline_in_task
);
629 TEST_F(IdleHelperTest
, TestLongIdlePeriodWithLatePendingDelayedTask
) {
630 base::TimeDelta pending_task_delay
= base::TimeDelta::FromMilliseconds(10);
631 base::TimeTicks deadline_in_task
;
634 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
637 // Advance clock until after delayed task was meant to be run.
638 clock_
->Advance(base::TimeDelta::FromMilliseconds(20));
640 // Post an idle task and then EnableLongIdlePeriod. Since there is a late
641 // pending delayed task this shouldn't actually start an idle period.
642 idle_task_runner_
->PostIdleTask(
643 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
644 idle_helper_
->EnableLongIdlePeriod();
646 EXPECT_EQ(0, run_count
);
648 // After the delayed task has been run we should trigger an idle period.
649 clock_
->Advance(maximum_idle_period_duration());
651 EXPECT_EQ(1, run_count
);
654 TEST_F(IdleHelperTestWithIdlePeriodObserver
, TestLongIdlePeriodRepeating
) {
655 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
656 std::vector
<base::TimeTicks
> actual_deadlines
;
659 EXPECT_CALL(*idle_helper_
, CanEnterLongIdlePeriod(_
, _
))
661 .WillRepeatedly(Return(true));
662 ExpectIdlePeriodStartsAndEnds(AtLeast(2));
664 max_idle_task_reposts
= 3;
665 base::TimeTicks
clock_before(clock_
->NowTicks());
666 base::TimeDelta
idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
667 idle_task_runner_
->PostIdleTask(
668 FROM_HERE
, base::Bind(&RepostingUpdateClockIdleTestTask
,
669 idle_task_runner_
, &run_count
, clock_
.get(),
670 idle_task_runtime
, &actual_deadlines
));
672 // Check each idle task runs in their own idle period.
673 idle_helper_
->EnableLongIdlePeriod();
675 EXPECT_EQ(3, run_count
);
678 testing::ElementsAre(
679 clock_before
+ maximum_idle_period_duration(),
680 clock_before
+ idle_task_runtime
+ maximum_idle_period_duration(),
681 clock_before
+ (2 * idle_task_runtime
) +
682 maximum_idle_period_duration()));
684 max_idle_task_reposts
= 5;
685 idle_task_runner_
->PostIdleTask(
686 FROM_HERE
, base::Bind(&RepostingUpdateClockIdleTestTask
,
687 idle_task_runner_
, &run_count
, clock_
.get(),
688 idle_task_runtime
, &actual_deadlines
));
689 idle_task_runner_
->PostIdleTask(
691 base::Bind(&EndIdlePeriodIdleTask
, base::Unretained(idle_helper_
.get())));
693 // Ensure that reposting tasks stop after EndIdlePeriod is called.
695 EXPECT_EQ(4, run_count
);
698 TEST_F(IdleHelperTest
, TestLongIdlePeriodDoesNotWakeScheduler
) {
699 base::TimeTicks deadline_in_task
;
702 // Start a long idle period and get the time it should end.
703 idle_helper_
->EnableLongIdlePeriod();
704 // The scheduler should not run the enable_next_long_idle_period task if
705 // there are no idle tasks and no other task woke up the scheduler, thus
706 // the idle period deadline shouldn't update at the end of the current long
708 base::TimeTicks idle_period_deadline
= CurrentIdleTaskDeadline();
709 clock_
->Advance(maximum_idle_period_duration());
712 base::TimeTicks new_idle_period_deadline
= CurrentIdleTaskDeadline();
713 EXPECT_EQ(idle_period_deadline
, new_idle_period_deadline
);
715 // Posting a after-wakeup idle task also shouldn't wake the scheduler or
716 // initiate the next long idle period.
717 idle_task_runner_
->PostIdleTaskAfterWakeup(
718 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
720 new_idle_period_deadline
= CurrentIdleTaskDeadline();
721 EXPECT_EQ(idle_period_deadline
, new_idle_period_deadline
);
722 EXPECT_EQ(0, run_count
);
724 // Running a normal task should initiate a new long idle period though.
725 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(&NullTask
));
727 new_idle_period_deadline
= CurrentIdleTaskDeadline();
728 EXPECT_EQ(idle_period_deadline
+ maximum_idle_period_duration(),
729 new_idle_period_deadline
);
731 EXPECT_EQ(1, run_count
);
734 TEST_F(IdleHelperTestWithIdlePeriodObserver
,
735 TestLongIdlePeriodWhenNotCanEnterLongIdlePeriod
) {
736 base::TimeDelta delay
= base::TimeDelta::FromMilliseconds(1000);
737 base::TimeDelta halfDelay
= base::TimeDelta::FromMilliseconds(500);
738 base::TimeTicks delayOver
= clock_
->NowTicks() + delay
;
739 base::TimeTicks deadline_in_task
;
742 ON_CALL(*idle_helper_
, CanEnterLongIdlePeriod(_
, _
))
743 .WillByDefault(Invoke(
744 [delay
, delayOver
](base::TimeTicks now
,
745 base::TimeDelta
* next_long_idle_period_delay_out
) {
746 if (now
>= delayOver
)
748 *next_long_idle_period_delay_out
= delay
;
752 EXPECT_CALL(*idle_helper_
, CanEnterLongIdlePeriod(_
, _
)).Times(2);
753 EXPECT_CALL(*idle_helper_
, OnIdlePeriodStarted()).Times(AnyNumber());
755 idle_task_runner_
->PostIdleTask(
756 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
758 // Make sure Idle tasks don't run until the delay has occurred.
759 idle_helper_
->EnableLongIdlePeriod();
761 EXPECT_EQ(0, run_count
);
763 clock_
->Advance(halfDelay
);
765 EXPECT_EQ(0, run_count
);
767 // Delay is finished, idle task should run.
768 clock_
->Advance(halfDelay
);
770 EXPECT_EQ(1, run_count
);
773 TEST_F(IdleHelperTest
, TestLongIdlePeriodImmediatelyRestartsIfMaxDeadline
) {
774 std::vector
<base::TimeTicks
> actual_deadlines
;
777 base::TimeTicks
clock_before(clock_
->NowTicks());
778 base::TimeDelta
idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
780 // The second idle period should happen immediately after the first the
781 // they have max deadlines.
782 max_idle_task_reposts
= 2;
783 idle_task_runner_
->PostIdleTask(
784 FROM_HERE
, base::Bind(&RepostingUpdateClockIdleTestTask
,
785 idle_task_runner_
, &run_count
, clock_
.get(),
786 idle_task_runtime
, &actual_deadlines
));
788 idle_helper_
->EnableLongIdlePeriod();
790 EXPECT_EQ(2, run_count
);
793 testing::ElementsAre(
794 clock_before
+ maximum_idle_period_duration(),
795 clock_before
+ idle_task_runtime
+ maximum_idle_period_duration()));
798 TEST_F(IdleHelperTest
, TestLongIdlePeriodRestartWaitsIfNotMaxDeadline
) {
799 base::TimeTicks actual_deadline
;
802 base::TimeDelta
pending_task_delay(base::TimeDelta::FromMilliseconds(20));
803 base::TimeDelta
idle_task_duration(base::TimeDelta::FromMilliseconds(10));
804 base::TimeTicks
expected_deadline(clock_
->NowTicks() + pending_task_delay
+
805 maximum_idle_period_duration() +
806 retry_enable_long_idle_period_delay());
808 // Post delayed task to ensure idle period doesn't have a max deadline.
809 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
812 max_idle_task_reposts
= 2;
813 idle_task_runner_
->PostIdleTask(
814 FROM_HERE
, base::Bind(&RepostingIdleTestTask
, idle_task_runner_
,
815 &run_count
, &actual_deadline
));
816 idle_helper_
->EnableLongIdlePeriod();
818 EXPECT_EQ(1, run_count
);
819 clock_
->Advance(idle_task_duration
);
821 // Next idle period shouldn't happen until the pending task has been run.
823 EXPECT_EQ(1, run_count
);
825 // Once the pending task is run the new idle period should start.
826 clock_
->Advance(pending_task_delay
- idle_task_duration
);
828 // Since the idle period tried to start before the pending task ran we have to
829 // wait for the idle helper to retry starting the long idle period.
830 clock_
->Advance(retry_enable_long_idle_period_delay());
833 EXPECT_EQ(2, run_count
);
834 EXPECT_EQ(expected_deadline
, actual_deadline
);
837 TEST_F(IdleHelperTest
, TestLongIdlePeriodPaused
) {
838 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
839 std::vector
<base::TimeTicks
> actual_deadlines
;
842 // If there are no idle tasks posted we should start in the paused state.
843 idle_helper_
->EnableLongIdlePeriod();
844 CheckIdlePeriodStateIs("in_long_idle_period_paused");
845 // There shouldn't be any delayed tasks posted by the idle helper when paused.
846 EXPECT_EQ(base::TimeTicks(),
847 scheduler_helper_
->NextPendingDelayedTaskRunTime());
849 // Posting a task should transition us to the an active state.
850 max_idle_task_reposts
= 2;
851 base::TimeTicks
clock_before(clock_
->NowTicks());
852 base::TimeDelta
idle_task_runtime(base::TimeDelta::FromMilliseconds(10));
853 idle_task_runner_
->PostIdleTask(
854 FROM_HERE
, base::Bind(&RepostingUpdateClockIdleTestTask
,
855 idle_task_runner_
, &run_count
, clock_
.get(),
856 idle_task_runtime
, &actual_deadlines
));
858 EXPECT_EQ(2, run_count
);
861 testing::ElementsAre(
862 clock_before
+ maximum_idle_period_duration(),
863 clock_before
+ idle_task_runtime
+ maximum_idle_period_duration()));
865 // Once all task have been run we should go back to the paused state.
866 CheckIdlePeriodStateIs("in_long_idle_period_paused");
867 EXPECT_EQ(base::TimeTicks(),
868 scheduler_helper_
->NextPendingDelayedTaskRunTime());
870 idle_helper_
->EndIdlePeriod();
871 CheckIdlePeriodStateIs("not_in_idle_period");
874 TEST_F(IdleHelperTest
, TestLongIdlePeriodWhenShutdown
) {
875 base::TimeTicks deadline_in_task
;
878 idle_task_runner_
->PostIdleTask(
879 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
880 scheduler_helper_
->Shutdown();
882 // We shouldn't be able to enter a long idle period when shutdown
883 idle_helper_
->EnableLongIdlePeriod();
885 CheckIdlePeriodStateIs("not_in_idle_period");
886 EXPECT_EQ(0, run_count
);
889 void TestCanExceedIdleDeadlineIfRequiredTask(IdleHelperForTest
* idle_helper
,
890 bool* can_exceed_idle_deadline_out
,
892 base::TimeTicks deadline
) {
893 *can_exceed_idle_deadline_out
=
894 idle_helper
->CanExceedIdleDeadlineIfRequired();
898 TEST_F(IdleHelperTest
, CanExceedIdleDeadlineIfRequired
) {
900 bool can_exceed_idle_deadline
= false;
902 // Should return false if not in an idle period.
903 EXPECT_FALSE(idle_helper_
->CanExceedIdleDeadlineIfRequired());
905 // Should return false for short idle periods.
906 idle_task_runner_
->PostIdleTask(
908 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask
, idle_helper_
.get(),
909 &can_exceed_idle_deadline
, &run_count
));
910 idle_helper_
->StartIdlePeriod(
911 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
912 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(10));
914 EXPECT_EQ(1, run_count
);
915 EXPECT_FALSE(can_exceed_idle_deadline
);
917 // Should return false for a long idle period which is shortened due to a
918 // pending delayed task.
919 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
920 base::TimeDelta::FromMilliseconds(10));
921 idle_task_runner_
->PostIdleTask(
923 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask
, idle_helper_
.get(),
924 &can_exceed_idle_deadline
, &run_count
));
925 idle_helper_
->EnableLongIdlePeriod();
927 EXPECT_EQ(2, run_count
);
928 EXPECT_FALSE(can_exceed_idle_deadline
);
930 // Next long idle period will be for the maximum time, so
931 // CanExceedIdleDeadlineIfRequired should return true.
932 clock_
->Advance(maximum_idle_period_duration());
933 idle_task_runner_
->PostIdleTask(
935 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask
, idle_helper_
.get(),
936 &can_exceed_idle_deadline
, &run_count
));
938 EXPECT_EQ(3, run_count
);
939 EXPECT_TRUE(can_exceed_idle_deadline
);
942 class IdleHelperWithQuiescencePeriodTest
: public BaseIdleHelperTest
{
945 kQuiescenceDelayMs
= 100,
946 kLongIdlePeriodMs
= 50,
949 IdleHelperWithQuiescencePeriodTest()
950 : BaseIdleHelperTest(
952 base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs
)) {}
954 ~IdleHelperWithQuiescencePeriodTest() override
{}
956 void SetUp() override
{
957 EXPECT_CALL(*idle_helper_
, OnIdlePeriodStarted()).Times(AnyNumber());
958 EXPECT_CALL(*idle_helper_
, OnIdlePeriodEnded()).Times(AnyNumber());
959 EXPECT_CALL(*idle_helper_
, CanEnterLongIdlePeriod(_
, _
))
961 .WillRepeatedly(Return(true));
962 EXPECT_CALL(*idle_helper_
, IsNotQuiescent()).Times(AnyNumber());
965 void MakeNonQuiescent() {
966 // Run an arbitrary task so we're deemed to be not quiescent.
967 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(NullTask
));
972 DISALLOW_COPY_AND_ASSIGN(IdleHelperWithQuiescencePeriodTest
);
975 class IdleHelperWithQuiescencePeriodTestWithIdlePeriodObserver
:
976 public IdleHelperWithQuiescencePeriodTest
{
979 IdleHelperWithQuiescencePeriodTestWithIdlePeriodObserver()
980 : IdleHelperWithQuiescencePeriodTest() {}
982 ~IdleHelperWithQuiescencePeriodTestWithIdlePeriodObserver() override
{}
984 void SetUp() override
{
985 // Don't set expectations on IdleHelper::Delegate.
989 DISALLOW_COPY_AND_ASSIGN(
990 IdleHelperWithQuiescencePeriodTestWithIdlePeriodObserver
);
994 TEST_F(IdleHelperWithQuiescencePeriodTest
,
995 LongIdlePeriodStartsImmediatelyIfQuiescent
) {
996 base::TimeTicks actual_deadline
;
998 max_idle_task_reposts
= 1;
999 idle_task_runner_
->PostIdleTask(
1000 FROM_HERE
, base::Bind(&RepostingIdleTestTask
, idle_task_runner_
,
1001 &run_count
, &actual_deadline
));
1003 idle_helper_
->EnableLongIdlePeriod();
1006 EXPECT_EQ(1, run_count
);
1009 TEST_F(IdleHelperWithQuiescencePeriodTestWithIdlePeriodObserver
,
1010 LongIdlePeriodDoesNotStartsImmediatelyIfBusy
) {
1012 EXPECT_CALL(*idle_helper_
, OnIdlePeriodStarted()).Times(0);
1013 EXPECT_CALL(*idle_helper_
, OnIdlePeriodEnded()).Times(0);
1014 EXPECT_CALL(*idle_helper_
, CanEnterLongIdlePeriod(_
, _
)).Times(0);
1015 EXPECT_CALL(*idle_helper_
, IsNotQuiescent()).Times(AtLeast(1));
1017 base::TimeTicks actual_deadline
;
1019 max_idle_task_reposts
= 1;
1020 idle_task_runner_
->PostIdleTask(
1021 FROM_HERE
, base::Bind(&RepostingIdleTestTask
, idle_task_runner_
,
1022 &run_count
, &actual_deadline
));
1024 idle_helper_
->EnableLongIdlePeriod();
1027 EXPECT_EQ(0, run_count
);
1029 scheduler_helper_
->Shutdown();
1032 TEST_F(IdleHelperWithQuiescencePeriodTest
,
1033 LongIdlePeriodStartsAfterQuiescence
) {
1035 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
1037 // Run a repeating task so we're deemed to be busy for the next 400ms.
1038 default_task_runner_
->PostTask(
1040 base::Bind(&RepeatingTask
, base::Unretained(default_task_runner_
.get()),
1041 10, base::TimeDelta::FromMilliseconds(40)));
1044 // In this scenario EnableLongIdlePeriod deems us not to be quiescent 5x in
1046 base::TimeTicks expected_deadline
=
1047 clock_
->NowTicks() + base::TimeDelta::FromMilliseconds(
1048 5 * kQuiescenceDelayMs
+ kLongIdlePeriodMs
);
1049 base::TimeTicks deadline_in_task
;
1050 idle_task_runner_
->PostIdleTask(
1051 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
1053 idle_helper_
->EnableLongIdlePeriod();
1055 EXPECT_EQ(1, run_count
);
1056 EXPECT_EQ(expected_deadline
, deadline_in_task
);
1059 TEST_F(IdleHelperWithQuiescencePeriodTest
,
1060 QuescienceCheckedForAfterLongIdlePeriodEnds
) {
1061 mock_task_runner_
->SetAutoAdvanceNowToPendingTasks(true);
1063 idle_task_runner_
->PostIdleTask(FROM_HERE
, base::Bind(&NullIdleTask
));
1064 idle_helper_
->EnableLongIdlePeriod();
1067 // Post a normal task to make the scheduler non-quiescent.
1068 default_task_runner_
->PostTask(FROM_HERE
, base::Bind(&NullTask
));
1071 // Post an idle task. The idle task won't run initially because the system is
1072 // not judged to be quiescent, but should be run after the quiescence delay.
1074 base::TimeTicks deadline_in_task
;
1075 base::TimeTicks expected_deadline
=
1076 clock_
->NowTicks() +
1077 base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs
+ kLongIdlePeriodMs
);
1078 idle_task_runner_
->PostIdleTask(
1079 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
1080 idle_helper_
->EnableLongIdlePeriod();
1083 EXPECT_EQ(1, run_count
);
1084 EXPECT_EQ(expected_deadline
, deadline_in_task
);
1087 TEST_F(IdleHelperTest
, NoShortIdlePeriodWhenDeadlineTooClose
) {
1089 base::TimeTicks deadline_in_task
;
1091 idle_task_runner_
->PostIdleTask(
1092 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
1094 base::TimeDelta
half_a_ms(base::TimeDelta::FromMicroseconds(50));
1095 base::TimeTicks
less_than_min_deadline(
1096 clock_
->NowTicks() + minimum_idle_period_duration() - half_a_ms
);
1097 base::TimeTicks
more_than_min_deadline(
1098 clock_
->NowTicks() + minimum_idle_period_duration() + half_a_ms
);
1100 idle_helper_
->StartIdlePeriod(
1101 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
1102 less_than_min_deadline
);
1104 EXPECT_EQ(0, run_count
);
1106 idle_helper_
->StartIdlePeriod(
1107 IdleHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD
, clock_
->NowTicks(),
1108 more_than_min_deadline
);
1110 EXPECT_EQ(1, run_count
);
1113 TEST_F(IdleHelperTest
, NoLongIdlePeriodWhenDeadlineTooClose
) {
1115 base::TimeTicks deadline_in_task
;
1117 base::TimeDelta
half_a_ms(base::TimeDelta::FromMicroseconds(50));
1118 base::TimeDelta
less_than_min_deadline_duration(
1119 minimum_idle_period_duration() - half_a_ms
);
1120 base::TimeDelta
more_than_min_deadline_duration(
1121 minimum_idle_period_duration() + half_a_ms
);
1123 idle_task_runner_
->PostIdleTask(
1124 FROM_HERE
, base::Bind(&IdleTestTask
, &run_count
, &deadline_in_task
));
1125 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
1126 less_than_min_deadline_duration
);
1128 idle_helper_
->EnableLongIdlePeriod();
1130 EXPECT_EQ(0, run_count
);
1132 idle_helper_
->EndIdlePeriod();
1133 clock_
->Advance(maximum_idle_period_duration());
1135 EXPECT_EQ(0, run_count
);
1137 default_task_runner_
->PostDelayedTask(FROM_HERE
, base::Bind(&NullTask
),
1138 more_than_min_deadline_duration
);
1139 idle_helper_
->EnableLongIdlePeriod();
1141 EXPECT_EQ(1, run_count
);
1144 } // namespace scheduler