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 "content/renderer/scheduler/task_queue_manager.h" | |
6 | |
7 #include "base/threading/thread.h" | |
8 #include "cc/test/ordered_simple_task_runner.h" | |
9 #include "cc/test/test_now_source.h" | |
10 #include "content/renderer/scheduler/nestable_task_runner_for_test.h" | |
11 #include "content/renderer/scheduler/renderer_scheduler_message_loop_delegate.h" | |
12 #include "content/renderer/scheduler/task_queue_selector.h" | |
13 #include "testing/gmock/include/gmock/gmock.h" | |
14 | |
15 using testing::ElementsAre; | |
16 using testing::_; | |
17 | |
18 namespace content { | |
19 namespace { | |
20 | |
21 class SelectorForTest : public TaskQueueSelector { | |
22 public: | |
23 ~SelectorForTest() override {} | |
24 | |
25 virtual void AppendQueueToService(size_t queue_index) = 0; | |
26 | |
27 virtual const std::vector<const base::TaskQueue*>& work_queues() = 0; | |
28 | |
29 void AsValueInto(base::trace_event::TracedValue* state) const override {} | |
30 }; | |
31 | |
32 // Always selects queue 0. | |
33 class AutomaticSelectorForTest : public SelectorForTest { | |
34 public: | |
35 AutomaticSelectorForTest() {} | |
36 ~AutomaticSelectorForTest() override {} | |
37 | |
38 void RegisterWorkQueues( | |
39 const std::vector<const base::TaskQueue*>& work_queues) override { | |
40 work_queues_ = work_queues; | |
41 } | |
42 | |
43 bool SelectWorkQueueToService(size_t* out_queue_index) override { | |
44 for (size_t i = 0; i < work_queues_.size(); i++) { | |
45 if (!work_queues_[i]->empty()) { | |
46 *out_queue_index = i; | |
47 return true; | |
48 } | |
49 } | |
50 return false; | |
51 } | |
52 | |
53 void AppendQueueToService(size_t queue_index) override { | |
54 DCHECK(false) << "Not supported"; | |
55 } | |
56 | |
57 const std::vector<const base::TaskQueue*>& work_queues() override { | |
58 return work_queues_; | |
59 } | |
60 | |
61 private: | |
62 std::vector<const base::TaskQueue*> work_queues_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(AutomaticSelectorForTest); | |
65 }; | |
66 | |
67 class ExplicitSelectorForTest : public SelectorForTest { | |
68 public: | |
69 ExplicitSelectorForTest() {} | |
70 ~ExplicitSelectorForTest() override {} | |
71 | |
72 void RegisterWorkQueues( | |
73 const std::vector<const base::TaskQueue*>& work_queues) override { | |
74 work_queues_ = work_queues; | |
75 } | |
76 | |
77 bool SelectWorkQueueToService(size_t* out_queue_index) override { | |
78 if (queues_to_service_.empty()) | |
79 return false; | |
80 *out_queue_index = queues_to_service_.front(); | |
81 queues_to_service_.pop_front(); | |
82 return true; | |
83 } | |
84 | |
85 void AppendQueueToService(size_t queue_index) override { | |
86 queues_to_service_.push_back(queue_index); | |
87 } | |
88 | |
89 const std::vector<const base::TaskQueue*>& work_queues() override { | |
90 return work_queues_; | |
91 } | |
92 | |
93 private: | |
94 std::deque<size_t> queues_to_service_; | |
95 std::vector<const base::TaskQueue*> work_queues_; | |
96 | |
97 DISALLOW_COPY_AND_ASSIGN(ExplicitSelectorForTest); | |
98 }; | |
99 | |
100 class TaskQueueManagerTest : public testing::Test { | |
101 protected: | |
102 enum class SelectorType { | |
103 Automatic, | |
104 Explicit, | |
105 }; | |
106 | |
107 void Initialize(size_t num_queues, SelectorType type) { | |
108 now_src_ = cc::TestNowSource::Create(1000); | |
109 test_task_runner_ = | |
110 make_scoped_refptr(new cc::OrderedSimpleTaskRunner(now_src_, false)); | |
111 selector_ = make_scoped_ptr(createSelectorForTest(type)); | |
112 manager_ = make_scoped_ptr(new TaskQueueManager( | |
113 num_queues, NestableTaskRunnerForTest::Create(test_task_runner_.get()), | |
114 selector_.get())); | |
115 manager_->SetTimeSourceForTesting(now_src_); | |
116 | |
117 EXPECT_EQ(num_queues, selector_->work_queues().size()); | |
118 } | |
119 | |
120 void InitializeWithRealMessageLoop(size_t num_queues, SelectorType type) { | |
121 message_loop_.reset(new base::MessageLoop()); | |
122 selector_ = make_scoped_ptr(createSelectorForTest(type)); | |
123 manager_ = make_scoped_ptr(new TaskQueueManager( | |
124 num_queues, | |
125 RendererSchedulerMessageLoopDelegate::Create(message_loop_.get()), | |
126 selector_.get())); | |
127 EXPECT_EQ(num_queues, selector_->work_queues().size()); | |
128 } | |
129 | |
130 SelectorForTest* createSelectorForTest(SelectorType type) { | |
131 switch (type) { | |
132 case SelectorType::Automatic: | |
133 return new AutomaticSelectorForTest(); | |
134 | |
135 case SelectorType::Explicit: | |
136 return new ExplicitSelectorForTest(); | |
137 } | |
138 | |
139 return nullptr; | |
140 } | |
141 | |
142 scoped_refptr<cc::TestNowSource> now_src_; | |
143 scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_; | |
144 scoped_ptr<SelectorForTest> selector_; | |
145 scoped_ptr<TaskQueueManager> manager_; | |
146 scoped_ptr<base::MessageLoop> message_loop_; | |
147 }; | |
148 | |
149 void PostFromNestedRunloop(base::MessageLoop* message_loop, | |
150 base::SingleThreadTaskRunner* runner, | |
151 std::vector<std::pair<base::Closure, bool>>* tasks) { | |
152 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); | |
153 for (std::pair<base::Closure, bool>& pair : *tasks) { | |
154 if (pair.second) { | |
155 runner->PostTask(FROM_HERE, pair.first); | |
156 } else { | |
157 runner->PostNonNestableTask(FROM_HERE, pair.first); | |
158 } | |
159 } | |
160 message_loop->RunUntilIdle(); | |
161 } | |
162 | |
163 void TestTask(int value, std::vector<int>* out_result) { | |
164 out_result->push_back(value); | |
165 } | |
166 | |
167 TEST_F(TaskQueueManagerTest, SingleQueuePosting) { | |
168 Initialize(1u, SelectorType::Automatic); | |
169 | |
170 std::vector<int> run_order; | |
171 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
172 manager_->TaskRunnerForQueue(0); | |
173 | |
174 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
175 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
176 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
177 | |
178 test_task_runner_->RunUntilIdle(); | |
179 EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); | |
180 } | |
181 | |
182 TEST_F(TaskQueueManagerTest, MultiQueuePosting) { | |
183 Initialize(3u, SelectorType::Explicit); | |
184 | |
185 std::vector<int> run_order; | |
186 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { | |
187 manager_->TaskRunnerForQueue(0), | |
188 manager_->TaskRunnerForQueue(1), | |
189 manager_->TaskRunnerForQueue(2)}; | |
190 | |
191 selector_->AppendQueueToService(0); | |
192 selector_->AppendQueueToService(1); | |
193 selector_->AppendQueueToService(2); | |
194 selector_->AppendQueueToService(0); | |
195 selector_->AppendQueueToService(1); | |
196 selector_->AppendQueueToService(2); | |
197 | |
198 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
199 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
200 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
201 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
202 runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order)); | |
203 runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order)); | |
204 | |
205 test_task_runner_->RunUntilIdle(); | |
206 EXPECT_THAT(run_order, ElementsAre(1, 3, 5, 2, 4, 6)); | |
207 } | |
208 | |
209 void NopTask() { | |
210 } | |
211 | |
212 TEST_F(TaskQueueManagerTest, NowNotCalledWhenThereAreNoDelayedTasks) { | |
213 Initialize(3u, SelectorType::Explicit); | |
214 | |
215 scoped_refptr<cc::TestNowSource> now_src = cc::TestNowSource::Create(1000); | |
216 manager_->SetTimeSourceForTesting(now_src); | |
217 | |
218 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { | |
219 manager_->TaskRunnerForQueue(0), | |
220 manager_->TaskRunnerForQueue(1), | |
221 manager_->TaskRunnerForQueue(2)}; | |
222 | |
223 selector_->AppendQueueToService(0); | |
224 selector_->AppendQueueToService(1); | |
225 selector_->AppendQueueToService(2); | |
226 selector_->AppendQueueToService(0); | |
227 selector_->AppendQueueToService(1); | |
228 selector_->AppendQueueToService(2); | |
229 | |
230 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
231 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
232 runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
233 runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
234 runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
235 runners[2]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
236 | |
237 test_task_runner_->RunUntilIdle(); | |
238 | |
239 EXPECT_EQ(0, now_src->NumNowCalls()); | |
240 } | |
241 | |
242 TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) { | |
243 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
244 | |
245 std::vector<int> run_order; | |
246 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
247 manager_->TaskRunnerForQueue(0); | |
248 | |
249 runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
250 | |
251 message_loop_->RunUntilIdle(); | |
252 EXPECT_THAT(run_order, ElementsAre(1)); | |
253 } | |
254 | |
255 TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) { | |
256 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
257 | |
258 std::vector<int> run_order; | |
259 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
260 manager_->TaskRunnerForQueue(0); | |
261 | |
262 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
263 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
264 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
265 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
266 runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order)); | |
267 | |
268 message_loop_->RunUntilIdle(); | |
269 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5)); | |
270 } | |
271 | |
272 TEST_F(TaskQueueManagerTest, NonNestableTaskDoesntExecuteInNestedLoop) { | |
273 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
274 | |
275 std::vector<int> run_order; | |
276 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
277 manager_->TaskRunnerForQueue(0); | |
278 | |
279 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
280 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
281 | |
282 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop; | |
283 tasks_to_post_from_nested_loop.push_back( | |
284 std::make_pair(base::Bind(&TestTask, 3, &run_order), false)); | |
285 tasks_to_post_from_nested_loop.push_back( | |
286 std::make_pair(base::Bind(&TestTask, 4, &run_order), true)); | |
287 tasks_to_post_from_nested_loop.push_back( | |
288 std::make_pair(base::Bind(&TestTask, 5, &run_order), true)); | |
289 | |
290 runner->PostTask( | |
291 FROM_HERE, | |
292 base::Bind(&PostFromNestedRunloop, message_loop_.get(), runner, | |
293 base::Unretained(&tasks_to_post_from_nested_loop))); | |
294 | |
295 message_loop_->RunUntilIdle(); | |
296 // Note we expect task 3 to run last because it's non-nestable. | |
297 EXPECT_THAT(run_order, ElementsAre(1, 2, 4, 5, 3)); | |
298 } | |
299 | |
300 TEST_F(TaskQueueManagerTest, QueuePolling) { | |
301 Initialize(1u, SelectorType::Automatic); | |
302 | |
303 std::vector<int> run_order; | |
304 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
305 manager_->TaskRunnerForQueue(0); | |
306 | |
307 EXPECT_TRUE(manager_->IsQueueEmpty(0)); | |
308 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
309 EXPECT_FALSE(manager_->IsQueueEmpty(0)); | |
310 | |
311 test_task_runner_->RunUntilIdle(); | |
312 EXPECT_TRUE(manager_->IsQueueEmpty(0)); | |
313 } | |
314 | |
315 TEST_F(TaskQueueManagerTest, DelayedTaskPosting) { | |
316 Initialize(1u, SelectorType::Automatic); | |
317 | |
318 std::vector<int> run_order; | |
319 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
320 manager_->TaskRunnerForQueue(0); | |
321 | |
322 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
323 runner->PostDelayedTask( | |
324 FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay); | |
325 EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime()); | |
326 EXPECT_TRUE(manager_->IsQueueEmpty(0)); | |
327 EXPECT_TRUE(run_order.empty()); | |
328 | |
329 // The task doesn't run before the delay has completed. | |
330 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9)); | |
331 EXPECT_TRUE(run_order.empty()); | |
332 | |
333 // After the delay has completed, the task runs normally. | |
334 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); | |
335 EXPECT_THAT(run_order, ElementsAre(1)); | |
336 } | |
337 | |
338 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) { | |
339 Initialize(1u, SelectorType::Automatic); | |
340 | |
341 std::vector<int> run_order; | |
342 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
343 manager_->TaskRunnerForQueue(0); | |
344 | |
345 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
346 base::TimeDelta::FromMilliseconds(10)); | |
347 | |
348 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
349 base::TimeDelta::FromMilliseconds(8)); | |
350 | |
351 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
352 base::TimeDelta::FromMilliseconds(5)); | |
353 | |
354 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), | |
355 test_task_runner_->DelayToNextTaskTime()); | |
356 | |
357 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
358 EXPECT_THAT(run_order, ElementsAre(3)); | |
359 EXPECT_EQ(base::TimeDelta::FromMilliseconds(3), | |
360 test_task_runner_->DelayToNextTaskTime()); | |
361 | |
362 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3)); | |
363 EXPECT_THAT(run_order, ElementsAre(3, 2)); | |
364 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2), | |
365 test_task_runner_->DelayToNextTaskTime()); | |
366 | |
367 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2)); | |
368 EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); | |
369 } | |
370 | |
371 TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) { | |
372 Initialize(1u, SelectorType::Automatic); | |
373 | |
374 std::vector<int> run_order; | |
375 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
376 manager_->TaskRunnerForQueue(0); | |
377 | |
378 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
379 base::TimeDelta::FromMilliseconds(1)); | |
380 | |
381 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
382 base::TimeDelta::FromMilliseconds(5)); | |
383 | |
384 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
385 base::TimeDelta::FromMilliseconds(10)); | |
386 | |
387 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), | |
388 test_task_runner_->DelayToNextTaskTime()); | |
389 | |
390 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); | |
391 EXPECT_THAT(run_order, ElementsAre(1)); | |
392 EXPECT_EQ(base::TimeDelta::FromMilliseconds(4), | |
393 test_task_runner_->DelayToNextTaskTime()); | |
394 | |
395 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4)); | |
396 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
397 EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), | |
398 test_task_runner_->DelayToNextTaskTime()); | |
399 | |
400 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
401 EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); | |
402 } | |
403 | |
404 TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) { | |
405 Initialize(1u, SelectorType::Automatic); | |
406 | |
407 std::vector<int> run_order; | |
408 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
409 manager_->TaskRunnerForQueue(0); | |
410 | |
411 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
412 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
413 delay); | |
414 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
415 delay); | |
416 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
417 delay); | |
418 | |
419 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); | |
420 } | |
421 | |
422 class TestObject { | |
423 public: | |
424 ~TestObject() { destructor_count_++; } | |
425 | |
426 void Run() { FAIL() << "TestObject::Run should not be called"; } | |
427 | |
428 static int destructor_count_; | |
429 }; | |
430 | |
431 int TestObject::destructor_count_ = 0; | |
432 | |
433 TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) { | |
434 Initialize(1u, SelectorType::Automatic); | |
435 | |
436 TestObject::destructor_count_ = 0; | |
437 | |
438 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
439 manager_->TaskRunnerForQueue(0); | |
440 | |
441 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
442 runner->PostDelayedTask( | |
443 FROM_HERE, base::Bind(&TestObject::Run, base::Owned(new TestObject())), | |
444 delay); | |
445 | |
446 manager_.reset(); | |
447 | |
448 EXPECT_EQ(1, TestObject::destructor_count_); | |
449 } | |
450 | |
451 TEST_F(TaskQueueManagerTest, ManualPumping) { | |
452 Initialize(1u, SelectorType::Automatic); | |
453 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
454 | |
455 std::vector<int> run_order; | |
456 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
457 manager_->TaskRunnerForQueue(0); | |
458 | |
459 // Posting a task when pumping is disabled doesn't result in work getting | |
460 // posted. | |
461 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
462 EXPECT_FALSE(test_task_runner_->HasPendingTasks()); | |
463 | |
464 // However polling still works. | |
465 EXPECT_FALSE(manager_->IsQueueEmpty(0)); | |
466 | |
467 // After pumping the task runs normally. | |
468 manager_->PumpQueue(0); | |
469 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
470 test_task_runner_->RunUntilIdle(); | |
471 EXPECT_THAT(run_order, ElementsAre(1)); | |
472 } | |
473 | |
474 TEST_F(TaskQueueManagerTest, ManualPumpingToggle) { | |
475 Initialize(1u, SelectorType::Automatic); | |
476 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
477 | |
478 std::vector<int> run_order; | |
479 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
480 manager_->TaskRunnerForQueue(0); | |
481 | |
482 // Posting a task when pumping is disabled doesn't result in work getting | |
483 // posted. | |
484 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
485 EXPECT_FALSE(test_task_runner_->HasPendingTasks()); | |
486 | |
487 // When pumping is enabled the task runs normally. | |
488 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AUTO); | |
489 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
490 test_task_runner_->RunUntilIdle(); | |
491 EXPECT_THAT(run_order, ElementsAre(1)); | |
492 } | |
493 | |
494 TEST_F(TaskQueueManagerTest, DenyRunning) { | |
495 Initialize(1u, SelectorType::Explicit); | |
496 | |
497 std::vector<int> run_order; | |
498 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
499 manager_->TaskRunnerForQueue(0); | |
500 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
501 | |
502 // Since we haven't appended a work queue to be selected, the task doesn't | |
503 // run. | |
504 test_task_runner_->RunUntilIdle(); | |
505 EXPECT_TRUE(run_order.empty()); | |
506 | |
507 // Pumping the queue again with a selected work queue runs the task. | |
508 manager_->PumpQueue(0); | |
509 selector_->AppendQueueToService(0); | |
510 test_task_runner_->RunUntilIdle(); | |
511 EXPECT_THAT(run_order, ElementsAre(1)); | |
512 } | |
513 | |
514 TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) { | |
515 Initialize(1u, SelectorType::Automatic); | |
516 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
517 | |
518 std::vector<int> run_order; | |
519 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
520 manager_->TaskRunnerForQueue(0); | |
521 | |
522 // Posting a delayed task when pumping will apply the delay, but won't cause | |
523 // work to executed afterwards. | |
524 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
525 runner->PostDelayedTask( | |
526 FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay); | |
527 | |
528 // After pumping but before the delay period has expired, task does not run. | |
529 manager_->PumpQueue(0); | |
530 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); | |
531 EXPECT_TRUE(run_order.empty()); | |
532 | |
533 // Once the delay has expired, pumping causes the task to run. | |
534 now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(5)); | |
535 manager_->PumpQueue(0); | |
536 EXPECT_TRUE(test_task_runner_->HasPendingTasks()); | |
537 test_task_runner_->RunPendingTasks(); | |
538 EXPECT_THAT(run_order, ElementsAre(1)); | |
539 } | |
540 | |
541 TEST_F(TaskQueueManagerTest, ManualPumpingWithMultipleDelayedTasks) { | |
542 Initialize(1u, SelectorType::Automatic); | |
543 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
544 | |
545 std::vector<int> run_order; | |
546 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
547 manager_->TaskRunnerForQueue(0); | |
548 | |
549 // Posting a delayed task when pumping will apply the delay, but won't cause | |
550 // work to executed afterwards. | |
551 base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1)); | |
552 base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10)); | |
553 base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20)); | |
554 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
555 delay1); | |
556 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order), | |
557 delay2); | |
558 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order), | |
559 delay3); | |
560 | |
561 now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(15)); | |
562 test_task_runner_->RunUntilIdle(); | |
563 EXPECT_TRUE(run_order.empty()); | |
564 | |
565 // Once the delay has expired, pumping causes the task to run. | |
566 manager_->PumpQueue(0); | |
567 test_task_runner_->RunUntilIdle(); | |
568 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
569 } | |
570 | |
571 TEST_F(TaskQueueManagerTest, DelayedTasksDontAutoRunWithManualPumping) { | |
572 Initialize(1u, SelectorType::Automatic); | |
573 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
574 | |
575 std::vector<int> run_order; | |
576 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
577 manager_->TaskRunnerForQueue(0); | |
578 | |
579 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); | |
580 runner->PostDelayedTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order), | |
581 delay); | |
582 | |
583 test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10)); | |
584 EXPECT_TRUE(run_order.empty()); | |
585 } | |
586 | |
587 TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) { | |
588 Initialize(1u, SelectorType::Automatic); | |
589 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::MANUAL); | |
590 | |
591 std::vector<int> run_order; | |
592 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
593 manager_->TaskRunnerForQueue(0); | |
594 | |
595 // Posting two tasks and pumping twice should result in two tasks in the work | |
596 // queue. | |
597 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
598 manager_->PumpQueue(0); | |
599 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
600 manager_->PumpQueue(0); | |
601 | |
602 EXPECT_EQ(2u, selector_->work_queues()[0]->size()); | |
603 } | |
604 | |
605 void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
606 int countdown, | |
607 std::vector<int>* out_result) { | |
608 out_result->push_back(countdown); | |
609 if (--countdown) { | |
610 runner->PostTask(FROM_HERE, | |
611 Bind(&ReentrantTestTask, runner, countdown, out_result)); | |
612 } | |
613 } | |
614 | |
615 TEST_F(TaskQueueManagerTest, ReentrantPosting) { | |
616 Initialize(1u, SelectorType::Automatic); | |
617 | |
618 std::vector<int> run_order; | |
619 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
620 manager_->TaskRunnerForQueue(0); | |
621 | |
622 runner->PostTask(FROM_HERE, Bind(&ReentrantTestTask, runner, 3, &run_order)); | |
623 | |
624 test_task_runner_->RunUntilIdle(); | |
625 EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); | |
626 } | |
627 | |
628 TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) { | |
629 Initialize(1u, SelectorType::Automatic); | |
630 | |
631 std::vector<int> run_order; | |
632 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
633 manager_->TaskRunnerForQueue(0); | |
634 | |
635 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
636 manager_.reset(); | |
637 selector_.reset(); | |
638 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
639 | |
640 test_task_runner_->RunUntilIdle(); | |
641 EXPECT_TRUE(run_order.empty()); | |
642 } | |
643 | |
644 void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
645 std::vector<int>* run_order) { | |
646 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, run_order)); | |
647 } | |
648 | |
649 TEST_F(TaskQueueManagerTest, PostFromThread) { | |
650 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
651 | |
652 std::vector<int> run_order; | |
653 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
654 manager_->TaskRunnerForQueue(0); | |
655 | |
656 base::Thread thread("TestThread"); | |
657 thread.Start(); | |
658 thread.message_loop()->PostTask( | |
659 FROM_HERE, base::Bind(&PostTaskToRunner, runner, &run_order)); | |
660 thread.Stop(); | |
661 | |
662 message_loop_->RunUntilIdle(); | |
663 EXPECT_THAT(run_order, ElementsAre(1)); | |
664 } | |
665 | |
666 void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, | |
667 int* run_count) { | |
668 (*run_count)++; | |
669 runner->PostTask( | |
670 FROM_HERE, | |
671 Bind(&RePostingTestTask, base::Unretained(runner.get()), run_count)); | |
672 } | |
673 | |
674 TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { | |
675 Initialize(1u, SelectorType::Automatic); | |
676 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
677 manager_->TaskRunnerForQueue(0); | |
678 | |
679 int run_count = 0; | |
680 runner->PostTask(FROM_HERE, | |
681 base::Bind(&RePostingTestTask, runner, &run_count)); | |
682 | |
683 test_task_runner_->RunPendingTasks(); | |
684 // NOTE without the executing_task_ check in MaybePostDoWorkOnMainRunner there | |
685 // will be two tasks here. | |
686 EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); | |
687 EXPECT_EQ(1, run_count); | |
688 } | |
689 | |
690 TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) { | |
691 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
692 | |
693 std::vector<int> run_order; | |
694 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
695 manager_->TaskRunnerForQueue(0); | |
696 | |
697 std::vector<std::pair<base::Closure, bool>> tasks_to_post_from_nested_loop; | |
698 tasks_to_post_from_nested_loop.push_back( | |
699 std::make_pair(base::Bind(&TestTask, 1, &run_order), true)); | |
700 | |
701 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 0, &run_order)); | |
702 runner->PostTask( | |
703 FROM_HERE, base::Bind(&PostFromNestedRunloop, message_loop_.get(), runner, | |
704 base::Unretained(&tasks_to_post_from_nested_loop))); | |
705 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
706 | |
707 message_loop_->RunUntilIdle(); | |
708 | |
709 EXPECT_THAT(run_order, ElementsAre(0, 2, 1)); | |
710 } | |
711 | |
712 TEST_F(TaskQueueManagerTest, WorkBatching) { | |
713 Initialize(1u, SelectorType::Automatic); | |
714 | |
715 manager_->SetWorkBatchSize(2); | |
716 | |
717 std::vector<int> run_order; | |
718 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
719 manager_->TaskRunnerForQueue(0); | |
720 | |
721 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
722 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
723 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
724 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order)); | |
725 | |
726 // Running one task in the host message loop should cause two posted tasks to | |
727 // get executed. | |
728 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); | |
729 test_task_runner_->RunPendingTasks(); | |
730 EXPECT_THAT(run_order, ElementsAre(1, 2)); | |
731 | |
732 // The second task runs the remaining two posted tasks. | |
733 EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); | |
734 test_task_runner_->RunPendingTasks(); | |
735 EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); | |
736 } | |
737 | |
738 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeup) { | |
739 Initialize(2u, SelectorType::Explicit); | |
740 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
741 | |
742 std::vector<int> run_order; | |
743 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
744 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
745 | |
746 selector_->AppendQueueToService(1); | |
747 selector_->AppendQueueToService(0); | |
748 selector_->AppendQueueToService(0); | |
749 | |
750 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
751 test_task_runner_->RunUntilIdle(); | |
752 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | |
753 | |
754 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
755 test_task_runner_->RunUntilIdle(); | |
756 EXPECT_TRUE(run_order.empty()); // Still shouldn't wake TQM. | |
757 | |
758 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
759 test_task_runner_->RunUntilIdle(); | |
760 // Executing a task on an auto pumped queue should wake the TQM. | |
761 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | |
762 } | |
763 | |
764 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupWhenAlreadyAwake) { | |
765 Initialize(2u, SelectorType::Explicit); | |
766 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
767 | |
768 std::vector<int> run_order; | |
769 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
770 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
771 | |
772 selector_->AppendQueueToService(1); | |
773 selector_->AppendQueueToService(0); | |
774 | |
775 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
776 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
777 test_task_runner_->RunUntilIdle(); | |
778 EXPECT_THAT(run_order, ElementsAre(2, 1)); // TQM was already awake. | |
779 } | |
780 | |
781 TEST_F(TaskQueueManagerTest, | |
782 AutoPumpAfterWakeupTriggeredByManuallyPumpedQueue) { | |
783 Initialize(2u, SelectorType::Explicit); | |
784 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
785 manager_->SetPumpPolicy(1, TaskQueueManager::PumpPolicy::MANUAL); | |
786 | |
787 std::vector<int> run_order; | |
788 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
789 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
790 | |
791 selector_->AppendQueueToService(1); | |
792 selector_->AppendQueueToService(0); | |
793 | |
794 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
795 test_task_runner_->RunUntilIdle(); | |
796 EXPECT_TRUE(run_order.empty()); // Shouldn't run - no other task to wake TQM. | |
797 | |
798 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
799 test_task_runner_->RunUntilIdle(); | |
800 // This still shouldn't wake TQM as manual queue was not pumped. | |
801 EXPECT_TRUE(run_order.empty()); | |
802 | |
803 manager_->PumpQueue(1); | |
804 test_task_runner_->RunUntilIdle(); | |
805 // Executing a task on an auto pumped queue should wake the TQM. | |
806 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
807 } | |
808 | |
809 void TestPostingTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
810 base::Closure task) { | |
811 task_runner->PostTask(FROM_HERE, task); | |
812 } | |
813 | |
814 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromTask) { | |
815 Initialize(2u, SelectorType::Explicit); | |
816 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
817 | |
818 std::vector<int> run_order; | |
819 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
820 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
821 | |
822 selector_->AppendQueueToService(1); | |
823 selector_->AppendQueueToService(1); | |
824 selector_->AppendQueueToService(0); | |
825 | |
826 // Check that a task which posts a task to an auto pump after wakeup queue | |
827 // doesn't cause the queue to wake up. | |
828 base::Closure after_wakeup_task = base::Bind(&TestTask, 1, &run_order); | |
829 runners[1]->PostTask( | |
830 FROM_HERE, | |
831 base::Bind(&TestPostingTask, runners[0], after_wakeup_task)); | |
832 test_task_runner_->RunUntilIdle(); | |
833 EXPECT_TRUE(run_order.empty()); | |
834 | |
835 // Wake up the queue. | |
836 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
837 test_task_runner_->RunUntilIdle(); | |
838 EXPECT_THAT(run_order, ElementsAre(2, 1)); | |
839 } | |
840 | |
841 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupFromMultipleTasks) { | |
842 Initialize(2u, SelectorType::Explicit); | |
843 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
844 | |
845 std::vector<int> run_order; | |
846 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
847 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
848 | |
849 selector_->AppendQueueToService(1); | |
850 selector_->AppendQueueToService(1); | |
851 selector_->AppendQueueToService(1); | |
852 selector_->AppendQueueToService(0); | |
853 selector_->AppendQueueToService(0); | |
854 | |
855 // Check that a task which posts a task to an auto pump after wakeup queue | |
856 // doesn't cause the queue to wake up. | |
857 base::Closure after_wakeup_task_1 = base::Bind(&TestTask, 1, &run_order); | |
858 base::Closure after_wakeup_task_2 = base::Bind(&TestTask, 2, &run_order); | |
859 runners[1]->PostTask( | |
860 FROM_HERE, | |
861 base::Bind(&TestPostingTask, runners[0], after_wakeup_task_1)); | |
862 runners[1]->PostTask( | |
863 FROM_HERE, | |
864 base::Bind(&TestPostingTask, runners[0], after_wakeup_task_2)); | |
865 test_task_runner_->RunUntilIdle(); | |
866 EXPECT_TRUE(run_order.empty()); | |
867 | |
868 // Wake up the queue. | |
869 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order)); | |
870 test_task_runner_->RunUntilIdle(); | |
871 EXPECT_THAT(run_order, ElementsAre(3, 1, 2)); | |
872 } | |
873 | |
874 TEST_F(TaskQueueManagerTest, AutoPumpAfterWakeupBecomesQuiescent) { | |
875 Initialize(2u, SelectorType::Explicit); | |
876 manager_->SetPumpPolicy(0, TaskQueueManager::PumpPolicy::AFTER_WAKEUP); | |
877 | |
878 int run_count = 0; | |
879 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
880 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
881 | |
882 selector_->AppendQueueToService(1); | |
883 selector_->AppendQueueToService(0); | |
884 selector_->AppendQueueToService(0); | |
885 // Append extra service queue '0' entries to the selector otherwise test will | |
886 // finish even if the RePostingTestTask woke each other up. | |
887 selector_->AppendQueueToService(0); | |
888 selector_->AppendQueueToService(0); | |
889 | |
890 // Check that if multiple tasks reposts themselves onto a pump-after-wakeup | |
891 // queue they don't wake each other and will eventually stop when no other | |
892 // tasks execute. | |
893 runners[0]->PostTask(FROM_HERE, | |
894 base::Bind(&RePostingTestTask, runners[0], &run_count)); | |
895 runners[0]->PostTask(FROM_HERE, | |
896 base::Bind(&RePostingTestTask, runners[0], &run_count)); | |
897 runners[1]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
898 test_task_runner_->RunUntilIdle(); | |
899 // The reposting tasks posted to the after wakeup queue shouldn't have woken | |
900 // each other up. | |
901 EXPECT_EQ(2, run_count); | |
902 } | |
903 | |
904 class MockTaskObserver : public base::MessageLoop::TaskObserver { | |
905 public: | |
906 MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task)); | |
907 MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task)); | |
908 }; | |
909 | |
910 TEST_F(TaskQueueManagerTest, TaskObserverAdding) { | |
911 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
912 MockTaskObserver observer; | |
913 | |
914 manager_->SetWorkBatchSize(2); | |
915 manager_->AddTaskObserver(&observer); | |
916 | |
917 std::vector<int> run_order; | |
918 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
919 manager_->TaskRunnerForQueue(0); | |
920 | |
921 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
922 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order)); | |
923 | |
924 // Two pairs of callbacks for the tasks above plus another one for the | |
925 // DoWork() posted by the task queue manager. | |
926 EXPECT_CALL(observer, WillProcessTask(_)).Times(3); | |
927 EXPECT_CALL(observer, DidProcessTask(_)).Times(3); | |
928 message_loop_->RunUntilIdle(); | |
929 } | |
930 | |
931 TEST_F(TaskQueueManagerTest, TaskObserverRemoving) { | |
932 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
933 MockTaskObserver observer; | |
934 manager_->SetWorkBatchSize(2); | |
935 manager_->AddTaskObserver(&observer); | |
936 manager_->RemoveTaskObserver(&observer); | |
937 | |
938 std::vector<int> run_order; | |
939 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
940 manager_->TaskRunnerForQueue(0); | |
941 | |
942 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order)); | |
943 | |
944 EXPECT_CALL(observer, WillProcessTask(_)).Times(0); | |
945 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
946 | |
947 message_loop_->RunUntilIdle(); | |
948 } | |
949 | |
950 void RemoveObserverTask(TaskQueueManager* manager, | |
951 base::MessageLoop::TaskObserver* observer) { | |
952 manager->RemoveTaskObserver(observer); | |
953 } | |
954 | |
955 TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) { | |
956 InitializeWithRealMessageLoop(1u, SelectorType::Automatic); | |
957 MockTaskObserver observer; | |
958 manager_->SetWorkBatchSize(3); | |
959 manager_->AddTaskObserver(&observer); | |
960 | |
961 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
962 manager_->TaskRunnerForQueue(0); | |
963 runner->PostTask(FROM_HERE, | |
964 base::Bind(&RemoveObserverTask, manager_.get(), &observer)); | |
965 | |
966 EXPECT_CALL(observer, WillProcessTask(_)).Times(1); | |
967 EXPECT_CALL(observer, DidProcessTask(_)).Times(0); | |
968 message_loop_->RunUntilIdle(); | |
969 } | |
970 | |
971 TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) { | |
972 Initialize(1u, SelectorType::Automatic); | |
973 scoped_refptr<base::SingleThreadTaskRunner> runner = | |
974 manager_->TaskRunnerForQueue(0); | |
975 EXPECT_TRUE(runner->RunsTasksOnCurrentThread()); | |
976 manager_.reset(); | |
977 EXPECT_TRUE(runner->RunsTasksOnCurrentThread()); | |
978 } | |
979 | |
980 TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime) { | |
981 scoped_refptr<cc::TestNowSource> clock(cc::TestNowSource::Create()); | |
982 Initialize(2u, SelectorType::Explicit); | |
983 manager_->SetTimeSourceForTesting(clock); | |
984 | |
985 scoped_refptr<base::SingleThreadTaskRunner> runners[2] = { | |
986 manager_->TaskRunnerForQueue(0), manager_->TaskRunnerForQueue(1)}; | |
987 | |
988 // With no delayed tasks. | |
989 EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null()); | |
990 | |
991 // With a non-delayed task. | |
992 runners[0]->PostTask(FROM_HERE, base::Bind(&NopTask)); | |
993 EXPECT_TRUE(manager_->NextPendingDelayedTaskRunTime().is_null()); | |
994 | |
995 // With a delayed task. | |
996 base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50); | |
997 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
998 EXPECT_EQ(clock->Now() + expected_delay, | |
999 manager_->NextPendingDelayedTaskRunTime()); | |
1000 | |
1001 // With another delayed task in the same queue with a longer delay. | |
1002 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), | |
1003 base::TimeDelta::FromMilliseconds(100)); | |
1004 EXPECT_EQ(clock->Now() + expected_delay, | |
1005 manager_->NextPendingDelayedTaskRunTime()); | |
1006 | |
1007 // With another delayed task in the same queue with a shorter delay. | |
1008 expected_delay = base::TimeDelta::FromMilliseconds(20); | |
1009 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
1010 EXPECT_EQ(clock->Now() + expected_delay, | |
1011 manager_->NextPendingDelayedTaskRunTime()); | |
1012 | |
1013 // With another delayed task in a different queue with a shorter delay. | |
1014 expected_delay = base::TimeDelta::FromMilliseconds(10); | |
1015 runners[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), expected_delay); | |
1016 EXPECT_EQ(clock->Now() + expected_delay, | |
1017 manager_->NextPendingDelayedTaskRunTime()); | |
1018 | |
1019 // Test it updates as time progresses | |
1020 clock->AdvanceNow(expected_delay); | |
1021 EXPECT_EQ(clock->Now(), manager_->NextPendingDelayedTaskRunTime()); | |
1022 } | |
1023 | |
1024 TEST_F(TaskQueueManagerTest, NextPendingDelayedTaskRunTime_MultipleQueues) { | |
1025 Initialize(3u, SelectorType::Automatic); | |
1026 | |
1027 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = { | |
1028 manager_->TaskRunnerForQueue(0), | |
1029 manager_->TaskRunnerForQueue(1), | |
1030 manager_->TaskRunnerForQueue(2)}; | |
1031 | |
1032 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); | |
1033 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5); | |
1034 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10); | |
1035 runners[0]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay1); | |
1036 runners[1]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay2); | |
1037 runners[2]->PostDelayedTask(FROM_HERE, base::Bind(&NopTask), delay3); | |
1038 | |
1039 EXPECT_EQ(now_src_->Now() + delay2, | |
1040 manager_->NextPendingDelayedTaskRunTime()); | |
1041 } | |
1042 | |
1043 } // namespace | |
1044 } // namespace content | |
1045 | |
OLD | NEW |