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