[ServiceWorker] Implement WebServiceWorkerContextClient::openWindow().
[chromium-blink-merge.git] / content / renderer / scheduler / renderer_scheduler_impl_unittest.cc
blobee16d04bece365535469dce5fa4acdbcb3be8ca3
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/renderer/scheduler/renderer_scheduler_impl.h"
7 #include "base/callback.h"
8 #include "cc/output/begin_frame_args.h"
9 #include "cc/test/ordered_simple_task_runner.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
13 namespace content {
15 class RendererSchedulerImplTest : public testing::Test {
16 public:
17 RendererSchedulerImplTest()
18 : clock_(cc::TestNowSource::Create(5000)),
19 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)),
20 scheduler_(new RendererSchedulerImpl(mock_task_runner_)),
21 default_task_runner_(scheduler_->DefaultTaskRunner()),
22 compositor_task_runner_(scheduler_->CompositorTaskRunner()),
23 loading_task_runner_(scheduler_->LoadingTaskRunner()),
24 idle_task_runner_(scheduler_->IdleTaskRunner()) {
25 scheduler_->SetTimeSourceForTesting(clock_);
27 ~RendererSchedulerImplTest() override {}
29 void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); }
31 void EnableIdleTasks() {
32 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
33 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
34 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
35 scheduler_->DidCommitFrameToCompositor();
38 protected:
39 scoped_refptr<cc::TestNowSource> clock_;
40 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
42 scoped_ptr<RendererSchedulerImpl> scheduler_;
43 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
44 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
45 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
46 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
48 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest);
51 void NullTask() {
54 void OrderedTestTask(int value, int* result) {
55 *result = (*result << 4) | value;
58 void UnorderedTestTask(int value, int* result) {
59 *result += value;
62 void AppendToVectorTestTask(std::vector<std::string>* vector,
63 std::string value) {
64 vector->push_back(value);
67 void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
68 std::string value,
69 base::TimeTicks deadline) {
70 AppendToVectorTestTask(vector, value);
73 void AppendToVectorReentrantTask(
74 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
75 std::vector<int>* vector,
76 int* reentrant_count,
77 int max_reentrant_count) {
78 vector->push_back((*reentrant_count)++);
79 if (*reentrant_count < max_reentrant_count) {
80 task_runner->PostTask(
81 FROM_HERE, base::Bind(AppendToVectorReentrantTask, task_runner, vector,
82 reentrant_count, max_reentrant_count));
86 void IdleTestTask(bool* task_run,
87 base::TimeTicks* deadline_out,
88 base::TimeTicks deadline) {
89 EXPECT_FALSE(*task_run);
90 *deadline_out = deadline;
91 *task_run = true;
94 void RepostingIdleTestTask(
95 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner,
96 int* run_count,
97 base::TimeTicks deadline) {
98 if (*run_count == 0) {
99 idle_task_runner->PostIdleTask(
100 FROM_HERE,
101 base::Bind(&RepostingIdleTestTask, idle_task_runner, run_count));
103 (*run_count)++;
106 void UpdateClockToDeadlineIdleTestTask(
107 scoped_refptr<cc::TestNowSource> clock,
108 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
109 int* run_count,
110 base::TimeTicks deadline) {
111 clock->SetNow(deadline);
112 // Due to the way in which OrderedSimpleTestRunner orders tasks and the fact
113 // that we updated the time within a task, the delayed pending task to call
114 // EndIdlePeriod will not happen until after a TaskQueueManager DoWork, so
115 // post a normal task here to ensure it runs before the next idle task.
116 task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
117 (*run_count)++;
120 void PostingYieldingTestTask(
121 RendererSchedulerImpl* scheduler,
122 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
123 bool simulate_input,
124 bool* should_yield_before,
125 bool* should_yield_after) {
126 *should_yield_before = scheduler->ShouldYieldForHighPriorityWork();
127 task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
128 if (simulate_input) {
129 scheduler->DidReceiveInputEventOnCompositorThread(
130 blink::WebInputEvent::GestureFlingStart);
132 *should_yield_after = scheduler->ShouldYieldForHighPriorityWork();
135 TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) {
136 int result = 0;
137 default_task_runner_->PostTask(FROM_HERE,
138 base::Bind(OrderedTestTask, 1, &result));
139 default_task_runner_->PostTask(FROM_HERE,
140 base::Bind(OrderedTestTask, 2, &result));
141 default_task_runner_->PostTask(FROM_HERE,
142 base::Bind(OrderedTestTask, 3, &result));
143 default_task_runner_->PostTask(FROM_HERE,
144 base::Bind(OrderedTestTask, 4, &result));
145 RunUntilIdle();
146 EXPECT_EQ(0x1234, result);
149 TEST_F(RendererSchedulerImplTest, TestPostDefaultAndCompositor) {
150 int result = 0;
151 default_task_runner_->PostTask(FROM_HERE,
152 base::Bind(&UnorderedTestTask, 1, &result));
153 compositor_task_runner_->PostTask(FROM_HERE,
154 base::Bind(&UnorderedTestTask, 2, &result));
155 RunUntilIdle();
156 EXPECT_EQ(3, result);
159 TEST_F(RendererSchedulerImplTest, TestRentrantTask) {
160 int count = 0;
161 std::vector<int> order;
162 default_task_runner_->PostTask(
163 FROM_HERE, base::Bind(AppendToVectorReentrantTask, default_task_runner_,
164 &order, &count, 5));
165 RunUntilIdle();
167 EXPECT_THAT(order, testing::ElementsAre(0, 1, 2, 3, 4));
170 TEST_F(RendererSchedulerImplTest, TestPostIdleTask) {
171 bool task_run = false;
172 base::TimeTicks expected_deadline =
173 clock_->Now() + base::TimeDelta::FromMilliseconds(2300);
174 base::TimeTicks deadline_in_task;
176 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
177 idle_task_runner_->PostIdleTask(
178 FROM_HERE, base::Bind(&IdleTestTask, &task_run, &deadline_in_task));
180 RunUntilIdle();
181 EXPECT_FALSE(task_run); // Shouldn't run yet as no WillBeginFrame.
183 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
184 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
185 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
186 RunUntilIdle();
187 EXPECT_FALSE(task_run); // Shouldn't run as no DidCommitFrameToCompositor.
189 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1200));
190 scheduler_->DidCommitFrameToCompositor();
191 RunUntilIdle();
192 EXPECT_FALSE(task_run); // We missed the deadline.
194 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
195 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
196 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
197 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(800));
198 scheduler_->DidCommitFrameToCompositor();
199 RunUntilIdle();
200 EXPECT_TRUE(task_run);
201 EXPECT_EQ(expected_deadline, deadline_in_task);
204 TEST_F(RendererSchedulerImplTest, TestRepostingIdleTask) {
205 int run_count = 0;
207 idle_task_runner_->PostIdleTask(
208 FROM_HERE,
209 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
210 EnableIdleTasks();
211 RunUntilIdle();
212 EXPECT_EQ(1, run_count);
214 // Reposted tasks shouldn't run until next idle period.
215 RunUntilIdle();
216 EXPECT_EQ(1, run_count);
218 EnableIdleTasks();
219 RunUntilIdle();
220 EXPECT_EQ(2, run_count);
223 TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) {
224 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
225 int run_count = 0;
227 // Post two UpdateClockToDeadlineIdleTestTask tasks.
228 idle_task_runner_->PostIdleTask(
229 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
230 default_task_runner_, &run_count));
231 idle_task_runner_->PostIdleTask(
232 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
233 default_task_runner_, &run_count));
235 EnableIdleTasks();
236 RunUntilIdle();
237 // Only the first idle task should execute since it's used up the deadline.
238 EXPECT_EQ(1, run_count);
240 EnableIdleTasks();
241 RunUntilIdle();
242 // Second task should be run on the next idle period.
243 EXPECT_EQ(2, run_count);
246 TEST_F(RendererSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
247 bool task_run = false;
249 base::TimeTicks deadline_in_task;
250 idle_task_runner_->PostIdleTask(
251 FROM_HERE, base::Bind(&IdleTestTask, &task_run, &deadline_in_task));
253 // Trigger the beginning of an idle period for 1000ms.
254 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
255 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
256 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
257 scheduler_->DidCommitFrameToCompositor();
259 // End the idle period early (after 500ms), and send a WillBeginFrame which
260 // specifies that the next idle period should end 1000ms from now.
261 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(500));
262 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
263 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
264 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
266 RunUntilIdle();
267 EXPECT_FALSE(task_run); // Not currently in an idle period.
269 // Trigger the start of the idle period before the task to end the previous
270 // idle period has been triggered.
271 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(400));
272 scheduler_->DidCommitFrameToCompositor();
274 // Post a task which simulates running until after the previous end idle
275 // period delayed task was scheduled for
276 scheduler_->DefaultTaskRunner()->PostTask(FROM_HERE, base::Bind(NullTask));
277 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(300));
279 RunUntilIdle();
280 EXPECT_TRUE(task_run); // We should still be in the new idle period.
283 TEST_F(RendererSchedulerImplTest, TestDefaultPolicy) {
284 std::vector<std::string> order;
286 loading_task_runner_->PostTask(
287 FROM_HERE,
288 base::Bind(&AppendToVectorTestTask, &order, std::string("L1")));
289 idle_task_runner_->PostIdleTask(
290 FROM_HERE,
291 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
292 default_task_runner_->PostTask(
293 FROM_HERE,
294 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
295 compositor_task_runner_->PostTask(
296 FROM_HERE,
297 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
298 default_task_runner_->PostTask(
299 FROM_HERE,
300 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
301 compositor_task_runner_->PostTask(
302 FROM_HERE,
303 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
305 EnableIdleTasks();
306 RunUntilIdle();
307 EXPECT_THAT(order, testing::ElementsAre(
308 std::string("L1"), std::string("D1"), std::string("C1"),
309 std::string("D2"), std::string("C2"), std::string("I1")));
312 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy) {
313 std::vector<std::string> order;
315 loading_task_runner_->PostTask(
316 FROM_HERE,
317 base::Bind(&AppendToVectorTestTask, &order, std::string("L1")));
318 idle_task_runner_->PostIdleTask(
319 FROM_HERE,
320 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
321 default_task_runner_->PostTask(
322 FROM_HERE,
323 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
324 compositor_task_runner_->PostTask(
325 FROM_HERE,
326 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
327 default_task_runner_->PostTask(
328 FROM_HERE,
329 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
330 compositor_task_runner_->PostTask(
331 FROM_HERE,
332 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
334 scheduler_->DidReceiveInputEventOnCompositorThread(
335 blink::WebInputEvent::GestureFlingStart);
336 EnableIdleTasks();
337 RunUntilIdle();
338 EXPECT_THAT(order, testing::ElementsAre(
339 std::string("C1"), std::string("C2"), std::string("D1"),
340 std::string("D2"), std::string("L1"), std::string("I1")));
343 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
344 std::vector<std::string> order;
346 idle_task_runner_->PostIdleTask(
347 FROM_HERE,
348 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
349 default_task_runner_->PostTask(
350 FROM_HERE,
351 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
352 compositor_task_runner_->PostTask(
353 FROM_HERE,
354 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
355 default_task_runner_->PostTask(
356 FROM_HERE,
357 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
358 compositor_task_runner_->PostTask(
359 FROM_HERE,
360 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
362 scheduler_->DidAnimateForInputOnCompositorThread();
363 EnableIdleTasks();
364 RunUntilIdle();
365 EXPECT_THAT(order, testing::ElementsAre(std::string("C1"), std::string("C2"),
366 std::string("D1"), std::string("D2"),
367 std::string("I1")));
370 TEST_F(RendererSchedulerImplTest,
371 DidReceiveInputEventOnCompositorThread_IgnoresMouseEvents) {
372 std::vector<std::string> order;
374 idle_task_runner_->PostIdleTask(
375 FROM_HERE,
376 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
377 default_task_runner_->PostTask(
378 FROM_HERE,
379 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
380 compositor_task_runner_->PostTask(
381 FROM_HERE,
382 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
383 default_task_runner_->PostTask(
384 FROM_HERE,
385 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
386 compositor_task_runner_->PostTask(
387 FROM_HERE,
388 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
390 scheduler_->DidReceiveInputEventOnCompositorThread(
391 blink::WebInputEvent::MouseMove);
392 EnableIdleTasks();
393 RunUntilIdle();
394 // Note compositor tasks are not prioritized.
395 EXPECT_THAT(order, testing::ElementsAre(std::string("D1"), std::string("C1"),
396 std::string("D2"), std::string("C2"),
397 std::string("I1")));
400 TEST_F(RendererSchedulerImplTest,
401 DidReceiveInputEventOnCompositorThread_IgnoresKeyboardEvents) {
402 std::vector<std::string> order;
404 idle_task_runner_->PostIdleTask(
405 FROM_HERE,
406 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
407 default_task_runner_->PostTask(
408 FROM_HERE,
409 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
410 compositor_task_runner_->PostTask(
411 FROM_HERE,
412 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
413 default_task_runner_->PostTask(
414 FROM_HERE,
415 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
416 compositor_task_runner_->PostTask(
417 FROM_HERE,
418 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
420 scheduler_->DidReceiveInputEventOnCompositorThread(
421 blink::WebInputEvent::KeyDown);
422 EnableIdleTasks();
423 RunUntilIdle();
424 // Note compositor tasks are not prioritized.
425 EXPECT_THAT(order, testing::ElementsAre(std::string("D1"), std::string("C1"),
426 std::string("D2"), std::string("C2"),
427 std::string("I1")));
430 TEST_F(RendererSchedulerImplTest,
431 TestCompositorPolicyDoesNotStarveDefaultTasks) {
432 std::vector<std::string> order;
434 default_task_runner_->PostTask(
435 FROM_HERE,
436 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
437 compositor_task_runner_->PostTask(
438 FROM_HERE,
439 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
440 for (int i = 0; i < 20; i++) {
441 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
443 compositor_task_runner_->PostTask(
444 FROM_HERE,
445 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
447 scheduler_->DidReceiveInputEventOnCompositorThread(
448 blink::WebInputEvent::GestureFlingStart);
449 RunUntilIdle();
450 // Ensure that the default D1 task gets to run at some point before the final
451 // C2 compositor task.
452 EXPECT_THAT(order, testing::ElementsAre(std::string("C1"), std::string("D1"),
453 std::string("C2")));
456 TEST_F(RendererSchedulerImplTest, TestCompositorPolicyEnds) {
457 std::vector<std::string> order;
459 default_task_runner_->PostTask(
460 FROM_HERE,
461 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
462 compositor_task_runner_->PostTask(
463 FROM_HERE,
464 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
465 default_task_runner_->PostTask(
466 FROM_HERE,
467 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
468 compositor_task_runner_->PostTask(
469 FROM_HERE,
470 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
472 scheduler_->DidReceiveInputEventOnCompositorThread(
473 blink::WebInputEvent::GestureFlingStart);
474 RunUntilIdle();
475 EXPECT_THAT(order,
476 testing::ElementsAre(std::string("C1"), std::string("C2"),
477 std::string("D1"), std::string("D2")));
479 order.clear();
480 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1000));
482 default_task_runner_->PostTask(
483 FROM_HERE,
484 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
485 compositor_task_runner_->PostTask(
486 FROM_HERE,
487 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
488 default_task_runner_->PostTask(
489 FROM_HERE,
490 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
491 compositor_task_runner_->PostTask(
492 FROM_HERE,
493 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
495 // Compositor policy mode should have ended now that the clock has advanced.
496 RunUntilIdle();
497 EXPECT_THAT(order,
498 testing::ElementsAre(std::string("D1"), std::string("C1"),
499 std::string("D2"), std::string("C2")));
502 TEST_F(RendererSchedulerImplTest, TestShouldYield) {
503 bool should_yield_before = false;
504 bool should_yield_after = false;
506 default_task_runner_->PostTask(
507 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
508 default_task_runner_, false, &should_yield_before,
509 &should_yield_after));
510 RunUntilIdle();
511 // Posting to default runner shouldn't cause yielding.
512 EXPECT_FALSE(should_yield_before);
513 EXPECT_FALSE(should_yield_after);
515 default_task_runner_->PostTask(
516 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
517 compositor_task_runner_, false,
518 &should_yield_before, &should_yield_after));
519 RunUntilIdle();
520 // Posting while not in compositor priority shouldn't cause yielding.
521 EXPECT_FALSE(should_yield_before);
522 EXPECT_FALSE(should_yield_after);
524 default_task_runner_->PostTask(
525 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
526 compositor_task_runner_, true, &should_yield_before,
527 &should_yield_after));
528 RunUntilIdle();
529 // We should be able to switch to compositor priority mid-task.
530 EXPECT_FALSE(should_yield_before);
531 EXPECT_TRUE(should_yield_after);
534 } // namespace content