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