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

Side by Side Diff: components/scheduler/base/task_queue_manager_unittest.cc

Issue 2118903002: scheduler: Move the Blink scheduler into Blink (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Another GYP fix Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "components/scheduler/base/task_queue_manager.h"
6
7 #include <stddef.h>
8
9 #include <utility>
10
11 #include "base/location.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/memory/ref_counted_memory.h"
14 #include "base/run_loop.h"
15 #include "base/single_thread_task_runner.h"
16 #include "base/test/simple_test_tick_clock.h"
17 #include "base/test/trace_event_analyzer.h"
18 #include "base/threading/thread.h"
19 #include "base/trace_event/blame_context.h"
20 #include "base/trace_event/trace_buffer.h"
21 #include "cc/test/ordered_simple_task_runner.h"
22 #include "components/scheduler/base/real_time_domain.h"
23 #include "components/scheduler/base/task_queue_impl.h"
24 #include "components/scheduler/base/task_queue_manager_delegate_for_test.h"
25 #include "components/scheduler/base/task_queue_selector.h"
26 #include "components/scheduler/base/test_count_uses_time_source.h"
27 #include "components/scheduler/base/test_task_time_tracker.h"
28 #include "components/scheduler/base/test_time_source.h"
29 #include "components/scheduler/base/virtual_time_domain.h"
30 #include "components/scheduler/base/work_queue.h"
31 #include "components/scheduler/base/work_queue_sets.h"
32 #include "testing/gmock/include/gmock/gmock.h"
33
34 using testing::ElementsAre;
35 using testing::ElementsAreArray;
36 using testing::_;
37 using scheduler::internal::EnqueueOrder;
38
39 namespace scheduler {
40
41 class MessageLoopTaskRunner : public TaskQueueManagerDelegateForTest {
42 public:
43 static scoped_refptr<MessageLoopTaskRunner> Create(
44 std::unique_ptr<base::TickClock> tick_clock) {
45 return make_scoped_refptr(new MessageLoopTaskRunner(std::move(tick_clock)));
46 }
47
48 // NestableTaskRunner implementation.
49 bool IsNested() const override {
50 return base::MessageLoop::current()->IsNested();
51 }
52
53 private:
54 explicit MessageLoopTaskRunner(std::unique_ptr<base::TickClock> tick_clock)
55 : TaskQueueManagerDelegateForTest(
56 base::MessageLoop::current()->task_runner(),
57 std::move(tick_clock)) {}
58 ~MessageLoopTaskRunner() override {}
59 };
60
61 class TaskQueueManagerTest : public testing::Test {
62 public:
63 TaskQueueManagerTest() {}
64 void DeleteTaskQueueManager() { manager_.reset(); }
65
66 protected:
67 void InitializeWithClock(size_t num_queues,
68 std::unique_ptr<base::TickClock> test_time_source) {
69 test_task_runner_ = make_scoped_refptr(
70 new cc::OrderedSimpleTaskRunner(now_src_.get(), false));
71 main_task_runner_ = TaskQueueManagerDelegateForTest::Create(
72 test_task_runner_.get(),
73 base::WrapUnique(new TestTimeSource(now_src_.get())));
74
75 manager_ = base::WrapUnique(new TaskQueueManager(
76 main_task_runner_, "test.scheduler", "test.scheduler",
77 "test.scheduler.debug"));
78 manager_->SetTaskTimeTracker(&test_task_time_tracker_);
79
80 for (size_t i = 0; i < num_queues; i++)
81 runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
82 }
83
84 void Initialize(size_t num_queues) {
85 now_src_.reset(new base::SimpleTestTickClock());
86 now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
87 InitializeWithClock(num_queues,
88 base::WrapUnique(new TestTimeSource(now_src_.get())));
89 }
90
91 void InitializeWithRealMessageLoop(size_t num_queues) {
92 now_src_.reset(new base::SimpleTestTickClock());
93 message_loop_.reset(new base::MessageLoop());
94 // A null clock triggers some assertions.
95 now_src_->Advance(base::TimeDelta::FromMicroseconds(1000));
96 manager_ = base::WrapUnique(new TaskQueueManager(
97 MessageLoopTaskRunner::Create(
98 base::WrapUnique(new TestTimeSource(now_src_.get()))),
99 "test.scheduler", "test.scheduler", "test.scheduler.debug"));
100 manager_->SetTaskTimeTracker(&test_task_time_tracker_);
101
102 for (size_t i = 0; i < num_queues; i++)
103 runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
104 }
105
106 std::unique_ptr<base::MessageLoop> message_loop_;
107 std::unique_ptr<base::SimpleTestTickClock> now_src_;
108 scoped_refptr<TaskQueueManagerDelegateForTest> main_task_runner_;
109 scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_;
110 std::unique_ptr<TaskQueueManager> manager_;
111 std::vector<scoped_refptr<internal::TaskQueueImpl>> runners_;
112 TestTaskTimeTracker test_task_time_tracker_;
113 };
114
115 void PostFromNestedRunloop(base::MessageLoop* message_loop,
116 base::SingleThreadTaskRunner* runner,
117 std::vector<std::pair<base::Closure, bool>>* tasks) {
118 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
119 for (std::pair<base::Closure, bool>& pair : *tasks) {
120 if (pair.second) {
121 runner->PostTask(FROM_HERE, pair.first);
122 } else {
123 runner->PostNonNestableTask(FROM_HERE, pair.first);
124 }
125 }
126 base::RunLoop().RunUntilIdle();
127 }
128
129 void NopTask() {}
130
131 TEST_F(TaskQueueManagerTest,
132 NowCalledMinimumNumberOfTimesToComputeTaskDurations) {
133 message_loop_.reset(new base::MessageLoop());
134 // This memory is managed by the TaskQueueManager, but we need to hold a
135 // pointer to this object to read out how many times Now was called.
136 TestCountUsesTimeSource* test_count_uses_time_source =
137 new TestCountUsesTimeSource();
138
139 manager_ = base::WrapUnique(new TaskQueueManager(
140 MessageLoopTaskRunner::Create(
141 base::WrapUnique(test_count_uses_time_source)),
142 "test.scheduler", "test.scheduler", "test.scheduler.debug"));
143 manager_->SetWorkBatchSize(6);
144 manager_->SetTaskTimeTracker(&test_task_time_tracker_);
145
146 for (size_t i = 0; i < 3; i++)
147 runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
148
149 runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
150 runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
151 runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
152 runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
153 runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
154 runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask));
155
156 message_loop_->RunUntilIdle();
157 // We need to call Now for the beginning of the first task, and then the end
158 // of every task after. We reuse the end time of one task for the start time
159 // of the next task. In this case, there were 6 tasks, so we expect 7 calls to
160 // Now.
161 EXPECT_EQ(7, test_count_uses_time_source->now_calls_count());
162 }
163
164 TEST_F(TaskQueueManagerTest,
165 NowNotCalledForNestedTasks) {
166 message_loop_.reset(new base::MessageLoop());
167 // This memory is managed by the TaskQueueManager, but we need to hold a
168 // pointer to this object to read out how many times Now was called.
169 TestCountUsesTimeSource* test_count_uses_time_source =
170 new TestCountUsesTimeSource();
171
172 manager_ = base::WrapUnique(new TaskQueueManager(
173 MessageLoopTaskRunner::Create(
174 base::WrapUnique(test_count_uses_time_source)),
175 "test.scheduler", "test.scheduler", "test.scheduler.debug"));
176 manager_->SetTaskTimeTracker(&test_task_time_tracker_);
177
178 runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue")));
179
180 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
181 for (int i = 0; i <= 6; ++i) {
182 tasks_to_post_from_nested_loop.push_back(
183 std::make_pair(base::Bind(&NopTask), true));
184 }
185
186 runners_[0]->PostTask(
187 FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(),
188 base::RetainedRef(runners_[0]),
189 base::Unretained(&tasks_to_post_from_nested_loop)));
190
191 message_loop_->RunUntilIdle();
192 // We need to call Now twice, to measure the start and end of the outermost
193 // task. We shouldn't call it for any of the nested tasks.
194 EXPECT_EQ(2, test_count_uses_time_source->now_calls_count());
195 }
196
197 void NullTask() {}
198
199 void TestTask(EnqueueOrder value, std::vector<EnqueueOrder>* out_result) {
200 out_result->push_back(value);
201 }
202
203 TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
204 Initialize(1u);
205
206 std::vector<EnqueueOrder> run_order;
207 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
208 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
209 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
210
211 test_task_runner_->RunUntilIdle();
212 EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
213 }
214
215 TEST_F(TaskQueueManagerTest, MultiQueuePosting) {
216 Initialize(3u);
217
218 std::vector<EnqueueOrder> run_order;
219 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
220 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
221 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
222 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
223 runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order));
224 runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order));
225
226 test_task_runner_->RunUntilIdle();
227 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5, 6));
228 }
229
230 TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) {
231 InitializeWithRealMessageLoop(1u);
232
233 std::vector<EnqueueOrder> run_order;
234 runners_[0]->PostNonNestableTask(FROM_HERE,
235 base::Bind(&TestTask, 1, &run_order));
236
237 message_loop_->RunUntilIdle();
238 EXPECT_THAT(run_order, ElementsAre(1));
239 }
240
241 TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) {
242 InitializeWithRealMessageLoop(1u);
243
244 std::vector<EnqueueOrder> run_order;
245 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
246 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
247 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
248 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
249 runners_[0]->PostNonNestableTask(FROM_HERE,
250 base::Bind(&TestTask, 5, &run_order));
251
252 message_loop_->RunUntilIdle();
253 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5));
254 }
255
256 TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) {
257 InitializeWithRealMessageLoop(1u);
258
259 std::vector<EnqueueOrder> run_order;
260 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
261 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
262
263 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
264 tasks_to_post_from_nested_loop.push_back(
265 std::make_pair(base::Bind(&TestTask, 3, &run_order), false));
266 tasks_to_post_from_nested_loop.push_back(
267 std::make_pair(base::Bind(&TestTask, 4, &run_order), true));
268 tasks_to_post_from_nested_loop.push_back(
269 std::make_pair(base::Bind(&TestTask, 5, &run_order), true));
270
271 runners_[0]->PostTask(
272 FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(),
273 base::RetainedRef(runners_[0]),
274 base::Unretained(&tasks_to_post_from_nested_loop)));
275
276 message_loop_->RunUntilIdle();
277 // Note we expect task 3 to run last because it's non-nestable.
278 EXPECT_THAT(run_order, ElementsAre(1, 2, 4, 5, 3));
279 }
280
281 TEST_F(TaskQueueManagerTest, QueuePolling) {
282 Initialize(1u);
283
284 std::vector<EnqueueOrder> run_order;
285 EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
286 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
287 EXPECT_TRUE(runners_[0]->HasPendingImmediateWork());
288
289 test_task_runner_->RunUntilIdle();
290 EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
291 }
292
293 TEST_F(TaskQueueManagerTest, DelayedTaskPosting) {
294 Initialize(1u);
295
296 std::vector<EnqueueOrder> run_order;
297 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
298 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
299 delay);
300 EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime());
301 EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
302 EXPECT_TRUE(run_order.empty());
303
304 // The task doesn't run before the delay has completed.
305 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9));
306 EXPECT_TRUE(run_order.empty());
307
308 // After the delay has completed, the task runs normally.
309 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
310 EXPECT_THAT(run_order, ElementsAre(1));
311 EXPECT_FALSE(runners_[0]->HasPendingImmediateWork());
312 }
313
314 bool MessageLoopTaskCounter(size_t* count) {
315 *count = *count + 1;
316 return true;
317 }
318
319 TEST_F(TaskQueueManagerTest, DelayedTaskExecutedInOneMessageLoopTask) {
320 Initialize(1u);
321
322 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
323 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay);
324
325 size_t task_count = 0;
326 test_task_runner_->RunTasksWhile(
327 base::Bind(&MessageLoopTaskCounter, &task_count));
328 EXPECT_EQ(1u, task_count);
329 }
330
331 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) {
332 Initialize(1u);
333
334 std::vector<EnqueueOrder> run_order;
335 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
336 base::TimeDelta::FromMilliseconds(10));
337
338 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
339 base::TimeDelta::FromMilliseconds(8));
340
341 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
342 base::TimeDelta::FromMilliseconds(5));
343
344 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
345 test_task_runner_->DelayToNextTaskTime());
346
347 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
348 EXPECT_THAT(run_order, ElementsAre(3));
349 EXPECT_EQ(base::TimeDelta::FromMilliseconds(3),
350 test_task_runner_->DelayToNextTaskTime());
351
352 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3));
353 EXPECT_THAT(run_order, ElementsAre(3, 2));
354 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2),
355 test_task_runner_->DelayToNextTaskTime());
356
357 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2));
358 EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
359 }
360
361 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) {
362 Initialize(1u);
363
364 std::vector<EnqueueOrder> run_order;
365 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
366 base::TimeDelta::FromMilliseconds(1));
367
368 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
369 base::TimeDelta::FromMilliseconds(5));
370
371 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
372 base::TimeDelta::FromMilliseconds(10));
373
374 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1),
375 test_task_runner_->DelayToNextTaskTime());
376
377 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1));
378 EXPECT_THAT(run_order, ElementsAre(1));
379 EXPECT_EQ(base::TimeDelta::FromMilliseconds(4),
380 test_task_runner_->DelayToNextTaskTime());
381
382 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4));
383 EXPECT_THAT(run_order, ElementsAre(1, 2));
384 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5),
385 test_task_runner_->DelayToNextTaskTime());
386
387 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
388 EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
389 }
390
391 TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) {
392 Initialize(1u);
393
394 std::vector<EnqueueOrder> run_order;
395 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
396 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
397 delay);
398 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
399 delay);
400 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
401 delay);
402
403 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
404 }
405
406 class TestObject {
407 public:
408 ~TestObject() { destructor_count_++; }
409
410 void Run() { FAIL() << "TestObject::Run should not be called"; }
411
412 static int destructor_count_;
413 };
414
415 int TestObject::destructor_count_ = 0;
416
417 TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) {
418 Initialize(1u);
419
420 TestObject::destructor_count_ = 0;
421
422 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
423 runners_[0]->PostDelayedTask(
424 FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())),
425 delay);
426 runners_[0]->PostTask(
427 FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())));
428
429 manager_.reset();
430
431 EXPECT_EQ(2, TestObject::destructor_count_);
432 }
433
434 TEST_F(TaskQueueManagerTest, ManualPumping) {
435 Initialize(1u);
436 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
437
438 std::vector<EnqueueOrder> run_order;
439 // Posting a task when pumping is disabled doesn't result in work getting
440 // posted.
441 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
442 EXPECT_FALSE(test_task_runner_->HasPendingTasks());
443
444 // However polling still works.
445 EXPECT_TRUE(runners_[0]->HasPendingImmediateWork());
446
447 // After pumping the task runs normally.
448 runners_[0]->PumpQueue(true);
449 EXPECT_TRUE(test_task_runner_->HasPendingTasks());
450 test_task_runner_->RunUntilIdle();
451 EXPECT_THAT(run_order, ElementsAre(1));
452 }
453
454 TEST_F(TaskQueueManagerTest, ManualPumpingToggle) {
455 Initialize(1u);
456 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
457
458 std::vector<EnqueueOrder> run_order;
459 // Posting a task when pumping is disabled doesn't result in work getting
460 // posted.
461 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
462 EXPECT_FALSE(test_task_runner_->HasPendingTasks());
463
464 // When pumping is enabled the task runs normally.
465 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
466 EXPECT_TRUE(test_task_runner_->HasPendingTasks());
467 test_task_runner_->RunUntilIdle();
468 EXPECT_THAT(run_order, ElementsAre(1));
469 }
470
471 TEST_F(TaskQueueManagerTest, DenyRunning_BeforePosting) {
472 Initialize(1u);
473
474 std::vector<EnqueueOrder> run_order;
475 runners_[0]->SetQueueEnabled(false);
476 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
477
478 test_task_runner_->RunUntilIdle();
479 EXPECT_TRUE(run_order.empty());
480
481 runners_[0]->SetQueueEnabled(true);
482 test_task_runner_->RunUntilIdle();
483 EXPECT_THAT(run_order, ElementsAre(1));
484 }
485
486 TEST_F(TaskQueueManagerTest, DenyRunning_AfterPosting) {
487 Initialize(1u);
488
489 std::vector<EnqueueOrder> run_order;
490 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
491 runners_[0]->SetQueueEnabled(false);
492
493 test_task_runner_->RunUntilIdle();
494 EXPECT_TRUE(run_order.empty());
495
496 runners_[0]->SetQueueEnabled(true);
497 test_task_runner_->RunUntilIdle();
498 EXPECT_THAT(run_order, ElementsAre(1));
499 }
500
501 TEST_F(TaskQueueManagerTest, DenyRunning_ManuallyPumpedTransitionsToAuto) {
502 Initialize(1u);
503
504 std::vector<EnqueueOrder> run_order;
505 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
506 runners_[0]->SetQueueEnabled(false);
507 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
508
509 test_task_runner_->RunUntilIdle();
510 EXPECT_TRUE(run_order.empty());
511
512 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
513 runners_[0]->SetQueueEnabled(true);
514 test_task_runner_->RunUntilIdle();
515 EXPECT_THAT(run_order, ElementsAre(1));
516 }
517
518 TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) {
519 Initialize(1u);
520 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
521
522 std::vector<EnqueueOrder> run_order;
523 // Posting a delayed task when pumping will apply the delay, but won't cause
524 // work to executed afterwards.
525 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
526 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
527 delay);
528
529 // After pumping but before the delay period has expired, task does not run.
530 runners_[0]->PumpQueue(true);
531 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5));
532 EXPECT_TRUE(run_order.empty());
533
534 // Once the delay has expired, pumping causes the task to run.
535 now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
536 runners_[0]->PumpQueue(true);
537 EXPECT_TRUE(test_task_runner_->HasPendingTasks());
538 test_task_runner_->RunPendingTasks();
539 EXPECT_THAT(run_order, ElementsAre(1));
540 }
541
542 TEST_F(TaskQueueManagerTest, ManualPumpingWithMultipleDelayedTasks) {
543 Initialize(1u);
544 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
545
546 std::vector<EnqueueOrder> run_order;
547 // Posting a delayed task when pumping will apply the delay, but won't cause
548 // work to executed afterwards.
549 base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1));
550 base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10));
551 base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20));
552 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
553 delay1);
554 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
555 delay2);
556 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
557 delay3);
558
559 now_src_->Advance(base::TimeDelta::FromMilliseconds(15));
560 test_task_runner_->RunUntilIdle();
561 EXPECT_TRUE(run_order.empty());
562
563 // Once the delay has expired, pumping causes the task to run.
564 runners_[0]->PumpQueue(true);
565 test_task_runner_->RunUntilIdle();
566 EXPECT_THAT(run_order, ElementsAre(1, 2));
567 }
568
569 TEST_F(TaskQueueManagerTest, DelayedTasksDontAutoRunWithManualPumping) {
570 Initialize(1u);
571 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
572
573 std::vector<EnqueueOrder> run_order;
574 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
575 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
576 delay);
577
578 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10));
579 EXPECT_TRUE(run_order.empty());
580 }
581
582 TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) {
583 Initialize(1u);
584 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
585
586 std::vector<EnqueueOrder> run_order;
587 // Posting two tasks and pumping twice should result in two tasks in the work
588 // queue.
589 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
590 runners_[0]->PumpQueue(true);
591 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
592 runners_[0]->PumpQueue(true);
593
594 EXPECT_EQ(2u, runners_[0]->immediate_work_queue()->Size());
595 }
596
597 void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
598 int countdown,
599 std::vector<EnqueueOrder>* out_result) {
600 out_result->push_back(countdown);
601 if (--countdown) {
602 runner->PostTask(FROM_HERE,
603 Bind(&ReentrantTestTask, runner, countdown, out_result));
604 }
605 }
606
607 TEST_F(TaskQueueManagerTest, ReentrantPosting) {
608 Initialize(1u);
609
610 std::vector<EnqueueOrder> run_order;
611 runners_[0]->PostTask(FROM_HERE,
612 Bind(&ReentrantTestTask, runners_[0], 3, &run_order));
613
614 test_task_runner_->RunUntilIdle();
615 EXPECT_THAT(run_order, ElementsAre(3, 2, 1));
616 }
617
618 TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) {
619 Initialize(1u);
620
621 std::vector<EnqueueOrder> run_order;
622 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
623 manager_.reset();
624 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
625
626 test_task_runner_->RunUntilIdle();
627 EXPECT_TRUE(run_order.empty());
628 }
629
630 void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner,
631 std::vector<EnqueueOrder>* run_order) {
632 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order));
633 }
634
635 TEST_F(TaskQueueManagerTest, PostFromThread) {
636 InitializeWithRealMessageLoop(1u);
637
638 std::vector<EnqueueOrder> run_order;
639 base::Thread thread("TestThread");
640 thread.Start();
641 thread.task_runner()->PostTask(
642 FROM_HERE, base::Bind(&PostTaskToRunner, runners_[0], &run_order));
643 thread.Stop();
644
645 message_loop_->RunUntilIdle();
646 EXPECT_THAT(run_order, ElementsAre(1));
647 }
648
649 void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
650 int* run_count) {
651 (*run_count)++;
652 runner->PostTask(FROM_HERE, Bind(&RePostingTestTask,
653 base::Unretained(runner.get()), run_count));
654 }
655
656 TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) {
657 Initialize(1u);
658
659 int run_count = 0;
660 runners_[0]->PostTask(
661 FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
662
663 test_task_runner_->RunPendingTasks();
664 // NOTE without the executing_task_ check in MaybeScheduleDoWork there
665 // will be two tasks here.
666 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks());
667 EXPECT_EQ(1, run_count);
668 }
669
670 TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) {
671 InitializeWithRealMessageLoop(1u);
672
673 std::vector<EnqueueOrder> run_order;
674 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
675 tasks_to_post_from_nested_loop.push_back(
676 std::make_pair(base::Bind(&TestTask, 1, &run_order), true));
677
678 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 0, &run_order));
679 runners_[0]->PostTask(
680 FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(),
681 base::RetainedRef(runners_[0]),
682 base::Unretained(&tasks_to_post_from_nested_loop)));
683 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
684
685 message_loop_->RunUntilIdle();
686
687 EXPECT_THAT(run_order, ElementsAre(0, 2, 1));
688 }
689
690 TEST_F(TaskQueueManagerTest, WorkBatching) {
691 Initialize(1u);
692
693 manager_->SetWorkBatchSize(2);
694
695 std::vector<EnqueueOrder> run_order;
696 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
697 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
698 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
699 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
700
701 // Running one task in the host message loop should cause two posted tasks to
702 // get executed.
703 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
704 test_task_runner_->RunPendingTasks();
705 EXPECT_THAT(run_order, ElementsAre(1, 2));
706
707 // The second task runs the remaining two posted tasks.
708 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u);
709 test_task_runner_->RunPendingTasks();
710 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
711 }
712
713 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) {
714 Initialize(2u);
715 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
716
717 std::vector<EnqueueOrder> run_order;
718 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
719 test_task_runner_->RunUntilIdle();
720 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
721
722 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
723 test_task_runner_->RunUntilIdle();
724 EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM.
725
726 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
727 test_task_runner_->RunUntilIdle();
728 // Executing a task on an auto pumped queue should wake the TQM.
729 EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
730 }
731
732 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) {
733 Initialize(2u);
734 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
735
736 std::vector<EnqueueOrder> run_order;
737 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
738 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
739 test_task_runner_->RunUntilIdle();
740 EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake.
741 }
742
743 TEST_F(TaskQueueManagerTest,
744 AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) {
745 Initialize(2u);
746 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
747 runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
748
749 std::vector<EnqueueOrder> run_order;
750 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
751 test_task_runner_->RunUntilIdle();
752 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM.
753
754 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
755 test_task_runner_->RunUntilIdle();
756 // This still shouldn't wake TQM as manual queue was not pumped.
757 EXPECT_TRUE(run_order.empty());
758
759 runners_[1]->PumpQueue(true);
760 test_task_runner_->RunUntilIdle();
761 // Executing a task on an auto pumped queue should wake the TQM.
762 EXPECT_THAT(run_order, ElementsAre(2, 1));
763 }
764
765 void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
766 base::Closure task) {
767 task_runner->PostTask(FROM_HERE, task);
768 }
769
770 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) {
771 Initialize(2u);
772 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
773
774 std::vector<EnqueueOrder> run_order;
775 // Check that a task which posts a task to an auto pump after wakeup queue
776 // doesn't cause the queue to wake up.
777 base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order);
778 runners_[1]->PostTask(
779 FROM_HERE, base::Bind(&TestPostingTask, runners_[0], after_wakeup_task));
780 test_task_runner_->RunUntilIdle();
781 EXPECT_TRUE(run_order.empty());
782
783 // Wake up the queue.
784 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
785 test_task_runner_->RunUntilIdle();
786 EXPECT_THAT(run_order, ElementsAre(2, 1));
787 }
788
789 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) {
790 Initialize(2u);
791 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
792
793 std::vector<EnqueueOrder> run_order;
794 // Check that a task which posts a task to an auto pump after wakeup queue
795 // doesn't cause the queue to wake up.
796 base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order);
797 base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order);
798 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0],
799 after_wakeup_task_1));
800 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0],
801 after_wakeup_task_2));
802 test_task_runner_->RunUntilIdle();
803 EXPECT_TRUE(run_order.empty());
804
805 // Wake up the queue.
806 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
807 test_task_runner_->RunUntilIdle();
808 EXPECT_THAT(run_order, ElementsAre(3, 1, 2));
809 }
810
811 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) {
812 Initialize(2u);
813 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
814
815 int run_count = 0;
816 // Check that if multiple tasks reposts themselves onto a pump-after-wakeup
817 // queue they don't wake each other and will eventually stop when no other
818 // tasks execute.
819 runners_[0]->PostTask(
820 FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
821 runners_[0]->PostTask(
822 FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count));
823 runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask));
824 test_task_runner_->RunUntilIdle();
825 // The reposting tasks posted to the after wakeup queue shouldn't have woken
826 // each other up.
827 EXPECT_EQ(2, run_count);
828 }
829
830 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWithDontWakeQueue) {
831 Initialize(1u);
832
833 scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue(
834 TaskQueue::Spec("test_queue 0")
835 .SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP));
836 scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue(
837 TaskQueue::Spec("test_queue 0")
838 .SetWakeupPolicy(TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES));
839 scoped_refptr<internal::TaskQueueImpl> queue2 = runners_[0];
840
841 std::vector<EnqueueOrder> run_order;
842 queue0->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
843 queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
844 test_task_runner_->RunUntilIdle();
845 // Executing a DONT_WAKE_OTHER_QUEUES queue shouldn't wake the autopump after
846 // wakeup queue.
847 EXPECT_THAT(run_order, ElementsAre(2));
848
849 queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
850 test_task_runner_->RunUntilIdle();
851 // Executing a CAN_WAKE_OTHER_QUEUES queue should wake the autopump after
852 // wakeup queue.
853 EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
854 }
855
856 class MockTaskObserver : public base::MessageLoop::TaskObserver {
857 public:
858 MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task));
859 MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task));
860 };
861
862 TEST_F(TaskQueueManagerTest, TaskObserverAdding) {
863 InitializeWithRealMessageLoop(1u);
864 MockTaskObserver observer;
865
866 manager_->SetWorkBatchSize(2);
867 manager_->AddTaskObserver(&observer);
868
869 std::vector<EnqueueOrder> run_order;
870 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
871 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
872
873 EXPECT_CALL(observer, WillProcessTask(_)).Times(2);
874 EXPECT_CALL(observer, DidProcessTask(_)).Times(2);
875 message_loop_->RunUntilIdle();
876 }
877
878 TEST_F(TaskQueueManagerTest, TaskObserverRemoving) {
879 InitializeWithRealMessageLoop(1u);
880 MockTaskObserver observer;
881 manager_->SetWorkBatchSize(2);
882 manager_->AddTaskObserver(&observer);
883 manager_->RemoveTaskObserver(&observer);
884
885 std::vector<EnqueueOrder> run_order;
886 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
887
888 EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
889 EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
890
891 message_loop_->RunUntilIdle();
892 }
893
894 void RemoveObserverTask(TaskQueueManager* manager,
895 base::MessageLoop::TaskObserver* observer) {
896 manager->RemoveTaskObserver(observer);
897 }
898
899 TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) {
900 InitializeWithRealMessageLoop(1u);
901 MockTaskObserver observer;
902 manager_->SetWorkBatchSize(3);
903 manager_->AddTaskObserver(&observer);
904
905 runners_[0]->PostTask(
906 FROM_HERE, base::Bind(&RemoveObserverTask, manager_.get(), &observer));
907
908 EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
909 EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
910 message_loop_->RunUntilIdle();
911 }
912
913 TEST_F(TaskQueueManagerTest, QueueTaskObserverAdding) {
914 InitializeWithRealMessageLoop(2u);
915 MockTaskObserver observer;
916
917 manager_->SetWorkBatchSize(2);
918 runners_[0]->AddTaskObserver(&observer);
919
920 std::vector<EnqueueOrder> run_order;
921 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
922 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
923
924 EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
925 EXPECT_CALL(observer, DidProcessTask(_)).Times(1);
926 message_loop_->RunUntilIdle();
927 }
928
929 TEST_F(TaskQueueManagerTest, QueueTaskObserverRemoving) {
930 InitializeWithRealMessageLoop(1u);
931 MockTaskObserver observer;
932 manager_->SetWorkBatchSize(2);
933 runners_[0]->AddTaskObserver(&observer);
934 runners_[0]->RemoveTaskObserver(&observer);
935
936 std::vector<EnqueueOrder> run_order;
937 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
938
939 EXPECT_CALL(observer, WillProcessTask(_)).Times(0);
940 EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
941
942 message_loop_->RunUntilIdle();
943 }
944
945 void RemoveQueueObserverTask(scoped_refptr<TaskQueue> queue,
946 base::MessageLoop::TaskObserver* observer) {
947 queue->RemoveTaskObserver(observer);
948 }
949
950 TEST_F(TaskQueueManagerTest, QueueTaskObserverRemovingInsideTask) {
951 InitializeWithRealMessageLoop(1u);
952 MockTaskObserver observer;
953 runners_[0]->AddTaskObserver(&observer);
954
955 runners_[0]->PostTask(
956 FROM_HERE, base::Bind(&RemoveQueueObserverTask, runners_[0], &observer));
957
958 EXPECT_CALL(observer, WillProcessTask(_)).Times(1);
959 EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
960 message_loop_->RunUntilIdle();
961 }
962
963 TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) {
964 Initialize(1u);
965 EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread());
966 manager_.reset();
967 EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread());
968 }
969
970 TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime) {
971 Initialize(2u);
972 now_src_->Advance(base::TimeDelta::FromMicroseconds(10000));
973
974 // With no delayed tasks.
975 base::TimeTicks run_time;
976 EXPECT_FALSE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
977
978 // With a non-delayed task.
979 runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
980 EXPECT_FALSE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
981
982 // With a delayed task.
983 base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50);
984 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
985 EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
986 EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
987
988 // With another delayed task in the same queue with a longer delay.
989 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask),
990 base::TimeDelta::FromMilliseconds(100));
991 EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
992 EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
993
994 // With another delayed task in the same queue with a shorter delay.
995 expected_delay = base::TimeDelta::FromMilliseconds(20);
996 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
997 EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
998 EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
999
1000 // With another delayed task in a different queue with a shorter delay.
1001 expected_delay = base::TimeDelta::FromMilliseconds(10);
1002 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay);
1003 EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
1004 EXPECT_EQ(now_src_->NowTicks() + expected_delay, run_time);
1005
1006 // Test it updates as time progresses
1007 now_src_->Advance(expected_delay);
1008 EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
1009 EXPECT_EQ(now_src_->NowTicks(), run_time);
1010 }
1011
1012 TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime_MultipleQueues) {
1013 Initialize(3u);
1014
1015 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50);
1016 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
1017 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10);
1018 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1);
1019 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay2);
1020 runners_[2]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay3);
1021 runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask));
1022
1023 base::TimeTicks run_time;
1024 EXPECT_TRUE(manager_->real_time_domain()->NextScheduledRunTime(&run_time));
1025 EXPECT_EQ(now_src_->NowTicks() + delay2, run_time);
1026 }
1027
1028 TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) {
1029 Initialize(1u);
1030
1031 runners_[0]->PostTask(
1032 FROM_HERE, base::Bind(&TaskQueueManagerTest::DeleteTaskQueueManager,
1033 base::Unretained(this)));
1034
1035 // This should not crash, assuming DoWork detects the TaskQueueManager has
1036 // been deleted.
1037 test_task_runner_->RunUntilIdle();
1038 }
1039
1040 TEST_F(TaskQueueManagerTest, GetAndClearSystemIsQuiescentBit) {
1041 Initialize(3u);
1042
1043 scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue(
1044 TaskQueue::Spec("test_queue 0").SetShouldMonitorQuiescence(true));
1045 scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue(
1046 TaskQueue::Spec("test_queue 1").SetShouldMonitorQuiescence(true));
1047 scoped_refptr<internal::TaskQueueImpl> queue2 = manager_->NewTaskQueue(
1048 TaskQueue::Spec("test_queue 2").SetShouldMonitorQuiescence(false));
1049
1050 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
1051
1052 queue0->PostTask(FROM_HERE, base::Bind(&NopTask));
1053 test_task_runner_->RunUntilIdle();
1054 EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
1055 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
1056
1057 queue1->PostTask(FROM_HERE, base::Bind(&NopTask));
1058 test_task_runner_->RunUntilIdle();
1059 EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
1060 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
1061
1062 queue2->PostTask(FROM_HERE, base::Bind(&NopTask));
1063 test_task_runner_->RunUntilIdle();
1064 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
1065
1066 queue0->PostTask(FROM_HERE, base::Bind(&NopTask));
1067 queue1->PostTask(FROM_HERE, base::Bind(&NopTask));
1068 test_task_runner_->RunUntilIdle();
1069 EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit());
1070 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit());
1071 }
1072
1073 TEST_F(TaskQueueManagerTest, HasPendingImmediateWork) {
1074 Initialize(2u);
1075 internal::TaskQueueImpl* queue0 = runners_[0].get();
1076 internal::TaskQueueImpl* queue1 = runners_[1].get();
1077 queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
1078 queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
1079
1080 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1081 EXPECT_FALSE(queue1->HasPendingImmediateWork());
1082
1083 queue0->PostTask(FROM_HERE, base::Bind(NullTask));
1084 queue1->PostTask(FROM_HERE, base::Bind(NullTask));
1085 EXPECT_TRUE(queue0->HasPendingImmediateWork());
1086 EXPECT_TRUE(queue1->HasPendingImmediateWork());
1087
1088 test_task_runner_->RunUntilIdle();
1089 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1090 EXPECT_TRUE(queue1->HasPendingImmediateWork());
1091
1092 queue1->PumpQueue(true);
1093 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1094 EXPECT_TRUE(queue1->HasPendingImmediateWork());
1095
1096 test_task_runner_->RunUntilIdle();
1097 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1098 EXPECT_FALSE(queue1->HasPendingImmediateWork());
1099 }
1100
1101 TEST_F(TaskQueueManagerTest, HasPendingImmediateWorkAndNeedsPumping) {
1102 Initialize(2u);
1103 internal::TaskQueueImpl* queue0 = runners_[0].get();
1104 internal::TaskQueueImpl* queue1 = runners_[1].get();
1105 queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO);
1106 queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL);
1107
1108 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1109 EXPECT_FALSE(queue0->NeedsPumping());
1110 EXPECT_FALSE(queue1->HasPendingImmediateWork());
1111 EXPECT_FALSE(queue1->NeedsPumping());
1112
1113 queue0->PostTask(FROM_HERE, base::Bind(NullTask));
1114 queue0->PostTask(FROM_HERE, base::Bind(NullTask));
1115 queue1->PostTask(FROM_HERE, base::Bind(NullTask));
1116 EXPECT_TRUE(queue0->HasPendingImmediateWork());
1117 EXPECT_TRUE(queue0->NeedsPumping());
1118 EXPECT_TRUE(queue1->HasPendingImmediateWork());
1119 EXPECT_TRUE(queue1->NeedsPumping());
1120
1121 test_task_runner_->SetRunTaskLimit(1);
1122 test_task_runner_->RunPendingTasks();
1123 EXPECT_TRUE(queue0->HasPendingImmediateWork());
1124 EXPECT_FALSE(queue0->NeedsPumping());
1125 EXPECT_TRUE(queue1->HasPendingImmediateWork());
1126 EXPECT_TRUE(queue1->NeedsPumping());
1127
1128 test_task_runner_->ClearRunTaskLimit();
1129 test_task_runner_->RunUntilIdle();
1130 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1131 EXPECT_FALSE(queue0->NeedsPumping());
1132 EXPECT_TRUE(queue1->HasPendingImmediateWork());
1133 EXPECT_TRUE(queue1->NeedsPumping());
1134
1135 queue1->PumpQueue(true);
1136 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1137 EXPECT_FALSE(queue0->NeedsPumping());
1138 EXPECT_TRUE(queue1->HasPendingImmediateWork());
1139 EXPECT_FALSE(queue1->NeedsPumping());
1140
1141 test_task_runner_->RunUntilIdle();
1142 EXPECT_FALSE(queue0->HasPendingImmediateWork());
1143 EXPECT_FALSE(queue0->NeedsPumping());
1144 EXPECT_FALSE(queue1->HasPendingImmediateWork());
1145 EXPECT_FALSE(queue1->NeedsPumping());
1146 }
1147
1148 void ExpensiveTestTask(int value,
1149 base::SimpleTestTickClock* clock,
1150 std::vector<EnqueueOrder>* out_result) {
1151 out_result->push_back(value);
1152 clock->Advance(base::TimeDelta::FromMilliseconds(1));
1153 }
1154
1155 TEST_F(TaskQueueManagerTest, ImmediateAndDelayedTaskInterleaving) {
1156 Initialize(1u);
1157
1158 std::vector<EnqueueOrder> run_order;
1159 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
1160 for (int i = 10; i < 19; i++) {
1161 runners_[0]->PostDelayedTask(
1162 FROM_HERE,
1163 base::Bind(&ExpensiveTestTask, i, now_src_.get(), &run_order),
1164 delay);
1165 }
1166
1167 test_task_runner_->RunForPeriod(delay);
1168
1169 for (int i = 0; i < 9; i++) {
1170 runners_[0]->PostTask(
1171 FROM_HERE,
1172 base::Bind(&ExpensiveTestTask, i, now_src_.get(), &run_order));
1173 }
1174
1175 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1176 test_task_runner_->RunUntilIdle();
1177
1178 // Delayed tasks are not allowed to starve out immediate work which is why
1179 // some of the immediate tasks run out of order.
1180 int expected_run_order[] = {
1181 10, 11, 12, 13, 0, 14, 15, 16, 1, 17, 18, 2, 3, 4, 5, 6, 7, 8
1182 };
1183 EXPECT_THAT(run_order, ElementsAreArray(expected_run_order));
1184 }
1185
1186 TEST_F(TaskQueueManagerTest,
1187 DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) {
1188 Initialize(1u);
1189
1190 std::vector<EnqueueOrder> run_order;
1191 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
1192 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
1193 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
1194 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
1195 delay);
1196
1197 now_src_->Advance(delay * 2);
1198 test_task_runner_->RunUntilIdle();
1199
1200 EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
1201 }
1202
1203 TEST_F(TaskQueueManagerTest,
1204 DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_DifferentQueues) {
1205 Initialize(2u);
1206
1207 std::vector<EnqueueOrder> run_order;
1208 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10);
1209 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
1210 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
1211 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
1212 delay);
1213
1214 now_src_->Advance(delay * 2);
1215 test_task_runner_->RunUntilIdle();
1216
1217 EXPECT_THAT(run_order, ElementsAre(2, 3, 1));
1218 }
1219
1220 TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) {
1221 Initialize(2u);
1222
1223 std::vector<EnqueueOrder> run_order;
1224 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10);
1225 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5);
1226 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
1227 delay1);
1228 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
1229 delay2);
1230
1231 now_src_->Advance(delay1 * 2);
1232 test_task_runner_->RunUntilIdle();
1233
1234 EXPECT_THAT(run_order, ElementsAre(2, 1));
1235 }
1236
1237 void CheckIsNested(bool* is_nested) {
1238 *is_nested = base::MessageLoop::current()->IsNested();
1239 }
1240
1241 void PostAndQuitFromNestedRunloop(base::RunLoop* run_loop,
1242 base::SingleThreadTaskRunner* runner,
1243 bool* was_nested) {
1244 base::MessageLoop::ScopedNestableTaskAllower allow(
1245 base::MessageLoop::current());
1246 runner->PostTask(FROM_HERE, run_loop->QuitClosure());
1247 runner->PostTask(FROM_HERE, base::Bind(&CheckIsNested, was_nested));
1248 run_loop->Run();
1249 }
1250
1251 TEST_F(TaskQueueManagerTest, QuitWhileNested) {
1252 // This test makes sure we don't continue running a work batch after a nested
1253 // run loop has been exited in the middle of the batch.
1254 InitializeWithRealMessageLoop(1u);
1255 manager_->SetWorkBatchSize(2);
1256
1257 bool was_nested = true;
1258 base::RunLoop run_loop;
1259 runners_[0]->PostTask(FROM_HERE, base::Bind(&PostAndQuitFromNestedRunloop,
1260 base::Unretained(&run_loop),
1261 base::RetainedRef(runners_[0]),
1262 base::Unretained(&was_nested)));
1263
1264 message_loop_->RunUntilIdle();
1265 EXPECT_FALSE(was_nested);
1266 }
1267
1268 class SequenceNumberCapturingTaskObserver
1269 : public base::MessageLoop::TaskObserver {
1270 public:
1271 // MessageLoop::TaskObserver overrides.
1272 void WillProcessTask(const base::PendingTask& pending_task) override {}
1273 void DidProcessTask(const base::PendingTask& pending_task) override {
1274 sequence_numbers_.push_back(pending_task.sequence_num);
1275 }
1276
1277 const std::vector<EnqueueOrder>& sequence_numbers() const {
1278 return sequence_numbers_;
1279 }
1280
1281 private:
1282 std::vector<EnqueueOrder> sequence_numbers_;
1283 };
1284
1285 TEST_F(TaskQueueManagerTest, SequenceNumSetWhenTaskIsPosted) {
1286 Initialize(1u);
1287
1288 SequenceNumberCapturingTaskObserver observer;
1289 manager_->AddTaskObserver(&observer);
1290
1291 // Register four tasks that will run in reverse order.
1292 std::vector<EnqueueOrder> run_order;
1293 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
1294 base::TimeDelta::FromMilliseconds(30));
1295 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
1296 base::TimeDelta::FromMilliseconds(20));
1297 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
1298 base::TimeDelta::FromMilliseconds(10));
1299 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
1300
1301 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40));
1302 ASSERT_THAT(run_order, ElementsAre(4, 3, 2, 1));
1303
1304 // The sequence numbers are a zero-based monotonically incrememting counter
1305 // which should be set when the task is posted rather than when it's enqueued
1306 // onto the Incoming queue.
1307 EXPECT_THAT(observer.sequence_numbers(), ElementsAre(3, 2, 1, 0));
1308
1309 manager_->RemoveTaskObserver(&observer);
1310 }
1311
1312 TEST_F(TaskQueueManagerTest, NewTaskQueues) {
1313 Initialize(1u);
1314
1315 scoped_refptr<internal::TaskQueueImpl> queue1 =
1316 manager_->NewTaskQueue(TaskQueue::Spec("foo"));
1317 scoped_refptr<internal::TaskQueueImpl> queue2 =
1318 manager_->NewTaskQueue(TaskQueue::Spec("bar"));
1319 scoped_refptr<internal::TaskQueueImpl> queue3 =
1320 manager_->NewTaskQueue(TaskQueue::Spec("baz"));
1321
1322 ASSERT_NE(queue1, queue2);
1323 ASSERT_NE(queue1, queue3);
1324 ASSERT_NE(queue2, queue3);
1325
1326 std::vector<EnqueueOrder> run_order;
1327 queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
1328 queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
1329 queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
1330 test_task_runner_->RunUntilIdle();
1331
1332 EXPECT_THAT(run_order, ElementsAre(1, 2, 3));
1333 }
1334
1335 TEST_F(TaskQueueManagerTest, UnregisterTaskQueue) {
1336 Initialize(1u);
1337
1338 scoped_refptr<internal::TaskQueueImpl> queue1 =
1339 manager_->NewTaskQueue(TaskQueue::Spec("foo"));
1340 scoped_refptr<internal::TaskQueueImpl> queue2 =
1341 manager_->NewTaskQueue(TaskQueue::Spec("bar"));
1342 scoped_refptr<internal::TaskQueueImpl> queue3 =
1343 manager_->NewTaskQueue(TaskQueue::Spec("baz"));
1344
1345 ASSERT_NE(queue1, queue2);
1346 ASSERT_NE(queue1, queue3);
1347 ASSERT_NE(queue2, queue3);
1348
1349 std::vector<EnqueueOrder> run_order;
1350 queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
1351 queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
1352 queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
1353
1354 queue2->UnregisterTaskQueue();
1355 test_task_runner_->RunUntilIdle();
1356
1357 EXPECT_THAT(run_order, ElementsAre(1, 3));
1358 }
1359
1360 TEST_F(TaskQueueManagerTest, UnregisterTaskQueue_WithDelayedTasks) {
1361 Initialize(2u);
1362
1363 // Register three delayed tasks
1364 std::vector<EnqueueOrder> run_order;
1365 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
1366 base::TimeDelta::FromMilliseconds(10));
1367 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
1368 base::TimeDelta::FromMilliseconds(20));
1369 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
1370 base::TimeDelta::FromMilliseconds(30));
1371
1372 runners_[1]->UnregisterTaskQueue();
1373 test_task_runner_->RunUntilIdle();
1374
1375 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40));
1376 ASSERT_THAT(run_order, ElementsAre(1, 3));
1377 }
1378
1379 namespace {
1380 void UnregisterQueue(scoped_refptr<internal::TaskQueueImpl> queue) {
1381 queue->UnregisterTaskQueue();
1382 }
1383 }
1384
1385 TEST_F(TaskQueueManagerTest, UnregisterTaskQueue_InTasks) {
1386 Initialize(3u);
1387
1388 std::vector<EnqueueOrder> run_order;
1389 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
1390 runners_[0]->PostTask(FROM_HERE, base::Bind(&UnregisterQueue, runners_[1]));
1391 runners_[0]->PostTask(FROM_HERE, base::Bind(&UnregisterQueue, runners_[2]));
1392 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
1393 runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
1394
1395 test_task_runner_->RunUntilIdle();
1396 ASSERT_THAT(run_order, ElementsAre(1));
1397 }
1398
1399 void PostTestTasksFromNestedMessageLoop(
1400 base::MessageLoop* message_loop,
1401 scoped_refptr<base::SingleThreadTaskRunner> main_runner,
1402 scoped_refptr<base::SingleThreadTaskRunner> wake_up_runner,
1403 std::vector<EnqueueOrder>* run_order) {
1404 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
1405 main_runner->PostNonNestableTask(FROM_HERE,
1406 base::Bind(&TestTask, 1, run_order));
1407 // The following should never get executed.
1408 wake_up_runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, run_order));
1409 base::RunLoop().RunUntilIdle();
1410 }
1411
1412 TEST_F(TaskQueueManagerTest, DeferredNonNestableTaskDoesNotTriggerWakeUp) {
1413 // This test checks that running (i.e., deferring) a non-nestable task in a
1414 // nested run loop does not trigger the pumping of an on-wakeup queue.
1415 InitializeWithRealMessageLoop(2u);
1416 runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP);
1417
1418 std::vector<EnqueueOrder> run_order;
1419 runners_[0]->PostTask(
1420 FROM_HERE,
1421 base::Bind(&PostTestTasksFromNestedMessageLoop, message_loop_.get(),
1422 runners_[0], runners_[1], base::Unretained(&run_order)));
1423
1424 message_loop_->RunUntilIdle();
1425 ASSERT_THAT(run_order, ElementsAre(1));
1426 }
1427
1428 namespace {
1429
1430 class MockObserver : public TaskQueueManager::Observer {
1431 public:
1432 MOCK_METHOD1(OnUnregisterTaskQueue,
1433 void(const scoped_refptr<TaskQueue>& queue));
1434 MOCK_METHOD2(OnTriedToExecuteBlockedTask,
1435 void(const TaskQueue& queue, const base::PendingTask& task));
1436 };
1437
1438 } // namespace
1439
1440 TEST_F(TaskQueueManagerTest, OnUnregisterTaskQueue) {
1441 Initialize(0u);
1442
1443 MockObserver observer;
1444 manager_->SetObserver(&observer);
1445
1446 scoped_refptr<internal::TaskQueueImpl> task_queue =
1447 manager_->NewTaskQueue(TaskQueue::Spec("test_queue"));
1448
1449 EXPECT_CALL(observer, OnUnregisterTaskQueue(_)).Times(1);
1450 task_queue->UnregisterTaskQueue();
1451
1452 manager_->SetObserver(nullptr);
1453 }
1454
1455 TEST_F(TaskQueueManagerTest, OnTriedToExecuteBlockedTask) {
1456 Initialize(0u);
1457
1458 MockObserver observer;
1459 manager_->SetObserver(&observer);
1460
1461 scoped_refptr<internal::TaskQueueImpl> task_queue = manager_->NewTaskQueue(
1462 TaskQueue::Spec("test_queue").SetShouldReportWhenExecutionBlocked(true));
1463 task_queue->SetQueueEnabled(false);
1464 task_queue->PostTask(FROM_HERE, base::Bind(&NopTask));
1465
1466 EXPECT_CALL(observer, OnTriedToExecuteBlockedTask(_, _)).Times(1);
1467 test_task_runner_->RunPendingTasks();
1468
1469 manager_->SetObserver(nullptr);
1470 }
1471
1472 TEST_F(TaskQueueManagerTest, ExecutedNonBlockedTask) {
1473 Initialize(0u);
1474
1475 MockObserver observer;
1476 manager_->SetObserver(&observer);
1477
1478 scoped_refptr<internal::TaskQueueImpl> task_queue = manager_->NewTaskQueue(
1479 TaskQueue::Spec("test_queue").SetShouldReportWhenExecutionBlocked(true));
1480 task_queue->PostTask(FROM_HERE, base::Bind(&NopTask));
1481
1482 EXPECT_CALL(observer, OnTriedToExecuteBlockedTask(_, _)).Times(0);
1483 test_task_runner_->RunPendingTasks();
1484
1485 manager_->SetObserver(nullptr);
1486 }
1487
1488 void HasOneRefTask(std::vector<bool>* log, internal::TaskQueueImpl* tq) {
1489 log->push_back(tq->HasOneRef());
1490 }
1491
1492 TEST_F(TaskQueueManagerTest, UnregisterTaskQueueInNestedLoop) {
1493 InitializeWithRealMessageLoop(1u);
1494
1495 // We retain a reference to the task queue even when the manager has deleted
1496 // its reference.
1497 scoped_refptr<internal::TaskQueueImpl> task_queue =
1498 manager_->NewTaskQueue(TaskQueue::Spec("test_queue"));
1499
1500 std::vector<bool> log;
1501 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop;
1502
1503 // Inside a nested run loop, call task_queue->UnregisterTaskQueue, bookended
1504 // by calls to HasOneRefTask to make sure the manager doesn't release its
1505 // reference until the nested run loop exits.
1506 // NB: This first HasOneRefTask is a sanity check.
1507 tasks_to_post_from_nested_loop.push_back(
1508 std::make_pair(base::Bind(&HasOneRefTask, base::Unretained(&log),
1509 base::Unretained(task_queue.get())),
1510 true));
1511 tasks_to_post_from_nested_loop.push_back(std::make_pair(
1512 base::Bind(&internal::TaskQueueImpl::UnregisterTaskQueue,
1513 base::Unretained(task_queue.get())), true));
1514 tasks_to_post_from_nested_loop.push_back(
1515 std::make_pair(base::Bind(&HasOneRefTask, base::Unretained(&log),
1516 base::Unretained(task_queue.get())),
1517 true));
1518 runners_[0]->PostTask(
1519 FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(),
1520 base::RetainedRef(runners_[0]),
1521 base::Unretained(&tasks_to_post_from_nested_loop)));
1522 message_loop_->RunUntilIdle();
1523
1524 // Add a final call to HasOneRefTask. This gives the manager a chance to
1525 // release its reference, and checks that it has.
1526 runners_[0]->PostTask(FROM_HERE,
1527 base::Bind(&HasOneRefTask, base::Unretained(&log),
1528 base::Unretained(task_queue.get())));
1529 message_loop_->RunUntilIdle();
1530
1531 EXPECT_THAT(log, ElementsAre(false, false, true));
1532 }
1533
1534 TEST_F(TaskQueueManagerTest, TimeDomainsAreIndependant) {
1535 Initialize(2u);
1536
1537 base::TimeTicks start_time = manager_->delegate()->NowTicks();
1538 std::unique_ptr<VirtualTimeDomain> domain_a(
1539 new VirtualTimeDomain(nullptr, start_time));
1540 std::unique_ptr<VirtualTimeDomain> domain_b(
1541 new VirtualTimeDomain(nullptr, start_time));
1542 manager_->RegisterTimeDomain(domain_a.get());
1543 manager_->RegisterTimeDomain(domain_b.get());
1544 runners_[0]->SetTimeDomain(domain_a.get());
1545 runners_[1]->SetTimeDomain(domain_b.get());
1546
1547 std::vector<EnqueueOrder> run_order;
1548 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
1549 base::TimeDelta::FromMilliseconds(10));
1550 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
1551 base::TimeDelta::FromMilliseconds(20));
1552 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
1553 base::TimeDelta::FromMilliseconds(30));
1554
1555 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order),
1556 base::TimeDelta::FromMilliseconds(10));
1557 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order),
1558 base::TimeDelta::FromMilliseconds(20));
1559 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order),
1560 base::TimeDelta::FromMilliseconds(30));
1561
1562 domain_b->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50));
1563 manager_->MaybeScheduleImmediateWork(FROM_HERE);
1564
1565 test_task_runner_->RunUntilIdle();
1566 EXPECT_THAT(run_order, ElementsAre(4, 5, 6));
1567
1568 domain_a->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50));
1569 manager_->MaybeScheduleImmediateWork(FROM_HERE);
1570
1571 test_task_runner_->RunUntilIdle();
1572 EXPECT_THAT(run_order, ElementsAre(4, 5, 6, 1, 2, 3));
1573
1574 runners_[0]->UnregisterTaskQueue();
1575 runners_[1]->UnregisterTaskQueue();
1576
1577 manager_->UnregisterTimeDomain(domain_a.get());
1578 manager_->UnregisterTimeDomain(domain_b.get());
1579 }
1580
1581 TEST_F(TaskQueueManagerTest, TimeDomainMigration) {
1582 Initialize(1u);
1583
1584 base::TimeTicks start_time = manager_->delegate()->NowTicks();
1585 std::unique_ptr<VirtualTimeDomain> domain_a(
1586 new VirtualTimeDomain(nullptr, start_time));
1587 manager_->RegisterTimeDomain(domain_a.get());
1588 runners_[0]->SetTimeDomain(domain_a.get());
1589
1590 std::vector<EnqueueOrder> run_order;
1591 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order),
1592 base::TimeDelta::FromMilliseconds(10));
1593 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order),
1594 base::TimeDelta::FromMilliseconds(20));
1595 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order),
1596 base::TimeDelta::FromMilliseconds(30));
1597 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order),
1598 base::TimeDelta::FromMilliseconds(40));
1599
1600 domain_a->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(20));
1601 manager_->MaybeScheduleImmediateWork(FROM_HERE);
1602 test_task_runner_->RunUntilIdle();
1603 EXPECT_THAT(run_order, ElementsAre(1, 2));
1604
1605 std::unique_ptr<VirtualTimeDomain> domain_b(
1606 new VirtualTimeDomain(nullptr, start_time));
1607 manager_->RegisterTimeDomain(domain_b.get());
1608 runners_[0]->SetTimeDomain(domain_b.get());
1609
1610 domain_b->AdvanceTo(start_time + base::TimeDelta::FromMilliseconds(50));
1611 manager_->MaybeScheduleImmediateWork(FROM_HERE);
1612
1613 test_task_runner_->RunUntilIdle();
1614 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4));
1615
1616 runners_[0]->UnregisterTaskQueue();
1617
1618 manager_->UnregisterTimeDomain(domain_a.get());
1619 manager_->UnregisterTimeDomain(domain_b.get());
1620 }
1621
1622 namespace {
1623 void ChromiumRunloopInspectionTask(
1624 scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner) {
1625 EXPECT_EQ(1u, test_task_runner->NumPendingTasks());
1626 }
1627 } // namespace
1628
1629 TEST_F(TaskQueueManagerTest, NumberOfPendingTasksOnChromiumRunLoop) {
1630 Initialize(1u);
1631
1632 // NOTE because tasks posted to the chromiumrun loop are not cancellable, we
1633 // will end up with a lot more tasks posted if the delayed tasks were posted
1634 // in the reverse order.
1635 // TODO(alexclarke): Consider talking to the message pump directly.
1636 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1637 for (int i = 1; i < 100; i++) {
1638 runners_[0]->PostDelayedTask(
1639 FROM_HERE,
1640 base::Bind(&ChromiumRunloopInspectionTask, test_task_runner_),
1641 base::TimeDelta::FromMilliseconds(i));
1642 }
1643 test_task_runner_->RunUntilIdle();
1644 }
1645
1646 namespace {
1647
1648 class QuadraticTask {
1649 public:
1650 QuadraticTask(scoped_refptr<internal::TaskQueueImpl> task_queue,
1651 base::TimeDelta delay,
1652 base::SimpleTestTickClock* now_src)
1653 : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {}
1654
1655 void SetShouldExit(base::Callback<bool()> should_exit) {
1656 should_exit_ = should_exit;
1657 }
1658
1659 void Run() {
1660 if (should_exit_.Run())
1661 return;
1662 count_++;
1663 task_queue_->PostDelayedTask(
1664 FROM_HERE, base::Bind(&QuadraticTask::Run, base::Unretained(this)),
1665 delay_);
1666 task_queue_->PostDelayedTask(
1667 FROM_HERE, base::Bind(&QuadraticTask::Run, base::Unretained(this)),
1668 delay_);
1669 now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
1670 }
1671
1672 int count() const { return count_; }
1673
1674 private:
1675 int count_;
1676 scoped_refptr<internal::TaskQueueImpl> task_queue_;
1677 base::TimeDelta delay_;
1678 base::Callback<bool()> should_exit_;
1679 base::SimpleTestTickClock* now_src_;
1680 };
1681
1682 class LinearTask {
1683 public:
1684 LinearTask(scoped_refptr<internal::TaskQueueImpl> task_queue,
1685 base::TimeDelta delay,
1686 base::SimpleTestTickClock* now_src)
1687 : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {}
1688
1689 void SetShouldExit(base::Callback<bool()> should_exit) {
1690 should_exit_ = should_exit;
1691 }
1692
1693 void Run() {
1694 if (should_exit_.Run())
1695 return;
1696 count_++;
1697 task_queue_->PostDelayedTask(
1698 FROM_HERE, base::Bind(&LinearTask::Run, base::Unretained(this)),
1699 delay_);
1700 now_src_->Advance(base::TimeDelta::FromMilliseconds(5));
1701 }
1702
1703 int count() const { return count_; }
1704
1705 private:
1706 int count_;
1707 scoped_refptr<internal::TaskQueueImpl> task_queue_;
1708 base::TimeDelta delay_;
1709 base::Callback<bool()> should_exit_;
1710 base::SimpleTestTickClock* now_src_;
1711 };
1712
1713 bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) {
1714 return quadratic_task->count() == 1000 || linear_task->count() == 1000;
1715 }
1716
1717 } // namespace
1718
1719 TEST_F(TaskQueueManagerTest,
1720 DelayedTasksDontBadlyStarveNonDelayedWork_SameQueue) {
1721 Initialize(1u);
1722
1723 QuadraticTask quadratic_delayed_task(
1724 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
1725 LinearTask linear_immediate_task(runners_[0], base::TimeDelta(),
1726 now_src_.get());
1727 base::Callback<bool()> should_exit =
1728 base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
1729 quadratic_delayed_task.SetShouldExit(should_exit);
1730 linear_immediate_task.SetShouldExit(should_exit);
1731
1732 quadratic_delayed_task.Run();
1733 linear_immediate_task.Run();
1734
1735 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1736 test_task_runner_->RunUntilIdle();
1737
1738 double ratio = static_cast<double>(linear_immediate_task.count()) /
1739 static_cast<double>(quadratic_delayed_task.count());
1740
1741 EXPECT_GT(ratio, 0.333);
1742 EXPECT_LT(ratio, 1.1);
1743 }
1744
1745 TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) {
1746 Initialize(1u);
1747
1748 QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
1749 now_src_.get());
1750 LinearTask linear_delayed_task(
1751 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
1752 base::Callback<bool()> should_exit =
1753 base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task);
1754
1755 quadratic_immediate_task.SetShouldExit(should_exit);
1756 linear_delayed_task.SetShouldExit(should_exit);
1757
1758 quadratic_immediate_task.Run();
1759 linear_delayed_task.Run();
1760
1761 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1762 test_task_runner_->RunUntilIdle();
1763
1764 double ratio = static_cast<double>(linear_delayed_task.count()) /
1765 static_cast<double>(quadratic_immediate_task.count());
1766
1767 // This is by design, we want to enforce a strict ordering in task execution
1768 // where by delayed tasks can not skip ahead of non-delayed work.
1769 EXPECT_GT(ratio, 0.0);
1770 EXPECT_LT(ratio, 0.1);
1771 }
1772
1773 TEST_F(TaskQueueManagerTest,
1774 DelayedTasksDontBadlyStarveNonDelayedWork_DifferentQueue) {
1775 Initialize(2u);
1776
1777 QuadraticTask quadratic_delayed_task(
1778 runners_[0], base::TimeDelta::FromMilliseconds(10), now_src_.get());
1779 LinearTask linear_immediate_task(runners_[1], base::TimeDelta(),
1780 now_src_.get());
1781 base::Callback<bool()> should_exit =
1782 base::Bind(ShouldExit, &quadratic_delayed_task, &linear_immediate_task);
1783 quadratic_delayed_task.SetShouldExit(should_exit);
1784 linear_immediate_task.SetShouldExit(should_exit);
1785
1786 quadratic_delayed_task.Run();
1787 linear_immediate_task.Run();
1788
1789 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1790 test_task_runner_->RunUntilIdle();
1791
1792 double ratio = static_cast<double>(linear_immediate_task.count()) /
1793 static_cast<double>(quadratic_delayed_task.count());
1794
1795 EXPECT_GT(ratio, 0.333);
1796 EXPECT_LT(ratio, 1.1);
1797 }
1798
1799 TEST_F(TaskQueueManagerTest,
1800 ImmediateWorkCanStarveDelayedTasks_DifferentQueue) {
1801 Initialize(2u);
1802
1803 QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(),
1804 now_src_.get());
1805 LinearTask linear_delayed_task(
1806 runners_[1], base::TimeDelta::FromMilliseconds(10), now_src_.get());
1807 base::Callback<bool()> should_exit =
1808 base::Bind(&ShouldExit, &quadratic_immediate_task, &linear_delayed_task);
1809
1810 quadratic_immediate_task.SetShouldExit(should_exit);
1811 linear_delayed_task.SetShouldExit(should_exit);
1812
1813 quadratic_immediate_task.Run();
1814 linear_delayed_task.Run();
1815
1816 test_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1817 test_task_runner_->RunUntilIdle();
1818
1819 double ratio = static_cast<double>(linear_delayed_task.count()) /
1820 static_cast<double>(quadratic_immediate_task.count());
1821
1822 // This is by design, we want to enforce a strict ordering in task execution
1823 // where by delayed tasks can not skip ahead of non-delayed work.
1824 EXPECT_GT(ratio, 0.0);
1825 EXPECT_LT(ratio, 0.1);
1826 }
1827
1828 TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_NoTaskRunning) {
1829 Initialize(1u);
1830
1831 EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
1832 }
1833
1834 namespace {
1835 void CurrentlyExecutingTaskQueueTestTask(TaskQueueManager* task_queue_manager,
1836 std::vector<TaskQueue*>* task_sources) {
1837 task_sources->push_back(task_queue_manager->currently_executing_task_queue());
1838 }
1839 }
1840
1841 TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_TaskRunning) {
1842 Initialize(2u);
1843
1844 internal::TaskQueueImpl* queue0 = runners_[0].get();
1845 internal::TaskQueueImpl* queue1 = runners_[1].get();
1846
1847 std::vector<TaskQueue*> task_sources;
1848 queue0->PostTask(FROM_HERE, base::Bind(&CurrentlyExecutingTaskQueueTestTask,
1849 manager_.get(), &task_sources));
1850 queue1->PostTask(FROM_HERE, base::Bind(&CurrentlyExecutingTaskQueueTestTask,
1851 manager_.get(), &task_sources));
1852 test_task_runner_->RunUntilIdle();
1853
1854 EXPECT_THAT(task_sources, ElementsAre(queue0, queue1));
1855 EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
1856 }
1857
1858 namespace {
1859 void RunloopCurrentlyExecutingTaskQueueTestTask(
1860 base::MessageLoop* message_loop,
1861 TaskQueueManager* task_queue_manager,
1862 std::vector<TaskQueue*>* task_sources,
1863 std::vector<std::pair<base::Closure, TaskQueue*>>* tasks) {
1864 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop);
1865 task_sources->push_back(task_queue_manager->currently_executing_task_queue());
1866
1867 for (std::pair<base::Closure, TaskQueue*>& pair : *tasks) {
1868 pair.second->PostTask(FROM_HERE, pair.first);
1869 }
1870
1871 base::RunLoop().RunUntilIdle();
1872 task_sources->push_back(task_queue_manager->currently_executing_task_queue());
1873 }
1874 }
1875
1876 TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_NestedLoop) {
1877 InitializeWithRealMessageLoop(3u);
1878
1879 TaskQueue* queue0 = runners_[0].get();
1880 TaskQueue* queue1 = runners_[1].get();
1881 TaskQueue* queue2 = runners_[2].get();
1882
1883 std::vector<TaskQueue*> task_sources;
1884 std::vector<std::pair<base::Closure, TaskQueue*>>
1885 tasks_to_post_from_nested_loop;
1886 tasks_to_post_from_nested_loop.push_back(
1887 std::make_pair(base::Bind(&CurrentlyExecutingTaskQueueTestTask,
1888 manager_.get(), &task_sources),
1889 queue1));
1890 tasks_to_post_from_nested_loop.push_back(
1891 std::make_pair(base::Bind(&CurrentlyExecutingTaskQueueTestTask,
1892 manager_.get(), &task_sources),
1893 queue2));
1894
1895 queue0->PostTask(
1896 FROM_HERE, base::Bind(&RunloopCurrentlyExecutingTaskQueueTestTask,
1897 message_loop_.get(), manager_.get(), &task_sources,
1898 &tasks_to_post_from_nested_loop));
1899
1900 message_loop_->RunUntilIdle();
1901 EXPECT_THAT(task_sources, ElementsAre(queue0, queue1, queue2, queue0));
1902 EXPECT_EQ(nullptr, manager_->currently_executing_task_queue());
1903 }
1904
1905 void OnTraceDataCollected(base::Closure quit_closure,
1906 base::trace_event::TraceResultBuffer* buffer,
1907 const scoped_refptr<base::RefCountedString>& json,
1908 bool has_more_events) {
1909 buffer->AddFragment(json->data());
1910 if (!has_more_events)
1911 quit_closure.Run();
1912 }
1913
1914 class TaskQueueManagerTestWithTracing : public TaskQueueManagerTest {
1915 public:
1916 void StartTracing();
1917 void StopTracing();
1918 std::unique_ptr<trace_analyzer::TraceAnalyzer> CreateTraceAnalyzer();
1919 };
1920
1921 void TaskQueueManagerTestWithTracing::StartTracing() {
1922 base::trace_event::TraceLog::GetInstance()->SetEnabled(
1923 base::trace_event::TraceConfig("*"),
1924 base::trace_event::TraceLog::RECORDING_MODE);
1925 }
1926
1927 void TaskQueueManagerTestWithTracing::StopTracing() {
1928 base::trace_event::TraceLog::GetInstance()->SetDisabled();
1929 }
1930
1931 std::unique_ptr<trace_analyzer::TraceAnalyzer>
1932 TaskQueueManagerTestWithTracing::CreateTraceAnalyzer() {
1933 base::trace_event::TraceResultBuffer buffer;
1934 base::trace_event::TraceResultBuffer::SimpleOutput trace_output;
1935 buffer.SetOutputCallback(trace_output.GetCallback());
1936 base::RunLoop run_loop;
1937 buffer.Start();
1938 base::trace_event::TraceLog::GetInstance()->Flush(
1939 Bind(&OnTraceDataCollected, run_loop.QuitClosure(),
1940 base::Unretained(&buffer)));
1941 run_loop.Run();
1942 buffer.Finish();
1943
1944 return base::WrapUnique(
1945 trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
1946 }
1947
1948 TEST_F(TaskQueueManagerTestWithTracing, BlameContextAttribution) {
1949 using trace_analyzer::Query;
1950
1951 InitializeWithRealMessageLoop(1u);
1952 TaskQueue* queue = runners_[0].get();
1953
1954 StartTracing();
1955 {
1956 base::trace_event::BlameContext blame_context("cat", "name", "type",
1957 "scope", 0, nullptr);
1958 blame_context.Initialize();
1959 queue->SetBlameContext(&blame_context);
1960 queue->PostTask(FROM_HERE, base::Bind(&NopTask));
1961 message_loop_->RunUntilIdle();
1962 }
1963 StopTracing();
1964 std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
1965 CreateTraceAnalyzer();
1966
1967 trace_analyzer::TraceEventVector events;
1968 Query q = Query::EventPhaseIs(TRACE_EVENT_PHASE_ENTER_CONTEXT) ||
1969 Query::EventPhaseIs(TRACE_EVENT_PHASE_LEAVE_CONTEXT);
1970 analyzer->FindEvents(q, &events);
1971
1972 EXPECT_EQ(2u, events.size());
1973 }
1974
1975 } // namespace scheduler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698