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 "platform/scheduler/base/time_domain.h" | 5 #include "platform/scheduler/base/time_domain.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/test/simple_test_tick_clock.h" | 9 #include "base/test/simple_test_tick_clock.h" |
10 #include "cc/test/ordered_simple_task_runner.h" | 10 #include "cc/test/ordered_simple_task_runner.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 namespace scheduler { | 23 namespace scheduler { |
24 | 24 |
25 class MockTimeDomain : public TimeDomain { | 25 class MockTimeDomain : public TimeDomain { |
26 public: | 26 public: |
27 explicit MockTimeDomain(TimeDomain::Observer* observer) | 27 explicit MockTimeDomain(TimeDomain::Observer* observer) |
28 : TimeDomain(observer), | 28 : TimeDomain(observer), |
29 now_(base::TimeTicks() + base::TimeDelta::FromSeconds(1)) {} | 29 now_(base::TimeTicks() + base::TimeDelta::FromSeconds(1)) {} |
30 | 30 |
31 ~MockTimeDomain() override {} | 31 ~MockTimeDomain() override {} |
32 | 32 |
33 using TimeDomain::CancelDelayedWork; | |
34 using TimeDomain::ClearExpiredWakeups; | |
35 using TimeDomain::NextScheduledRunTime; | 33 using TimeDomain::NextScheduledRunTime; |
36 using TimeDomain::NextScheduledTaskQueue; | 34 using TimeDomain::NextScheduledTaskQueue; |
37 using TimeDomain::ScheduleDelayedWork; | 35 using TimeDomain::ScheduleDelayedWork; |
38 using TimeDomain::UnregisterQueue; | 36 using TimeDomain::UnregisterQueue; |
39 using TimeDomain::UpdateWorkQueues; | 37 using TimeDomain::UpdateWorkQueues; |
40 using TimeDomain::RegisterAsUpdatableTaskQueue; | 38 using TimeDomain::RegisterAsUpdatableTaskQueue; |
41 | 39 |
42 // TimeSource implementation: | 40 // TimeSource implementation: |
43 LazyNow CreateLazyNow() const override { return LazyNow(now_); } | 41 LazyNow CreateLazyNow() const override { return LazyNow(now_); } |
44 base::TimeTicks Now() const override { return now_; } | 42 base::TimeTicks Now() const override { return now_; } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 | 90 |
93 base::TimeTicks next_scheduled_runtime; | 91 base::TimeTicks next_scheduled_runtime; |
94 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); | 92 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); |
95 EXPECT_EQ(delayed_runtime, next_scheduled_runtime); | 93 EXPECT_EQ(delayed_runtime, next_scheduled_runtime); |
96 | 94 |
97 TaskQueue* next_task_queue; | 95 TaskQueue* next_task_queue; |
98 EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue)); | 96 EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue)); |
99 EXPECT_EQ(task_queue_.get(), next_task_queue); | 97 EXPECT_EQ(task_queue_.get(), next_task_queue); |
100 } | 98 } |
101 | 99 |
| 100 TEST_F(TimeDomainTest, ScheduleDelayedWorkSupersedesPreviousWakeup) { |
| 101 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); |
| 102 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(100); |
| 103 base::TimeTicks delayed_runtime1 = time_domain_->Now() + delay1; |
| 104 base::TimeTicks delayed_runtime2 = time_domain_->Now() + delay2; |
| 105 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); |
| 106 base::TimeTicks now = time_domain_->Now(); |
| 107 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime1, now); |
| 108 |
| 109 base::TimeTicks next_scheduled_runtime; |
| 110 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); |
| 111 EXPECT_EQ(delayed_runtime1, next_scheduled_runtime); |
| 112 |
| 113 Mock::VerifyAndClearExpectations(time_domain_.get()); |
| 114 |
| 115 // Now scheduler a later wakeup, which should replace the previously requested |
| 116 // one. |
| 117 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay2)); |
| 118 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime2, now); |
| 119 |
| 120 EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); |
| 121 EXPECT_EQ(delayed_runtime2, next_scheduled_runtime); |
| 122 } |
| 123 |
102 TEST_F(TimeDomainTest, RequestWakeup_OnlyCalledForEarlierTasks) { | 124 TEST_F(TimeDomainTest, RequestWakeup_OnlyCalledForEarlierTasks) { |
| 125 scoped_refptr<internal::TaskQueueImpl> task_queue2 = |
| 126 make_scoped_refptr(new internal::TaskQueueImpl( |
| 127 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue2"), |
| 128 "test.category", "test.category")); |
| 129 |
| 130 scoped_refptr<internal::TaskQueueImpl> task_queue3 = |
| 131 make_scoped_refptr(new internal::TaskQueueImpl( |
| 132 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue3"), |
| 133 "test.category", "test.category")); |
| 134 |
| 135 scoped_refptr<internal::TaskQueueImpl> task_queue4 = |
| 136 make_scoped_refptr(new internal::TaskQueueImpl( |
| 137 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue4"), |
| 138 "test.category", "test.category")); |
| 139 |
103 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); | 140 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); |
104 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); | 141 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); |
105 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(30); | 142 base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(30); |
106 base::TimeDelta delay4 = base::TimeDelta::FromMilliseconds(1); | 143 base::TimeDelta delay4 = base::TimeDelta::FromMilliseconds(1); |
107 | 144 |
108 // RequestWakeup should always be called if there are no other wakeups. | 145 // RequestWakeup should always be called if there are no other wakeups. |
109 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); | 146 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); |
110 base::TimeTicks now = time_domain_->Now(); | 147 base::TimeTicks now = time_domain_->Now(); |
111 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay1, now); | 148 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay1, now); |
112 | 149 |
113 Mock::VerifyAndClearExpectations(time_domain_.get()); | 150 Mock::VerifyAndClearExpectations(time_domain_.get()); |
114 | 151 |
115 // RequestWakeup should not be called when scheduling later tasks. | 152 // RequestWakeup should not be called when scheduling later tasks. |
116 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(0); | 153 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(0); |
117 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay2, now); | 154 time_domain_->ScheduleDelayedWork(task_queue2.get(), now + delay2, now); |
118 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay3, now); | 155 time_domain_->ScheduleDelayedWork(task_queue3.get(), now + delay3, now); |
119 | 156 |
120 // RequestWakeup should be called when scheduling earlier tasks. | 157 // RequestWakeup should be called when scheduling earlier tasks. |
121 Mock::VerifyAndClearExpectations(time_domain_.get()); | 158 Mock::VerifyAndClearExpectations(time_domain_.get()); |
122 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay4)); | 159 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay4)); |
123 time_domain_->ScheduleDelayedWork(task_queue_.get(), now + delay4, now); | 160 time_domain_->ScheduleDelayedWork(task_queue4.get(), now + delay4, now); |
124 } | 161 } |
125 | 162 |
126 TEST_F(TimeDomainTest, UnregisterQueue) { | 163 TEST_F(TimeDomainTest, UnregisterQueue) { |
127 scoped_refptr<internal::TaskQueueImpl> task_queue2_ = | 164 scoped_refptr<internal::TaskQueueImpl> task_queue2_ = |
128 make_scoped_refptr(new internal::TaskQueueImpl( | 165 make_scoped_refptr(new internal::TaskQueueImpl( |
129 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue2"), | 166 nullptr, time_domain_.get(), TaskQueue::Spec("test_queue2"), |
130 "test.category", "test.category")); | 167 "test.category", "test.category")); |
131 | 168 |
132 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(1); | 169 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(1); |
133 base::TimeTicks now = time_domain_->Now(); | 170 base::TimeTicks now = time_domain_->Now(); |
(...skipping 30 matching lines...) Expand all Loading... |
164 time_domain_->UpdateWorkQueues(lazy_now); | 201 time_domain_->UpdateWorkQueues(lazy_now); |
165 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | 202 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); |
166 EXPECT_EQ(delayed_runtime, next_run_time); | 203 EXPECT_EQ(delayed_runtime, next_run_time); |
167 | 204 |
168 time_domain_->SetNow(delayed_runtime); | 205 time_domain_->SetNow(delayed_runtime); |
169 lazy_now = time_domain_->CreateLazyNow(); | 206 lazy_now = time_domain_->CreateLazyNow(); |
170 time_domain_->UpdateWorkQueues(lazy_now); | 207 time_domain_->UpdateWorkQueues(lazy_now); |
171 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | 208 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); |
172 } | 209 } |
173 | 210 |
174 TEST_F(TimeDomainTest, ClearExpiredWakeups) { | |
175 base::TimeTicks now = time_domain_->Now(); | |
176 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); | |
177 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); | |
178 base::TimeTicks run_time1 = now + delay1; | |
179 base::TimeTicks run_time2 = now + delay2; | |
180 | |
181 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)).Times(AnyNumber()); | |
182 time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time1, now); | |
183 time_domain_->ScheduleDelayedWork(task_queue_.get(), run_time2, now); | |
184 | |
185 base::TimeTicks next_run_time; | |
186 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
187 EXPECT_EQ(run_time1, next_run_time); | |
188 | |
189 time_domain_->SetNow(run_time1); | |
190 time_domain_->ClearExpiredWakeups(); | |
191 | |
192 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
193 EXPECT_EQ(run_time2, next_run_time); | |
194 | |
195 time_domain_->SetNow(run_time2); | |
196 time_domain_->ClearExpiredWakeups(); | |
197 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
198 } | |
199 | |
200 TEST_F(TimeDomainTest, CancelDelayedWork) { | |
201 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); | |
202 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay)); | |
203 base::TimeTicks now = time_domain_->Now(); | |
204 base::TimeTicks delayed_runtime = now + delay; | |
205 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime, now); | |
206 | |
207 base::TimeTicks next_run_time; | |
208 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
209 EXPECT_EQ(delayed_runtime, next_run_time); | |
210 | |
211 time_domain_->CancelDelayedWork(task_queue_.get(), delayed_runtime); | |
212 EXPECT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
213 } | |
214 | |
215 TEST_F(TimeDomainTest, CancelDelayedWorkTaskQueueDoesntMatch) { | |
216 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); | |
217 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay)); | |
218 base::TimeTicks now = time_domain_->Now(); | |
219 base::TimeTicks delayed_runtime = now + delay; | |
220 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime, now); | |
221 | |
222 base::TimeTicks next_run_time; | |
223 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
224 EXPECT_EQ(delayed_runtime, next_run_time); | |
225 | |
226 time_domain_->CancelDelayedWork(nullptr, delayed_runtime); | |
227 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
228 EXPECT_EQ(delayed_runtime, next_run_time); | |
229 } | |
230 | |
231 TEST_F(TimeDomainTest, CancelDelayedWorkTwoWakeUpsCancelFirst) { | |
232 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); | |
233 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(150); | |
234 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); | |
235 base::TimeTicks now = time_domain_->Now(); | |
236 base::TimeTicks delayed_runtime1 = now + delay1; | |
237 base::TimeTicks delayed_runtime2 = now + delay2; | |
238 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime1, now); | |
239 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime2, now); | |
240 | |
241 base::TimeTicks next_run_time; | |
242 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
243 EXPECT_EQ(delayed_runtime1, next_run_time); | |
244 Mock::VerifyAndClearExpectations(time_domain_.get()); | |
245 | |
246 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay2)); | |
247 time_domain_->CancelDelayedWork(task_queue_.get(), delayed_runtime1); | |
248 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
249 EXPECT_EQ(delayed_runtime2, next_run_time); | |
250 } | |
251 | |
252 TEST_F(TimeDomainTest, CancelDelayedWorkTwoWakeUpsCancelSecond) { | |
253 base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); | |
254 base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(150); | |
255 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, delay1)); | |
256 base::TimeTicks now = time_domain_->Now(); | |
257 base::TimeTicks delayed_runtime1 = now + delay1; | |
258 base::TimeTicks delayed_runtime2 = now + delay2; | |
259 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime1, now); | |
260 time_domain_->ScheduleDelayedWork(task_queue_.get(), delayed_runtime2, now); | |
261 | |
262 base::TimeTicks next_run_time; | |
263 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
264 EXPECT_EQ(delayed_runtime1, next_run_time); | |
265 Mock::VerifyAndClearExpectations(time_domain_.get()); | |
266 | |
267 time_domain_->CancelDelayedWork(task_queue_.get(), delayed_runtime2); | |
268 ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
269 EXPECT_EQ(delayed_runtime1, next_run_time); | |
270 | |
271 time_domain_->SetNow(delayed_runtime1); | |
272 LazyNow lazy_now = time_domain_->CreateLazyNow(); | |
273 time_domain_->UpdateWorkQueues(lazy_now); | |
274 ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); | |
275 } | |
276 | |
277 namespace { | 211 namespace { |
278 class MockObserver : public TimeDomain::Observer { | 212 class MockObserver : public TimeDomain::Observer { |
279 public: | 213 public: |
280 ~MockObserver() override {} | 214 ~MockObserver() override {} |
281 | 215 |
282 MOCK_METHOD0(OnTimeDomainHasImmediateWork, void()); | 216 MOCK_METHOD0(OnTimeDomainHasImmediateWork, void()); |
283 MOCK_METHOD0(OnTimeDomainHasDelayedWork, void()); | 217 MOCK_METHOD0(OnTimeDomainHasDelayedWork, void()); |
284 }; | 218 }; |
285 } // namespace | 219 } // namespace |
286 | 220 |
(...skipping 15 matching lines...) Expand all Loading... |
302 TEST_F(TimeDomainWithObserverTest, OnTimeDomainHasDelayedWork) { | 236 TEST_F(TimeDomainWithObserverTest, OnTimeDomainHasDelayedWork) { |
303 EXPECT_CALL(*observer_, OnTimeDomainHasDelayedWork()); | 237 EXPECT_CALL(*observer_, OnTimeDomainHasDelayedWork()); |
304 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)); | 238 EXPECT_CALL(*time_domain_.get(), RequestWakeup(_, _)); |
305 base::TimeTicks now = time_domain_->Now(); | 239 base::TimeTicks now = time_domain_->Now(); |
306 time_domain_->ScheduleDelayedWork( | 240 time_domain_->ScheduleDelayedWork( |
307 task_queue_.get(), now + base::TimeDelta::FromMilliseconds(10), now); | 241 task_queue_.get(), now + base::TimeDelta::FromMilliseconds(10), now); |
308 } | 242 } |
309 | 243 |
310 } // namespace scheduler | 244 } // namespace scheduler |
311 } // namespace blink | 245 } // namespace blink |
OLD | NEW |