OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "base/test/test_mock_time_task_runner.h" | 5 #include "base/test/test_mock_time_task_runner.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/macros.h" | 8 #include "base/macros.h" |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 return task_runner_->Now(); | 67 return task_runner_->Now(); |
68 } | 68 } |
69 | 69 |
70 } // namespace | 70 } // namespace |
71 | 71 |
72 // TestMockTimeTaskRunner::TestOrderedPendingTask ----------------------------- | 72 // TestMockTimeTaskRunner::TestOrderedPendingTask ----------------------------- |
73 | 73 |
74 // Subclass of TestPendingTask which has a strictly monotonically increasing ID | 74 // Subclass of TestPendingTask which has a strictly monotonically increasing ID |
75 // for every task, so that tasks posted with the same 'time to run' can be run | 75 // for every task, so that tasks posted with the same 'time to run' can be run |
76 // in the order of being posted. | 76 // in the order of being posted. |
77 struct TestMockTimeTaskRunner::TestOrderedPendingTask | 77 struct TestMockTimeTaskRunner::TestOrderedPendingTaskInfo |
78 : public base::TestPendingTask { | 78 : public base::TestPendingTaskInfo { |
79 TestOrderedPendingTask(); | 79 TestOrderedPendingTaskInfo(); |
80 TestOrderedPendingTask(const tracked_objects::Location& location, | 80 TestOrderedPendingTaskInfo(const tracked_objects::Location& location, |
81 const Closure& task, | 81 TimeTicks post_time, |
82 TimeTicks post_time, | 82 TimeDelta delay, |
83 TimeDelta delay, | 83 size_t ordinal, |
84 size_t ordinal, | 84 TestNestability nestability); |
85 TestNestability nestability); | 85 ~TestOrderedPendingTaskInfo(); |
86 ~TestOrderedPendingTask(); | |
87 | 86 |
88 size_t ordinal; | 87 size_t ordinal; |
89 }; | 88 }; |
90 | 89 |
91 TestMockTimeTaskRunner::TestOrderedPendingTask::TestOrderedPendingTask() | 90 TestMockTimeTaskRunner::TestOrderedPendingTaskInfo::TestOrderedPendingTaskInfo() |
92 : ordinal(0) { | 91 : ordinal(0) {} |
93 } | |
94 | 92 |
95 TestMockTimeTaskRunner::TestOrderedPendingTask::TestOrderedPendingTask( | 93 TestMockTimeTaskRunner::TestOrderedPendingTaskInfo::TestOrderedPendingTaskInfo( |
96 const tracked_objects::Location& location, | 94 const tracked_objects::Location& location, |
97 const Closure& task, | |
98 TimeTicks post_time, | 95 TimeTicks post_time, |
99 TimeDelta delay, | 96 TimeDelta delay, |
100 size_t ordinal, | 97 size_t ordinal, |
101 TestNestability nestability) | 98 TestNestability nestability) |
102 : base::TestPendingTask(location, task, post_time, delay, nestability), | 99 : base::TestPendingTaskInfo(location, post_time, delay, nestability), |
103 ordinal(ordinal) { | 100 ordinal(ordinal) {} |
104 } | |
105 | 101 |
106 TestMockTimeTaskRunner::TestOrderedPendingTask::~TestOrderedPendingTask() { | 102 TestMockTimeTaskRunner::TestOrderedPendingTaskInfo:: |
107 } | 103 ~TestOrderedPendingTaskInfo() {} |
108 | 104 |
109 // TestMockTimeTaskRunner ----------------------------------------------------- | 105 // TestMockTimeTaskRunner ----------------------------------------------------- |
110 | 106 |
111 bool TestMockTimeTaskRunner::TemporalOrder::operator()( | 107 bool TestMockTimeTaskRunner::TemporalOrder::operator()( |
112 const TestOrderedPendingTask& first_task, | 108 const TestOrderedPendingTaskInfo& first_task, |
113 const TestOrderedPendingTask& second_task) const { | 109 const TestOrderedPendingTaskInfo& second_task) const { |
114 if (first_task.GetTimeToRun() == second_task.GetTimeToRun()) | 110 if (first_task.GetTimeToRun() == second_task.GetTimeToRun()) |
115 return first_task.ordinal > second_task.ordinal; | 111 return first_task.ordinal < second_task.ordinal; |
116 return first_task.GetTimeToRun() > second_task.GetTimeToRun(); | 112 return first_task.GetTimeToRun() < second_task.GetTimeToRun(); |
117 } | 113 } |
118 | 114 |
119 TestMockTimeTaskRunner::TestMockTimeTaskRunner() | 115 TestMockTimeTaskRunner::TestMockTimeTaskRunner() |
120 : now_(Time::UnixEpoch()), next_task_ordinal_(0) { | 116 : now_(Time::UnixEpoch()), next_task_ordinal_(0) { |
121 } | 117 } |
122 | 118 |
123 TestMockTimeTaskRunner::TestMockTimeTaskRunner(Time start_time, | 119 TestMockTimeTaskRunner::TestMockTimeTaskRunner(Time start_time, |
124 TimeTicks start_ticks) | 120 TimeTicks start_ticks) |
125 : now_(Time::UnixEpoch()), now_ticks_(start_ticks), next_task_ordinal_(0) {} | 121 : now_(Time::UnixEpoch()), now_ticks_(start_ticks), next_task_ordinal_(0) {} |
126 | 122 |
(...skipping 15 matching lines...) Expand all Loading... |
142 } | 138 } |
143 | 139 |
144 void TestMockTimeTaskRunner::FastForwardUntilNoTasksRemain() { | 140 void TestMockTimeTaskRunner::FastForwardUntilNoTasksRemain() { |
145 DCHECK(thread_checker_.CalledOnValidThread()); | 141 DCHECK(thread_checker_.CalledOnValidThread()); |
146 ProcessAllTasksNoLaterThan(TimeDelta::Max()); | 142 ProcessAllTasksNoLaterThan(TimeDelta::Max()); |
147 } | 143 } |
148 | 144 |
149 void TestMockTimeTaskRunner::ClearPendingTasks() { | 145 void TestMockTimeTaskRunner::ClearPendingTasks() { |
150 DCHECK(thread_checker_.CalledOnValidThread()); | 146 DCHECK(thread_checker_.CalledOnValidThread()); |
151 AutoLock scoped_lock(tasks_lock_); | 147 AutoLock scoped_lock(tasks_lock_); |
152 while (!tasks_.empty()) | 148 tasks_.clear(); |
153 tasks_.pop(); | |
154 } | 149 } |
155 | 150 |
156 Time TestMockTimeTaskRunner::Now() const { | 151 Time TestMockTimeTaskRunner::Now() const { |
157 DCHECK(thread_checker_.CalledOnValidThread()); | 152 DCHECK(thread_checker_.CalledOnValidThread()); |
158 return now_; | 153 return now_; |
159 } | 154 } |
160 | 155 |
161 TimeTicks TestMockTimeTaskRunner::NowTicks() const { | 156 TimeTicks TestMockTimeTaskRunner::NowTicks() const { |
162 DCHECK(thread_checker_.CalledOnValidThread()); | 157 DCHECK(thread_checker_.CalledOnValidThread()); |
163 return now_ticks_; | 158 return now_ticks_; |
164 } | 159 } |
165 | 160 |
166 std::unique_ptr<Clock> TestMockTimeTaskRunner::GetMockClock() const { | 161 std::unique_ptr<Clock> TestMockTimeTaskRunner::GetMockClock() const { |
167 DCHECK(thread_checker_.CalledOnValidThread()); | 162 DCHECK(thread_checker_.CalledOnValidThread()); |
168 return MakeUnique<MockClock>(this); | 163 return MakeUnique<MockClock>(this); |
169 } | 164 } |
170 | 165 |
171 std::unique_ptr<TickClock> TestMockTimeTaskRunner::GetMockTickClock() const { | 166 std::unique_ptr<TickClock> TestMockTimeTaskRunner::GetMockTickClock() const { |
172 DCHECK(thread_checker_.CalledOnValidThread()); | 167 DCHECK(thread_checker_.CalledOnValidThread()); |
173 return MakeUnique<MockTickClock>(this); | 168 return MakeUnique<MockTickClock>(this); |
174 } | 169 } |
175 | 170 |
176 std::deque<TestPendingTask> TestMockTimeTaskRunner::TakePendingTasks() { | 171 TestPendingTaskQueue TestMockTimeTaskRunner::TakePendingTasks() { |
177 std::deque<TestPendingTask> tasks; | 172 TestPendingTaskQueue tasks; |
178 while (!tasks_.empty()) { | 173 for (auto& task : tasks_) |
179 tasks.push_back(tasks_.top()); | 174 tasks.push_back(std::move(task)); |
180 tasks_.pop(); | 175 tasks_.clear(); |
181 } | |
182 return tasks; | 176 return tasks; |
183 } | 177 } |
184 | 178 |
185 bool TestMockTimeTaskRunner::HasPendingTask() const { | 179 bool TestMockTimeTaskRunner::HasPendingTask() const { |
186 DCHECK(thread_checker_.CalledOnValidThread()); | 180 DCHECK(thread_checker_.CalledOnValidThread()); |
187 return !tasks_.empty(); | 181 return !tasks_.empty(); |
188 } | 182 } |
189 | 183 |
190 size_t TestMockTimeTaskRunner::GetPendingTaskCount() const { | 184 size_t TestMockTimeTaskRunner::GetPendingTaskCount() const { |
191 DCHECK(thread_checker_.CalledOnValidThread()); | 185 DCHECK(thread_checker_.CalledOnValidThread()); |
192 return tasks_.size(); | 186 return tasks_.size(); |
193 } | 187 } |
194 | 188 |
195 TimeDelta TestMockTimeTaskRunner::NextPendingTaskDelay() const { | 189 TimeDelta TestMockTimeTaskRunner::NextPendingTaskDelay() const { |
196 DCHECK(thread_checker_.CalledOnValidThread()); | 190 DCHECK(thread_checker_.CalledOnValidThread()); |
197 return tasks_.empty() ? TimeDelta::Max() | 191 if (tasks_.empty()) |
198 : tasks_.top().GetTimeToRun() - now_ticks_; | 192 return TimeDelta::Max(); |
| 193 |
| 194 const TestPendingTaskInfo& task_info = tasks_.begin()->first; |
| 195 return task_info.GetTimeToRun() - now_ticks_; |
199 } | 196 } |
200 | 197 |
201 bool TestMockTimeTaskRunner::RunsTasksOnCurrentThread() const { | 198 bool TestMockTimeTaskRunner::RunsTasksOnCurrentThread() const { |
202 return thread_checker_.CalledOnValidThread(); | 199 return thread_checker_.CalledOnValidThread(); |
203 } | 200 } |
204 | 201 |
205 bool TestMockTimeTaskRunner::PostDelayedTask( | 202 bool TestMockTimeTaskRunner::PostDelayedTask( |
206 const tracked_objects::Location& from_here, | 203 const tracked_objects::Location& from_here, |
207 const Closure& task, | 204 const Closure& task, |
208 TimeDelta delay) { | 205 TimeDelta delay) { |
209 AutoLock scoped_lock(tasks_lock_); | 206 AutoLock scoped_lock(tasks_lock_); |
210 tasks_.push(TestOrderedPendingTask(from_here, task, now_ticks_, delay, | 207 |
211 next_task_ordinal_++, | 208 TestOrderedPendingTaskInfo task_info(from_here, now_ticks_, delay, |
212 TestPendingTask::NESTABLE)); | 209 next_task_ordinal_++, |
| 210 TestPendingTaskInfo::NESTABLE); |
| 211 tasks_.insert(std::make_pair(task_info, task)); |
213 return true; | 212 return true; |
214 } | 213 } |
215 | 214 |
216 bool TestMockTimeTaskRunner::PostNonNestableDelayedTask( | 215 bool TestMockTimeTaskRunner::PostNonNestableDelayedTask( |
217 const tracked_objects::Location& from_here, | 216 const tracked_objects::Location& from_here, |
218 const Closure& task, | 217 const Closure& task, |
219 TimeDelta delay) { | 218 TimeDelta delay) { |
220 return PostDelayedTask(from_here, task, delay); | 219 return PostDelayedTask(from_here, task, delay); |
221 } | 220 } |
222 | 221 |
(...skipping 11 matching lines...) Expand all Loading... |
234 | 233 |
235 void TestMockTimeTaskRunner::OnAfterTaskRun() { | 234 void TestMockTimeTaskRunner::OnAfterTaskRun() { |
236 // Empty default implementation. | 235 // Empty default implementation. |
237 } | 236 } |
238 | 237 |
239 void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) { | 238 void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) { |
240 DCHECK_GE(max_delta, TimeDelta()); | 239 DCHECK_GE(max_delta, TimeDelta()); |
241 const TimeTicks original_now_ticks = now_ticks_; | 240 const TimeTicks original_now_ticks = now_ticks_; |
242 while (!IsElapsingStopped()) { | 241 while (!IsElapsingStopped()) { |
243 OnBeforeSelectingTask(); | 242 OnBeforeSelectingTask(); |
244 TestPendingTask task_info; | 243 TestPendingTaskInfo task_info; |
245 if (!DequeueNextTask(original_now_ticks, max_delta, &task_info)) | 244 OnceClosure task; |
| 245 if (!DequeueNextTask(original_now_ticks, max_delta, &task_info, &task)) |
246 break; | 246 break; |
247 // If tasks were posted with a negative delay, task_info.GetTimeToRun() will | 247 // If tasks were posted with a negative delay, task_info.GetTimeToRun() will |
248 // be less than |now_ticks_|. ForwardClocksUntilTickTime() takes care of not | 248 // be less than |now_ticks_|. ForwardClocksUntilTickTime() takes care of not |
249 // moving the clock backwards in this case. | 249 // moving the clock backwards in this case. |
250 ForwardClocksUntilTickTime(task_info.GetTimeToRun()); | 250 ForwardClocksUntilTickTime(task_info.GetTimeToRun()); |
251 task_info.task.Run(); | 251 std::move(task).Run(); |
252 OnAfterTaskRun(); | 252 OnAfterTaskRun(); |
253 } | 253 } |
254 } | 254 } |
255 | 255 |
256 void TestMockTimeTaskRunner::ForwardClocksUntilTickTime(TimeTicks later_ticks) { | 256 void TestMockTimeTaskRunner::ForwardClocksUntilTickTime(TimeTicks later_ticks) { |
257 if (later_ticks <= now_ticks_) | 257 if (later_ticks <= now_ticks_) |
258 return; | 258 return; |
259 | 259 |
260 now_ += later_ticks - now_ticks_; | 260 now_ += later_ticks - now_ticks_; |
261 now_ticks_ = later_ticks; | 261 now_ticks_ = later_ticks; |
262 OnAfterTimePassed(); | 262 OnAfterTimePassed(); |
263 } | 263 } |
264 | 264 |
265 bool TestMockTimeTaskRunner::DequeueNextTask(const TimeTicks& reference, | 265 bool TestMockTimeTaskRunner::DequeueNextTask( |
266 const TimeDelta& max_delta, | 266 const TimeTicks& reference, |
267 TestPendingTask* next_task) { | 267 const TimeDelta& max_delta, |
| 268 TestPendingTaskInfo* next_task_info, |
| 269 OnceClosure* next_task) { |
268 AutoLock scoped_lock(tasks_lock_); | 270 AutoLock scoped_lock(tasks_lock_); |
269 if (!tasks_.empty() && | 271 if (tasks_.empty()) |
270 (tasks_.top().GetTimeToRun() - reference) <= max_delta) { | 272 return false; |
271 *next_task = tasks_.top(); | 273 |
272 tasks_.pop(); | 274 auto itr = tasks_.begin(); |
273 return true; | 275 const TestPendingTaskInfo& task_info = itr->first; |
274 } | 276 if ((task_info.GetTimeToRun() - reference) > max_delta) |
275 return false; | 277 return false; |
| 278 |
| 279 *next_task_info = task_info; |
| 280 *next_task = std::move(itr->second); |
| 281 tasks_.erase(itr); |
| 282 return true; |
276 } | 283 } |
277 | 284 |
278 } // namespace base | 285 } // namespace base |
OLD | NEW |