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

Side by Side Diff: base/task/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: Strip out everything else than TaskQueueManager. Added tests. 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 "base/task/task_queue_manager.h"
6
7 #include "base/task/task_queue_scheduler.h"
8 #include "base/test/test_simple_task_runner.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace base {
12 namespace {
13
14 class SchedulerForTest : public TaskQueueScheduler {
15 public:
16 SchedulerForTest() {}
17
18 virtual void RegisterWorkQueues(
19 const std::vector<const TaskQueue*>& work_queues) override {
20 work_queues_ = work_queues;
21 }
22
23 virtual bool ChooseWorkQueueToService(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 TaskQueue*>& work_queues() { return work_queues_; }
36
37 private:
38 std::deque<size_t> queues_to_service_;
39 std::vector<const base::TaskQueue*> work_queues_;
40 };
41
42 class TaskQueueManagerTest : public testing::Test {
43 public:
44 protected:
45 void Initialize(size_t num_queues) {
46 test_task_runner_ = make_scoped_refptr(new TestSimpleTaskRunner());
47 scheduler_ = make_scoped_ptr(new SchedulerForTest);
48 manager_ = make_scoped_ptr(
49 new TaskQueueManager(num_queues, test_task_runner_, scheduler_.get()));
50 }
51
52 scoped_refptr<TestSimpleTaskRunner> test_task_runner_;
53 scoped_ptr<SchedulerForTest> scheduler_;
54 scoped_ptr<TaskQueueManager> manager_;
55 };
56
57 void TestTask(int value, std::vector<int>* out_result) {
58 out_result->push_back(value);
59 }
60
61 TEST_F(TaskQueueManagerTest, SingleQueuePosting) {
62 Initialize(1u);
63 EXPECT_EQ(1u, scheduler_->work_queues().size());
64
65 std::vector<int> run_order;
66 scoped_refptr<base::SingleThreadTaskRunner> runner =
67 manager_->TaskRunnerForQueue(0);
68
69 runner->PostTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
70 runner->PostTask(FROM_HERE, Bind(&TestTask, 2, &run_order));
71 runner->PostTask(FROM_HERE, Bind(&TestTask, 3, &run_order));
72
73 scheduler_->AppendQueueToService(0);
74 scheduler_->AppendQueueToService(0);
75 scheduler_->AppendQueueToService(0);
76
77 test_task_runner_->RunUntilIdle();
78 EXPECT_EQ(1, run_order[0]);
79 EXPECT_EQ(2, run_order[1]);
80 EXPECT_EQ(3, run_order[2]);
81 }
82
83 TEST_F(TaskQueueManagerTest, MultiQueuePosting) {
84 Initialize(3u);
85 EXPECT_EQ(3u, scheduler_->work_queues().size());
86
87 std::vector<int> run_order;
88 scoped_refptr<base::SingleThreadTaskRunner> runners[3] = {
89 manager_->TaskRunnerForQueue(0),
90 manager_->TaskRunnerForQueue(1),
91 manager_->TaskRunnerForQueue(2)};
92
93 scheduler_->AppendQueueToService(0);
94 scheduler_->AppendQueueToService(1);
95 scheduler_->AppendQueueToService(2);
96 scheduler_->AppendQueueToService(0);
97 scheduler_->AppendQueueToService(1);
98 scheduler_->AppendQueueToService(2);
99
100 runners[0]->PostTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
101 runners[0]->PostTask(FROM_HERE, Bind(&TestTask, 2, &run_order));
102 runners[1]->PostTask(FROM_HERE, Bind(&TestTask, 3, &run_order));
103 runners[1]->PostTask(FROM_HERE, Bind(&TestTask, 4, &run_order));
104 runners[2]->PostTask(FROM_HERE, Bind(&TestTask, 5, &run_order));
105 runners[2]->PostTask(FROM_HERE, Bind(&TestTask, 6, &run_order));
106
107 test_task_runner_->RunUntilIdle();
108 EXPECT_EQ(1, run_order[0]);
109 EXPECT_EQ(3, run_order[1]);
110 EXPECT_EQ(5, run_order[2]);
111 EXPECT_EQ(2, run_order[3]);
112 EXPECT_EQ(4, run_order[4]);
113 EXPECT_EQ(6, run_order[5]);
114 }
115
116 TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) {
117 Initialize(1u);
118 EXPECT_EQ(1u, scheduler_->work_queues().size());
119
120 std::vector<int> run_order;
121 scoped_refptr<base::SingleThreadTaskRunner> runner =
122 manager_->TaskRunnerForQueue(0);
123
124 runner->PostNonNestableTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
125
126 // Non-nestable tasks never make it to the scheduler.
127 test_task_runner_->RunUntilIdle();
128 EXPECT_EQ(1, run_order[0]);
129 }
130
131 TEST_F(TaskQueueManagerTest, QueuePolling) {
132 Initialize(1u);
133
134 std::vector<int> run_order;
135 scoped_refptr<base::SingleThreadTaskRunner> runner =
136 manager_->TaskRunnerForQueue(0);
137
138 EXPECT_FALSE(manager_->PollQueue(0));
139 runner->PostTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
140 EXPECT_TRUE(manager_->PollQueue(0));
141
142 scheduler_->AppendQueueToService(0);
143 test_task_runner_->RunUntilIdle();
144 EXPECT_FALSE(manager_->PollQueue(0));
145 }
146
147 TEST_F(TaskQueueManagerTest, DelayedTaskPosting) {
148 Initialize(1u);
149
150 std::vector<int> run_order;
151 scoped_refptr<base::SingleThreadTaskRunner> runner =
152 manager_->TaskRunnerForQueue(0);
153
154 scheduler_->AppendQueueToService(0);
155
156 TimeDelta delay(TimeDelta::FromMilliseconds(10));
157 runner->PostDelayedTask(FROM_HERE, Bind(&TestTask, 1, &run_order), delay);
158 EXPECT_EQ(delay, test_task_runner_->NextPendingTaskDelay());
159 EXPECT_FALSE(manager_->PollQueue(0));
160 EXPECT_TRUE(run_order.empty());
161
162 // The task is inserted to the incoming queue only after the delay.
163 test_task_runner_->RunPendingTasks();
164 EXPECT_TRUE(manager_->PollQueue(0));
165 EXPECT_TRUE(run_order.empty());
166
167 // After the delay the task runs normally.
168 scheduler_->AppendQueueToService(0);
169 test_task_runner_->RunUntilIdle();
170 EXPECT_EQ(1, run_order[0]);
171 }
172
173 TEST_F(TaskQueueManagerTest, ManualPumping) {
174 Initialize(1u);
175 manager_->SetAutoPump(0, false);
176
177 std::vector<int> run_order;
178 scoped_refptr<base::SingleThreadTaskRunner> runner =
179 manager_->TaskRunnerForQueue(0);
180
181 // Posting a task when pumping is disabled doesn't result in work getting
182 // posted.
183 runner->PostTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
184 EXPECT_FALSE(test_task_runner_->HasPendingTask());
185
186 // However polling still works.
187 EXPECT_TRUE(manager_->PollQueue(0));
188
189 // After pumping the task runs normally.
190 manager_->PumpQueue(0);
191 EXPECT_TRUE(test_task_runner_->HasPendingTask());
192 scheduler_->AppendQueueToService(0);
193 test_task_runner_->RunUntilIdle();
194 EXPECT_EQ(1, run_order[0]);
195 }
196
197 TEST_F(TaskQueueManagerTest, ManualPumpingToggle) {
198 Initialize(1u);
199 manager_->SetAutoPump(0, false);
200
201 std::vector<int> run_order;
202 scoped_refptr<base::SingleThreadTaskRunner> runner =
203 manager_->TaskRunnerForQueue(0);
204
205 // Posting a task when pumping is disabled doesn't result in work getting
206 // posted.
207 runner->PostTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
208 EXPECT_FALSE(test_task_runner_->HasPendingTask());
209
210 // When pumping is enabled the task runs normally.
211 manager_->SetAutoPump(0, true);
212 EXPECT_TRUE(test_task_runner_->HasPendingTask());
213 scheduler_->AppendQueueToService(0);
214 test_task_runner_->RunUntilIdle();
215 EXPECT_EQ(1, run_order[0]);
216 }
217
218 TEST_F(TaskQueueManagerTest, DenyRunning) {
219 Initialize(1u);
220
221 std::vector<int> run_order;
222 scoped_refptr<base::SingleThreadTaskRunner> runner =
223 manager_->TaskRunnerForQueue(0);
224 runner->PostTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
225
226 // Since we haven't scheduled a work queue to be selected, the task doesn't
227 // run.
228 test_task_runner_->RunUntilIdle();
229 EXPECT_TRUE(run_order.empty());
230
231 // Pumping the queue again with a scheduled work queue runs the task.
232 manager_->PumpQueue(0);
233 scheduler_->AppendQueueToService(0);
234 test_task_runner_->RunUntilIdle();
235 EXPECT_EQ(1, run_order[0]);
236 }
237
238 TEST_F(TaskQueueManagerTest, ManualPumpingWithDelayedTask) {
239 Initialize(1u);
240 manager_->SetAutoPump(0, false);
241
242 std::vector<int> run_order;
243 scoped_refptr<base::SingleThreadTaskRunner> runner =
244 manager_->TaskRunnerForQueue(0);
245
246 // Posting a delayed task when pumping will apply the delay, but won't cause
247 // work to executed afterwards.
248 TimeDelta delay(TimeDelta::FromMilliseconds(10));
249 runner->PostDelayedTask(FROM_HERE, Bind(&TestTask, 1, &run_order), delay);
250 test_task_runner_->RunUntilIdle();
251 EXPECT_TRUE(run_order.empty());
252
253 // After pumping the task runs normally.
254 manager_->PumpQueue(0);
255 EXPECT_TRUE(test_task_runner_->HasPendingTask());
256 scheduler_->AppendQueueToService(0);
257 test_task_runner_->RunUntilIdle();
258 EXPECT_EQ(1, run_order[0]);
259 }
260
261 void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner,
262 int countdown,
263 std::vector<int>* out_result) {
264 out_result->push_back(countdown);
265 if (--countdown) {
266 runner->PostTask(FROM_HERE,
267 Bind(&ReentrantTestTask, runner, countdown, out_result));
268 }
269 }
270
271 TEST_F(TaskQueueManagerTest, ReentrantPosting) {
272 Initialize(1u);
273 EXPECT_EQ(1u, scheduler_->work_queues().size());
274
275 std::vector<int> run_order;
276 scoped_refptr<base::SingleThreadTaskRunner> runner =
277 manager_->TaskRunnerForQueue(0);
278
279 runner->PostTask(FROM_HERE, Bind(&ReentrantTestTask, runner, 3, &run_order));
280
281 scheduler_->AppendQueueToService(0);
282 scheduler_->AppendQueueToService(0);
283 scheduler_->AppendQueueToService(0);
284
285 test_task_runner_->RunUntilIdle();
286 EXPECT_EQ(3, run_order[0]);
287 EXPECT_EQ(2, run_order[1]);
288 EXPECT_EQ(1, run_order[2]);
289 }
290
291 TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) {
292 Initialize(1u);
293
294 std::vector<int> run_order;
295 scoped_refptr<base::SingleThreadTaskRunner> runner =
296 manager_->TaskRunnerForQueue(0);
297
298 runner->PostTask(FROM_HERE, Bind(&TestTask, 1, &run_order));
299 manager_.reset();
300 scheduler_.reset();
301
302 test_task_runner_->RunUntilIdle();
303 EXPECT_TRUE(run_order.empty());
304 }
305
306 } // namespace
307 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698