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

Side by Side Diff: content/browser/startup_task_runner_unittest.cc

Issue 2726523002: Pass Callback to TaskRunner by value and consume it on invocation (1) (Closed)
Patch Set: erase Closure* Created 3 years, 8 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/startup_task_runner.h" 5 #include "content/browser/startup_task_runner.h"
6 6
7 #include <utility>
8
7 #include "base/bind.h" 9 #include "base/bind.h"
8 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
9 #include "base/callback.h" 11 #include "base/callback.h"
10 #include "base/location.h" 12 #include "base/location.h"
11 #include "base/run_loop.h" 13 #include "base/run_loop.h"
12 #include "base/task_runner.h" 14 #include "base/task_runner.h"
13 15
14 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
16 18
17 namespace content { 19 namespace content {
18 namespace { 20 namespace {
19 21
20 using base::Closure; 22 using base::Closure;
21 using testing::_; 23 using testing::_;
22 using testing::Assign; 24 using testing::Assign;
23 using testing::Invoke; 25 using testing::Invoke;
24 using testing::WithArg;
25 26
26 int observer_calls = 0; 27 int observer_calls = 0;
27 int task_count = 0; 28 int task_count = 0;
28 int observer_result; 29 int observer_result;
29 base::Closure task;
30
31 // I couldn't get gMock's SaveArg to compile, hence had to save the argument
32 // this way
33 bool SaveTaskArg(const Closure& arg) {
34 task = arg;
35 return true;
36 }
37 30
38 void Observer(int result) { 31 void Observer(int result) {
39 observer_calls++; 32 observer_calls++;
40 observer_result = result; 33 observer_result = result;
41 } 34 }
42 35
43 class StartupTaskRunnerTest : public testing::Test { 36 class StartupTaskRunnerTest : public testing::Test {
44 public: 37 public:
45 void SetUp() override { 38 void SetUp() override {
46 last_task_ = 0; 39 last_task_ = 0;
(...skipping 30 matching lines...) Expand all
77 // We can't use the real message loop, even if we want to, since doing so on 70 // We can't use the real message loop, even if we want to, since doing so on
78 // Android requires a complex Java infrastructure. The test would have to built 71 // Android requires a complex Java infrastructure. The test would have to built
79 // as a content_shell test; but content_shell startup invokes the class we are 72 // as a content_shell test; but content_shell startup invokes the class we are
80 // trying to test. 73 // trying to test.
81 // 74 //
82 // The mocks are not directly in TaskRunnerProxy because reference counted 75 // The mocks are not directly in TaskRunnerProxy because reference counted
83 // objects seem to confuse the mocking framework 76 // objects seem to confuse the mocking framework
84 77
85 class MockTaskRunner { 78 class MockTaskRunner {
86 public: 79 public:
87 MOCK_METHOD3( 80 MOCK_METHOD2(PostDelayedTask,
88 PostDelayedTask, 81 bool(const tracked_objects::Location&, base::TimeDelta));
89 bool(const tracked_objects::Location&, const Closure&, base::TimeDelta)); 82 MOCK_METHOD2(PostNonNestableDelayedTask,
90 MOCK_METHOD3( 83 bool(const tracked_objects::Location&, base::TimeDelta));
91 PostNonNestableDelayedTask,
92 bool(const tracked_objects::Location&, const Closure&, base::TimeDelta));
93 }; 84 };
94 85
95 class TaskRunnerProxy : public base::SingleThreadTaskRunner { 86 class TaskRunnerProxy : public base::SingleThreadTaskRunner {
96 public: 87 public:
97 TaskRunnerProxy(MockTaskRunner* mock) : mock_(mock) {} 88 TaskRunnerProxy(MockTaskRunner* mock) : mock_(mock) {}
98 bool RunsTasksOnCurrentThread() const override { return true; } 89 bool RunsTasksOnCurrentThread() const override { return true; }
99 bool PostDelayedTask(const tracked_objects::Location& location, 90 bool PostDelayedTask(const tracked_objects::Location& location,
100 const Closure& closure, 91 base::Closure closure,
101 base::TimeDelta delta) override { 92 base::TimeDelta delta) override {
102 return mock_->PostDelayedTask(location, closure, delta); 93 last_task_ = std::move(closure);
94 return mock_->PostDelayedTask(location, delta);
103 } 95 }
104 bool PostNonNestableDelayedTask(const tracked_objects::Location& location, 96 bool PostNonNestableDelayedTask(const tracked_objects::Location& location,
105 const Closure& closure, 97 base::Closure closure,
106 base::TimeDelta delta) override { 98 base::TimeDelta delta) override {
107 return mock_->PostNonNestableDelayedTask(location, closure, delta); 99 last_task_ = std::move(closure);
100 return mock_->PostNonNestableDelayedTask(location, delta);
108 } 101 }
109 102
103 base::Closure TakeLastTaskClosure() { return std::move(last_task_); }
104
110 private: 105 private:
106 ~TaskRunnerProxy() override {}
107
111 MockTaskRunner* mock_; 108 MockTaskRunner* mock_;
112 ~TaskRunnerProxy() override {} 109 base::Closure last_task_;
113 }; 110 };
114 111
115 TEST_F(StartupTaskRunnerTest, SynchronousExecution) { 112 TEST_F(StartupTaskRunnerTest, SynchronousExecution) {
116 MockTaskRunner mock_runner; 113 MockTaskRunner mock_runner;
117 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 114 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
118 115
119 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 116 EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
120 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 117 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0);
121 118
122 StartupTaskRunner runner(base::Bind(&Observer), proxy); 119 StartupTaskRunner runner(base::Bind(&Observer), proxy);
123 120
124 StartupTask task1 = 121 StartupTask task1 =
125 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this)); 122 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
126 runner.AddTask(task1); 123 runner.AddTask(task1);
127 EXPECT_EQ(GetLastTask(), 0); 124 EXPECT_EQ(GetLastTask(), 0);
128 StartupTask task2 = 125 StartupTask task2 =
129 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 126 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
130 runner.AddTask(task2); 127 runner.AddTask(task2);
(...skipping 16 matching lines...) Expand all
147 // No more tasks should be run and the observer should not have been called 144 // No more tasks should be run and the observer should not have been called
148 // again 145 // again
149 EXPECT_EQ(task_count, 2); 146 EXPECT_EQ(task_count, 2);
150 EXPECT_EQ(observer_calls, 1); 147 EXPECT_EQ(observer_calls, 1);
151 } 148 }
152 149
153 TEST_F(StartupTaskRunnerTest, NullObserver) { 150 TEST_F(StartupTaskRunnerTest, NullObserver) {
154 MockTaskRunner mock_runner; 151 MockTaskRunner mock_runner;
155 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 152 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
156 153
157 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 154 EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
158 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 155 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0);
159 156
160 StartupTaskRunner runner(base::Callback<void(int)>(), proxy); 157 StartupTaskRunner runner(base::Callback<void(int)>(), proxy);
161 158
162 StartupTask task1 = 159 StartupTask task1 =
163 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this)); 160 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
164 runner.AddTask(task1); 161 runner.AddTask(task1);
165 EXPECT_EQ(GetLastTask(), 0); 162 EXPECT_EQ(GetLastTask(), 0);
166 StartupTask task2 = 163 StartupTask task2 =
167 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 164 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
168 runner.AddTask(task2); 165 runner.AddTask(task2);
(...skipping 13 matching lines...) Expand all
182 // No more tasks should have been run 179 // No more tasks should have been run
183 EXPECT_EQ(task_count, 2); 180 EXPECT_EQ(task_count, 2);
184 181
185 EXPECT_EQ(observer_calls, 0); 182 EXPECT_EQ(observer_calls, 0);
186 } 183 }
187 184
188 TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) { 185 TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) {
189 MockTaskRunner mock_runner; 186 MockTaskRunner mock_runner;
190 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 187 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
191 188
192 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 189 EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
193 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 190 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0);
194 191
195 StartupTaskRunner runner(base::Bind(&Observer), proxy); 192 StartupTaskRunner runner(base::Bind(&Observer), proxy);
196 193
197 StartupTask task3 = 194 StartupTask task3 =
198 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this)); 195 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
199 runner.AddTask(task3); 196 runner.AddTask(task3);
200 EXPECT_EQ(GetLastTask(), 0); 197 EXPECT_EQ(GetLastTask(), 0);
201 StartupTask task2 = 198 StartupTask task2 =
202 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 199 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
203 runner.AddTask(task2); 200 runner.AddTask(task2);
(...skipping 16 matching lines...) Expand all
220 // no more tasks should have run 217 // no more tasks should have run
221 EXPECT_EQ(observer_calls, 1); 218 EXPECT_EQ(observer_calls, 1);
222 EXPECT_EQ(task_count, 1); 219 EXPECT_EQ(task_count, 1);
223 } 220 }
224 221
225 TEST_F(StartupTaskRunnerTest, AsynchronousExecution) { 222 TEST_F(StartupTaskRunnerTest, AsynchronousExecution) {
226 223
227 MockTaskRunner mock_runner; 224 MockTaskRunner mock_runner;
228 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 225 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
229 226
230 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 227 EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
231 EXPECT_CALL( 228 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(
232 mock_runner, 229 _, base::TimeDelta::FromMilliseconds(0)))
233 PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0)))
234 .Times(testing::Between(2, 3)) 230 .Times(testing::Between(2, 3))
235 .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg))); 231 .WillRepeatedly(testing::Return(true));
236 232
237 StartupTaskRunner runner(base::Bind(&Observer), proxy); 233 StartupTaskRunner runner(base::Bind(&Observer), proxy);
238 234
239 StartupTask task1 = 235 StartupTask task1 =
240 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this)); 236 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
241 runner.AddTask(task1); 237 runner.AddTask(task1);
242 StartupTask task2 = 238 StartupTask task2 =
243 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 239 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
244 runner.AddTask(task2); 240 runner.AddTask(task2);
245 241
246 // Nothing should run until we tell them to. 242 // Nothing should run until we tell them to.
247 EXPECT_EQ(GetLastTask(), 0); 243 EXPECT_EQ(GetLastTask(), 0);
248 runner.StartRunningTasksAsync(); 244 runner.StartRunningTasksAsync();
249 245
250 // No tasks should have run yet, since we the message loop hasn't run. 246 // No tasks should have run yet, since we the message loop hasn't run.
251 EXPECT_EQ(GetLastTask(), 0); 247 EXPECT_EQ(GetLastTask(), 0);
252 248
253 // Fake the actual message loop. Each time a task is run a new task should 249 // Fake the actual message loop. Each time a task is run a new task should
254 // be added to the queue, hence updating "task". The loop should actually run 250 // be added to the queue, hence updating "task". The loop should actually run
255 // at most 3 times (once for each task plus possibly once for the observer), 251 // at most 3 times (once for each task plus possibly once for the observer),
256 // the "4" is a backstop. 252 // the "4" is a backstop.
257 for (int i = 0; i < 4 && observer_calls == 0; i++) { 253 for (int i = 0; i < 4 && observer_calls == 0; i++) {
258 task.Run(); 254 proxy->TakeLastTaskClosure().Run();
259 EXPECT_EQ(i + 1, GetLastTask()); 255 EXPECT_EQ(i + 1, GetLastTask());
260 } 256 }
261 EXPECT_EQ(task_count, 2); 257 EXPECT_EQ(task_count, 2);
262 EXPECT_EQ(observer_calls, 1); 258 EXPECT_EQ(observer_calls, 1);
263 EXPECT_EQ(observer_result, 0); 259 EXPECT_EQ(observer_result, 0);
264 260
265 // Check that running synchronously now doesn't do anything 261 // Check that running synchronously now doesn't do anything
266 262
267 runner.RunAllTasksNow(); 263 runner.RunAllTasksNow();
268 EXPECT_EQ(task_count, 2); 264 EXPECT_EQ(task_count, 2);
269 EXPECT_EQ(observer_calls, 1); 265 EXPECT_EQ(observer_calls, 1);
270 } 266 }
271 267
272 TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) { 268 TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) {
273 269
274 MockTaskRunner mock_runner; 270 MockTaskRunner mock_runner;
275 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 271 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
276 272
277 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 273 EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0);
278 EXPECT_CALL( 274 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(
279 mock_runner, 275 _, base::TimeDelta::FromMilliseconds(0)))
280 PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0)))
281 .Times(testing::Between(1, 2)) 276 .Times(testing::Between(1, 2))
282 .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg))); 277 .WillRepeatedly(testing::Return(true));
283 278
284 StartupTaskRunner runner(base::Bind(&Observer), proxy); 279 StartupTaskRunner runner(base::Bind(&Observer), proxy);
285 280
286 StartupTask task3 = 281 StartupTask task3 =
287 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this)); 282 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
288 runner.AddTask(task3); 283 runner.AddTask(task3);
289 StartupTask task2 = 284 StartupTask task2 =
290 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 285 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
291 runner.AddTask(task2); 286 runner.AddTask(task2);
292 287
293 // Nothing should run until we tell them to. 288 // Nothing should run until we tell them to.
294 EXPECT_EQ(GetLastTask(), 0); 289 EXPECT_EQ(GetLastTask(), 0);
295 runner.StartRunningTasksAsync(); 290 runner.StartRunningTasksAsync();
296 291
297 // No tasks should have run yet, since we the message loop hasn't run. 292 // No tasks should have run yet, since we the message loop hasn't run.
298 EXPECT_EQ(GetLastTask(), 0); 293 EXPECT_EQ(GetLastTask(), 0);
299 294
300 // Fake the actual message loop. Each time a task is run a new task should 295 // Fake the actual message loop. Each time a task is run a new task should
301 // be added to the queue, hence updating "task". The loop should actually run 296 // be added to the queue, hence updating "task". The loop should actually run
302 // at most twice (once for the failed task plus possibly once for the 297 // at most twice (once for the failed task plus possibly once for the
303 // observer), the "4" is a backstop. 298 // observer), the "4" is a backstop.
304 for (int i = 0; i < 4 && observer_calls == 0; i++) { 299 for (int i = 0; i < 4 && observer_calls == 0; i++)
305 task.Run(); 300 proxy->TakeLastTaskClosure().Run();
306 }
307 EXPECT_EQ(GetLastTask(), 3); 301 EXPECT_EQ(GetLastTask(), 3);
308 EXPECT_EQ(task_count, 1); 302 EXPECT_EQ(task_count, 1);
309 303
310 EXPECT_EQ(observer_calls, 1); 304 EXPECT_EQ(observer_calls, 1);
311 EXPECT_EQ(observer_result, 1); 305 EXPECT_EQ(observer_result, 1);
312 306
313 // Check that running synchronously now doesn't do anything 307 // Check that running synchronously now doesn't do anything
314 runner.RunAllTasksNow(); 308 runner.RunAllTasksNow();
315 EXPECT_EQ(observer_calls, 1); 309 EXPECT_EQ(observer_calls, 1);
316 EXPECT_EQ(task_count, 1); 310 EXPECT_EQ(task_count, 1);
317 } 311 }
318 } // namespace 312 } // namespace
319 } // namespace content 313 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/dom_storage/dom_storage_task_runner.cc ('k') | content/child/worker_thread_registry.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698