Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 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 | |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 7 | #include <utility> |
| 8 | |
Avi Drissman | adac2199 | 2023-01-11 23:46:39 | [diff] [blame] | 9 | #include "base/functional/bind.h" |
| 10 | #include "base/functional/callback.h" |
| 11 | #include "base/functional/callback_helpers.h" |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 12 | #include "base/location.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 13 | #include "base/memory/raw_ptr.h" |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 14 | #include "base/run_loop.h" |
Patrick Monette | 643cdf6 | 2021-10-15 19:13:42 | [diff] [blame] | 15 | #include "base/task/single_thread_task_runner.h" |
| 16 | #include "base/task/task_runner.h" |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 17 | |
| 18 | #include "testing/gmock/include/gmock/gmock.h" |
| 19 | #include "testing/gtest/include/gtest/gtest.h" |
| 20 | |
| 21 | namespace content { |
| 22 | namespace { |
| 23 | |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 24 | using testing::_; |
| 25 | using testing::Assign; |
| 26 | using testing::Invoke; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 27 | |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 28 | int observer_calls = 0; |
| 29 | int task_count = 0; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 30 | int observer_result; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 31 | |
Chidera Olibie | 76bdf2a | 2025-07-04 19:10:32 | [diff] [blame] | 32 | void Observer(int result, base::TimeDelta max_task_duration) { |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 33 | observer_calls++; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 34 | observer_result = result; |
| 35 | } |
| 36 | |
| 37 | class StartupTaskRunnerTest : public testing::Test { |
| 38 | public: |
dcheng | fa85b15 | 2014-10-28 01:13:42 | [diff] [blame] | 39 | void SetUp() override { |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 40 | last_task_ = 0; |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 41 | observer_calls = 0; |
| 42 | task_count = 0; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 43 | } |
| 44 | |
| 45 | int Task1() { |
| 46 | last_task_ = 1; |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 47 | task_count++; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 48 | return 0; |
| 49 | } |
| 50 | |
| 51 | int Task2() { |
| 52 | last_task_ = 2; |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 53 | task_count++; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 54 | return 0; |
| 55 | } |
| 56 | |
| 57 | int FailingTask() { |
| 58 | // Task returning failure |
| 59 | last_task_ = 3; |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 60 | task_count++; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 61 | return 1; |
| 62 | } |
| 63 | |
| 64 | int GetLastTask() { return last_task_; } |
| 65 | |
| 66 | private: |
| 67 | |
| 68 | int last_task_; |
| 69 | }; |
| 70 | |
| 71 | // We can't use the real message loop, even if we want to, since doing so on |
| 72 | // Android requires a complex Java infrastructure. The test would have to built |
| 73 | // as a content_shell test; but content_shell startup invokes the class we are |
| 74 | // trying to test. |
| 75 | // |
| 76 | // The mocks are not directly in TaskRunnerProxy because reference counted |
| 77 | // objects seem to confuse the mocking framework |
| 78 | |
| 79 | class MockTaskRunner { |
| 80 | public: |
Brett Wilson | 1c99002 | 2017-09-12 20:11:15 | [diff] [blame] | 81 | MOCK_METHOD2(PostDelayedTask, bool(const base::Location&, base::TimeDelta)); |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 82 | MOCK_METHOD2(PostNonNestableDelayedTask, |
Brett Wilson | 1c99002 | 2017-09-12 20:11:15 | [diff] [blame] | 83 | bool(const base::Location&, base::TimeDelta)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 84 | }; |
| 85 | |
| 86 | class TaskRunnerProxy : public base::SingleThreadTaskRunner { |
| 87 | public: |
Chidera Olibie | 76bdf2a | 2025-07-04 19:10:32 | [diff] [blame] | 88 | explicit TaskRunnerProxy(MockTaskRunner* mock) : mock_(mock) {} |
peary2 | 3322df6 | 2017-05-09 03:55:48 | [diff] [blame] | 89 | bool RunsTasksInCurrentSequence() const override { return true; } |
Brett Wilson | 1c99002 | 2017-09-12 20:11:15 | [diff] [blame] | 90 | bool PostDelayedTask(const base::Location& location, |
tzik | 6e42784 | 2017-04-05 10:13:21 | [diff] [blame] | 91 | base::OnceClosure closure, |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 92 | base::TimeDelta delta) override { |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 93 | last_task_ = std::move(closure); |
| 94 | return mock_->PostDelayedTask(location, delta); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 95 | } |
Brett Wilson | 1c99002 | 2017-09-12 20:11:15 | [diff] [blame] | 96 | bool PostNonNestableDelayedTask(const base::Location& location, |
tzik | 6e42784 | 2017-04-05 10:13:21 | [diff] [blame] | 97 | base::OnceClosure closure, |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 98 | base::TimeDelta delta) override { |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 99 | last_task_ = std::move(closure); |
| 100 | return mock_->PostNonNestableDelayedTask(location, delta); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 101 | } |
| 102 | |
tzik | 6e42784 | 2017-04-05 10:13:21 | [diff] [blame] | 103 | base::OnceClosure TakeLastTaskClosure() { return std::move(last_task_); } |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 104 | |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 105 | private: |
dcheng | c2282aa | 2014-10-21 12:07:58 | [diff] [blame] | 106 | ~TaskRunnerProxy() override {} |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 107 | |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 108 | raw_ptr<MockTaskRunner> mock_; |
tzik | 6e42784 | 2017-04-05 10:13:21 | [diff] [blame] | 109 | base::OnceClosure last_task_; |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 110 | }; |
| 111 | |
| 112 | TEST_F(StartupTaskRunnerTest, SynchronousExecution) { |
| 113 | MockTaskRunner mock_runner; |
| 114 | scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); |
| 115 | |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 116 | EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0); |
| 117 | EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 118 | |
Mark Pilgrim | b9350ee | 2018-06-18 22:25:22 | [diff] [blame] | 119 | StartupTaskRunner runner(base::BindOnce(&Observer), proxy); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 120 | |
| 121 | StartupTask task1 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 122 | base::BindOnce(&StartupTaskRunnerTest::Task1, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 123 | runner.AddTask(std::move(task1)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 124 | EXPECT_EQ(GetLastTask(), 0); |
| 125 | StartupTask task2 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 126 | base::BindOnce(&StartupTaskRunnerTest::Task2, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 127 | runner.AddTask(std::move(task2)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 128 | |
| 129 | // Nothing should run until we tell them to. |
| 130 | EXPECT_EQ(GetLastTask(), 0); |
[email protected] | 232e09d | 2013-08-27 15:29:56 | [diff] [blame] | 131 | runner.RunAllTasksNow(); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 132 | |
| 133 | // On an immediate StartupTaskRunner the tasks should now all have run. |
| 134 | EXPECT_EQ(GetLastTask(), 2); |
| 135 | |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 136 | EXPECT_EQ(task_count, 2); |
| 137 | EXPECT_EQ(observer_calls, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 138 | EXPECT_EQ(observer_result, 0); |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 139 | |
| 140 | // Running the tasks asynchronously shouldn't do anything |
| 141 | // In particular Post... should not be called |
| 142 | runner.StartRunningTasksAsync(); |
| 143 | |
| 144 | // No more tasks should be run and the observer should not have been called |
| 145 | // again |
| 146 | EXPECT_EQ(task_count, 2); |
| 147 | EXPECT_EQ(observer_calls, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 148 | } |
| 149 | |
| 150 | TEST_F(StartupTaskRunnerTest, NullObserver) { |
| 151 | MockTaskRunner mock_runner; |
| 152 | scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); |
| 153 | |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 154 | EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0); |
| 155 | EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 156 | |
Chidera Olibie | 76bdf2a | 2025-07-04 19:10:32 | [diff] [blame] | 157 | StartupTaskRunner runner(base::OnceCallback<void(int, base::TimeDelta)>(), |
| 158 | proxy); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 159 | |
| 160 | StartupTask task1 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 161 | base::BindOnce(&StartupTaskRunnerTest::Task1, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 162 | runner.AddTask(std::move(task1)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 163 | EXPECT_EQ(GetLastTask(), 0); |
| 164 | StartupTask task2 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 165 | base::BindOnce(&StartupTaskRunnerTest::Task2, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 166 | runner.AddTask(std::move(task2)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 167 | |
| 168 | // Nothing should run until we tell them to. |
| 169 | EXPECT_EQ(GetLastTask(), 0); |
[email protected] | 232e09d | 2013-08-27 15:29:56 | [diff] [blame] | 170 | runner.RunAllTasksNow(); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 171 | |
| 172 | // On an immediate StartupTaskRunner the tasks should now all have run. |
| 173 | EXPECT_EQ(GetLastTask(), 2); |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 174 | EXPECT_EQ(task_count, 2); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 175 | |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 176 | // Running the tasks asynchronously shouldn't do anything |
| 177 | // In particular Post... should not be called |
| 178 | runner.StartRunningTasksAsync(); |
| 179 | |
| 180 | // No more tasks should have been run |
| 181 | EXPECT_EQ(task_count, 2); |
| 182 | |
| 183 | EXPECT_EQ(observer_calls, 0); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 184 | } |
| 185 | |
| 186 | TEST_F(StartupTaskRunnerTest, SynchronousExecutionFailedTask) { |
| 187 | MockTaskRunner mock_runner; |
| 188 | scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); |
| 189 | |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 190 | EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0); |
| 191 | EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, _)).Times(0); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 192 | |
Mark Pilgrim | b9350ee | 2018-06-18 22:25:22 | [diff] [blame] | 193 | StartupTaskRunner runner(base::BindOnce(&Observer), proxy); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 194 | |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 195 | StartupTask task3 = base::BindOnce(&StartupTaskRunnerTest::FailingTask, |
| 196 | base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 197 | runner.AddTask(std::move(task3)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 198 | EXPECT_EQ(GetLastTask(), 0); |
| 199 | StartupTask task2 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 200 | base::BindOnce(&StartupTaskRunnerTest::Task2, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 201 | runner.AddTask(std::move(task2)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 202 | |
| 203 | // Nothing should run until we tell them to. |
| 204 | EXPECT_EQ(GetLastTask(), 0); |
[email protected] | 232e09d | 2013-08-27 15:29:56 | [diff] [blame] | 205 | runner.RunAllTasksNow(); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 206 | |
| 207 | // Only the first task should have run, since it failed |
| 208 | EXPECT_EQ(GetLastTask(), 3); |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 209 | EXPECT_EQ(task_count, 1); |
| 210 | EXPECT_EQ(observer_calls, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 211 | EXPECT_EQ(observer_result, 1); |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 212 | |
| 213 | // After a failed task all remaining tasks should be cancelled |
| 214 | // In particular Post... should not be called by running asynchronously |
| 215 | runner.StartRunningTasksAsync(); |
| 216 | |
| 217 | // The observer should only be called the first time the queue completes and |
| 218 | // no more tasks should have run |
| 219 | EXPECT_EQ(observer_calls, 1); |
| 220 | EXPECT_EQ(task_count, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 221 | } |
| 222 | |
| 223 | TEST_F(StartupTaskRunnerTest, AsynchronousExecution) { |
| 224 | |
| 225 | MockTaskRunner mock_runner; |
| 226 | scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); |
| 227 | |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 228 | EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0); |
Peter Kasting | e5a38ed | 2021-10-02 03:06:35 | [diff] [blame] | 229 | EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, base::Milliseconds(0))) |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 230 | .Times(testing::Between(2, 3)) |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 231 | .WillRepeatedly(testing::Return(true)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 232 | |
Mark Pilgrim | b9350ee | 2018-06-18 22:25:22 | [diff] [blame] | 233 | StartupTaskRunner runner(base::BindOnce(&Observer), proxy); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 234 | |
| 235 | StartupTask task1 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 236 | base::BindOnce(&StartupTaskRunnerTest::Task1, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 237 | runner.AddTask(std::move(task1)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 238 | StartupTask task2 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 239 | base::BindOnce(&StartupTaskRunnerTest::Task2, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 240 | runner.AddTask(std::move(task2)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 241 | |
| 242 | // Nothing should run until we tell them to. |
| 243 | EXPECT_EQ(GetLastTask(), 0); |
[email protected] | 232e09d | 2013-08-27 15:29:56 | [diff] [blame] | 244 | runner.StartRunningTasksAsync(); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 245 | |
| 246 | // No tasks should have run yet, since we the message loop hasn't run. |
| 247 | EXPECT_EQ(GetLastTask(), 0); |
| 248 | |
| 249 | // Fake the actual message loop. Each time a task is run a new task should |
| 250 | // be added to the queue, hence updating "task". The loop should actually run |
| 251 | // at most 3 times (once for each task plus possibly once for the observer), |
| 252 | // the "4" is a backstop. |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 253 | for (int i = 0; i < 4 && observer_calls == 0; i++) { |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 254 | proxy->TakeLastTaskClosure().Run(); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 255 | EXPECT_EQ(i + 1, GetLastTask()); |
| 256 | } |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 257 | EXPECT_EQ(task_count, 2); |
| 258 | EXPECT_EQ(observer_calls, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 259 | EXPECT_EQ(observer_result, 0); |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 260 | |
| 261 | // Check that running synchronously now doesn't do anything |
| 262 | |
| 263 | runner.RunAllTasksNow(); |
| 264 | EXPECT_EQ(task_count, 2); |
| 265 | EXPECT_EQ(observer_calls, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 266 | } |
| 267 | |
| 268 | TEST_F(StartupTaskRunnerTest, AsynchronousExecutionFailedTask) { |
| 269 | |
| 270 | MockTaskRunner mock_runner; |
| 271 | scoped_refptr<TaskRunnerProxy> proxy = new TaskRunnerProxy(&mock_runner); |
| 272 | |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 273 | EXPECT_CALL(mock_runner, PostDelayedTask(_, _)).Times(0); |
Peter Kasting | e5a38ed | 2021-10-02 03:06:35 | [diff] [blame] | 274 | EXPECT_CALL(mock_runner, PostNonNestableDelayedTask(_, base::Milliseconds(0))) |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 275 | .Times(testing::Between(1, 2)) |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 276 | .WillRepeatedly(testing::Return(true)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 277 | |
Mark Pilgrim | b9350ee | 2018-06-18 22:25:22 | [diff] [blame] | 278 | StartupTaskRunner runner(base::BindOnce(&Observer), proxy); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 279 | |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 280 | StartupTask task3 = base::BindOnce(&StartupTaskRunnerTest::FailingTask, |
| 281 | base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 282 | runner.AddTask(std::move(task3)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 283 | StartupTask task2 = |
danakj | f416ce9d | 2019-12-11 20:45:45 | [diff] [blame] | 284 | base::BindOnce(&StartupTaskRunnerTest::Task2, base::Unretained(this)); |
Tommy Nyquist | 4b749d0 | 2018-03-20 21:46:29 | [diff] [blame] | 285 | runner.AddTask(std::move(task2)); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 286 | |
| 287 | // Nothing should run until we tell them to. |
| 288 | EXPECT_EQ(GetLastTask(), 0); |
[email protected] | 232e09d | 2013-08-27 15:29:56 | [diff] [blame] | 289 | runner.StartRunningTasksAsync(); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 290 | |
Chidera Olibie | 76bdf2a | 2025-07-04 19:10:32 | [diff] [blame] | 291 | // No tasks should have run yet, since the message loop hasn't run. |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 292 | EXPECT_EQ(GetLastTask(), 0); |
| 293 | |
Chidera Olibie | 76bdf2a | 2025-07-04 19:10:32 | [diff] [blame] | 294 | // Fake the actual message loop. Each time a task is run, a new task should |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 295 | // be added to the queue, hence updating "task". The loop should actually run |
| 296 | // at most twice (once for the failed task plus possibly once for the |
| 297 | // observer), the "4" is a backstop. |
tzik | 070c8ffb | 2017-03-29 05:28:12 | [diff] [blame] | 298 | for (int i = 0; i < 4 && observer_calls == 0; i++) |
| 299 | proxy->TakeLastTaskClosure().Run(); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 300 | EXPECT_EQ(GetLastTask(), 3); |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 301 | EXPECT_EQ(task_count, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 302 | |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 303 | EXPECT_EQ(observer_calls, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 304 | EXPECT_EQ(observer_result, 1); |
[email protected] | b07c081 | 2013-10-10 21:39:15 | [diff] [blame] | 305 | |
| 306 | // Check that running synchronously now doesn't do anything |
| 307 | runner.RunAllTasksNow(); |
| 308 | EXPECT_EQ(observer_calls, 1); |
| 309 | EXPECT_EQ(task_count, 1); |
[email protected] | 57624ab | 2013-08-01 16:01:51 | [diff] [blame] | 310 | } |
| 311 | } // namespace |
| 312 | } // namespace content |