OLD | NEW |
| (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/child/task_queue_manager.h" | |
6 | |
7 #include "base/location.h" | |
8 #include "base/run_loop.h" | |
9 #include "base/single_thread_task_runner.h" | |
10 #include "base/test/simple_test_tick_clock.h" | |
11 #include "base/threading/thread.h" | |
12 #include "cc/test/ordered_simple_task_runner.h" | |
13 #include "components/scheduler/child/nestable_task_runner_for_test.h" | |
14 #include "components/scheduler/child/scheduler_task_runner_delegate_impl.h" | |
15 #include "components/scheduler/child/task_queue_impl.h" | |
16 #include "components/scheduler/child/task_queue_selector.h" | |
17 #include "components/scheduler/child/task_queue_sets.h" | |
18 #include "components/scheduler/child/test_time_source.h" | |
19 #include "components/scheduler/test/test_always_fail_time_source.h" | |
20 #include "testing/gmock/include/gmock/gmock.h" | |
21 | |
22 using testing::ElementsAre; | |
23 using testing::_; | |
24 | |
25 namespace scheduler { | |
26 | |
27 class TaskQueueManagerTest : public testing::Test { | |
28 public: | |
29 void DeleteTaskQueueManager() { manager_.reset(); } | |
30 | |
31 protected: | |
32 void Initialize(size_t num_queues) { | |
33 now_src_.reset(new base::SimpleTestTickClock()); | |
34 now_src_->Advance(base::TimeDelta::FromMicroseconds(1000)); | |
35 test_task_runner_ = make_scoped_refptr( | |
36 new cc::OrderedSimpleTaskRunner(now_src_.get(), false)); | |
37 main_task_runner_ = | |
38 NestableTaskRunnerForTest::Create(test_task_runner_.get()); | |
39 manager_ = make_scoped_ptr(new TaskQueueManager( | |
40 main_task_runner_, "test.scheduler", "test.scheduler.debug")); | |
41 manager_->SetTimeSourceForTesting( | |
42 make_scoped_ptr(new TestTimeSource(now_src_.get()))); | |
43 | |
44 for (size_t i = 0; i < num_queues; i++) | |
45 runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue"))); | |
46 } | |
47 | |
48 void InitializeWithRealMessageLoop(size_t num_queues) { | |
49 message_loop_.reset(new base::MessageLoop()); | |
50 manager_ = make_scoped_ptr(new TaskQueueManager( | |
51 SchedulerTaskRunnerDelegateImpl::Create(message_loop_.get()), | |
52 "test.scheduler", "test.scheduler.debug")); | |
53 | |
54 for (size_t i = 0; i < num_queues; i++) | |
55 runners_.push_back(manager_->NewTaskQueue(TaskQueue::Spec("test_queue"))); | |
56 } | |
57 | |
58 scoped_ptr<base::MessageLoop> message_loop_; | |
59 scoped_ptr<base::SimpleTestTickClock> now_src_; | |
60 scoped_refptr<NestableTaskRunnerForTest> main_task_runner_; | |
61 scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_; | |
62 scoped_ptr<TaskQueueManager> manager_; | |
63 std::vector<scoped_refptr<internal::TaskQueueImpl>> runners_; | |
64 }; | |
65 | |
66 void PostFromNestedRunloop(base::MessageLoop* message_loop, | |
67 base::SingleThreadTaskRunner* runner, | |
68 std::vector<std::pair<base::Closure, bool>>* tasks) { | |
69 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); | |
70 for (std::pair<base::Closure, bool>& pair : *tasks) { | |
71 if (pair.second) { | |
72 runner->PostTask(FROM_HERE, pair.first); | |
73 } else { | |
74 runner->PostNonNestableTask(FROM_HERE, pair.first); | |
75 } | |
76 } | |
77 message_loop->RunUntilIdle(); | |
78 } | |
79 | |
80 void NullTask() { | |
81 } | |
82 | |
83 void TestTask(int value, std::vector<int>* out_result) { | |
84 out_result->push_back(value); | |
85 } | |
86 | |
87 TEST_F(TaskQueueManagerTest, SingleQueuePosting) { | |
88 Initialize(1u); | |
89 | |
90 std::vector<int> run_order; | |
91 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
92 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
93 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
94 | |
95 test_task_runner_->RunUntilIdle(); | |
96 EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); | |
97 } | |
98 | |
99 TEST_F(TaskQueueManagerTest, MultiQueuePosting) { | |
100 Initialize(3u); | |
101 | |
102 std::vector<int> run_order; | |
103 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
104 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
105 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
106 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
107 runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order)); | |
108 runners_[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order)); | |
109 | |
110 test_task_runner_->RunUntilIdle(); | |
111 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5, 6)); | |
112 } | |
113 | |
114 void NopTask() { | |
115 } | |
116 | |
117 TEST_F(TaskQueueManagerTest, NowNotCalledWhenThereAreNoDelayedTasks) { | |
118 Initialize(3u); | |
119 | |
120 manager_->SetTimeSourceForTesting( | |
121 make_scoped_ptr(new TestAlwaysFailTimeSource())); | |
122 | |
123 runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
124 runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
125 runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
126 runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
127 runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
128 runners_[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
129 | |
130 test_task_runner_->RunUntilIdle(); | |
131 } | |
132 | |
133 TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) { | |
134 InitializeWithRealMessageLoop(1u); | |
135 | |
136 std::vector<int> run_order; | |
137 runners_[0]->PostNonNestableTask(FROM_HERE, | |
138 base::Bind(&TestTask, 1, &run_order)); | |
139 | |
140 message_loop_->RunUntilIdle(); | |
141 EXPECT_THAT(run_order, ElementsAre(1)); | |
142 } | |
143 | |
144 TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) { | |
145 InitializeWithRealMessageLoop(1u); | |
146 | |
147 std::vector<int> run_order; | |
148 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
149 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
150 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
151 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
152 runners_[0]->PostNonNestableTask(FROM_HERE, | |
153 base::Bind(&TestTask, 5, &run_order)); | |
154 | |
155 message_loop_->RunUntilIdle(); | |
156 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5)); | |
157 } | |
158 | |
159 TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) { | |
160 InitializeWithRealMessageLoop(1u); | |
161 | |
162 std::vector<int> run_order; | |
163 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
164 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
165 | |
166 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop; | |
167 tasks_to_post_from_nested_loop.push_back( | |
168 std::make_pair(base::Bind(&TestTask, 3, &run_order), false)); | |
169 tasks_to_post_from_nested_loop.push_back( | |
170 std::make_pair(base::Bind(&TestTask, 4, &run_order), true)); | |
171 tasks_to_post_from_nested_loop.push_back( | |
172 std::make_pair(base::Bind(&TestTask, 5, &run_order), true)); | |
173 | |
174 runners_[0]->PostTask( | |
175 FROM_HERE, | |
176 base::Bind(&PostFromNestedRunloop, message_loop_.get(), runners_[0], | |
177 base::Unretained(&tasks_to_post_from_nested_loop))); | |
178 | |
179 message_loop_->RunUntilIdle(); | |
180 // Note we expect task 3 to run last because it's non-nestable. | |
181 EXPECT_THAT(run_order, ElementsAre(1, 2, 4, 5, 3)); | |
182 } | |
183 | |
184 TEST_F(TaskQueueManagerTest, QueuePolling) { | |
185 Initialize(1u); | |
186 | |
187 std::vector<int> run_order; | |
188 EXPECT_TRUE(runners_[0]->IsQueueEmpty()); | |
189 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
190 EXPECT_FALSE(runners_[0]->IsQueueEmpty()); | |
191 | |
192 test_task_runner_->RunUntilIdle(); | |
193 EXPECT_TRUE(runners_[0]->IsQueueEmpty()); | |
194 } | |
195 | |
196 TEST_F(TaskQueueManagerTest, DelayedTaskPosting) { | |
197 Initialize(1u); | |
198 | |
199 std::vector<int> run_order; | |
200 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
201 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
202 delay); | |
203 EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime()); | |
204 EXPECT_TRUE(runners_[0]->IsQueueEmpty()); | |
205 EXPECT_TRUE(run_order.empty()); | |
206 | |
207 // The task doesn't run before the delay has completed. | |
208 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9)); | |
209 EXPECT_TRUE(run_order.empty()); | |
210 | |
211 // After the delay has completed, the task runs normally. | |
212 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); | |
213 EXPECT_THAT(run_order, ElementsAre(1)); | |
214 } | |
215 | |
216 bool MessageLoopTaskCounter(size_t* count) { | |
217 *count = *count + 1; | |
218 return true; | |
219 } | |
220 | |
221 TEST_F(TaskQueueManagerTest, DelayedTaskExecutedInOneMessageLoopTask) { | |
222 Initialize(1u); | |
223 | |
224 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
225 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay); | |
226 | |
227 size_t task_count = 0; | |
228 test_task_runner_->RunTasksWhile( | |
229 base::Bind(&MessageLoopTaskCounter, &task_count)); | |
230 EXPECT_EQ(1u, task_count); | |
231 } | |
232 | |
233 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) { | |
234 Initialize(1u); | |
235 | |
236 std::vector<int> run_order; | |
237 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
238 base::TimeDelta::FromMilliseconds(10)); | |
239 | |
240 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
241 base::TimeDelta::FromMilliseconds(8)); | |
242 | |
243 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
244 base::TimeDelta::FromMilliseconds(5)); | |
245 | |
246 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), | |
247 test_task_runner_->DelayToNextTaskTime()); | |
248 | |
249 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
250 EXPECT_THAT(run_order, ElementsAre(3)); | |
251 EXPECT_EQ(base::TimeDelta::FromMilliseconds(3), | |
252 test_task_runner_->DelayToNextTaskTime()); | |
253 | |
254 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3)); | |
255 EXPECT_THAT(run_order, ElementsAre(3, 2)); | |
256 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2), | |
257 test_task_runner_->DelayToNextTaskTime()); | |
258 | |
259 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2)); | |
260 EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); | |
261 } | |
262 | |
263 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) { | |
264 Initialize(1u); | |
265 | |
266 std::vector<int> run_order; | |
267 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
268 base::TimeDelta::FromMilliseconds(1)); | |
269 | |
270 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
271 base::TimeDelta::FromMilliseconds(5)); | |
272 | |
273 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
274 base::TimeDelta::FromMilliseconds(10)); | |
275 | |
276 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), | |
277 test_task_runner_->DelayToNextTaskTime()); | |
278 | |
279 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); | |
280 EXPECT_THAT(run_order, ElementsAre(1)); | |
281 EXPECT_EQ(base::TimeDelta::FromMilliseconds(4), | |
282 test_task_runner_->DelayToNextTaskTime()); | |
283 | |
284 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4)); | |
285 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
286 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), | |
287 test_task_runner_->DelayToNextTaskTime()); | |
288 | |
289 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
290 EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); | |
291 } | |
292 | |
293 TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) { | |
294 Initialize(1u); | |
295 | |
296 std::vector<int> 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 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
301 delay); | |
302 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
303 delay); | |
304 | |
305 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); | |
306 } | |
307 | |
308 class TestObject { | |
309 public: | |
310 ~TestObject() { destructor_count_++; } | |
311 | |
312 void Run() { FAIL() << "TestObject::Run should not be called"; } | |
313 | |
314 static int destructor_count_; | |
315 }; | |
316 | |
317 int TestObject::destructor_count_ = 0; | |
318 | |
319 TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) { | |
320 Initialize(1u); | |
321 | |
322 TestObject::destructor_count_ = 0; | |
323 | |
324 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
325 runners_[0]->PostDelayedTask( | |
326 FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())), | |
327 delay); | |
328 runners_[0]->PostTask( | |
329 FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject()))); | |
330 | |
331 manager_.reset(); | |
332 | |
333 EXPECT_EQ(2, TestObject::destructor_count_); | |
334 } | |
335 | |
336 TEST_F(TaskQueueManagerTest, ManualPumping) { | |
337 Initialize(1u); | |
338 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
339 | |
340 std::vector<int> run_order; | |
341 // Posting a task when pumping is disabled doesn't result in work getting | |
342 // posted. | |
343 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
344 EXPECT_FALSE(test_task_runner_->HasPendingTasks()); | |
345 | |
346 // However polling still works. | |
347 EXPECT_FALSE(runners_[0]->IsQueueEmpty()); | |
348 | |
349 // After pumping the task runs normally. | |
350 runners_[0]->PumpQueue(); | |
351 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
352 test_task_runner_->RunUntilIdle(); | |
353 EXPECT_THAT(run_order, ElementsAre(1)); | |
354 } | |
355 | |
356 TEST_F(TaskQueueManagerTest, ManualPumpingToggle) { | |
357 Initialize(1u); | |
358 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
359 | |
360 std::vector<int> run_order; | |
361 // Posting a task when pumping is disabled doesn't result in work getting | |
362 // posted. | |
363 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
364 EXPECT_FALSE(test_task_runner_->HasPendingTasks()); | |
365 | |
366 // When pumping is enabled the task runs normally. | |
367 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); | |
368 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
369 test_task_runner_->RunUntilIdle(); | |
370 EXPECT_THAT(run_order, ElementsAre(1)); | |
371 } | |
372 | |
373 TEST_F(TaskQueueManagerTest, DenyRunning_BeforePosting) { | |
374 Initialize(1u); | |
375 | |
376 std::vector<int> run_order; | |
377 runners_[0]->SetQueuePriority(TaskQueue::DISABLED_PRIORITY); | |
378 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
379 | |
380 test_task_runner_->RunUntilIdle(); | |
381 EXPECT_TRUE(run_order.empty()); | |
382 | |
383 runners_[0]->SetQueuePriority(TaskQueue::NORMAL_PRIORITY); | |
384 test_task_runner_->RunUntilIdle(); | |
385 EXPECT_THAT(run_order, ElementsAre(1)); | |
386 } | |
387 | |
388 TEST_F(TaskQueueManagerTest, DenyRunning_AfterPosting) { | |
389 Initialize(1u); | |
390 | |
391 std::vector<int> run_order; | |
392 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
393 runners_[0]->SetQueuePriority(TaskQueue::DISABLED_PRIORITY); | |
394 | |
395 test_task_runner_->RunUntilIdle(); | |
396 EXPECT_TRUE(run_order.empty()); | |
397 | |
398 runners_[0]->SetQueuePriority(TaskQueue::NORMAL_PRIORITY); | |
399 test_task_runner_->RunUntilIdle(); | |
400 EXPECT_THAT(run_order, ElementsAre(1)); | |
401 } | |
402 | |
403 TEST_F(TaskQueueManagerTest, DenyRunning_ManuallyPumpedTransitionsToAuto) { | |
404 Initialize(1u); | |
405 | |
406 std::vector<int> run_order; | |
407 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
408 runners_[0]->SetQueuePriority(TaskQueue::DISABLED_PRIORITY); | |
409 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
410 | |
411 test_task_runner_->RunUntilIdle(); | |
412 EXPECT_TRUE(run_order.empty()); | |
413 | |
414 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); | |
415 runners_[0]->SetQueuePriority(TaskQueue::NORMAL_PRIORITY); | |
416 test_task_runner_->RunUntilIdle(); | |
417 EXPECT_THAT(run_order, ElementsAre(1)); | |
418 } | |
419 | |
420 TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) { | |
421 Initialize(1u); | |
422 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
423 | |
424 std::vector<int> run_order; | |
425 // Posting a delayed task when pumping will apply the delay, but won't cause | |
426 // work to executed afterwards. | |
427 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
428 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
429 delay); | |
430 | |
431 // After pumping but before the delay period has expired, task does not run. | |
432 runners_[0]->PumpQueue(); | |
433 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
434 EXPECT_TRUE(run_order.empty()); | |
435 | |
436 // Once the delay has expired, pumping causes the task to run. | |
437 now_src_->Advance(base::TimeDelta::FromMilliseconds(5)); | |
438 runners_[0]->PumpQueue(); | |
439 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
440 test_task_runner_->RunPendingTasks(); | |
441 EXPECT_THAT(run_order, ElementsAre(1)); | |
442 } | |
443 | |
444 TEST_F(TaskQueueManagerTest, ManualPumpingWithMultipleDelayedTasks) { | |
445 Initialize(1u); | |
446 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
447 | |
448 std::vector<int> run_order; | |
449 // Posting a delayed task when pumping will apply the delay, but won't cause | |
450 // work to executed afterwards. | |
451 base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1)); | |
452 base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10)); | |
453 base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20)); | |
454 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
455 delay1); | |
456 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
457 delay2); | |
458 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
459 delay3); | |
460 | |
461 now_src_->Advance(base::TimeDelta::FromMilliseconds(15)); | |
462 test_task_runner_->RunUntilIdle(); | |
463 EXPECT_TRUE(run_order.empty()); | |
464 | |
465 // Once the delay has expired, pumping causes the task to run. | |
466 runners_[0]->PumpQueue(); | |
467 test_task_runner_->RunUntilIdle(); | |
468 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
469 } | |
470 | |
471 TEST_F(TaskQueueManagerTest, DelayedTasksDontAutoRunWithManualPumping) { | |
472 Initialize(1u); | |
473 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
474 | |
475 std::vector<int> run_order; | |
476 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
477 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
478 delay); | |
479 | |
480 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10)); | |
481 EXPECT_TRUE(run_order.empty()); | |
482 } | |
483 | |
484 TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) { | |
485 Initialize(1u); | |
486 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
487 | |
488 std::vector<int> run_order; | |
489 // Posting two tasks and pumping twice should result in two tasks in the work | |
490 // queue. | |
491 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
492 runners_[0]->PumpQueue(); | |
493 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
494 runners_[0]->PumpQueue(); | |
495 | |
496 EXPECT_EQ(2u, runners_[0]->WorkQueueSizeForTest()); | |
497 } | |
498 | |
499 void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
500 int countdown, | |
501 std::vector<int>* out_result) { | |
502 out_result->push_back(countdown); | |
503 if (--countdown) { | |
504 runner->PostTask(FROM_HERE, | |
505 Bind(&ReentrantTestTask, runner, countdown, out_result)); | |
506 } | |
507 } | |
508 | |
509 TEST_F(TaskQueueManagerTest, ReentrantPosting) { | |
510 Initialize(1u); | |
511 | |
512 std::vector<int> run_order; | |
513 runners_[0]->PostTask(FROM_HERE, | |
514 Bind(&ReentrantTestTask, runners_[0], 3, &run_order)); | |
515 | |
516 test_task_runner_->RunUntilIdle(); | |
517 EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); | |
518 } | |
519 | |
520 TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) { | |
521 Initialize(1u); | |
522 | |
523 std::vector<int> run_order; | |
524 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
525 manager_.reset(); | |
526 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
527 | |
528 test_task_runner_->RunUntilIdle(); | |
529 EXPECT_TRUE(run_order.empty()); | |
530 } | |
531 | |
532 void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
533 std::vector<int>* run_order) { | |
534 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order)); | |
535 } | |
536 | |
537 TEST_F(TaskQueueManagerTest, PostFromThread) { | |
538 InitializeWithRealMessageLoop(1u); | |
539 | |
540 std::vector<int> run_order; | |
541 base::Thread thread("TestThread"); | |
542 thread.Start(); | |
543 thread.task_runner()->PostTask( | |
544 FROM_HERE, base::Bind(&PostTaskToRunner, runners_[0], &run_order)); | |
545 thread.Stop(); | |
546 | |
547 message_loop_->RunUntilIdle(); | |
548 EXPECT_THAT(run_order, ElementsAre(1)); | |
549 } | |
550 | |
551 void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
552 int* run_count) { | |
553 (*run_count)++; | |
554 runner->PostTask(FROM_HERE, Bind(&RePostingTestTask, | |
555 base::Unretained(runner.get()), run_count)); | |
556 } | |
557 | |
558 TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { | |
559 Initialize(1u); | |
560 | |
561 int run_count = 0; | |
562 runners_[0]->PostTask( | |
563 FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count)); | |
564 | |
565 test_task_runner_->RunPendingTasks(); | |
566 // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there | |
567 // will be two tasks here. | |
568 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); | |
569 EXPECT_EQ(1, run_count); | |
570 } | |
571 | |
572 TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) { | |
573 InitializeWithRealMessageLoop(1u); | |
574 | |
575 std::vector<int> run_order; | |
576 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop; | |
577 tasks_to_post_from_nested_loop.push_back( | |
578 std::make_pair(base::Bind(&TestTask, 1, &run_order), true)); | |
579 | |
580 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 0, &run_order)); | |
581 runners_[0]->PostTask( | |
582 FROM_HERE, | |
583 base::Bind(&PostFromNestedRunloop, message_loop_.get(), runners_[0], | |
584 base::Unretained(&tasks_to_post_from_nested_loop))); | |
585 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
586 | |
587 message_loop_->RunUntilIdle(); | |
588 | |
589 EXPECT_THAT(run_order, ElementsAre(0, 2, 1)); | |
590 } | |
591 | |
592 TEST_F(TaskQueueManagerTest, WorkBatching) { | |
593 Initialize(1u); | |
594 | |
595 manager_->SetWorkBatchSize(2); | |
596 | |
597 std::vector<int> run_order; | |
598 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
599 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
600 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
601 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
602 | |
603 // Running one task in the host message loop should cause two posted tasks to | |
604 // get executed. | |
605 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); | |
606 test_task_runner_->RunPendingTasks(); | |
607 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
608 | |
609 // The second task runs the remaining two posted tasks. | |
610 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); | |
611 test_task_runner_->RunPendingTasks(); | |
612 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); | |
613 } | |
614 | |
615 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) { | |
616 Initialize(2u); | |
617 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP); | |
618 | |
619 std::vector<int> run_order; | |
620 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
621 test_task_runner_->RunUntilIdle(); | |
622 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | |
623 | |
624 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
625 test_task_runner_->RunUntilIdle(); | |
626 EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM. | |
627 | |
628 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
629 test_task_runner_->RunUntilIdle(); | |
630 // Executing a task on an auto pumped queue should wake the TQM. | |
631 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | |
632 } | |
633 | |
634 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) { | |
635 Initialize(2u); | |
636 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP); | |
637 | |
638 std::vector<int> run_order; | |
639 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
640 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
641 test_task_runner_->RunUntilIdle(); | |
642 EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake. | |
643 } | |
644 | |
645 TEST_F(TaskQueueManagerTest, | |
646 AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) { | |
647 Initialize(2u); | |
648 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP); | |
649 runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
650 | |
651 std::vector<int> run_order; | |
652 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
653 test_task_runner_->RunUntilIdle(); | |
654 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | |
655 | |
656 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
657 test_task_runner_->RunUntilIdle(); | |
658 // This still shouldn't wake TQM as manual queue was not pumped. | |
659 EXPECT_TRUE(run_order.empty()); | |
660 | |
661 runners_[1]->PumpQueue(); | |
662 test_task_runner_->RunUntilIdle(); | |
663 // Executing a task on an auto pumped queue should wake the TQM. | |
664 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
665 } | |
666 | |
667 void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
668 base::Closure task) { | |
669 task_runner->PostTask(FROM_HERE, task); | |
670 } | |
671 | |
672 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) { | |
673 Initialize(2u); | |
674 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP); | |
675 | |
676 std::vector<int> run_order; | |
677 // Check that a task which posts a task to an auto pump after wakeup queue | |
678 // doesn't cause the queue to wake up. | |
679 base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order); | |
680 runners_[1]->PostTask( | |
681 FROM_HERE, base::Bind(&TestPostingTask, runners_[0], after_wakeup_task)); | |
682 test_task_runner_->RunUntilIdle(); | |
683 EXPECT_TRUE(run_order.empty()); | |
684 | |
685 // Wake up the queue. | |
686 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
687 test_task_runner_->RunUntilIdle(); | |
688 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
689 } | |
690 | |
691 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) { | |
692 Initialize(2u); | |
693 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP); | |
694 | |
695 std::vector<int> run_order; | |
696 // Check that a task which posts a task to an auto pump after wakeup queue | |
697 // doesn't cause the queue to wake up. | |
698 base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order); | |
699 base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order); | |
700 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0], | |
701 after_wakeup_task_1)); | |
702 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestPostingTask, runners_[0], | |
703 after_wakeup_task_2)); | |
704 test_task_runner_->RunUntilIdle(); | |
705 EXPECT_TRUE(run_order.empty()); | |
706 | |
707 // Wake up the queue. | |
708 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
709 test_task_runner_->RunUntilIdle(); | |
710 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | |
711 } | |
712 | |
713 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) { | |
714 Initialize(2u); | |
715 runners_[0]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP); | |
716 | |
717 int run_count = 0; | |
718 // Check that if multiple tasks reposts themselves onto a pump-after-wakeup | |
719 // queue they don't wake each other and will eventually stop when no other | |
720 // tasks execute. | |
721 runners_[0]->PostTask( | |
722 FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count)); | |
723 runners_[0]->PostTask( | |
724 FROM_HERE, base::Bind(&RePostingTestTask, runners_[0], &run_count)); | |
725 runners_[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
726 test_task_runner_->RunUntilIdle(); | |
727 // The reposting tasks posted to the after wakeup queue shouldn't have woken | |
728 // each other up. | |
729 EXPECT_EQ(2, run_count); | |
730 } | |
731 | |
732 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWithDontWakeQueue) { | |
733 Initialize(1u); | |
734 | |
735 scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue( | |
736 TaskQueue::Spec("test_queue 0") | |
737 .SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP)); | |
738 scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue( | |
739 TaskQueue::Spec("test_queue 0") | |
740 .SetWakeupPolicy(TaskQueue::WakeupPolicy::DONT_WAKE_OTHER_QUEUES)); | |
741 scoped_refptr<internal::TaskQueueImpl> queue2 = runners_[0]; | |
742 | |
743 std::vector<int> run_order; | |
744 queue0->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
745 queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
746 test_task_runner_->RunUntilIdle(); | |
747 // Executing a DONT_WAKE_OTHER_QUEUES queue shouldn't wake the autopump after | |
748 // wakeup queue. | |
749 EXPECT_THAT(run_order, ElementsAre(2)); | |
750 | |
751 queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
752 test_task_runner_->RunUntilIdle(); | |
753 // Executing a CAN_WAKE_OTHER_QUEUES queue should wake the autopump after | |
754 // wakeup queue. | |
755 EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); | |
756 } | |
757 | |
758 class MockTaskObserver : public base::MessageLoop::TaskObserver { | |
759 public: | |
760 MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task)); | |
761 MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task)); | |
762 }; | |
763 | |
764 TEST_F(TaskQueueManagerTest, TaskObserverAdding) { | |
765 InitializeWithRealMessageLoop(1u); | |
766 MockTaskObserver observer; | |
767 | |
768 manager_->SetWorkBatchSize(2); | |
769 manager_->AddTaskObserver(&observer); | |
770 | |
771 std::vector<int> run_order; | |
772 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
773 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
774 | |
775 EXPECT_CALL(observer, WillProcessTask(_)).Times(2); | |
776 EXPECT_CALL(observer, DidProcessTask(_)).Times(2); | |
777 message_loop_->RunUntilIdle(); | |
778 } | |
779 | |
780 TEST_F(TaskQueueManagerTest, TaskObserverRemoving) { | |
781 InitializeWithRealMessageLoop(1u); | |
782 MockTaskObserver observer; | |
783 manager_->SetWorkBatchSize(2); | |
784 manager_->AddTaskObserver(&observer); | |
785 manager_->RemoveTaskObserver(&observer); | |
786 | |
787 std::vector<int> run_order; | |
788 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
789 | |
790 EXPECT_CALL(observer, WillProcessTask(_)).Times(0); | |
791 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
792 | |
793 message_loop_->RunUntilIdle(); | |
794 } | |
795 | |
796 void RemoveObserverTask(TaskQueueManager* manager, | |
797 base::MessageLoop::TaskObserver* observer) { | |
798 manager->RemoveTaskObserver(observer); | |
799 } | |
800 | |
801 TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) { | |
802 InitializeWithRealMessageLoop(1u); | |
803 MockTaskObserver observer; | |
804 manager_->SetWorkBatchSize(3); | |
805 manager_->AddTaskObserver(&observer); | |
806 | |
807 runners_[0]->PostTask( | |
808 FROM_HERE, base::Bind(&RemoveObserverTask, manager_.get(), &observer)); | |
809 | |
810 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); | |
811 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
812 message_loop_->RunUntilIdle(); | |
813 } | |
814 | |
815 TEST_F(TaskQueueManagerTest, QueueTaskObserverAdding) { | |
816 InitializeWithRealMessageLoop(2u); | |
817 MockTaskObserver observer; | |
818 | |
819 manager_->SetWorkBatchSize(2); | |
820 runners_[0]->AddTaskObserver(&observer); | |
821 | |
822 std::vector<int> run_order; | |
823 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
824 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
825 | |
826 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); | |
827 EXPECT_CALL(observer, DidProcessTask(_)).Times(1); | |
828 message_loop_->RunUntilIdle(); | |
829 } | |
830 | |
831 TEST_F(TaskQueueManagerTest, QueueTaskObserverRemoving) { | |
832 InitializeWithRealMessageLoop(1u); | |
833 MockTaskObserver observer; | |
834 manager_->SetWorkBatchSize(2); | |
835 runners_[0]->AddTaskObserver(&observer); | |
836 runners_[0]->RemoveTaskObserver(&observer); | |
837 | |
838 std::vector<int> run_order; | |
839 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
840 | |
841 EXPECT_CALL(observer, WillProcessTask(_)).Times(0); | |
842 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
843 | |
844 message_loop_->RunUntilIdle(); | |
845 } | |
846 | |
847 void RemoveQueueObserverTask(scoped_refptr<TaskQueue> queue, | |
848 base::MessageLoop::TaskObserver* observer) { | |
849 queue->RemoveTaskObserver(observer); | |
850 } | |
851 | |
852 TEST_F(TaskQueueManagerTest, QueueTaskObserverRemovingInsideTask) { | |
853 InitializeWithRealMessageLoop(1u); | |
854 MockTaskObserver observer; | |
855 runners_[0]->AddTaskObserver(&observer); | |
856 | |
857 runners_[0]->PostTask( | |
858 FROM_HERE, base::Bind(&RemoveQueueObserverTask, runners_[0], &observer)); | |
859 | |
860 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); | |
861 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
862 message_loop_->RunUntilIdle(); | |
863 } | |
864 | |
865 TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) { | |
866 Initialize(1u); | |
867 EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread()); | |
868 manager_.reset(); | |
869 EXPECT_TRUE(runners_[0]->RunsTasksOnCurrentThread()); | |
870 } | |
871 | |
872 TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime) { | |
873 scoped_ptr<base::SimpleTestTickClock> clock(new base::SimpleTestTickClock()); | |
874 clock->Advance(base::TimeDelta::FromMicroseconds(10000)); | |
875 Initialize(2u); | |
876 manager_->SetTimeSourceForTesting( | |
877 make_scoped_ptr(new TestTimeSource(clock.get()))); | |
878 | |
879 // With no delayed tasks. | |
880 EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null()); | |
881 | |
882 // With a non-delayed task. | |
883 runners_[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
884 EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null()); | |
885 | |
886 // With a delayed task. | |
887 base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50); | |
888 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
889 EXPECT_EQ(clock->NowTicks() + expected_delay, | |
890 manager_->NextPendingDelayedTaskRunTime()); | |
891 | |
892 // With another delayed task in the same queue with a longer delay. | |
893 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), | |
894 base::TimeDelta::FromMilliseconds(100)); | |
895 EXPECT_EQ(clock->NowTicks() + expected_delay, | |
896 manager_->NextPendingDelayedTaskRunTime()); | |
897 | |
898 // With another delayed task in the same queue with a shorter delay. | |
899 expected_delay = base::TimeDelta::FromMilliseconds(20); | |
900 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
901 EXPECT_EQ(clock->NowTicks() + expected_delay, | |
902 manager_->NextPendingDelayedTaskRunTime()); | |
903 | |
904 // With another delayed task in a different queue with a shorter delay. | |
905 expected_delay = base::TimeDelta::FromMilliseconds(10); | |
906 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
907 EXPECT_EQ(clock->NowTicks() + expected_delay, | |
908 manager_->NextPendingDelayedTaskRunTime()); | |
909 | |
910 // Test it updates as time progresses | |
911 clock->Advance(expected_delay); | |
912 EXPECT_EQ(clock->NowTicks(), manager_->NextPendingDelayedTaskRunTime()); | |
913 } | |
914 | |
915 TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime_MultipleQueues) { | |
916 Initialize(3u); | |
917 | |
918 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); | |
919 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5); | |
920 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10); | |
921 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1); | |
922 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay2); | |
923 runners_[2]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay3); | |
924 | |
925 EXPECT_EQ(now_src_->NowTicks() + delay2, | |
926 manager_->NextPendingDelayedTaskRunTime()); | |
927 } | |
928 | |
929 TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) { | |
930 Initialize(1u); | |
931 | |
932 runners_[0]->PostTask( | |
933 FROM_HERE, base::Bind(&TaskQueueManagerTest::DeleteTaskQueueManager, | |
934 base::Unretained(this))); | |
935 | |
936 // This should not crash, assuming DoWork detects the TaskQueueManager has | |
937 // been deleted. | |
938 test_task_runner_->RunUntilIdle(); | |
939 } | |
940 | |
941 TEST_F(TaskQueueManagerTest, GetAndClearSystemIsQuiescentBit) { | |
942 Initialize(3u); | |
943 | |
944 scoped_refptr<internal::TaskQueueImpl> queue0 = manager_->NewTaskQueue( | |
945 TaskQueue::Spec("test_queue 0").SetShouldMonitorQuiescence(true)); | |
946 scoped_refptr<internal::TaskQueueImpl> queue1 = manager_->NewTaskQueue( | |
947 TaskQueue::Spec("test_queue 1").SetShouldMonitorQuiescence(true)); | |
948 scoped_refptr<internal::TaskQueueImpl> queue2 = manager_->NewTaskQueue( | |
949 TaskQueue::Spec("test_queue 2").SetShouldMonitorQuiescence(false)); | |
950 | |
951 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); | |
952 | |
953 queue0->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
954 test_task_runner_->RunUntilIdle(); | |
955 EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit()); | |
956 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); | |
957 | |
958 queue1->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
959 test_task_runner_->RunUntilIdle(); | |
960 EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit()); | |
961 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); | |
962 | |
963 queue2->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
964 test_task_runner_->RunUntilIdle(); | |
965 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); | |
966 | |
967 queue0->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
968 queue1->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
969 test_task_runner_->RunUntilIdle(); | |
970 EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit()); | |
971 EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); | |
972 } | |
973 | |
974 TEST_F(TaskQueueManagerTest, IsQueueEmpty) { | |
975 Initialize(2u); | |
976 internal::TaskQueueImpl* queue0 = runners_[0].get(); | |
977 internal::TaskQueueImpl* queue1 = runners_[1].get(); | |
978 queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); | |
979 queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
980 | |
981 EXPECT_TRUE(queue0->IsQueueEmpty()); | |
982 EXPECT_TRUE(queue1->IsQueueEmpty()); | |
983 | |
984 queue0->PostTask(FROM_HERE, base::Bind(NullTask)); | |
985 queue1->PostTask(FROM_HERE, base::Bind(NullTask)); | |
986 EXPECT_FALSE(queue0->IsQueueEmpty()); | |
987 EXPECT_FALSE(queue1->IsQueueEmpty()); | |
988 | |
989 test_task_runner_->RunUntilIdle(); | |
990 EXPECT_TRUE(queue0->IsQueueEmpty()); | |
991 EXPECT_FALSE(queue1->IsQueueEmpty()); | |
992 | |
993 queue1->PumpQueue(); | |
994 EXPECT_TRUE(queue0->IsQueueEmpty()); | |
995 EXPECT_FALSE(queue1->IsQueueEmpty()); | |
996 | |
997 test_task_runner_->RunUntilIdle(); | |
998 EXPECT_TRUE(queue0->IsQueueEmpty()); | |
999 EXPECT_TRUE(queue1->IsQueueEmpty()); | |
1000 } | |
1001 | |
1002 TEST_F(TaskQueueManagerTest, GetQueueState) { | |
1003 Initialize(2u); | |
1004 internal::TaskQueueImpl* queue0 = runners_[0].get(); | |
1005 internal::TaskQueueImpl* queue1 = runners_[1].get(); | |
1006 queue0->SetPumpPolicy(TaskQueue::PumpPolicy::AUTO); | |
1007 queue1->SetPumpPolicy(TaskQueue::PumpPolicy::MANUAL); | |
1008 | |
1009 EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); | |
1010 EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue1->GetQueueState()); | |
1011 | |
1012 queue0->PostTask(FROM_HERE, base::Bind(NullTask)); | |
1013 queue0->PostTask(FROM_HERE, base::Bind(NullTask)); | |
1014 queue1->PostTask(FROM_HERE, base::Bind(NullTask)); | |
1015 EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue0->GetQueueState()); | |
1016 EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState()); | |
1017 | |
1018 test_task_runner_->SetRunTaskLimit(1); | |
1019 test_task_runner_->RunPendingTasks(); | |
1020 EXPECT_EQ(TaskQueue::QueueState::HAS_WORK, queue0->GetQueueState()); | |
1021 EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState()); | |
1022 | |
1023 test_task_runner_->ClearRunTaskLimit(); | |
1024 test_task_runner_->RunUntilIdle(); | |
1025 EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); | |
1026 EXPECT_EQ(TaskQueue::QueueState::NEEDS_PUMPING, queue1->GetQueueState()); | |
1027 | |
1028 queue1->PumpQueue(); | |
1029 EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); | |
1030 EXPECT_EQ(TaskQueue::QueueState::HAS_WORK, queue1->GetQueueState()); | |
1031 | |
1032 test_task_runner_->RunUntilIdle(); | |
1033 EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue0->GetQueueState()); | |
1034 EXPECT_EQ(TaskQueue::QueueState::EMPTY, queue1->GetQueueState()); | |
1035 } | |
1036 | |
1037 TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfNonDelayedTask) { | |
1038 Initialize(2u); | |
1039 | |
1040 std::vector<int> run_order; | |
1041 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); | |
1042 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
1043 delay); | |
1044 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
1045 runners_[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
1046 | |
1047 now_src_->Advance(delay * 2); | |
1048 // After task 2 has run, the automatic selector will have to choose between | |
1049 // tasks 1 and 3. The sequence numbers are used to choose between the two | |
1050 // tasks and if they are correct task 1 will run last. | |
1051 test_task_runner_->RunUntilIdle(); | |
1052 | |
1053 EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); | |
1054 } | |
1055 | |
1056 TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) { | |
1057 Initialize(2u); | |
1058 | |
1059 std::vector<int> run_order; | |
1060 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); | |
1061 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5); | |
1062 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
1063 delay1); | |
1064 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
1065 delay2); | |
1066 | |
1067 now_src_->Advance(delay1 * 2); | |
1068 test_task_runner_->RunUntilIdle(); | |
1069 | |
1070 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
1071 } | |
1072 | |
1073 TEST_F(TaskQueueManagerTest, DelayedTaskWithAbsoluteRunTime) { | |
1074 Initialize(1u); | |
1075 | |
1076 // One task in the past, two with the exact same run time and one in the | |
1077 // future. | |
1078 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); | |
1079 base::TimeTicks runTime1 = now_src_->NowTicks() - delay; | |
1080 base::TimeTicks runTime2 = now_src_->NowTicks(); | |
1081 base::TimeTicks runTime3 = now_src_->NowTicks(); | |
1082 base::TimeTicks runTime4 = now_src_->NowTicks() + delay; | |
1083 | |
1084 std::vector<int> run_order; | |
1085 runners_[0]->PostDelayedTaskAt( | |
1086 FROM_HERE, base::Bind(&TestTask, 1, &run_order), runTime1); | |
1087 runners_[0]->PostDelayedTaskAt( | |
1088 FROM_HERE, base::Bind(&TestTask, 2, &run_order), runTime2); | |
1089 runners_[0]->PostDelayedTaskAt( | |
1090 FROM_HERE, base::Bind(&TestTask, 3, &run_order), runTime3); | |
1091 runners_[0]->PostDelayedTaskAt( | |
1092 FROM_HERE, base::Bind(&TestTask, 4, &run_order), runTime4); | |
1093 | |
1094 now_src_->Advance(2 * delay); | |
1095 test_task_runner_->RunUntilIdle(); | |
1096 | |
1097 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); | |
1098 } | |
1099 | |
1100 void CheckIsNested(bool* is_nested) { | |
1101 *is_nested = base::MessageLoop::current()->IsNested(); | |
1102 } | |
1103 | |
1104 void PostAndQuitFromNestedRunloop(base::RunLoop* run_loop, | |
1105 base::SingleThreadTaskRunner* runner, | |
1106 bool* was_nested) { | |
1107 base::MessageLoop::ScopedNestableTaskAllower allow( | |
1108 base::MessageLoop::current()); | |
1109 runner->PostTask(FROM_HERE, run_loop->QuitClosure()); | |
1110 runner->PostTask(FROM_HERE, base::Bind(&CheckIsNested, was_nested)); | |
1111 run_loop->Run(); | |
1112 } | |
1113 | |
1114 TEST_F(TaskQueueManagerTest, QuitWhileNested) { | |
1115 // This test makes sure we don't continue running a work batch after a nested | |
1116 // run loop has been exited in the middle of the batch. | |
1117 InitializeWithRealMessageLoop(1u); | |
1118 manager_->SetWorkBatchSize(2); | |
1119 | |
1120 bool was_nested = true; | |
1121 base::RunLoop run_loop; | |
1122 runners_[0]->PostTask( | |
1123 FROM_HERE, | |
1124 base::Bind(&PostAndQuitFromNestedRunloop, base::Unretained(&run_loop), | |
1125 runners_[0], base::Unretained(&was_nested))); | |
1126 | |
1127 message_loop_->RunUntilIdle(); | |
1128 EXPECT_FALSE(was_nested); | |
1129 } | |
1130 | |
1131 class SequenceNumberCapturingTaskObserver | |
1132 : public base::MessageLoop::TaskObserver { | |
1133 public: | |
1134 // MessageLoop::TaskObserver overrides. | |
1135 void WillProcessTask(const base::PendingTask& pending_task) override {} | |
1136 void DidProcessTask(const base::PendingTask& pending_task) override { | |
1137 sequence_numbers_.push_back(pending_task.sequence_num); | |
1138 } | |
1139 | |
1140 const std::vector<int>& sequence_numbers() const { return sequence_numbers_; } | |
1141 | |
1142 private: | |
1143 std::vector<int> sequence_numbers_; | |
1144 }; | |
1145 | |
1146 TEST_F(TaskQueueManagerTest, SequenceNumSetWhenTaskIsPosted) { | |
1147 Initialize(1u); | |
1148 | |
1149 SequenceNumberCapturingTaskObserver observer; | |
1150 manager_->AddTaskObserver(&observer); | |
1151 | |
1152 // Register four tasks that will run in reverse order. | |
1153 std::vector<int> run_order; | |
1154 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
1155 base::TimeDelta::FromMilliseconds(30)); | |
1156 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
1157 base::TimeDelta::FromMilliseconds(20)); | |
1158 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
1159 base::TimeDelta::FromMilliseconds(10)); | |
1160 runners_[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
1161 | |
1162 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40)); | |
1163 ASSERT_THAT(run_order, ElementsAre(4, 3, 2, 1)); | |
1164 | |
1165 // The sequence numbers are a zero-based monotonically incrememting counter | |
1166 // which should be set when the task is posted rather than when it's enqueued | |
1167 // onto the incomming queue. | |
1168 EXPECT_THAT(observer.sequence_numbers(), ElementsAre(3, 2, 1, 0)); | |
1169 | |
1170 manager_->RemoveTaskObserver(&observer); | |
1171 } | |
1172 | |
1173 TEST_F(TaskQueueManagerTest, NewTaskQueues) { | |
1174 Initialize(1u); | |
1175 | |
1176 scoped_refptr<internal::TaskQueueImpl> queue1 = | |
1177 manager_->NewTaskQueue(TaskQueue::Spec("foo")); | |
1178 scoped_refptr<internal::TaskQueueImpl> queue2 = | |
1179 manager_->NewTaskQueue(TaskQueue::Spec("bar")); | |
1180 scoped_refptr<internal::TaskQueueImpl> queue3 = | |
1181 manager_->NewTaskQueue(TaskQueue::Spec("baz")); | |
1182 | |
1183 ASSERT_NE(queue1, queue2); | |
1184 ASSERT_NE(queue1, queue3); | |
1185 ASSERT_NE(queue2, queue3); | |
1186 | |
1187 std::vector<int> run_order; | |
1188 queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
1189 queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
1190 queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
1191 test_task_runner_->RunUntilIdle(); | |
1192 | |
1193 EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); | |
1194 } | |
1195 | |
1196 TEST_F(TaskQueueManagerTest, UnregisterTaskQueue) { | |
1197 Initialize(1u); | |
1198 | |
1199 scoped_refptr<internal::TaskQueueImpl> queue1 = | |
1200 manager_->NewTaskQueue(TaskQueue::Spec("foo")); | |
1201 scoped_refptr<internal::TaskQueueImpl> queue2 = | |
1202 manager_->NewTaskQueue(TaskQueue::Spec("bar")); | |
1203 scoped_refptr<internal::TaskQueueImpl> queue3 = | |
1204 manager_->NewTaskQueue(TaskQueue::Spec("baz")); | |
1205 | |
1206 ASSERT_NE(queue1, queue2); | |
1207 ASSERT_NE(queue1, queue3); | |
1208 ASSERT_NE(queue2, queue3); | |
1209 | |
1210 std::vector<int> run_order; | |
1211 queue1->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
1212 queue2->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
1213 queue3->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
1214 | |
1215 queue2->UnregisterTaskQueue(); | |
1216 test_task_runner_->RunUntilIdle(); | |
1217 | |
1218 EXPECT_THAT(run_order, ElementsAre(1, 3)); | |
1219 } | |
1220 | |
1221 TEST_F(TaskQueueManagerTest, UnregisterTaskQueue_WithDelayedTasks) { | |
1222 Initialize(2u); | |
1223 | |
1224 // Register three delayed tasks | |
1225 std::vector<int> run_order; | |
1226 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
1227 base::TimeDelta::FromMilliseconds(10)); | |
1228 runners_[1]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
1229 base::TimeDelta::FromMilliseconds(20)); | |
1230 runners_[0]->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
1231 base::TimeDelta::FromMilliseconds(30)); | |
1232 | |
1233 runners_[1]->UnregisterTaskQueue(); | |
1234 test_task_runner_->RunUntilIdle(); | |
1235 | |
1236 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40)); | |
1237 ASSERT_THAT(run_order, ElementsAre(1, 3)); | |
1238 } | |
1239 | |
1240 void PostTestTasksFromNestedMessageLoop( | |
1241 base::MessageLoop* message_loop, | |
1242 scoped_refptr<base::SingleThreadTaskRunner> main_runner, | |
1243 scoped_refptr<base::SingleThreadTaskRunner> wake_up_runner, | |
1244 std::vector<int>* run_order) { | |
1245 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); | |
1246 main_runner->PostNonNestableTask(FROM_HERE, | |
1247 base::Bind(&TestTask, 1, run_order)); | |
1248 // The following should never get executed. | |
1249 wake_up_runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, run_order)); | |
1250 message_loop->RunUntilIdle(); | |
1251 } | |
1252 | |
1253 TEST_F(TaskQueueManagerTest, DeferredNonNestableTaskDoesNotTriggerWakeUp) { | |
1254 // This test checks that running (i.e., deferring) a non-nestable task in a | |
1255 // nested run loop does not trigger the pumping of an on-wakeup queue. | |
1256 InitializeWithRealMessageLoop(2u); | |
1257 runners_[1]->SetPumpPolicy(TaskQueue::PumpPolicy::AFTER_WAKEUP); | |
1258 | |
1259 std::vector<int> run_order; | |
1260 runners_[0]->PostTask( | |
1261 FROM_HERE, | |
1262 base::Bind(&PostTestTasksFromNestedMessageLoop, message_loop_.get(), | |
1263 runners_[0], runners_[1], base::Unretained(&run_order))); | |
1264 | |
1265 message_loop_->RunUntilIdle(); | |
1266 ASSERT_THAT(run_order, ElementsAre(1)); | |
1267 } | |
1268 | |
1269 namespace { | |
1270 | |
1271 class MockObserver : public TaskQueueManager::Observer { | |
1272 public: | |
1273 MOCK_METHOD1(OnUnregisterTaskQueue, | |
1274 void(const scoped_refptr<internal::TaskQueueImpl>& queue)); | |
1275 }; | |
1276 | |
1277 } // namespace | |
1278 | |
1279 TEST_F(TaskQueueManagerTest, OnUnregisterTaskQueue) { | |
1280 Initialize(0u); | |
1281 | |
1282 MockObserver observer; | |
1283 manager_->SetObserver(&observer); | |
1284 | |
1285 scoped_refptr<internal::TaskQueueImpl> task_queue = | |
1286 manager_->NewTaskQueue(TaskQueue::Spec("test_queue")); | |
1287 | |
1288 EXPECT_CALL(observer, OnUnregisterTaskQueue(_)).Times(1); | |
1289 task_queue->UnregisterTaskQueue(); | |
1290 | |
1291 manager_->SetObserver(nullptr); | |
1292 } | |
1293 | |
1294 } // namespace scheduler | |
OLD | NEW |