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/task_queue_manager.h"
7 #include "base/threading/thread.h"
8 #include "cc/test/ordered_simple_task_runner.h"
9 #include "cc/test/test_now_source.h"
10 #include "content/child/scheduler/nestable_task_runner_for_test.h"
11 #include "content/child/scheduler/scheduler_message_loop_delegate.h"
12 #include "content/child/scheduler/task_queue_selector.h"
13 #include "testing/gmock/include/gmock/gmock.h"
15 using testing::ElementsAre
;
21 class SelectorForTest
: public TaskQueueSelector
{
23 ~SelectorForTest() override
{}
25 virtual void AppendQueueToService(size_t queue_index
) = 0;
27 virtual const std::vector
<const base::TaskQueue
*>& work_queues() = 0;
29 void AsValueInto(base::trace_event::TracedValue
* state
) const override
{}
32 // Always selects queue 0.
33 class AutomaticSelectorForTest
: public SelectorForTest
{
35 AutomaticSelectorForTest() {}
36 ~AutomaticSelectorForTest() override
{}
38 void RegisterWorkQueues(
39 const std::vector
<const base::TaskQueue
*>& work_queues
) override
{
40 work_queues_
= work_queues
;
43 bool SelectWorkQueueToService(size_t* out_queue_index
) override
{
44 for (size_t i
= 0; i
< work_queues_
.size(); i
++) {
45 if (!work_queues_
[i
]->empty()) {
53 void AppendQueueToService(size_t queue_index
) override
{
54 DCHECK(false) << "Not supported";
57 const std::vector
<const base::TaskQueue
*>& work_queues() override
{
62 std::vector
<const base::TaskQueue
*> work_queues_
;
64 DISALLOW_COPY_AND_ASSIGN(AutomaticSelectorForTest
);
67 class ExplicitSelectorForTest
: public SelectorForTest
{
69 ExplicitSelectorForTest() {}
70 ~ExplicitSelectorForTest() override
{}
72 void RegisterWorkQueues(
73 const std::vector
<const base::TaskQueue
*>& work_queues
) override
{
74 work_queues_
= work_queues
;
77 bool SelectWorkQueueToService(size_t* out_queue_index
) override
{
78 if (queues_to_service_
.empty())
80 *out_queue_index
= queues_to_service_
.front();
81 queues_to_service_
.pop_front();
85 void AppendQueueToService(size_t queue_index
) override
{
86 queues_to_service_
.push_back(queue_index
);
89 const std::vector
<const base::TaskQueue
*>& work_queues() override
{
94 std::deque
<size_t> queues_to_service_
;
95 std::vector
<const base::TaskQueue
*> work_queues_
;
97 DISALLOW_COPY_AND_ASSIGN(ExplicitSelectorForTest
);
100 class TaskQueueManagerTest
: public testing::Test
{
102 enum class SelectorType
{
107 void Initialize(size_t num_queues
, SelectorType type
) {
108 now_src_
= cc::TestNowSource::Create(1000);
110 make_scoped_refptr(new cc::OrderedSimpleTaskRunner(now_src_
, false));
111 selector_
= make_scoped_ptr(createSelectorForTest(type
));
112 manager_
= make_scoped_ptr(new TaskQueueManager(
113 num_queues
, NestableTaskRunnerForTest::Create(test_task_runner_
.get()),
114 selector_
.get(), "test.scheduler"));
115 manager_
->SetTimeSourceForTesting(now_src_
);
117 EXPECT_EQ(num_queues
, selector_
->work_queues().size());
120 void InitializeWithRealMessageLoop(size_t num_queues
, SelectorType type
) {
121 message_loop_
.reset(new base::MessageLoop());
122 selector_
= make_scoped_ptr(createSelectorForTest(type
));
123 manager_
= make_scoped_ptr(new TaskQueueManager(
124 num_queues
, SchedulerMessageLoopDelegate::Create(message_loop_
.get()),
125 selector_
.get(), "test.scheduler"));
126 EXPECT_EQ(num_queues
, selector_
->work_queues().size());
129 SelectorForTest
* createSelectorForTest(SelectorType type
) {
131 case SelectorType::Automatic
:
132 return new AutomaticSelectorForTest();
134 case SelectorType::Explicit
:
135 return new ExplicitSelectorForTest();
141 scoped_refptr
<cc::TestNowSource
> now_src_
;
142 scoped_refptr
<cc::OrderedSimpleTaskRunner
> test_task_runner_
;
143 scoped_ptr
<SelectorForTest
> selector_
;
144 scoped_ptr
<TaskQueueManager
> manager_
;
145 scoped_ptr
<base::MessageLoop
> message_loop_
;
148 void PostFromNestedRunloop(base::MessageLoop
* message_loop
,
149 base::SingleThreadTaskRunner
* runner
,
150 std::vector
<std::pair
<base::Closure
, bool>>* tasks
) {
151 base::MessageLoop::ScopedNestableTaskAllower
allow(message_loop
);
152 for (std::pair
<base::Closure
, bool>& pair
: *tasks
) {
154 runner
->PostTask(FROM_HERE
, pair
.first
);
156 runner
->PostNonNestableTask(FROM_HERE
, pair
.first
);
159 message_loop
->RunUntilIdle();
162 void TestTask(int value
, std::vector
<int>* out_result
) {
163 out_result
->push_back(value
);
166 TEST_F(TaskQueueManagerTest
, SingleQueuePosting
) {
167 Initialize(1u, SelectorType::Automatic
);
169 std::vector
<int> run_order
;
170 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
171 manager_
->TaskRunnerForQueue(0);
173 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
174 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
175 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
177 test_task_runner_
->RunUntilIdle();
178 EXPECT_THAT(run_order
, ElementsAre(1, 2, 3));
181 TEST_F(TaskQueueManagerTest
, MultiQueuePosting
) {
182 Initialize(3u, SelectorType::Explicit
);
184 std::vector
<int> run_order
;
185 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[3] = {
186 manager_
->TaskRunnerForQueue(0),
187 manager_
->TaskRunnerForQueue(1),
188 manager_
->TaskRunnerForQueue(2)};
190 selector_
->AppendQueueToService(0);
191 selector_
->AppendQueueToService(1);
192 selector_
->AppendQueueToService(2);
193 selector_
->AppendQueueToService(0);
194 selector_
->AppendQueueToService(1);
195 selector_
->AppendQueueToService(2);
197 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
198 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
199 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
200 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 4, &run_order
));
201 runners
[2]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 5, &run_order
));
202 runners
[2]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 6, &run_order
));
204 test_task_runner_
->RunUntilIdle();
205 EXPECT_THAT(run_order
, ElementsAre(1, 3, 5, 2, 4, 6));
211 TEST_F(TaskQueueManagerTest
, NowNotCalledWhenThereAreNoDelayedTasks
) {
212 Initialize(3u, SelectorType::Explicit
);
214 scoped_refptr
<cc::TestNowSource
> now_src
= cc::TestNowSource::Create(1000);
215 manager_
->SetTimeSourceForTesting(now_src
);
217 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[3] = {
218 manager_
->TaskRunnerForQueue(0),
219 manager_
->TaskRunnerForQueue(1),
220 manager_
->TaskRunnerForQueue(2)};
222 selector_
->AppendQueueToService(0);
223 selector_
->AppendQueueToService(1);
224 selector_
->AppendQueueToService(2);
225 selector_
->AppendQueueToService(0);
226 selector_
->AppendQueueToService(1);
227 selector_
->AppendQueueToService(2);
229 runners
[0]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
230 runners
[0]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
231 runners
[1]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
232 runners
[1]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
233 runners
[2]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
234 runners
[2]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
236 test_task_runner_
->RunUntilIdle();
238 EXPECT_EQ(0, now_src
->NumNowCalls());
241 TEST_F(TaskQueueManagerTest
, NonNestableTaskPosting
) {
242 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
244 std::vector
<int> run_order
;
245 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
246 manager_
->TaskRunnerForQueue(0);
248 runner
->PostNonNestableTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
250 message_loop_
->RunUntilIdle();
251 EXPECT_THAT(run_order
, ElementsAre(1));
254 TEST_F(TaskQueueManagerTest
, NonNestableTaskExecutesInExpectedOrder
) {
255 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
257 std::vector
<int> run_order
;
258 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
259 manager_
->TaskRunnerForQueue(0);
261 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
262 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
263 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
264 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 4, &run_order
));
265 runner
->PostNonNestableTask(FROM_HERE
, base::Bind(&TestTask
, 5, &run_order
));
267 message_loop_
->RunUntilIdle();
268 EXPECT_THAT(run_order
, ElementsAre(1, 2, 3, 4, 5));
271 TEST_F(TaskQueueManagerTest
, NonNestableTaskDoesntExecuteInNestedLoop
) {
272 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
274 std::vector
<int> run_order
;
275 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
276 manager_
->TaskRunnerForQueue(0);
278 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
279 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
281 std::vector
<std::pair
<base::Closure
, bool>> tasks_to_post_from_nested_loop
;
282 tasks_to_post_from_nested_loop
.push_back(
283 std::make_pair(base::Bind(&TestTask
, 3, &run_order
), false));
284 tasks_to_post_from_nested_loop
.push_back(
285 std::make_pair(base::Bind(&TestTask
, 4, &run_order
), true));
286 tasks_to_post_from_nested_loop
.push_back(
287 std::make_pair(base::Bind(&TestTask
, 5, &run_order
), true));
290 FROM_HERE
, base::Bind(&PostFromNestedRunloop
, message_loop_
.get(), runner
,
291 base::Unretained(&tasks_to_post_from_nested_loop
)));
293 message_loop_
->RunUntilIdle();
294 // Note we expect task 3 to run last because it's non-nestable.
295 EXPECT_THAT(run_order
, ElementsAre(1, 2, 4, 5, 3));
298 TEST_F(TaskQueueManagerTest
, QueuePolling
) {
299 Initialize(1u, SelectorType::Automatic
);
301 std::vector
<int> run_order
;
302 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
303 manager_
->TaskRunnerForQueue(0);
305 EXPECT_TRUE(manager_
->IsQueueEmpty(0));
306 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
307 EXPECT_FALSE(manager_
->IsQueueEmpty(0));
309 test_task_runner_
->RunUntilIdle();
310 EXPECT_TRUE(manager_
->IsQueueEmpty(0));
313 TEST_F(TaskQueueManagerTest
, DelayedTaskPosting
) {
314 Initialize(1u, SelectorType::Automatic
);
316 std::vector
<int> run_order
;
317 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
318 manager_
->TaskRunnerForQueue(0);
320 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
321 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
323 EXPECT_EQ(delay
, test_task_runner_
->DelayToNextTaskTime());
324 EXPECT_TRUE(manager_
->IsQueueEmpty(0));
325 EXPECT_TRUE(run_order
.empty());
327 // The task doesn't run before the delay has completed.
328 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(9));
329 EXPECT_TRUE(run_order
.empty());
331 // After the delay has completed, the task runs normally.
332 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
333 EXPECT_THAT(run_order
, ElementsAre(1));
336 TEST_F(TaskQueueManagerTest
, DelayedTaskPosting_MultipleTasks_DecendingOrder
) {
337 Initialize(1u, SelectorType::Automatic
);
339 std::vector
<int> run_order
;
340 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
341 manager_
->TaskRunnerForQueue(0);
343 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
344 base::TimeDelta::FromMilliseconds(10));
346 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
),
347 base::TimeDelta::FromMilliseconds(8));
349 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
),
350 base::TimeDelta::FromMilliseconds(5));
352 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
353 test_task_runner_
->DelayToNextTaskTime());
355 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
356 EXPECT_THAT(run_order
, ElementsAre(3));
357 EXPECT_EQ(base::TimeDelta::FromMilliseconds(3),
358 test_task_runner_
->DelayToNextTaskTime());
360 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(3));
361 EXPECT_THAT(run_order
, ElementsAre(3, 2));
362 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2),
363 test_task_runner_
->DelayToNextTaskTime());
365 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(2));
366 EXPECT_THAT(run_order
, ElementsAre(3, 2, 1));
369 TEST_F(TaskQueueManagerTest
, DelayedTaskPosting_MultipleTasks_AscendingOrder
) {
370 Initialize(1u, SelectorType::Automatic
);
372 std::vector
<int> run_order
;
373 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
374 manager_
->TaskRunnerForQueue(0);
376 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
377 base::TimeDelta::FromMilliseconds(1));
379 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
),
380 base::TimeDelta::FromMilliseconds(5));
382 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
),
383 base::TimeDelta::FromMilliseconds(10));
385 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
386 test_task_runner_
->DelayToNextTaskTime());
388 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
389 EXPECT_THAT(run_order
, ElementsAre(1));
390 EXPECT_EQ(base::TimeDelta::FromMilliseconds(4),
391 test_task_runner_
->DelayToNextTaskTime());
393 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(4));
394 EXPECT_THAT(run_order
, ElementsAre(1, 2));
395 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
396 test_task_runner_
->DelayToNextTaskTime());
398 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
399 EXPECT_THAT(run_order
, ElementsAre(1, 2, 3));
402 TEST_F(TaskQueueManagerTest
, PostDelayedTask_SharesUnderlyingDelayedTasks
) {
403 Initialize(1u, SelectorType::Automatic
);
405 std::vector
<int> run_order
;
406 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
407 manager_
->TaskRunnerForQueue(0);
409 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
410 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
412 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
),
414 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
),
417 EXPECT_EQ(1u, test_task_runner_
->NumPendingTasks());
422 ~TestObject() { destructor_count_
++; }
424 void Run() { FAIL() << "TestObject::Run should not be called"; }
426 static int destructor_count_
;
429 int TestObject::destructor_count_
= 0;
431 TEST_F(TaskQueueManagerTest
, PendingDelayedTasksRemovedOnShutdown
) {
432 Initialize(1u, SelectorType::Automatic
);
434 TestObject::destructor_count_
= 0;
436 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
437 manager_
->TaskRunnerForQueue(0);
439 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
440 runner
->PostDelayedTask(
441 FROM_HERE
, base::Bind(&TestObject::Run
, base::Owned(new TestObject())),
444 FROM_HERE
, base::Bind(&TestObject::Run
, base::Owned(new TestObject())));
448 EXPECT_EQ(2, TestObject::destructor_count_
);
451 TEST_F(TaskQueueManagerTest
, ManualPumping
) {
452 Initialize(1u, SelectorType::Automatic
);
453 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
455 std::vector
<int> run_order
;
456 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
457 manager_
->TaskRunnerForQueue(0);
459 // Posting a task when pumping is disabled doesn't result in work getting
461 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
462 EXPECT_FALSE(test_task_runner_
->HasPendingTasks());
464 // However polling still works.
465 EXPECT_FALSE(manager_
->IsQueueEmpty(0));
467 // After pumping the task runs normally.
468 manager_
->PumpQueue(0);
469 EXPECT_TRUE(test_task_runner_
->HasPendingTasks());
470 test_task_runner_
->RunUntilIdle();
471 EXPECT_THAT(run_order
, ElementsAre(1));
474 TEST_F(TaskQueueManagerTest
, ManualPumpingToggle
) {
475 Initialize(1u, SelectorType::Automatic
);
476 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
478 std::vector
<int> run_order
;
479 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
480 manager_
->TaskRunnerForQueue(0);
482 // Posting a task when pumping is disabled doesn't result in work getting
484 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
485 EXPECT_FALSE(test_task_runner_
->HasPendingTasks());
487 // When pumping is enabled the task runs normally.
488 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AUTO
);
489 EXPECT_TRUE(test_task_runner_
->HasPendingTasks());
490 test_task_runner_
->RunUntilIdle();
491 EXPECT_THAT(run_order
, ElementsAre(1));
494 TEST_F(TaskQueueManagerTest
, DenyRunning
) {
495 Initialize(1u, SelectorType::Explicit
);
497 std::vector
<int> run_order
;
498 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
499 manager_
->TaskRunnerForQueue(0);
500 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
502 // Since we haven't appended a work queue to be selected, the task doesn't
504 test_task_runner_
->RunUntilIdle();
505 EXPECT_TRUE(run_order
.empty());
507 // Pumping the queue again with a selected work queue runs the task.
508 manager_
->PumpQueue(0);
509 selector_
->AppendQueueToService(0);
510 test_task_runner_
->RunUntilIdle();
511 EXPECT_THAT(run_order
, ElementsAre(1));
514 TEST_F(TaskQueueManagerTest
, ManualPumpingWithDelayedTask
) {
515 Initialize(1u, SelectorType::Automatic
);
516 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
518 std::vector
<int> run_order
;
519 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
520 manager_
->TaskRunnerForQueue(0);
522 // Posting a delayed task when pumping will apply the delay, but won't cause
523 // work to executed afterwards.
524 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
525 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
528 // After pumping but before the delay period has expired, task does not run.
529 manager_
->PumpQueue(0);
530 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
531 EXPECT_TRUE(run_order
.empty());
533 // Once the delay has expired, pumping causes the task to run.
534 now_src_
->AdvanceNow(base::TimeDelta::FromMilliseconds(5));
535 manager_
->PumpQueue(0);
536 EXPECT_TRUE(test_task_runner_
->HasPendingTasks());
537 test_task_runner_
->RunPendingTasks();
538 EXPECT_THAT(run_order
, ElementsAre(1));
541 TEST_F(TaskQueueManagerTest
, ManualPumpingWithMultipleDelayedTasks
) {
542 Initialize(1u, SelectorType::Automatic
);
543 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
545 std::vector
<int> run_order
;
546 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
547 manager_
->TaskRunnerForQueue(0);
549 // Posting a delayed task when pumping will apply the delay, but won't cause
550 // work to executed afterwards.
551 base::TimeDelta
delay1(base::TimeDelta::FromMilliseconds(1));
552 base::TimeDelta
delay2(base::TimeDelta::FromMilliseconds(10));
553 base::TimeDelta
delay3(base::TimeDelta::FromMilliseconds(20));
554 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
556 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
),
558 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
),
561 now_src_
->AdvanceNow(base::TimeDelta::FromMilliseconds(15));
562 test_task_runner_
->RunUntilIdle();
563 EXPECT_TRUE(run_order
.empty());
565 // Once the delay has expired, pumping causes the task to run.
566 manager_
->PumpQueue(0);
567 test_task_runner_
->RunUntilIdle();
568 EXPECT_THAT(run_order
, ElementsAre(1, 2));
571 TEST_F(TaskQueueManagerTest
, DelayedTasksDontAutoRunWithManualPumping
) {
572 Initialize(1u, SelectorType::Automatic
);
573 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
575 std::vector
<int> run_order
;
576 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
577 manager_
->TaskRunnerForQueue(0);
579 base::TimeDelta
delay(base::TimeDelta::FromMilliseconds(10));
580 runner
->PostDelayedTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
),
583 test_task_runner_
->RunForPeriod(base::TimeDelta::FromMilliseconds(10));
584 EXPECT_TRUE(run_order
.empty());
587 TEST_F(TaskQueueManagerTest
, ManualPumpingWithNonEmptyWorkQueue
) {
588 Initialize(1u, SelectorType::Automatic
);
589 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL
);
591 std::vector
<int> run_order
;
592 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
593 manager_
->TaskRunnerForQueue(0);
595 // Posting two tasks and pumping twice should result in two tasks in the work
597 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
598 manager_
->PumpQueue(0);
599 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
600 manager_
->PumpQueue(0);
602 EXPECT_EQ(2u, selector_
->work_queues()[0]->size());
605 void ReentrantTestTask(scoped_refptr
<base::SingleThreadTaskRunner
> runner
,
607 std::vector
<int>* out_result
) {
608 out_result
->push_back(countdown
);
610 runner
->PostTask(FROM_HERE
,
611 Bind(&ReentrantTestTask
, runner
, countdown
, out_result
));
615 TEST_F(TaskQueueManagerTest
, ReentrantPosting
) {
616 Initialize(1u, SelectorType::Automatic
);
618 std::vector
<int> run_order
;
619 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
620 manager_
->TaskRunnerForQueue(0);
622 runner
->PostTask(FROM_HERE
, Bind(&ReentrantTestTask
, runner
, 3, &run_order
));
624 test_task_runner_
->RunUntilIdle();
625 EXPECT_THAT(run_order
, ElementsAre(3, 2, 1));
628 TEST_F(TaskQueueManagerTest
, NoTasksAfterShutdown
) {
629 Initialize(1u, SelectorType::Automatic
);
631 std::vector
<int> run_order
;
632 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
633 manager_
->TaskRunnerForQueue(0);
635 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
638 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
640 test_task_runner_
->RunUntilIdle();
641 EXPECT_TRUE(run_order
.empty());
644 void PostTaskToRunner(scoped_refptr
<base::SingleThreadTaskRunner
> runner
,
645 std::vector
<int>* run_order
) {
646 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, run_order
));
649 TEST_F(TaskQueueManagerTest
, PostFromThread
) {
650 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
652 std::vector
<int> run_order
;
653 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
654 manager_
->TaskRunnerForQueue(0);
656 base::Thread
thread("TestThread");
658 thread
.message_loop()->PostTask(
659 FROM_HERE
, base::Bind(&PostTaskToRunner
, runner
, &run_order
));
662 message_loop_
->RunUntilIdle();
663 EXPECT_THAT(run_order
, ElementsAre(1));
666 void RePostingTestTask(scoped_refptr
<base::SingleThreadTaskRunner
> runner
,
669 runner
->PostTask(FROM_HERE
, Bind(&RePostingTestTask
,
670 base::Unretained(runner
.get()), run_count
));
673 TEST_F(TaskQueueManagerTest
, DoWorkCantPostItselfMultipleTimes
) {
674 Initialize(1u, SelectorType::Automatic
);
675 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
676 manager_
->TaskRunnerForQueue(0);
679 runner
->PostTask(FROM_HERE
,
680 base::Bind(&RePostingTestTask
, runner
, &run_count
));
682 test_task_runner_
->RunPendingTasks();
683 // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there
684 // will be two tasks here.
685 EXPECT_EQ(1u, test_task_runner_
->NumPendingTasks());
686 EXPECT_EQ(1, run_count
);
689 TEST_F(TaskQueueManagerTest
, PostFromNestedRunloop
) {
690 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
692 std::vector
<int> run_order
;
693 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
694 manager_
->TaskRunnerForQueue(0);
696 std::vector
<std::pair
<base::Closure
, bool>> tasks_to_post_from_nested_loop
;
697 tasks_to_post_from_nested_loop
.push_back(
698 std::make_pair(base::Bind(&TestTask
, 1, &run_order
), true));
700 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 0, &run_order
));
702 FROM_HERE
, base::Bind(&PostFromNestedRunloop
, message_loop_
.get(), runner
,
703 base::Unretained(&tasks_to_post_from_nested_loop
)));
704 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
706 message_loop_
->RunUntilIdle();
708 EXPECT_THAT(run_order
, ElementsAre(0, 2, 1));
711 TEST_F(TaskQueueManagerTest
, WorkBatching
) {
712 Initialize(1u, SelectorType::Automatic
);
714 manager_
->SetWorkBatchSize(2);
716 std::vector
<int> run_order
;
717 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
718 manager_
->TaskRunnerForQueue(0);
720 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
721 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
722 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
723 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 4, &run_order
));
725 // Running one task in the host message loop should cause two posted tasks to
727 EXPECT_EQ(test_task_runner_
->NumPendingTasks(), 1u);
728 test_task_runner_
->RunPendingTasks();
729 EXPECT_THAT(run_order
, ElementsAre(1, 2));
731 // The second task runs the remaining two posted tasks.
732 EXPECT_EQ(test_task_runner_
->NumPendingTasks(), 1u);
733 test_task_runner_
->RunPendingTasks();
734 EXPECT_THAT(run_order
, ElementsAre(1, 2, 3, 4));
737 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeup
) {
738 Initialize(2u, SelectorType::Explicit
);
739 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
741 std::vector
<int> run_order
;
742 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
743 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
745 selector_
->AppendQueueToService(1);
746 selector_
->AppendQueueToService(0);
747 selector_
->AppendQueueToService(0);
749 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
750 test_task_runner_
->RunUntilIdle();
751 EXPECT_TRUE(run_order
.empty()); // Shouldn't run - no other task to wake TQM.
753 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
754 test_task_runner_
->RunUntilIdle();
755 EXPECT_TRUE(run_order
.empty()); // Still shouldn't wake TQM.
757 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
758 test_task_runner_
->RunUntilIdle();
759 // Executing a task on an auto pumped queue should wake the TQM.
760 EXPECT_THAT(run_order
, ElementsAre(3, 1, 2));
763 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupWhenAlreadyAwake
) {
764 Initialize(2u, SelectorType::Explicit
);
765 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
767 std::vector
<int> run_order
;
768 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
769 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
771 selector_
->AppendQueueToService(1);
772 selector_
->AppendQueueToService(0);
774 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
775 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
776 test_task_runner_
->RunUntilIdle();
777 EXPECT_THAT(run_order
, ElementsAre(2, 1)); // TQM was already awake.
780 TEST_F(TaskQueueManagerTest
,
781 AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue
) {
782 Initialize(2u, SelectorType::Explicit
);
783 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
784 manager_
->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL
);
786 std::vector
<int> run_order
;
787 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
788 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
790 selector_
->AppendQueueToService(1);
791 selector_
->AppendQueueToService(0);
793 runners
[0]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
794 test_task_runner_
->RunUntilIdle();
795 EXPECT_TRUE(run_order
.empty()); // Shouldn't run - no other task to wake TQM.
797 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
798 test_task_runner_
->RunUntilIdle();
799 // This still shouldn't wake TQM as manual queue was not pumped.
800 EXPECT_TRUE(run_order
.empty());
802 manager_
->PumpQueue(1);
803 test_task_runner_
->RunUntilIdle();
804 // Executing a task on an auto pumped queue should wake the TQM.
805 EXPECT_THAT(run_order
, ElementsAre(2, 1));
808 void TestPostingTask(scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
,
809 base::Closure task
) {
810 task_runner
->PostTask(FROM_HERE
, task
);
813 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupFromTask
) {
814 Initialize(2u, SelectorType::Explicit
);
815 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
817 std::vector
<int> run_order
;
818 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
819 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
821 selector_
->AppendQueueToService(1);
822 selector_
->AppendQueueToService(1);
823 selector_
->AppendQueueToService(0);
825 // Check that a task which posts a task to an auto pump after wakeup queue
826 // doesn't cause the queue to wake up.
827 base::Closure after_wakeup_task
= base::Bind(&TestTask
, 1, &run_order
);
828 runners
[1]->PostTask(
829 FROM_HERE
, base::Bind(&TestPostingTask
, runners
[0], after_wakeup_task
));
830 test_task_runner_
->RunUntilIdle();
831 EXPECT_TRUE(run_order
.empty());
833 // Wake up the queue.
834 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
835 test_task_runner_
->RunUntilIdle();
836 EXPECT_THAT(run_order
, ElementsAre(2, 1));
839 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupFromMultipleTasks
) {
840 Initialize(2u, SelectorType::Explicit
);
841 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
843 std::vector
<int> run_order
;
844 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
845 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
847 selector_
->AppendQueueToService(1);
848 selector_
->AppendQueueToService(1);
849 selector_
->AppendQueueToService(1);
850 selector_
->AppendQueueToService(0);
851 selector_
->AppendQueueToService(0);
853 // Check that a task which posts a task to an auto pump after wakeup queue
854 // doesn't cause the queue to wake up.
855 base::Closure after_wakeup_task_1
= base::Bind(&TestTask
, 1, &run_order
);
856 base::Closure after_wakeup_task_2
= base::Bind(&TestTask
, 2, &run_order
);
857 runners
[1]->PostTask(
858 FROM_HERE
, base::Bind(&TestPostingTask
, runners
[0], after_wakeup_task_1
));
859 runners
[1]->PostTask(
860 FROM_HERE
, base::Bind(&TestPostingTask
, runners
[0], after_wakeup_task_2
));
861 test_task_runner_
->RunUntilIdle();
862 EXPECT_TRUE(run_order
.empty());
864 // Wake up the queue.
865 runners
[1]->PostTask(FROM_HERE
, base::Bind(&TestTask
, 3, &run_order
));
866 test_task_runner_
->RunUntilIdle();
867 EXPECT_THAT(run_order
, ElementsAre(3, 1, 2));
870 TEST_F(TaskQueueManagerTest
, AutoPumpAfterWakeupBecomesQuiescent
) {
871 Initialize(2u, SelectorType::Explicit
);
872 manager_
->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP
);
875 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
876 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
878 selector_
->AppendQueueToService(1);
879 selector_
->AppendQueueToService(0);
880 selector_
->AppendQueueToService(0);
881 // Append extra service queue '0' entries to the selector otherwise test will
882 // finish even if the RePostingTestTask woke each other up.
883 selector_
->AppendQueueToService(0);
884 selector_
->AppendQueueToService(0);
886 // Check that if multiple tasks reposts themselves onto a pump-after-wakeup
887 // queue they don't wake each other and will eventually stop when no other
889 runners
[0]->PostTask(FROM_HERE
,
890 base::Bind(&RePostingTestTask
, runners
[0], &run_count
));
891 runners
[0]->PostTask(FROM_HERE
,
892 base::Bind(&RePostingTestTask
, runners
[0], &run_count
));
893 runners
[1]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
894 test_task_runner_
->RunUntilIdle();
895 // The reposting tasks posted to the after wakeup queue shouldn't have woken
897 EXPECT_EQ(2, run_count
);
900 class MockTaskObserver
: public base::MessageLoop::TaskObserver
{
902 MOCK_METHOD1(DidProcessTask
, void(const base::PendingTask
& task
));
903 MOCK_METHOD1(WillProcessTask
, void(const base::PendingTask
& task
));
906 TEST_F(TaskQueueManagerTest
, TaskObserverAdding
) {
907 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
908 MockTaskObserver observer
;
910 manager_
->SetWorkBatchSize(2);
911 manager_
->AddTaskObserver(&observer
);
913 std::vector
<int> run_order
;
914 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
915 manager_
->TaskRunnerForQueue(0);
917 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
918 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 2, &run_order
));
920 // Two pairs of callbacks for the tasks above plus another one for the
921 // DoWork() posted by the task queue manager.
922 EXPECT_CALL(observer
, WillProcessTask(_
)).Times(3);
923 EXPECT_CALL(observer
, DidProcessTask(_
)).Times(3);
924 message_loop_
->RunUntilIdle();
927 TEST_F(TaskQueueManagerTest
, TaskObserverRemoving
) {
928 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
929 MockTaskObserver observer
;
930 manager_
->SetWorkBatchSize(2);
931 manager_
->AddTaskObserver(&observer
);
932 manager_
->RemoveTaskObserver(&observer
);
934 std::vector
<int> run_order
;
935 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
936 manager_
->TaskRunnerForQueue(0);
938 runner
->PostTask(FROM_HERE
, base::Bind(&TestTask
, 1, &run_order
));
940 EXPECT_CALL(observer
, WillProcessTask(_
)).Times(0);
941 EXPECT_CALL(observer
, DidProcessTask(_
)).Times(0);
943 message_loop_
->RunUntilIdle();
946 void RemoveObserverTask(TaskQueueManager
* manager
,
947 base::MessageLoop::TaskObserver
* observer
) {
948 manager
->RemoveTaskObserver(observer
);
951 TEST_F(TaskQueueManagerTest
, TaskObserverRemovingInsideTask
) {
952 InitializeWithRealMessageLoop(1u, SelectorType::Automatic
);
953 MockTaskObserver observer
;
954 manager_
->SetWorkBatchSize(3);
955 manager_
->AddTaskObserver(&observer
);
957 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
958 manager_
->TaskRunnerForQueue(0);
959 runner
->PostTask(FROM_HERE
,
960 base::Bind(&RemoveObserverTask
, manager_
.get(), &observer
));
962 EXPECT_CALL(observer
, WillProcessTask(_
)).Times(1);
963 EXPECT_CALL(observer
, DidProcessTask(_
)).Times(0);
964 message_loop_
->RunUntilIdle();
967 TEST_F(TaskQueueManagerTest
, ThreadCheckAfterTermination
) {
968 Initialize(1u, SelectorType::Automatic
);
969 scoped_refptr
<base::SingleThreadTaskRunner
> runner
=
970 manager_
->TaskRunnerForQueue(0);
971 EXPECT_TRUE(runner
->RunsTasksOnCurrentThread());
973 EXPECT_TRUE(runner
->RunsTasksOnCurrentThread());
976 TEST_F(TaskQueueManagerTest
, NextPendingDelayedTaskRunTime
) {
977 scoped_refptr
<cc::TestNowSource
> clock(cc::TestNowSource::Create());
978 Initialize(2u, SelectorType::Explicit
);
979 manager_
->SetTimeSourceForTesting(clock
);
981 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[2] = {
982 manager_
->TaskRunnerForQueue(0), manager_
->TaskRunnerForQueue(1)};
984 // With no delayed tasks.
985 EXPECT_TRUE(manager_
->NextPendingDelayedTaskRunTime().is_null());
987 // With a non-delayed task.
988 runners
[0]->PostTask(FROM_HERE
, base::Bind(&NopTask
));
989 EXPECT_TRUE(manager_
->NextPendingDelayedTaskRunTime().is_null());
991 // With a delayed task.
992 base::TimeDelta expected_delay
= base::TimeDelta::FromMilliseconds(50);
993 runners
[0]->PostDelayedTask(FROM_HERE
, base::Bind(&NopTask
), expected_delay
);
994 EXPECT_EQ(clock
->Now() + expected_delay
,
995 manager_
->NextPendingDelayedTaskRunTime());
997 // With another delayed task in the same queue with a longer delay.
998 runners
[0]->PostDelayedTask(FROM_HERE
, base::Bind(&NopTask
),
999 base::TimeDelta::FromMilliseconds(100));
1000 EXPECT_EQ(clock
->Now() + expected_delay
,
1001 manager_
->NextPendingDelayedTaskRunTime());
1003 // With another delayed task in the same queue with a shorter delay.
1004 expected_delay
= base::TimeDelta::FromMilliseconds(20);
1005 runners
[0]->PostDelayedTask(FROM_HERE
, base::Bind(&NopTask
), expected_delay
);
1006 EXPECT_EQ(clock
->Now() + expected_delay
,
1007 manager_
->NextPendingDelayedTaskRunTime());
1009 // With another delayed task in a different queue with a shorter delay.
1010 expected_delay
= base::TimeDelta::FromMilliseconds(10);
1011 runners
[1]->PostDelayedTask(FROM_HERE
, base::Bind(&NopTask
), expected_delay
);
1012 EXPECT_EQ(clock
->Now() + expected_delay
,
1013 manager_
->NextPendingDelayedTaskRunTime());
1015 // Test it updates as time progresses
1016 clock
->AdvanceNow(expected_delay
);
1017 EXPECT_EQ(clock
->Now(), manager_
->NextPendingDelayedTaskRunTime());
1020 TEST_F(TaskQueueManagerTest
, NextPendingDelayedTaskRunTime_MultipleQueues
) {
1021 Initialize(3u, SelectorType::Automatic
);
1023 scoped_refptr
<base::SingleThreadTaskRunner
> runners
[3] = {
1024 manager_
->TaskRunnerForQueue(0),
1025 manager_
->TaskRunnerForQueue(1),
1026 manager_
->TaskRunnerForQueue(2)};
1028 base::TimeDelta delay1
= base::TimeDelta::FromMilliseconds(50);
1029 base::TimeDelta delay2
= base::TimeDelta::FromMilliseconds(5);
1030 base::TimeDelta delay3
= base::TimeDelta::FromMilliseconds(10);
1031 runners
[0]->PostDelayedTask(FROM_HERE
, base::Bind(&NopTask
), delay1
);
1032 runners
[1]->PostDelayedTask(FROM_HERE
, base::Bind(&NopTask
), delay2
);
1033 runners
[2]->PostDelayedTask(FROM_HERE
, base::Bind(&NopTask
), delay3
);
1035 EXPECT_EQ(now_src_
->Now() + delay2
,
1036 manager_
->NextPendingDelayedTaskRunTime());
1040 } // namespace content