Add an UMA stat to be able to see if the User pods are show on start screen,
[chromium-blink-merge.git] / content / child / scheduler / scheduler_helper_unittest.cc
blobe2d19d75b11d36158bc4935be781d8b9670e8846
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"
14 using testing::_;
15 using testing::Invoke;
16 using testing::Return;
18 namespace content {
20 namespace {
21 void AppendToVectorTestTask(std::vector<std::string>* vector,
22 std::string value) {
23 vector->push_back(value);
26 void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
27 std::string value,
28 base::TimeTicks deadline) {
29 AppendToVectorTestTask(vector, value);
32 void NullTask() {
35 void AppendToVectorReentrantTask(
36 base::SingleThreadTaskRunner* task_runner,
37 std::vector<int>* vector,
38 int* reentrant_count,
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) {
55 (*run_count)++;
56 *deadline_out = deadline;
59 int max_idle_task_reposts = 2;
61 void RepostingIdleTestTask(
62 SingleThreadIdleTaskRunner* idle_task_runner,
63 int* run_count,
64 base::TimeTicks deadline) {
65 if ((*run_count + 1) < max_idle_task_reposts) {
66 idle_task_runner->PostIdleTask(
67 FROM_HERE,
68 base::Bind(&RepostingIdleTestTask,
69 base::Unretained(idle_task_runner), run_count));
71 (*run_count)++;
74 void UpdateClockToDeadlineIdleTestTask(
75 scoped_refptr<cc::TestNowSource> clock,
76 base::SingleThreadTaskRunner* task_runner,
77 int* run_count,
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));
85 (*run_count)++;
89 }; // namespace
91 class SchedulerHelperForTest : public SchedulerHelper,
92 public SchedulerHelper::SchedulerHelperDelegate {
93 public:
94 explicit SchedulerHelperForTest(
95 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
96 : SchedulerHelper(main_task_runner,
97 this,
98 "test.scheduler",
99 TRACE_DISABLED_BY_DEFAULT("test.scheduler"),
100 TASK_QUEUE_COUNT) {}
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 {
116 public:
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()) {
147 } else {
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();
157 else
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
165 // - 'I': Idle 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()) {
170 std::string task;
171 stream >> task;
172 switch (task[0]) {
173 case 'D':
174 default_task_runner_->PostTask(
175 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
176 break;
177 case 'I':
178 idle_task_runner_->PostIdleTask(
179 FROM_HERE,
180 base::Bind(&AppendToVectorIdleTestTask, run_order, task));
181 break;
182 default:
183 NOTREACHED();
188 protected:
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);
197 return 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");
217 RunUntilIdle();
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) {
224 int count = 0;
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));
229 RunUntilIdle();
231 EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4));
234 TEST_F(SchedulerHelperTest, TestPostIdleTask) {
235 int run_count = 0;
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));
244 RunUntilIdle();
245 EXPECT_EQ(0, run_count);
247 scheduler_helper_->StartIdlePeriod(
248 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
249 clock_->Now(),
250 expected_deadline,
251 true);
252 RunUntilIdle();
253 EXPECT_EQ(1, run_count);
254 EXPECT_EQ(expected_deadline, deadline_in_task);
257 TEST_F(SchedulerHelperTest, TestPostIdleTask_EndIdlePeriod) {
258 int run_count = 0;
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));
265 RunUntilIdle();
266 EXPECT_EQ(0, run_count);
268 scheduler_helper_->StartIdlePeriod(
269 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
270 clock_->Now(),
271 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
272 true);
273 scheduler_helper_->EndIdlePeriod();
274 RunUntilIdle();
275 EXPECT_EQ(0, run_count);
278 TEST_F(SchedulerHelperTest, TestRepostingIdleTask) {
279 int run_count = 0;
281 max_idle_task_reposts = 2;
282 idle_task_runner_->PostIdleTask(
283 FROM_HERE,
284 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
285 scheduler_helper_->StartIdlePeriod(
286 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
287 clock_->Now(),
288 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
289 true);
290 RunUntilIdle();
291 EXPECT_EQ(1, run_count);
293 // Reposted tasks shouldn't run until next idle period.
294 RunUntilIdle();
295 EXPECT_EQ(1, run_count);
297 scheduler_helper_->StartIdlePeriod(
298 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
299 clock_->Now(),
300 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
301 true);
302 RunUntilIdle();
303 EXPECT_EQ(2, run_count);
306 TEST_F(SchedulerHelperTest, TestIdleTaskExceedsDeadline) {
307 int run_count = 0;
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,
319 clock_->Now(),
320 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
321 true);
322 RunUntilIdle();
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,
329 clock_->Now(),
330 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
331 true);
332 RunUntilIdle();
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;
339 int run_count = 0;
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,
346 clock_->Now(),
347 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
348 true);
349 RunUntilIdle();
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,
358 clock_->Now(),
359 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
360 true);
361 RunUntilIdle();
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));
367 RunUntilIdle();
368 // Must start a new idle period before idle task runs.
369 scheduler_helper_->StartIdlePeriod(
370 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
371 clock_->Now(),
372 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
373 true);
374 RunUntilIdle();
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;
381 int run_count = 0;
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));
387 RunUntilIdle();
388 // Must start a new idle period before idle task runs.
389 scheduler_helper_->StartIdlePeriod(
390 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
391 clock_->Now(),
392 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
393 true);
394 RunUntilIdle();
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;
401 int run_count = 0;
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,
410 clock_->Now(),
411 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
412 true);
413 RunUntilIdle();
414 // Must start a new idle period before after-wakeup idle task runs.
415 scheduler_helper_->StartIdlePeriod(
416 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
417 clock_->Now(),
418 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
419 true);
420 RunUntilIdle();
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(_, _))
431 .Times(2)
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.
440 EXPECT_GT(
441 task_queue_manager->NextPendingDelayedTaskRunTime(), base::TimeTicks());
443 RunUntilIdle();
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(_, _))
457 .Times(1)
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.
466 EXPECT_GT(
467 task_queue_manager->NextPendingDelayedTaskRunTime(), base::TimeTicks());
469 scheduler_helper_->EndIdlePeriod();
470 RunUntilIdle();
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 {
479 public:
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) {
488 if (pair.second) {
489 idle_task_runner_->PostIdleTask(FROM_HERE, pair.first);
490 } else {
491 idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first);
494 scheduler_helper_->StartIdlePeriod(
495 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
496 clock_->Now(),
497 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
498 true);
499 message_loop_->RunUntilIdle();
502 private:
503 DISALLOW_COPY_AND_ASSIGN(SchedulerHelperWithMessageLoopTest);
506 TEST_F(SchedulerHelperWithMessageLoopTest,
507 NonNestableIdleTaskDoesntExecuteInNestedLoop) {
508 std::vector<std::string> order;
509 idle_task_runner_->PostIdleTask(
510 FROM_HERE,
511 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1")));
512 idle_task_runner_->PostIdleTask(
513 FROM_HERE,
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")),
520 false));
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(
527 FROM_HERE,
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,
534 clock_->Now(),
535 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
536 true);
537 RunUntilIdle();
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"),
541 std::string("3")));
544 TEST_F(SchedulerHelperTest, TestLongIdlePeriod) {
545 base::TimeTicks expected_deadline =
546 clock_->Now() + maximum_idle_period_duration();
547 base::TimeTicks deadline_in_task;
548 int run_count = 0;
550 idle_task_runner_->PostIdleTask(
551 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
553 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
554 .Times(2)
555 .WillRepeatedly(Return(true));
557 RunUntilIdle();
558 EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period.
560 scheduler_helper_->InitiateLongIdlePeriod();
561 RunUntilIdle();
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;
570 int run_count = 0;
572 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
573 .Times(2)
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),
579 pending_task_delay);
581 scheduler_helper_->InitiateLongIdlePeriod();
582 RunUntilIdle();
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;
590 int run_count = 0;
592 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
593 .Times(3)
594 .WillRepeatedly(Return(true));
596 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
597 pending_task_delay);
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();
607 RunUntilIdle();
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());
612 RunUntilIdle();
613 EXPECT_EQ(1, run_count);
616 TEST_F(SchedulerHelperTest, TestLongIdlePeriodRepeating) {
617 int run_count = 0;
619 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
620 .Times(2)
621 .WillRepeatedly(Return(true));
623 max_idle_task_reposts = 3;
624 idle_task_runner_->PostIdleTask(
625 FROM_HERE,
626 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
628 scheduler_helper_->InitiateLongIdlePeriod();
629 RunUntilIdle();
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
633 // gets run.
634 clock_->AdvanceNow(maximum_idle_period_duration());
635 RunUntilIdle();
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();
642 RunUntilIdle();
643 EXPECT_EQ(2, run_count);
646 TEST_F(SchedulerHelperTest, TestLongIdlePeriodDoesNotWakeScheduler) {
647 base::TimeTicks deadline_in_task;
648 int run_count = 0;
650 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
651 .Times(3)
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
659 // idle period.
660 base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
661 clock_->AdvanceNow(maximum_idle_period_duration());
662 RunUntilIdle();
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));
672 RunUntilIdle();
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));
679 RunUntilIdle();
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;
692 int run_count = 0;
694 ON_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
695 .WillByDefault(Invoke([delay, delayOver](
696 base::TimeTicks now,
697 base::TimeDelta* next_long_idle_period_delay_out) {
698 if (now >= delayOver)
699 return true;
700 *next_long_idle_period_delay_out = delay;
701 return false;
702 }));
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();
711 RunUntilIdle();
712 EXPECT_EQ(0, run_count);
714 clock_->AdvanceNow(halfDelay);
715 RunUntilIdle();
716 EXPECT_EQ(0, run_count);
718 // Delay is finished, idle task should run.
719 clock_->AdvanceNow(halfDelay);
720 RunUntilIdle();
721 EXPECT_EQ(1, run_count);
724 void TestCanExceedIdleDeadlineIfRequiredTask(SchedulerHelperForTest* scheduler,
725 bool* can_exceed_idle_deadline_out,
726 int* run_count,
727 base::TimeTicks deadline) {
728 *can_exceed_idle_deadline_out = scheduler->CanExceedIdleDeadlineIfRequired();
729 (*run_count)++;
732 TEST_F(SchedulerHelperTest, CanExceedIdleDeadlineIfRequired) {
733 int run_count = 0;
734 bool can_exceed_idle_deadline = false;
736 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
737 .Times(3)
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,
747 &run_count));
748 scheduler_helper_->StartIdlePeriod(
749 SchedulerHelper::IdlePeriodState::IN_SHORT_IDLE_PERIOD,
750 clock_->Now(),
751 clock_->Now() + base::TimeDelta::FromMilliseconds(10),
752 true);
753 RunUntilIdle();
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,
764 &run_count));
765 scheduler_helper_->InitiateLongIdlePeriod();
766 RunUntilIdle();
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,
776 &run_count));
777 RunUntilIdle();
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