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

Side by Side Diff: components/scheduler/child/worker_scheduler_impl_unittest.cc

Issue 1151353003: [scheduler]: Avoid waking up the scheduler to end long idle periods. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@end_idle_sync_2
Patch Set: Fix Win for realz hopefully... Created 5 years, 6 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
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « components/scheduler/child/worker_scheduler_impl.cc ('k') | components/scheduler/renderer/renderer_scheduler_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698