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

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

Issue 19957002: Run the later parts of startup as UI thread tasks (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Run the later parts of startup as UI thread tasks - Jam's nits Created 7 years, 4 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') | content/content_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/browser/startup_task_runner.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/callback.h"
10 #include "base/location.h"
11 #include "base/run_loop.h"
12 #include "base/task_runner.h"
13
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace content {
18 namespace {
19
20 using base::Closure;
21 using testing::_;
22 using testing::Assign;
23 using testing::Invoke;
24 using testing::WithArg;
25
26 bool observer_called = false;
27 int observer_result;
28 base::Closure task;
29
30 // I couldn't get gMock's SaveArg to compile, hence had to save the argument
31 // this way
32 bool SaveTaskArg(const Closure& arg) {
33 task = arg;
34 return true;
35 }
36
37 void Observer(int result) {
38 observer_called = true;
39 observer_result = result;
40 }
41
42 class StartupTaskRunnerTest : public testing::Test {
43 public:
44
45 virtual void SetUp() {
46 last_task_ = 0;
47 observer_called = false;
48 }
49
50 int Task1() {
51 last_task_ = 1;
52 return 0;
53 }
54
55 int Task2() {
56 last_task_ = 2;
57 return 0;
58 }
59
60 int FailingTask() {
61 // Task returning failure
62 last_task_ = 3;
63 return 1;
64 }
65
66 int GetLastTask() { return last_task_; }
67
68 private:
69
70 int last_task_;
71 };
72
73 // We can't use the real message loop, even if we want to, since doing so on
74 // Android requires a complex Java infrastructure. The test would have to built
75 // as a content_shell test; but content_shell startup invokes the class we are
76 // trying to test.
77 //
78 // The mocks are not directly in TaskRunnerProxy because reference counted
79 // objects seem to confuse the mocking framework
80
81 class MockTaskRunner {
82 public:
83 MOCK_METHOD3(
84 PostDelayedTask,
85 bool(const tracked_objects::Location&, const Closure&, base::TimeDelta));
86 MOCK_METHOD3(
87 PostNonNestableDelayedTask,
88 bool(const tracked_objects::Location&, const Closure&, base::TimeDelta));
89 };
90
91 class TaskRunnerProxy : public base::SingleThreadTaskRunner {
92 public:
93 TaskRunnerProxy(MockTaskRunner* mock) : mock_(mock) {}
94 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
95 virtual bool PostDelayedTask(const tracked_objects::Location& location,
96 const Closure& closure,
97 base::TimeDelta delta) OVERRIDE {
98 return mock_->PostDelayedTask(location, closure, delta);
99 }
100 virtual bool PostNonNestableDelayedTask(
101 const tracked_objects::Location& location,
102 const Closure& closure,
103 base::TimeDelta delta) OVERRIDE {
104 return mock_->PostNonNestableDelayedTask(location, closure, delta);
105 }
106
107 private:
108 MockTaskRunner* mock_;
109 virtual ~TaskRunnerProxy() {}
110 };
111
112 TEST_F(StartupTaskRunnerTest, SynchronousExecution) {
113 MockTaskRunner mock_runner;
114 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
115
116 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
117 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
118
119 scoped_refptr<StartupTaskRunner> runner =
120 new StartupTaskRunner(false, base::Bind(&Observer), proxy);
121
122 StartupTask task1 =
123 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
124 runner->AddTask(task1);
125 EXPECT_EQ(GetLastTask(), 0);
126 StartupTask task2 =
127 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
128 runner->AddTask(task2);
129
130 // Nothing should run until we tell them to.
131 EXPECT_EQ(GetLastTask(), 0);
132 runner->StartRunningTasks();
133
134 // On an immediate StartupTaskRunner the tasks should now all have run.
135 EXPECT_EQ(GetLastTask(), 2);
136
137 EXPECT_TRUE(observer_called);
138 EXPECT_EQ(observer_result, 0);
139 }
140
141 TEST_F(StartupTaskRunnerTest, NullObserver) {
142 MockTaskRunner mock_runner;
143 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
144
145 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
146 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
147
148 scoped_refptr<StartupTaskRunner> runner =
149 new StartupTaskRunner(false, base::Callback<void(int)>(), proxy);
150
151 StartupTask task1 =
152 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
153 runner->AddTask(task1);
154 EXPECT_EQ(GetLastTask(), 0);
155 StartupTask task2 =
156 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
157 runner->AddTask(task2);
158
159 // Nothing should run until we tell them to.
160 EXPECT_EQ(GetLastTask(), 0);
161 runner->StartRunningTasks();
162
163 // On an immediate StartupTaskRunner the tasks should now all have run.
164 EXPECT_EQ(GetLastTask(), 2);
165
166 EXPECT_FALSE(observer_called);
167 }
168
169 TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) {
170 MockTaskRunner mock_runner;
171 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
172
173 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
174 EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _, _)).Times(0);
175
176 scoped_refptr<StartupTaskRunner> runner =
177 new StartupTaskRunner(false, base::Bind(&Observer), proxy);
178
179 StartupTask task3 =
180 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
181 runner->AddTask(task3);
182 EXPECT_EQ(GetLastTask(), 0);
183 StartupTask task2 =
184 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
185 runner->AddTask(task2);
186
187 // Nothing should run until we tell them to.
188 EXPECT_EQ(GetLastTask(), 0);
189 runner->StartRunningTasks();
190
191 // Only the first task should have run, since it failed
192 EXPECT_EQ(GetLastTask(), 3);
193
194 EXPECT_TRUE(observer_called);
195 EXPECT_EQ(observer_result, 1);
196 }
197
198 TEST_F(StartupTaskRunnerTest, AsynchronousExecution) {
199
200 MockTaskRunner mock_runner;
201 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
202
203 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
204 EXPECT_CALL(
205 mock_runner,
206 PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0)))
207 .Times(testing::Between(2, 3))
208 .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg)));
209
210 scoped_refptr<StartupTaskRunner> runner =
211 new StartupTaskRunner(true, base::Bind(&Observer), proxy);
212
213 StartupTask task1 =
214 base::Bind(&StartupTaskRunnerTest::Task1, base::Unretained(this));
215 runner->AddTask(task1);
216 StartupTask task2 =
217 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
218 runner->AddTask(task2);
219
220 // Nothing should run until we tell them to.
221 EXPECT_EQ(GetLastTask(), 0);
222 runner->StartRunningTasks();
223
224 // No tasks should have run yet, since we the message loop hasn't run.
225 EXPECT_EQ(GetLastTask(), 0);
226
227 // Fake the actual message loop. Each time a task is run a new task should
228 // be added to the queue, hence updating "task". The loop should actually run
229 // at most 3 times (once for each task plus possibly once for the observer),
230 // the "4" is a backstop.
231 for (int i = 0; i < 4 && !observer_called; i++) {
232 task.Run();
233 EXPECT_EQ(i + 1, GetLastTask());
234 }
235 EXPECT_TRUE(observer_called);
236 EXPECT_EQ(observer_result, 0);
237 }
238
239 TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) {
240
241 MockTaskRunner mock_runner;
242 scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner);
243
244 EXPECT_CALL(mock_runner, PostDelayedTask(_, _, _)).Times(0);
245 EXPECT_CALL(
246 mock_runner,
247 PostNonNestableDelayedTask(_, _, base::TimeDelta::FromMilliseconds(0)))
248 .Times(testing::Between(1, 2))
249 .WillRepeatedly(WithArg<1>(Invoke(SaveTaskArg)));
250
251 scoped_refptr<StartupTaskRunner> runner =
252 new StartupTaskRunner(true, base::Bind(&Observer), proxy);
253
254 StartupTask task3 =
255 base::Bind(&StartupTaskRunnerTest::FailingTask, base::Unretained(this));
256 runner->AddTask(task3);
257 StartupTask task2 =
258 base::Bind(&StartupTaskRunnerTest::Task2, base::Unretained(this));
259 runner->AddTask(task2);
260
261 // Nothing should run until we tell them to.
262 EXPECT_EQ(GetLastTask(), 0);
263 runner->StartRunningTasks();
264
265 // No tasks should have run yet, since we the message loop hasn't run.
266 EXPECT_EQ(GetLastTask(), 0);
267
268 // Fake the actual message loop. Each time a task is run a new task should
269 // be added to the queue, hence updating "task". The loop should actually run
270 // at most twice (once for the failed task plus possibly once for the
271 // observer), the "4" is a backstop.
272 for (int i = 0; i < 4 && !observer_called; i++) {
273 task.Run();
274 }
275 EXPECT_EQ(GetLastTask(), 3);
276
277 EXPECT_TRUE(observer_called);
278 EXPECT_EQ(observer_result, 1);
279 }
280 } // namespace
281 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/startup_task_runner.cc ('k') | content/content_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698