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

Side by Side Diff: content/renderer/scheduler/task_queue_manager_unittest.cc

Issue 637303003: content: Add task queue manager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Back to content. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/scheduler/task_queue_manager.h"
6
7 #include "base/test/test_simple_task_runner.h"
8 #include "content/renderer/scheduler/task_queue_selector.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace content {
12 namespace {
13
14 class SelectorForTest : public TaskQueueSelector {
15 public:
16 SelectorForTest() {}
17
18 virtual void RegisterWorkQueues(
19 const std::vector<const base::TaskQueue*>& work_queues) override {
20 work_queues_ = work_queues;
21 }
22
23 virtual bool SelectWorkQueueToService(size_t* out_queue_index) override {
24 if (queues_to_service_.empty())
25 return false;
26 *out_queue_index = queues_to_service_.front();
27 queues_to_service_.pop_front();
28 return true;
29 }
30
31 void AppendQueueToService(size_t queue_index) {
32 queues_to_service_.push_back(queue_index);
33 }
34
35 const std::vector<const base::TaskQueue*>& work_queues() {
36 return work_queues_;
37 }
38
39 private:
40 std::deque<size_t> queues_to_service_;
41 std::vector<const base::TaskQueue*> work_queues_;
42 };
jochen (gone - plz use gerrit) 2014/10/20 13:35:31 nit. disallow copy & assign
Sami 2014/10/20 15:29:57 Done.
43
44 class TaskQueueManagerTest : public testing::Test {
45 public:
jochen (gone - plz use gerrit) 2014/10/20 13:35:31 nit. not needed
Sami 2014/10/20 15:29:57 Done.
46 protected:
47 void Initialize(size_t num_queues) {
48 test_task_runner_ = make_scoped_refptr(new base::TestSimpleTaskRunner());
49 selector_ = make_scoped_ptr(new SelectorForTest);
50 manager_ = make_scoped_ptr(
51 new TaskQueueManager(num_queues, test_task_runner_, selector_.get()));
52 }
53
54 scoped_refptr<base::TestSimpleTaskRunner> test_task_runner_;
55 scoped_ptr<SelectorForTest> selector_;
56 scoped_ptr<TaskQueueManager> manager_;
57 };
58
59 void TestTask(int value, std::vector<int>* out_result) {
60 out_result->push_back(value);
61 }
62
63 TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
64 Initialize(1u);
65 EXPECT_EQ(1u, selector_->work_queues().size());
66
67 std::vector<int> run_order;
68 scoped_refptr<base::SingleThreadTaskRunner> runner =
69 manager_->TaskRunnerForQueue(0);
70
71 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
72 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
73 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
74
75 selector_->AppendQueueToService(0);
76 selector_->AppendQueueToService(0);
77 selector_->AppendQueueToService(0);
78
79 test_task_runner_->RunUntilIdle();
80 EXPECT_EQ(1, run_order[0]);
81 EXPECT_EQ(2, run_order[1]);
82 EXPECT_EQ(3, run_order[2]);
83 }
84
85 TEST_F(TaskQueueManagerTest, MultiQueuePosting) {
86 Initialize(3u);
87 EXPECT_EQ(3u, selector_->work_queues().size());
88
89 std::vector<int> run_order;
90 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
91 manager_->TaskRunnerForQueue(0),
92 manager_->TaskRunnerForQueue(1),
93 manager_->TaskRunnerForQueue(2)};
94
95 selector_->AppendQueueToService(0);
96 selector_->AppendQueueToService(1);
97 selector_->AppendQueueToService(2);
98 selector_->AppendQueueToService(0);
99 selector_->AppendQueueToService(1);
100 selector_->AppendQueueToService(2);
101
102 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
103 runners[0]->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
104 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 3, &run_order));
105 runners[1]->PostTask(FROM_HERE, base::Bind(&TestTask, 4, &run_order));
106 runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 5, &run_order));
107 runners[2]->PostTask(FROM_HERE, base::Bind(&TestTask, 6, &run_order));
108
109 test_task_runner_->RunUntilIdle();
110 EXPECT_EQ(1, run_order[0]);
111 EXPECT_EQ(3, run_order[1]);
112 EXPECT_EQ(5, run_order[2]);
113 EXPECT_EQ(2, run_order[3]);
114 EXPECT_EQ(4, run_order[4]);
115 EXPECT_EQ(6, run_order[5]);
116 }
117
118 TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) {
119 Initialize(1u);
120 EXPECT_EQ(1u, selector_->work_queues().size());
121
122 std::vector<int> run_order;
123 scoped_refptr<base::SingleThreadTaskRunner> runner =
124 manager_->TaskRunnerForQueue(0);
125
126 runner->PostNonNestableTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
127
128 // Non-nestable tasks never make it to the selector.
129 test_task_runner_->RunUntilIdle();
130 EXPECT_EQ(1, run_order[0]);
131 }
132
133 TEST_F(TaskQueueManagerTest, QueuePolling) {
134 Initialize(1u);
135
136 std::vector<int> run_order;
137 scoped_refptr<base::SingleThreadTaskRunner> runner =
138 manager_->TaskRunnerForQueue(0);
139
140 EXPECT_FALSE(manager_->PollQueue(0));
141 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
142 EXPECT_TRUE(manager_->PollQueue(0));
143
144 selector_->AppendQueueToService(0);
145 test_task_runner_->RunUntilIdle();
146 EXPECT_FALSE(manager_->PollQueue(0));
147 }
148
149 TEST_F(TaskQueueManagerTest, DelayedTaskPosting) {
150 Initialize(1u);
151
152 std::vector<int> run_order;
153 scoped_refptr<base::SingleThreadTaskRunner> runner =
154 manager_->TaskRunnerForQueue(0);
155
156 selector_->AppendQueueToService(0);
157
158 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
159 runner->PostDelayedTask(
160 FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay);
161 EXPECT_EQ(delay, test_task_runner_->NextPendingTaskDelay());
162 EXPECT_FALSE(manager_->PollQueue(0));
163 EXPECT_TRUE(run_order.empty());
164
165 // The task is inserted to the incoming queue only after the delay.
166 test_task_runner_->RunPendingTasks();
167 EXPECT_TRUE(manager_->PollQueue(0));
168 EXPECT_TRUE(run_order.empty());
169
170 // After the delay the task runs normally.
171 selector_->AppendQueueToService(0);
172 test_task_runner_->RunUntilIdle();
173 EXPECT_EQ(1, run_order[0]);
174 }
175
176 TEST_F(TaskQueueManagerTest, ManualPumping) {
177 Initialize(1u);
178 manager_->SetAutoPump(0, false);
179
180 std::vector<int> run_order;
181 scoped_refptr<base::SingleThreadTaskRunner> runner =
182 manager_->TaskRunnerForQueue(0);
183
184 // Posting a task when pumping is disabled doesn't result in work getting
185 // posted.
186 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
187 EXPECT_FALSE(test_task_runner_->HasPendingTask());
188
189 // However polling still works.
190 EXPECT_TRUE(manager_->PollQueue(0));
191
192 // After pumping the task runs normally.
193 manager_->PumpQueue(0);
194 EXPECT_TRUE(test_task_runner_->HasPendingTask());
195 selector_->AppendQueueToService(0);
196 test_task_runner_->RunUntilIdle();
197 EXPECT_EQ(1, run_order[0]);
198 }
199
200 TEST_F(TaskQueueManagerTest, ManualPumpingToggle) {
201 Initialize(1u);
202 manager_->SetAutoPump(0, false);
203
204 std::vector<int> run_order;
205 scoped_refptr<base::SingleThreadTaskRunner> runner =
206 manager_->TaskRunnerForQueue(0);
207
208 // Posting a task when pumping is disabled doesn't result in work getting
209 // posted.
210 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
211 EXPECT_FALSE(test_task_runner_->HasPendingTask());
212
213 // When pumping is enabled the task runs normally.
214 manager_->SetAutoPump(0, true);
215 EXPECT_TRUE(test_task_runner_->HasPendingTask());
216 selector_->AppendQueueToService(0);
217 test_task_runner_->RunUntilIdle();
218 EXPECT_EQ(1, run_order[0]);
219 }
220
221 TEST_F(TaskQueueManagerTest, DenyRunning) {
222 Initialize(1u);
223
224 std::vector<int> run_order;
225 scoped_refptr<base::SingleThreadTaskRunner> runner =
226 manager_->TaskRunnerForQueue(0);
227 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
228
229 // Since we haven't appended a work queue to be selected, the task doesn't
230 // run.
231 test_task_runner_->RunUntilIdle();
232 EXPECT_TRUE(run_order.empty());
233
234 // Pumping the queue again with a selected work queue runs the task.
235 manager_->PumpQueue(0);
236 selector_->AppendQueueToService(0);
237 test_task_runner_->RunUntilIdle();
238 EXPECT_EQ(1, run_order[0]);
239 }
240
241 TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) {
242 Initialize(1u);
243 manager_->SetAutoPump(0, false);
244
245 std::vector<int> run_order;
246 scoped_refptr<base::SingleThreadTaskRunner> runner =
247 manager_->TaskRunnerForQueue(0);
248
249 // Posting a delayed task when pumping will apply the delay, but won't cause
250 // work to executed afterwards.
251 base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10));
252 runner->PostDelayedTask(
253 FROM_HERE, base::Bind(&TestTask, 1, &run_order), delay);
254 test_task_runner_->RunUntilIdle();
255 EXPECT_TRUE(run_order.empty());
256
257 // After pumping the task runs normally.
258 manager_->PumpQueue(0);
259 EXPECT_TRUE(test_task_runner_->HasPendingTask());
260 selector_->AppendQueueToService(0);
261 test_task_runner_->RunUntilIdle();
262 EXPECT_EQ(1, run_order[0]);
263 }
264
265 TEST_F(TaskQueueManagerTest, ManualPumpingWithNonEmptyWorkQueue) {
266 Initialize(1u);
267 manager_->SetAutoPump(0, false);
268
269 std::vector<int> run_order;
270 scoped_refptr<base::SingleThreadTaskRunner> runner =
271 manager_->TaskRunnerForQueue(0);
272
273 // Posting two tasks and pumping twice should result in two tasks in the work
274 // queue.
275 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
276 manager_->PumpQueue(0);
277 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 2, &run_order));
278 manager_->PumpQueue(0);
279
280 EXPECT_EQ(2u, selector_->work_queues()[0]->size());
281 }
282
283 void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
284 int countdown,
285 std::vector<int>* out_result) {
286 out_result->push_back(countdown);
287 if (--countdown) {
288 runner->PostTask(FROM_HERE,
289 Bind(&ReentrantTestTask, runner, countdown, out_result));
290 }
291 }
292
293 TEST_F(TaskQueueManagerTest, ReentrantPosting) {
294 Initialize(1u);
295 EXPECT_EQ(1u, selector_->work_queues().size());
296
297 std::vector<int> run_order;
298 scoped_refptr<base::SingleThreadTaskRunner> runner =
299 manager_->TaskRunnerForQueue(0);
300
301 runner->PostTask(FROM_HERE, Bind(&ReentrantTestTask, runner, 3, &run_order));
302
303 selector_->AppendQueueToService(0);
304 selector_->AppendQueueToService(0);
305 selector_->AppendQueueToService(0);
306
307 test_task_runner_->RunUntilIdle();
308 EXPECT_EQ(3, run_order[0]);
309 EXPECT_EQ(2, run_order[1]);
310 EXPECT_EQ(1, run_order[2]);
311 }
312
313 TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) {
314 Initialize(1u);
315
316 std::vector<int> run_order;
317 scoped_refptr<base::SingleThreadTaskRunner> runner =
318 manager_->TaskRunnerForQueue(0);
319
320 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
321 manager_.reset();
322 selector_.reset();
323 runner->PostTask(FROM_HERE, base::Bind(&TestTask, 1, &run_order));
324
325 test_task_runner_->RunUntilIdle();
326 EXPECT_TRUE(run_order.empty());
327 }
328
329 } // namespace
330 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698