| 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 "components/scheduler/child/worker_scheduler_impl.h" | 5 #include "components/scheduler/child/worker_scheduler_impl.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "cc/test/ordered_simple_task_runner.h" | 9 #include "cc/test/ordered_simple_task_runner.h" |
| 10 #include "cc/test/test_now_source.h" | 10 #include "cc/test/test_now_source.h" |
| 11 #include "components/scheduler/child/nestable_task_runner_for_test.h" | 11 #include "components/scheduler/child/nestable_task_runner_for_test.h" |
| 12 #include "components/scheduler/child/scheduler_message_loop_delegate.h" | 12 #include "components/scheduler/child/scheduler_message_loop_delegate.h" |
| 13 #include "components/scheduler/child/test_time_source.h" | 13 #include "components/scheduler/child/test_time_source.h" |
| 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 using testing::ElementsAreArray; | 17 using testing::ElementsAreArray; |
| 18 | 18 |
| 19 namespace scheduler { | 19 namespace scheduler { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 void NopTask() { | 22 void NopTask() { |
| 23 } | 23 } |
| 24 | 24 |
| 25 int TimeTicksToIntMs(const base::TimeTicks& time) { | 25 int TimeTicksToIntMs(const base::TimeTicks& time) { |
| 26 return static_cast<int>((time - base::TimeTicks()).InMilliseconds()); | 26 return static_cast<int>((time - base::TimeTicks()).InMilliseconds()); |
| 27 } | 27 } |
| 28 | 28 |
| 29 void WakeUpTask(std::vector<std::string>* timeline, cc::TestNowSource* clock) { | |
| 30 if (timeline) { | |
| 31 timeline->push_back(base::StringPrintf("run WakeUpTask @ %d", | |
| 32 TimeTicksToIntMs(clock->Now()))); | |
| 33 } | |
| 34 } | |
| 35 | |
| 36 void RecordTimelineTask(std::vector<std::string>* timeline, | 29 void RecordTimelineTask(std::vector<std::string>* timeline, |
| 37 cc::TestNowSource* clock) { | 30 cc::TestNowSource* clock) { |
| 38 timeline->push_back(base::StringPrintf("run RecordTimelineTask @ %d", | 31 timeline->push_back(base::StringPrintf("run RecordTimelineTask @ %d", |
| 39 TimeTicksToIntMs(clock->Now()))); | 32 TimeTicksToIntMs(clock->Now()))); |
| 40 } | 33 } |
| 41 | 34 |
| 42 void AppendToVectorTestTask(std::vector<std::string>* vector, | 35 void AppendToVectorTestTask(std::vector<std::string>* vector, |
| 43 std::string value) { | 36 std::string value) { |
| 44 vector->push_back(value); | 37 vector->push_back(value); |
| 45 } | 38 } |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 timeline_->push_back(base::StringPrintf("RunUntilIdle begin @ %d", | 130 timeline_->push_back(base::StringPrintf("RunUntilIdle begin @ %d", |
| 138 TimeTicksToIntMs(clock_->Now()))); | 131 TimeTicksToIntMs(clock_->Now()))); |
| 139 } | 132 } |
| 140 mock_task_runner_->RunUntilIdle(); | 133 mock_task_runner_->RunUntilIdle(); |
| 141 if (timeline_) { | 134 if (timeline_) { |
| 142 timeline_->push_back(base::StringPrintf("RunUntilIdle end @ %d", | 135 timeline_->push_back(base::StringPrintf("RunUntilIdle end @ %d", |
| 143 TimeTicksToIntMs(clock_->Now()))); | 136 TimeTicksToIntMs(clock_->Now()))); |
| 144 } | 137 } |
| 145 } | 138 } |
| 146 | 139 |
| 147 void InitAndPostDelayedWakeupTask() { | |
| 148 Init(); | |
| 149 // WorkerSchedulerImpl::Init causes a delayed task to be posted on the | |
| 150 // after wakeup control runner. We need a task to wake the system up | |
| 151 // AFTER the delay for this has expired. | |
| 152 default_task_runner_->PostDelayedTask( | |
| 153 FROM_HERE, base::Bind(&WakeUpTask, base::Unretained(timeline_), | |
| 154 base::Unretained(clock_.get())), | |
| 155 base::TimeDelta::FromMilliseconds(100)); | |
| 156 } | |
| 157 | |
| 158 // Helper for posting several tasks of specific types. |task_descriptor| is a | 140 // Helper for posting several tasks of specific types. |task_descriptor| is a |
| 159 // string with space delimited task identifiers. The first letter of each | 141 // string with space delimited task identifiers. The first letter of each |
| 160 // task identifier specifies the task type: | 142 // task identifier specifies the task type: |
| 161 // - 'D': Default task | 143 // - 'D': Default task |
| 162 // - 'I': Idle task | 144 // - 'I': Idle task |
| 163 void PostTestTasks(std::vector<std::string>* run_order, | 145 void PostTestTasks(std::vector<std::string>* run_order, |
| 164 const std::string& task_descriptor) { | 146 const std::string& task_descriptor) { |
| 165 std::istringstream stream(task_descriptor); | 147 std::istringstream stream(task_descriptor); |
| 166 while (!stream.eof()) { | 148 while (!stream.eof()) { |
| 167 std::string task; | 149 std::string task; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 195 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_; | 177 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_; |
| 196 scoped_ptr<WorkerSchedulerImplForTest> scheduler_; | 178 scoped_ptr<WorkerSchedulerImplForTest> scheduler_; |
| 197 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | 179 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; |
| 198 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; | 180 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; |
| 199 std::vector<std::string>* timeline_; // NOT OWNED | 181 std::vector<std::string>* timeline_; // NOT OWNED |
| 200 | 182 |
| 201 DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerImplTest); | 183 DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerImplTest); |
| 202 }; | 184 }; |
| 203 | 185 |
| 204 TEST_F(WorkerSchedulerImplTest, TestPostDefaultTask) { | 186 TEST_F(WorkerSchedulerImplTest, TestPostDefaultTask) { |
| 205 InitAndPostDelayedWakeupTask(); | 187 Init(); |
| 206 | 188 |
| 207 std::vector<std::string> run_order; | 189 std::vector<std::string> run_order; |
| 208 PostTestTasks(&run_order, "D1 D2 D3 D4"); | 190 PostTestTasks(&run_order, "D1 D2 D3 D4"); |
| 209 | 191 |
| 210 RunUntilIdle(); | 192 RunUntilIdle(); |
| 211 EXPECT_THAT(run_order, | 193 EXPECT_THAT(run_order, |
| 212 testing::ElementsAre(std::string("D1"), std::string("D2"), | 194 testing::ElementsAre(std::string("D1"), std::string("D2"), |
| 213 std::string("D3"), std::string("D4"))); | 195 std::string("D3"), std::string("D4"))); |
| 214 } | 196 } |
| 215 | 197 |
| 216 TEST_F(WorkerSchedulerImplTest, TestPostIdleTask) { | 198 TEST_F(WorkerSchedulerImplTest, TestPostIdleTask) { |
| 217 InitAndPostDelayedWakeupTask(); | 199 Init(); |
| 218 | 200 |
| 219 std::vector<std::string> run_order; | 201 std::vector<std::string> run_order; |
| 220 PostTestTasks(&run_order, "I1"); | 202 PostTestTasks(&run_order, "I1"); |
| 221 | 203 |
| 222 RunUntilIdle(); | 204 RunUntilIdle(); |
| 223 EXPECT_THAT(run_order, testing::ElementsAre(std::string("I1"))); | 205 EXPECT_THAT(run_order, testing::ElementsAre(std::string("I1"))); |
| 224 } | 206 } |
| 225 | 207 |
| 226 TEST_F(WorkerSchedulerImplTest, TestPostIdleTask_NoWakeup) { | 208 TEST_F(WorkerSchedulerImplTest, TestPostDefaultAndIdleTasks) { |
| 227 Init(); | 209 Init(); |
| 228 std::vector<std::string> run_order; | |
| 229 PostTestTasks(&run_order, "I1"); | |
| 230 | |
| 231 RunUntilIdle(); | |
| 232 EXPECT_TRUE(run_order.empty()); | |
| 233 } | |
| 234 | |
| 235 TEST_F(WorkerSchedulerImplTest, TestPostDefaultAndIdleTasks) { | |
| 236 InitAndPostDelayedWakeupTask(); | |
| 237 | 210 |
| 238 std::vector<std::string> run_order; | 211 std::vector<std::string> run_order; |
| 239 PostTestTasks(&run_order, "I1 D2 D3 D4"); | 212 PostTestTasks(&run_order, "I1 D2 D3 D4"); |
| 240 | 213 |
| 241 RunUntilIdle(); | 214 RunUntilIdle(); |
| 242 EXPECT_THAT(run_order, | 215 EXPECT_THAT(run_order, |
| 243 testing::ElementsAre(std::string("D2"), std::string("D3"), | 216 testing::ElementsAre(std::string("D2"), std::string("D3"), |
| 244 std::string("D4"), std::string("I1"))); | 217 std::string("D4"), std::string("I1"))); |
| 245 } | 218 } |
| 246 | 219 |
| 247 TEST_F(WorkerSchedulerImplTest, TestPostIdleTaskWithWakeupNeeded_NoWakeup) { | |
| 248 InitAndPostDelayedWakeupTask(); | |
| 249 | |
| 250 RunUntilIdle(); | |
| 251 // The delayed call to EnableLongIdlePeriod happened and it posted a call to | |
| 252 // EnableLongIdlePeriod on the after wakeup control queue. | |
| 253 | |
| 254 std::vector<std::string> run_order; | |
| 255 PostTestTasks(&run_order, "I1"); | |
| 256 | |
| 257 RunUntilIdle(); | |
| 258 EXPECT_TRUE(run_order.empty()); | |
| 259 } | |
| 260 | |
| 261 TEST_F(WorkerSchedulerImplTest, TestPostDefaultDelayedAndIdleTasks) { | 220 TEST_F(WorkerSchedulerImplTest, TestPostDefaultDelayedAndIdleTasks) { |
| 262 InitAndPostDelayedWakeupTask(); | 221 Init(); |
| 263 | 222 |
| 264 std::vector<std::string> run_order; | 223 std::vector<std::string> run_order; |
| 265 PostTestTasks(&run_order, "I1 D2 D3 D4"); | 224 PostTestTasks(&run_order, "I1 D2 D3 D4"); |
| 266 | 225 |
| 267 default_task_runner_->PostDelayedTask( | 226 default_task_runner_->PostDelayedTask( |
| 268 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "DELAYED"), | 227 FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "DELAYED"), |
| 269 base::TimeDelta::FromMilliseconds(1000)); | 228 base::TimeDelta::FromMilliseconds(1000)); |
| 270 | 229 |
| 271 RunUntilIdle(); | 230 RunUntilIdle(); |
| 272 EXPECT_THAT(run_order, | 231 EXPECT_THAT(run_order, |
| 273 testing::ElementsAre(std::string("D2"), std::string("D3"), | 232 testing::ElementsAre(std::string("D2"), std::string("D3"), |
| 274 std::string("D4"), std::string("I1"), | 233 std::string("D4"), std::string("I1"), |
| 275 std::string("DELAYED"))); | 234 std::string("DELAYED"))); |
| 276 } | 235 } |
| 277 | 236 |
| 237 TEST_F(WorkerSchedulerImplTest, TestIdleTaskWhenIsNotQuiescent) { |
| 238 std::vector<std::string> timeline; |
| 239 RecordTimelineEvents(&timeline); |
| 240 Init(); |
| 241 |
| 242 timeline.push_back("Post default task"); |
| 243 // Post a delayed task timed to occur mid way during the long idle period. |
| 244 default_task_runner_->PostTask( |
| 245 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline), |
| 246 base::Unretained(clock_.get()))); |
| 247 RunUntilIdle(); |
| 248 |
| 249 timeline.push_back("Post idle task"); |
| 250 idle_task_runner_->PostIdleTask(FROM_HERE, |
| 251 base::Bind(&TimelineIdleTestTask, &timeline)); |
| 252 |
| 253 RunUntilIdle(); |
| 254 |
| 255 std::string expected_timeline[] = {"CanEnterLongIdlePeriod @ 5", |
| 256 "Post default task", |
| 257 "run RecordTimelineTask @ 5", |
| 258 "Post idle task", |
| 259 "IsNotQuiescent @ 5", |
| 260 "CanEnterLongIdlePeriod @ 305", |
| 261 "run TimelineIdleTestTask deadline 355"}; |
| 262 |
| 263 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline)); |
| 264 } |
| 265 |
| 278 TEST_F(WorkerSchedulerImplTest, TestIdleDeadlineWithPendingDelayedTask) { | 266 TEST_F(WorkerSchedulerImplTest, TestIdleDeadlineWithPendingDelayedTask) { |
| 279 std::vector<std::string> timeline; | 267 std::vector<std::string> timeline; |
| 280 RecordTimelineEvents(&timeline); | 268 RecordTimelineEvents(&timeline); |
| 281 InitAndPostDelayedWakeupTask(); | 269 Init(); |
| 282 | 270 |
| 283 timeline.push_back("Post delayed and idle tasks"); | 271 timeline.push_back("Post delayed and idle tasks"); |
| 284 // Post a delayed task timed to occur mid way during the long idle period. | 272 // Post a delayed task timed to occur mid way during the long idle period. |
| 285 default_task_runner_->PostDelayedTask( | 273 default_task_runner_->PostDelayedTask( |
| 286 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline), | 274 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline), |
| 287 base::Unretained(clock_.get())), | 275 base::Unretained(clock_.get())), |
| 288 base::TimeDelta::FromMilliseconds(420)); | 276 base::TimeDelta::FromMilliseconds(20)); |
| 289 idle_task_runner_->PostIdleTask(FROM_HERE, | 277 idle_task_runner_->PostIdleTask(FROM_HERE, |
| 290 base::Bind(&TimelineIdleTestTask, &timeline)); | 278 base::Bind(&TimelineIdleTestTask, &timeline)); |
| 291 | 279 |
| 292 RunUntilIdle(); | 280 RunUntilIdle(); |
| 293 | 281 |
| 294 std::string expected_timeline[] = { | 282 std::string expected_timeline[] = { |
| 295 "CanEnterLongIdlePeriod @ 5", | 283 "CanEnterLongIdlePeriod @ 5", |
| 296 "Post delayed and idle tasks", | 284 "Post delayed and idle tasks", |
| 297 "IsNotQuiescent @ 105", | 285 "CanEnterLongIdlePeriod @ 5", |
| 298 "CanEnterLongIdlePeriod @ 405", | 286 "run TimelineIdleTestTask deadline 25", // Note the short 20ms deadline. |
| 299 "run TimelineIdleTestTask deadline 425", // Note the short 20ms deadline. | 287 "run RecordTimelineTask @ 25"}; |
| 300 "CanEnterLongIdlePeriod @ 425", | |
| 301 "run RecordTimelineTask @ 425"}; | |
| 302 | 288 |
| 303 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline)); | 289 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline)); |
| 304 } | 290 } |
| 305 | 291 |
| 306 TEST_F(WorkerSchedulerImplTest, | 292 TEST_F(WorkerSchedulerImplTest, |
| 307 TestIdleDeadlineWithPendingDelayedTaskFarInTheFuture) { | 293 TestIdleDeadlineWithPendingDelayedTaskFarInTheFuture) { |
| 308 std::vector<std::string> timeline; | 294 std::vector<std::string> timeline; |
| 309 RecordTimelineEvents(&timeline); | 295 RecordTimelineEvents(&timeline); |
| 310 InitAndPostDelayedWakeupTask(); | 296 Init(); |
| 311 | 297 |
| 312 timeline.push_back("Post delayed and idle tasks"); | 298 timeline.push_back("Post delayed and idle tasks"); |
| 313 // Post a delayed task timed to occur well after the long idle period. | 299 // Post a delayed task timed to occur well after the long idle period. |
| 314 default_task_runner_->PostDelayedTask( | 300 default_task_runner_->PostDelayedTask( |
| 315 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline), | 301 FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline), |
| 316 base::Unretained(clock_.get())), | 302 base::Unretained(clock_.get())), |
| 317 base::TimeDelta::FromMilliseconds(1000)); | 303 base::TimeDelta::FromMilliseconds(500)); |
| 318 idle_task_runner_->PostIdleTask(FROM_HERE, | 304 idle_task_runner_->PostIdleTask(FROM_HERE, |
| 319 base::Bind(&TimelineIdleTestTask, &timeline)); | 305 base::Bind(&TimelineIdleTestTask, &timeline)); |
| 320 | 306 |
| 321 RunUntilIdle(); | 307 RunUntilIdle(); |
| 322 | 308 |
| 323 std::string expected_timeline[] = { | 309 std::string expected_timeline[] = { |
| 324 "CanEnterLongIdlePeriod @ 5", | 310 "CanEnterLongIdlePeriod @ 5", |
| 325 "Post delayed and idle tasks", | 311 "Post delayed and idle tasks", |
| 326 "IsNotQuiescent @ 105", | 312 "CanEnterLongIdlePeriod @ 5", |
| 327 "CanEnterLongIdlePeriod @ 405", | 313 "run TimelineIdleTestTask deadline 55", // Note the full 50ms deadline. |
| 328 "run TimelineIdleTestTask deadline 455", // Note the full 50ms deadline. | 314 "run RecordTimelineTask @ 505"}; |
| 329 "CanEnterLongIdlePeriod @ 455", | |
| 330 "run RecordTimelineTask @ 1005"}; | |
| 331 | 315 |
| 332 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline)); | 316 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline)); |
| 333 } | 317 } |
| 334 | 318 |
| 335 TEST_F(WorkerSchedulerImplTest, | 319 TEST_F(WorkerSchedulerImplTest, TestPostIdleTaskAfterRunningUntilIdle) { |
| 336 TestPostIdleTaskAfterRunningUntilIdle_NoWakeUp) { | 320 Init(); |
| 337 InitAndPostDelayedWakeupTask(); | |
| 338 | 321 |
| 339 default_task_runner_->PostDelayedTask( | 322 default_task_runner_->PostDelayedTask( |
| 340 FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000)); | 323 FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000)); |
| 341 RunUntilIdle(); | 324 RunUntilIdle(); |
| 342 | 325 |
| 343 // The delayed call to EnableLongIdlePeriod happened and it posted a call to | |
| 344 // EnableLongIdlePeriod on the after wakeup control queue. Without an other | |
| 345 // non-idle task posted, the idle tasks won't run. | |
| 346 std::vector<std::string> run_order; | |
| 347 PostTestTasks(&run_order, "I1 I2"); | |
| 348 | |
| 349 RunUntilIdle(); | |
| 350 EXPECT_TRUE(run_order.empty()); | |
| 351 } | |
| 352 | |
| 353 TEST_F(WorkerSchedulerImplTest, | |
| 354 TestPostIdleTaskAfterRunningUntilIdle_WithWakeUp) { | |
| 355 InitAndPostDelayedWakeupTask(); | |
| 356 | |
| 357 default_task_runner_->PostDelayedTask( | |
| 358 FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000)); | |
| 359 RunUntilIdle(); | |
| 360 // The delayed call to EnableLongIdlePeriod happened and it posted a call to | |
| 361 // EnableLongIdlePeriod on the after wakeup control queue. Without an other | |
| 362 // non-idle task posted, the idle tasks won't run. | |
| 363 | |
| 364 std::vector<std::string> run_order; | 326 std::vector<std::string> run_order; |
| 365 PostTestTasks(&run_order, "I1 I2 D3"); | 327 PostTestTasks(&run_order, "I1 I2 D3"); |
| 366 | 328 |
| 367 RunUntilIdle(); | 329 RunUntilIdle(); |
| 368 EXPECT_THAT(run_order, | 330 EXPECT_THAT(run_order, |
| 369 testing::ElementsAre(std::string("D3"), std::string("I1"), | 331 testing::ElementsAre(std::string("D3"), std::string("I1"), |
| 370 std::string("I2"))); | 332 std::string("I2"))); |
| 371 } | 333 } |
| 372 | 334 |
| 373 TEST_F(WorkerSchedulerImplTest, TestLongIdlePeriodTimeline) { | 335 TEST_F(WorkerSchedulerImplTest, TestLongIdlePeriodTimeline) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 "RunUntilIdle end @ 55", | 372 "RunUntilIdle end @ 55", |
| 411 "PostIdleTaskAfterWakeup", | 373 "PostIdleTaskAfterWakeup", |
| 412 "RunUntilIdle begin @ 55", // NOTE idle task doesn't run till later. | 374 "RunUntilIdle begin @ 55", // NOTE idle task doesn't run till later. |
| 413 "RunUntilIdle end @ 55", | 375 "RunUntilIdle end @ 55", |
| 414 "Post RecordTimelineTask", | 376 "Post RecordTimelineTask", |
| 415 "RunUntilIdle begin @ 55", | 377 "RunUntilIdle begin @ 55", |
| 416 "run RecordTimelineTask @ 55", | 378 "run RecordTimelineTask @ 55", |
| 417 "IsNotQuiescent @ 55", // NOTE we have to wait for quiescence. | 379 "IsNotQuiescent @ 55", // NOTE we have to wait for quiescence. |
| 418 "CanEnterLongIdlePeriod @ 355", | 380 "CanEnterLongIdlePeriod @ 355", |
| 419 "run TimelineIdleTestTask deadline 405", | 381 "run TimelineIdleTestTask deadline 405", |
| 420 "CanEnterLongIdlePeriod @ 405", | 382 "RunUntilIdle end @ 355"}; |
| 421 "RunUntilIdle end @ 455"}; | |
| 422 | 383 |
| 423 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline)); | 384 EXPECT_THAT(timeline, ElementsAreArray(expected_timeline)); |
| 424 } | 385 } |
| 425 | 386 |
| 426 } // namespace scheduler | 387 } // namespace scheduler |
| OLD | NEW |