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

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

Issue 25348004: Empty startup task queue when tasks run synchronously (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Empty startup task queue when tasks run synchronously - fix nits and upload problems Created 7 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
« no previous file with comments | « content/browser/startup_task_runner.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/task_runner.h" 12 #include "base/task_runner.h"
13 13
14 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 16
17 namespace content { 17 namespace content {
18 namespace { 18 namespace {
19 19
20 using base::Closure; 20 using base::Closure;
21 using testing::_; 21 using testing::_;
22 using testing::Assign; 22 using testing::Assign;
23 using testing::Invoke; 23 using testing::Invoke;
24 using testing::WithArg; 24 using testing::WithArg;
25 25
26 bool observer_called = false; 26 int observer_calls = 0;
27 int task_count = 0;
27 int observer_result; 28 int observer_result;
28 base::Closure task; 29 base::Closure task;
29 30
30 // I couldn't get gMock's SaveArg to compile, hence had to save the argument 31 // I couldn't get gMock's SaveArg to compile, hence had to save the argument
31 // this way 32 // this way
32 bool SaveTaskArg(const Closure& arg) { 33 bool SaveTaskArg(const Closure& arg) {
33 task = arg; 34 task = arg;
34 return true; 35 return true;
35 } 36 }
36 37
37 void Observer(int result) { 38 void Observer(int result) {
38 observer_called = true; 39 observer_calls++;
39 observer_result = result; 40 observer_result = result;
40 } 41 }
41 42
42 class StartupTaskRunnerTest : public testing::Test { 43 class StartupTaskRunnerTest : public testing::Test {
43 public: 44 public:
44 45
45 virtual void SetUp() { 46 virtual void SetUp() {
46 last_task_ = 0; 47 last_task_ = 0;
47 observer_called = false; 48 observer_calls = 0;
49 task_count = 0;
48 } 50 }
49 51
50 int Task1() { 52 int Task1() {
51 last_task_ = 1; 53 last_task_ = 1;
54 task_count++;
52 return 0; 55 return 0;
53 } 56 }
54 57
55 int Task2() { 58 int Task2() {
56 last_task_ = 2; 59 last_task_ = 2;
60 task_count++;
57 return 0; 61 return 0;
58 } 62 }
59 63
60 int FailingTask() { 64 int FailingTask() {
61 // Task returning failure 65 // Task returning failure
62 last_task_ = 3; 66 last_task_ = 3;
67 task_count++;
63 return 1; 68 return 1;
64 } 69 }
65 70
66 int GetLastTask() { return last_task_; } 71 int GetLastTask() { return last_task_; }
67 72
68 private: 73 private:
69 74
70 int last_task_; 75 int last_task_;
71 }; 76 };
72 77
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 131 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
127 runner.AddTask(task2); 132 runner.AddTask(task2);
128 133
129 // Nothing should run until we tell them to. 134 // Nothing should run until we tell them to.
130 EXPECT_EQ(GetLastTask(), 0); 135 EXPECT_EQ(GetLastTask(), 0);
131 runner.RunAllTasksNow(); 136 runner.RunAllTasksNow();
132 137
133 // On an immediate StartupTaskRunner the tasks should now all have run. 138 // On an immediate StartupTaskRunner the tasks should now all have run.
134 EXPECT_EQ(GetLastTask(), 2); 139 EXPECT_EQ(GetLastTask(), 2);
135 140
136 EXPECT_TRUE(observer_called); 141 EXPECT_EQ(task_count, 2);
142 EXPECT_EQ(observer_calls, 1);
137 EXPECT_EQ(observer_result, 0); 143 EXPECT_EQ(observer_result, 0);
144
145 // Running the tasks asynchronously shouldn't do anything
146 // In particular Post... should not be called
147 runner.StartRunningTasksAsync();
148
149 // No more tasks should be run and the observer should not have been called
150 // again
151 EXPECT_EQ(task_count, 2);
152 EXPECT_EQ(observer_calls, 1);
138 } 153 }
139 154
140 TEST_F(StartupTaskRunnerTest, NullObserver) { 155 TEST_F(StartupTaskRunnerTest, NullObserver) {
141 MockTaskRunner mock_runner; 156 MockTaskRunner mock_runner;
142 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 157 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
143 158
144 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 159 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
145 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 160 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
146 161
147 StartupTaskRunner runner(base::Callback<void(int)>(), proxy); 162 StartupTaskRunner runner(base::Callback<void(int)>(), proxy);
148 163
149 StartupTask task1 = 164 StartupTask task1 =
150 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this)); 165 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
151 runner.AddTask(task1); 166 runner.AddTask(task1);
152 EXPECT_EQ(GetLastTask(), 0); 167 EXPECT_EQ(GetLastTask(), 0);
153 StartupTask task2 = 168 StartupTask task2 =
154 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 169 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
155 runner.AddTask(task2); 170 runner.AddTask(task2);
156 171
157 // Nothing should run until we tell them to. 172 // Nothing should run until we tell them to.
158 EXPECT_EQ(GetLastTask(), 0); 173 EXPECT_EQ(GetLastTask(), 0);
159 runner.RunAllTasksNow(); 174 runner.RunAllTasksNow();
160 175
161 // On an immediate StartupTaskRunner the tasks should now all have run. 176 // On an immediate StartupTaskRunner the tasks should now all have run.
162 EXPECT_EQ(GetLastTask(), 2); 177 EXPECT_EQ(GetLastTask(), 2);
178 EXPECT_EQ(task_count, 2);
163 179
164 EXPECT_FALSE(observer_called); 180 // Running the tasks asynchronously shouldn't do anything
181 // In particular Post... should not be called
182 runner.StartRunningTasksAsync();
183
184 // No more tasks should have been run
185 EXPECT_EQ(task_count, 2);
186
187 EXPECT_EQ(observer_calls, 0);
165 } 188 }
166 189
167 TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) { 190 TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) {
168 MockTaskRunner mock_runner; 191 MockTaskRunner mock_runner;
169 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 192 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
170 193
171 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 194 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
172 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0); 195 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
173 196
174 StartupTaskRunner runner(base::Bind(&Observer), proxy); 197 StartupTaskRunner runner(base::Bind(&Observer), proxy);
175 198
176 StartupTask task3 = 199 StartupTask task3 =
177 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this)); 200 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
178 runner.AddTask(task3); 201 runner.AddTask(task3);
179 EXPECT_EQ(GetLastTask(), 0); 202 EXPECT_EQ(GetLastTask(), 0);
180 StartupTask task2 = 203 StartupTask task2 =
181 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this)); 204 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
182 runner.AddTask(task2); 205 runner.AddTask(task2);
183 206
184 // Nothing should run until we tell them to. 207 // Nothing should run until we tell them to.
185 EXPECT_EQ(GetLastTask(), 0); 208 EXPECT_EQ(GetLastTask(), 0);
186 runner.RunAllTasksNow(); 209 runner.RunAllTasksNow();
187 210
188 // Only the first task should have run, since it failed 211 // Only the first task should have run, since it failed
189 EXPECT_EQ(GetLastTask(), 3); 212 EXPECT_EQ(GetLastTask(), 3);
213 EXPECT_EQ(task_count, 1);
214 EXPECT_EQ(observer_calls, 1);
215 EXPECT_EQ(observer_result, 1);
190 216
191 EXPECT_TRUE(observer_called); 217 // After a failed task all remaining tasks should be cancelled
192 EXPECT_EQ(observer_result, 1); 218 // In particular Post... should not be called by running asynchronously
219 runner.StartRunningTasksAsync();
220
221 // The observer should only be called the first time the queue completes and
222 // no more tasks should have run
223 EXPECT_EQ(observer_calls, 1);
224 EXPECT_EQ(task_count, 1);
193 } 225 }
194 226
195 TEST_F(StartupTaskRunnerTest, AsynchronousExecution) { 227 TEST_F(StartupTaskRunnerTest, AsynchronousExecution) {
196 228
197 MockTaskRunner mock_runner; 229 MockTaskRunner mock_runner;
198 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 230 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
199 231
200 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 232 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
201 EXPECT_CALL( 233 EXPECT_CALL(
202 mock_runner, 234 mock_runner,
(...skipping 14 matching lines...) Expand all
217 EXPECT_EQ(GetLastTask(), 0); 249 EXPECT_EQ(GetLastTask(), 0);
218 runner.StartRunningTasksAsync(); 250 runner.StartRunningTasksAsync();
219 251
220 // No tasks should have run yet, since we the message loop hasn't run. 252 // No tasks should have run yet, since we the message loop hasn't run.
221 EXPECT_EQ(GetLastTask(), 0); 253 EXPECT_EQ(GetLastTask(), 0);
222 254
223 // Fake the actual message loop. Each time a task is run a new task should 255 // Fake the actual message loop. Each time a task is run a new task should
224 // be added to the queue, hence updating "task". The loop should actually run 256 // be added to the queue, hence updating "task". The loop should actually run
225 // at most 3 times (once for each task plus possibly once for the observer), 257 // at most 3 times (once for each task plus possibly once for the observer),
226 // the "4" is a backstop. 258 // the "4" is a backstop.
227 for (int i = 0; i < 4 && !observer_called; i++) { 259 for (int i = 0; i < 4 && observer_calls == 0; i++) {
228 task.Run(); 260 task.Run();
229 EXPECT_EQ(i + 1, GetLastTask()); 261 EXPECT_EQ(i + 1, GetLastTask());
230 } 262 }
231 EXPECT_TRUE(observer_called); 263 EXPECT_EQ(task_count, 2);
264 EXPECT_EQ(observer_calls, 1);
232 EXPECT_EQ(observer_result, 0); 265 EXPECT_EQ(observer_result, 0);
266
267 // Check that running synchronously now doesn't do anything
268
269 runner.RunAllTasksNow();
270 EXPECT_EQ(task_count, 2);
271 EXPECT_EQ(observer_calls, 1);
233 } 272 }
234 273
235 TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) { 274 TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) {
236 275
237 MockTaskRunner mock_runner; 276 MockTaskRunner mock_runner;
238 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); 277 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
239 278
240 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0); 279 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
241 EXPECT_CALL( 280 EXPECT_CALL(
242 mock_runner, 281 mock_runner,
(...skipping 14 matching lines...) Expand all
257 EXPECT_EQ(GetLastTask(), 0); 296 EXPECT_EQ(GetLastTask(), 0);
258 runner.StartRunningTasksAsync(); 297 runner.StartRunningTasksAsync();
259 298
260 // No tasks should have run yet, since we the message loop hasn't run. 299 // No tasks should have run yet, since we the message loop hasn't run.
261 EXPECT_EQ(GetLastTask(), 0); 300 EXPECT_EQ(GetLastTask(), 0);
262 301
263 // Fake the actual message loop. Each time a task is run a new task should 302 // Fake the actual message loop. Each time a task is run a new task should
264 // be added to the queue, hence updating "task". The loop should actually run 303 // be added to the queue, hence updating "task". The loop should actually run
265 // at most twice (once for the failed task plus possibly once for the 304 // at most twice (once for the failed task plus possibly once for the
266 // observer), the "4" is a backstop. 305 // observer), the "4" is a backstop.
267 for (int i = 0; i < 4 && !observer_called; i++) { 306 for (int i = 0; i < 4 && observer_calls == 0; i++) {
268 task.Run(); 307 task.Run();
269 } 308 }
270 EXPECT_EQ(GetLastTask(), 3); 309 EXPECT_EQ(GetLastTask(), 3);
310 EXPECT_EQ(task_count, 1);
271 311
272 EXPECT_TRUE(observer_called); 312 EXPECT_EQ(observer_calls, 1);
273 EXPECT_EQ(observer_result, 1); 313 EXPECT_EQ(observer_result, 1);
314
315 // Check that running synchronously now doesn't do anything
316 runner.RunAllTasksNow();
317 EXPECT_EQ(observer_calls, 1);
318 EXPECT_EQ(task_count, 1);
274 } 319 }
275 } // namespace 320 } // namespace
276 } // namespace content 321 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/startup_task_runner.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698