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

Unified Diff: content/child/scheduler/scheduler_helper_unittest.cc

Issue 1025323003: Introduce a SchedulerHelper in content/child/scheduler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Sami's comments Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: content/child/scheduler/scheduler_helper_unittest.cc
diff --git a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc b/content/child/scheduler/scheduler_helper_unittest.cc
similarity index 28%
copy from content/renderer/scheduler/renderer_scheduler_impl_unittest.cc
copy to content/child/scheduler/scheduler_helper_unittest.cc
index 870be4a086a5ff9e3ca6eeb246f589431cccbbbb..97869bf229f04e4a653165578e39f456d157c0ac 100644
--- a/content/renderer/scheduler/renderer_scheduler_impl_unittest.cc
+++ b/content/child/scheduler/scheduler_helper_unittest.cc
@@ -2,33 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/renderer/scheduler/renderer_scheduler_impl.h"
+#include "content/child/scheduler/scheduler_helper.h"
#include "base/callback.h"
-#include "cc/output/begin_frame_args.h"
#include "cc/test/ordered_simple_task_runner.h"
-#include "content/renderer/scheduler/nestable_task_runner_for_test.h"
-#include "content/renderer/scheduler/renderer_scheduler_message_loop_delegate.h"
+#include "content/child/scheduler/nestable_task_runner_for_test.h"
+#include "content/child/scheduler/scheduler_message_loop_delegate.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+using testing::_;
+using testing::Invoke;
+using testing::Return;
+
namespace content {
namespace {
-class FakeInputEvent : public blink::WebInputEvent {
- public:
- explicit FakeInputEvent(blink::WebInputEvent::Type event_type)
- : WebInputEvent(sizeof(FakeInputEvent)) {
- type = event_type;
- }
-
- FakeInputEvent(blink::WebInputEvent::Type event_type, int event_modifiers)
- : WebInputEvent(sizeof(FakeInputEvent)) {
- type = event_type;
- modifiers = event_modifiers;
- }
-};
-
void AppendToVectorTestTask(std::vector<std::string>* vector,
std::string value) {
vector->push_back(value);
@@ -40,38 +29,95 @@ void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
AppendToVectorTestTask(vector, value);
}
+void NullTask() {
+}
+
+void AppendToVectorReentrantTask(
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+ std::vector<int>* vector,
+ int* reentrant_count,
+ int max_reentrant_count) {
+ vector->push_back((*reentrant_count)++);
+ if (*reentrant_count < max_reentrant_count) {
+ task_runner->PostTask(
+ FROM_HERE, base::Bind(AppendToVectorReentrantTask, task_runner, vector,
+ reentrant_count, max_reentrant_count));
+ }
+}
+
+void IdleTestTask(int* run_count,
+ base::TimeTicks* deadline_out,
+ base::TimeTicks deadline) {
+ (*run_count)++;
+ *deadline_out = deadline;
+}
+
+int max_idle_task_reposts = 2;
+
+void RepostingIdleTestTask(
+ scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner,
+ int* run_count,
+ base::TimeTicks deadline) {
+ if ((*run_count + 1) < max_idle_task_reposts) {
+ idle_task_runner->PostIdleTask(
+ FROM_HERE,
+ base::Bind(&RepostingIdleTestTask, idle_task_runner, run_count));
+ }
+ (*run_count)++;
+}
+
}; // namespace
-class RendererSchedulerImplTest : public testing::Test {
+class SchedulerHelperForTest : public SchedulerHelper,
+ public SchedulerHelper::SchedulerHelperDelegate {
public:
- using Policy = RendererSchedulerImpl::Policy;
+ explicit SchedulerHelperForTest(
+ scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
+ : SchedulerHelper(main_task_runner,
+ this,
+ "test.scheduler",
+ TRACE_DISABLED_BY_DEFAULT("test.scheduler"),
+ TASK_QUEUE_COUNT) {}
+
+ ~SchedulerHelperForTest() override {}
+
+ using IdlePeriodState = SchedulerHelper::IdlePeriodState;
+ using SchedulerHelper::CanExceedIdleDeadlineIfRequired;
+ using SchedulerHelper::EndIdlePeriod;
+ using SchedulerHelper::StartIdlePeriod;
+ using SchedulerHelper::InitiateLongIdlePeriod;
+ using SchedulerHelper::EstimatedEndOfIdle;
+
+ // SchedulerHelperDelegate implementation:
+ MOCK_METHOD2(CanEnterLongIdlePeriod,
+ bool(base::TimeTicks now,
+ base::TimeDelta* next_long_idle_period_delay_out));
+};
- RendererSchedulerImplTest()
+class SchedulerHelperTest : public testing::Test {
+ public:
+ SchedulerHelperTest()
: clock_(cc::TestNowSource::Create(5000)),
mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)),
nestable_task_runner_(
NestableTaskRunnerForTest::Create(mock_task_runner_)),
- scheduler_(new RendererSchedulerImpl(nestable_task_runner_)),
- default_task_runner_(scheduler_->DefaultTaskRunner()),
- compositor_task_runner_(scheduler_->CompositorTaskRunner()),
- loading_task_runner_(scheduler_->LoadingTaskRunner()),
- idle_task_runner_(scheduler_->IdleTaskRunner()) {
- scheduler_->SetTimeSourceForTesting(clock_);
+ scheduler_helper_(new SchedulerHelperForTest(nestable_task_runner_)),
+ default_task_runner_(scheduler_helper_->DefaultTaskRunner()),
+ idle_task_runner_(scheduler_helper_->IdleTaskRunner()) {
+ scheduler_helper_->SetTimeSourceForTesting(clock_);
}
- RendererSchedulerImplTest(base::MessageLoop* message_loop)
+ SchedulerHelperTest(base::MessageLoop* message_loop)
: clock_(cc::TestNowSource::Create(5000)),
message_loop_(message_loop),
nestable_task_runner_(
- RendererSchedulerMessageLoopDelegate::Create(message_loop)),
- scheduler_(new RendererSchedulerImpl(nestable_task_runner_)),
- default_task_runner_(scheduler_->DefaultTaskRunner()),
- compositor_task_runner_(scheduler_->CompositorTaskRunner()),
- loading_task_runner_(scheduler_->LoadingTaskRunner()),
- idle_task_runner_(scheduler_->IdleTaskRunner()) {
- scheduler_->SetTimeSourceForTesting(clock_);
+ SchedulerMessageLoopDelegate::Create(message_loop)),
+ scheduler_helper_(new SchedulerHelperForTest(nestable_task_runner_)),
+ default_task_runner_(scheduler_helper_->DefaultTaskRunner()),
+ idle_task_runner_(scheduler_helper_->IdleTaskRunner()) {
+ scheduler_helper_->SetTimeSourceForTesting(clock_);
}
- ~RendererSchedulerImplTest() override {}
+ ~SchedulerHelperTest() override {}
void TearDown() override {
DCHECK(!mock_task_runner_.get() || !message_loop_.get());
@@ -94,33 +140,10 @@ class RendererSchedulerImplTest : public testing::Test {
message_loop_->RunUntilIdle();
}
- void DoMainFrame() {
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
- scheduler_->DidCommitFrameToCompositor();
- }
-
- void EnableIdleTasks() { DoMainFrame(); }
-
- Policy CurrentPolicy() { return scheduler_->current_policy_; }
-
- void EnsureUrgentPolicyUpdatePostedOnMainThread() {
- base::AutoLock lock(scheduler_->incoming_signals_lock_);
- scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
- }
-
- void ScheduleDelayedPolicyUpdate(base::TimeDelta delay) {
- scheduler_->delayed_update_policy_runner_.SetDeadline(FROM_HERE, delay,
- clock_->Now());
- }
-
// Helper for posting several tasks of specific types. |task_descriptor| is a
// string with space delimited task identifiers. The first letter of each
// task identifier specifies the task type:
// - 'D': Default task
- // - 'C': Compositor task
- // - 'L': Loading task
// - 'I': Idle task
void PostTestTasks(std::vector<std::string>* run_order,
const std::string& task_descriptor) {
@@ -133,14 +156,6 @@ class RendererSchedulerImplTest : public testing::Test {
default_task_runner_->PostTask(
FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
break;
- case 'C':
- compositor_task_runner_->PostTask(
- FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
- break;
- case 'L':
- loading_task_runner_->PostTask(
- FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
- break;
case 'I':
idle_task_runner_->PostIdleTask(
FROM_HERE,
@@ -153,19 +168,14 @@ class RendererSchedulerImplTest : public testing::Test {
}
protected:
- static base::TimeDelta priority_escalation_after_input_duration() {
- return base::TimeDelta::FromMilliseconds(
- RendererSchedulerImpl::kPriorityEscalationAfterInputMillis);
- }
-
static base::TimeDelta maximum_idle_period_duration() {
return base::TimeDelta::FromMilliseconds(
- RendererSchedulerImpl::kMaximumIdlePeriodMillis);
+ SchedulerHelper::kMaximumIdlePeriodMillis);
}
- base::TimeTicks CurrentIdleTaskDeadline() {
+ base::TimeTicks CurrentIdleTaskDeadlineForTesting() {
base::TimeTicks deadline;
- scheduler_->CurrentIdleTaskDeadlineCallback(&deadline);
+ scheduler_helper_->CurrentIdleTaskDeadlineCallback(&deadline);
return deadline;
}
@@ -175,92 +185,14 @@ class RendererSchedulerImplTest : public testing::Test {
scoped_ptr<base::MessageLoop> message_loop_;
scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
- scoped_ptr<RendererSchedulerImpl> scheduler_;
+ scoped_ptr<SchedulerHelperForTest> scheduler_helper_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
- scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
- DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest);
+ DISALLOW_COPY_AND_ASSIGN(SchedulerHelperTest);
};
-void NullTask() {
-}
-
-void AppendToVectorReentrantTask(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- std::vector<int>* vector,
- int* reentrant_count,
- int max_reentrant_count) {
- vector->push_back((*reentrant_count)++);
- if (*reentrant_count < max_reentrant_count) {
- task_runner->PostTask(
- FROM_HERE, base::Bind(AppendToVectorReentrantTask, task_runner, vector,
- reentrant_count, max_reentrant_count));
- }
-}
-
-void IdleTestTask(int* run_count,
- base::TimeTicks* deadline_out,
- base::TimeTicks deadline) {
- (*run_count)++;
- *deadline_out = deadline;
-}
-
-void RepostingIdleTestTask(
- scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner,
- int* run_count,
- base::TimeTicks deadline) {
- if (*run_count == 0) {
- idle_task_runner->PostIdleTask(
- FROM_HERE,
- base::Bind(&RepostingIdleTestTask, idle_task_runner, run_count));
- }
- (*run_count)++;
-}
-
-void UpdateClockToDeadlineIdleTestTask(
- scoped_refptr<cc::TestNowSource> clock,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- int* run_count,
- base::TimeTicks deadline) {
- clock->SetNow(deadline);
- // Due to the way in which OrderedSimpleTestRunner orders tasks and the fact
- // that we updated the time within a task, the delayed pending task to call
- // EndIdlePeriod will not happen until after a TaskQueueManager DoWork, so
- // post a normal task here to ensure it runs before the next idle task.
- task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
- (*run_count)++;
-}
-
-void PostingYieldingTestTask(
- RendererSchedulerImpl* scheduler,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- bool simulate_input,
- bool* should_yield_before,
- bool* should_yield_after) {
- *should_yield_before = scheduler->ShouldYieldForHighPriorityWork();
- task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
- if (simulate_input) {
- scheduler->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- }
- *should_yield_after = scheduler->ShouldYieldForHighPriorityWork();
-}
-
-void AnticipationTestTask(RendererSchedulerImpl* scheduler,
- bool simulate_input,
- bool* is_anticipated_before,
- bool* is_anticipated_after) {
- *is_anticipated_before = scheduler->IsHighPriorityWorkAnticipated();
- if (simulate_input) {
- scheduler->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- }
- *is_anticipated_after = scheduler->IsHighPriorityWorkAnticipated();
-}
-
-TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) {
+TEST_F(SchedulerHelperTest, TestPostDefaultTask) {
std::vector<std::string> run_order;
PostTestTasks(&run_order, "D1 D2 D3 D4");
@@ -270,15 +202,7 @@ TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) {
std::string("D3"), std::string("D4")));
}
-TEST_F(RendererSchedulerImplTest, TestPostDefaultAndCompositor) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "D1 C1");
- RunUntilIdle();
- EXPECT_THAT(run_order, testing::Contains("D1"));
- EXPECT_THAT(run_order, testing::Contains("C1"));
-}
-
-TEST_F(RendererSchedulerImplTest, TestRentrantTask) {
+TEST_F(SchedulerHelperTest, TestRentrantTask) {
int count = 0;
std::vector<int> run_order;
default_task_runner_->PostTask(
@@ -289,10 +213,11 @@ TEST_F(RendererSchedulerImplTest, TestRentrantTask) {
EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4));
}
-TEST_F(RendererSchedulerImplTest, TestPostIdleTask) {
+TEST_F(SchedulerHelperTest, TestPostIdleTask) {
int run_count = 0;
base::TimeTicks expected_deadline =
clock_->Now() + base::TimeDelta::FromMilliseconds(2300);
+ scheduler_helper_->SetEstimatedEndOfIdle(expected_deadline);
base::TimeTicks deadline_in_task;
clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
@@ -300,79 +225,64 @@ TEST_F(RendererSchedulerImplTest, TestPostIdleTask) {
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
RunUntilIdle();
- EXPECT_EQ(0, run_count); // Shouldn't run yet as no WillBeginFrame.
-
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
- RunUntilIdle();
- EXPECT_EQ(0, run_count); // Shouldn't run as no DidCommitFrameToCompositor.
-
- clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1200));
- scheduler_->DidCommitFrameToCompositor();
- RunUntilIdle();
- EXPECT_EQ(0, run_count); // We missed the deadline.
+ EXPECT_EQ(0, run_count);
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
- clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(800));
- scheduler_->DidCommitFrameToCompositor();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
EXPECT_EQ(1, run_count);
EXPECT_EQ(expected_deadline, deadline_in_task);
}
-TEST_F(RendererSchedulerImplTest, TestRepostingIdleTask) {
+TEST_F(SchedulerHelperTest, TestPostIdleTask_EndIdlePeriod) {
int run_count = 0;
+ base::TimeTicks deadline_in_task;
+ clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
- EnableIdleTasks();
- RunUntilIdle();
- EXPECT_EQ(1, run_count);
+ FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
- // Reposted tasks shouldn't run until next idle period.
RunUntilIdle();
- EXPECT_EQ(1, run_count);
+ EXPECT_EQ(0, run_count);
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
+ scheduler_helper_->EndIdlePeriod();
RunUntilIdle();
- EXPECT_EQ(2, run_count);
+ EXPECT_EQ(0, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) {
rmcilroy 2015/03/27 19:01:59 Please move this test here (SchedulerHelperUnittes
alex clarke (OOO till 29th) 2015/03/30 12:23:30 Done.
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
+TEST_F(SchedulerHelperTest, TestRepostingIdleTask) {
int run_count = 0;
- // Post two UpdateClockToDeadlineIdleTestTask tasks.
+ max_idle_task_reposts = 2;
idle_task_runner_->PostIdleTask(
- FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
- default_task_runner_, &run_count));
- idle_task_runner_->PostIdleTask(
- FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
- default_task_runner_, &run_count));
+ FROM_HERE,
+ base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
+ RunUntilIdle();
+ EXPECT_EQ(1, run_count);
- EnableIdleTasks();
+ // Reposted tasks shouldn't run until next idle period.
RunUntilIdle();
- // Only the first idle task should execute since it's used up the deadline.
EXPECT_EQ(1, run_count);
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
- // Second task should be run on the next idle period.
EXPECT_EQ(2, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeup) {
+TEST_F(SchedulerHelperTest, TestPostIdleTaskAfterWakeup) {
base::TimeTicks deadline_in_task;
int run_count = 0;
idle_task_runner_->PostIdleTaskAfterWakeup(
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
// Shouldn't run yet as no other task woke up the scheduler.
EXPECT_EQ(0, run_count);
@@ -380,7 +290,8 @@ TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeup) {
idle_task_runner_->PostIdleTaskAfterWakeup(
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
// Another after wakeup idle task shouldn't wake the scheduler.
EXPECT_EQ(0, run_count);
@@ -388,13 +299,15 @@ TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeup) {
default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
RunUntilIdle();
- EnableIdleTasks(); // Must start a new idle period before idle task runs.
+ // Must start a new idle period before idle task runs.
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
// Execution of default task queue task should trigger execution of idle task.
EXPECT_EQ(2, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeupWhileAwake) {
+TEST_F(SchedulerHelperTest, TestPostIdleTaskAfterWakeupWhileAwake) {
base::TimeTicks deadline_in_task;
int run_count = 0;
@@ -403,13 +316,15 @@ TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeupWhileAwake) {
default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
RunUntilIdle();
- EnableIdleTasks(); // Must start a new idle period before idle task runs.
+ // Must start a new idle period before idle task runs.
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
// Should run as the scheduler was already awakened by the normal task.
EXPECT_EQ(1, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestPostIdleTaskWakesAfterWakeupIdleTask) {
+TEST_F(SchedulerHelperTest, TestPostIdleTaskWakesAfterWakeupIdleTask) {
base::TimeTicks deadline_in_task;
int run_count = 0;
@@ -418,631 +333,22 @@ TEST_F(RendererSchedulerImplTest, TestPostIdleTaskWakesAfterWakeupIdleTask) {
idle_task_runner_->PostIdleTask(
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
// Must start a new idle period before after-wakeup idle task runs.
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
// Normal idle task should wake up after-wakeup idle task.
EXPECT_EQ(2, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
- int run_count = 0;
rmcilroy 2015/03/27 19:01:59 Could you add a test similar to this one (using st
alex clarke (OOO till 29th) 2015/03/30 12:23:30 Done. This was a bit of a pain, sadly there are o
-
- base::TimeTicks deadline_in_task;
- idle_task_runner_->PostIdleTask(
- FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
-
- // Trigger the beginning of an idle period for 1000ms.
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
- DoMainFrame();
-
- // End the idle period early (after 500ms), and send a WillBeginFrame which
- // specifies that the next idle period should end 1000ms from now.
- clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(500));
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
-
- RunUntilIdle();
- EXPECT_EQ(0, run_count); // Not currently in an idle period.
-
- // Trigger the start of the idle period before the task to end the previous
- // idle period has been triggered.
- clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(400));
- scheduler_->DidCommitFrameToCompositor();
-
- // Post a task which simulates running until after the previous end idle
- // period delayed task was scheduled for
- scheduler_->DefaultTaskRunner()->PostTask(FROM_HERE, base::Bind(NullTask));
- clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(300));
-
- RunUntilIdle();
- EXPECT_EQ(1, run_count); // We should still be in the new idle period.
-}
-
-TEST_F(RendererSchedulerImplTest, TestDefaultPolicy) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
-
- EnableIdleTasks();
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("L1"), std::string("D1"),
- std::string("C1"), std::string("D2"),
- std::string("C2"), std::string("I1")));
-}
-
-TEST_F(RendererSchedulerImplTest, TestCompositorPolicy) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- EnableIdleTasks();
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2"),
- std::string("L1"), std::string("I1")));
-}
-
-TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
-
- scheduler_->DidAnimateForInputOnCompositorThread();
- EnableIdleTasks();
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2"),
- std::string("I1")));
-}
-
-TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
-
- // Observation of touchstart should defer execution of loading tasks.
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2")));
-
- // Meta events like TapDown/FlingCancel shouldn't affect the priority.
- run_order.clear();
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingCancel));
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureTapDown));
- RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Action events like ScrollBegin will kick us back into compositor priority,
- // allowing servie of the loading and idle queues.
- run_order.clear();
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
- RunUntilIdle();
- EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1")));
-}
-
-TEST_F(RendererSchedulerImplTest,
- DidReceiveInputEventOnCompositorThread_IgnoresMouseMove_WhenMouseUp) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::MouseMove));
- EnableIdleTasks();
- RunUntilIdle();
- // Note compositor tasks are not prioritized.
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("D1"), std::string("C1"),
- std::string("D2"), std::string("C2"),
- std::string("I1")));
-}
-
-TEST_F(RendererSchedulerImplTest,
- DidReceiveInputEventOnCompositorThread_MouseMove_WhenMouseDown) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(FakeInputEvent(
- blink::WebInputEvent::MouseMove, blink::WebInputEvent::LeftButtonDown));
- EnableIdleTasks();
- RunUntilIdle();
- // Note compositor tasks are prioritized.
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2"),
- std::string("I1")));
-}
-
-TEST_F(RendererSchedulerImplTest,
- DidReceiveInputEventOnCompositorThread_MouseWheel) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::MouseWheel));
- EnableIdleTasks();
- RunUntilIdle();
- // Note compositor tasks are prioritized.
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2"),
- std::string("I1")));
-}
-
-TEST_F(RendererSchedulerImplTest,
- DidReceiveInputEventOnCompositorThread_IgnoresKeyboardEvents) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::KeyDown));
- EnableIdleTasks();
- RunUntilIdle();
- // Note compositor tasks are not prioritized.
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("D1"), std::string("C1"),
- std::string("D2"), std::string("C2"),
- std::string("I1")));
-}
-
-TEST_F(RendererSchedulerImplTest,
- TestCompositorPolicyDoesNotStarveDefaultTasks) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "D1 C1");
-
- for (int i = 0; i < 20; i++) {
- compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
- }
- PostTestTasks(&run_order, "C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- RunUntilIdle();
- // Ensure that the default D1 task gets to run at some point before the final
- // C2 compositor task.
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("D1"),
- std::string("C2")));
-}
-
-TEST_F(RendererSchedulerImplTest, TestCompositorPolicyEnds) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "D1 C1 D2 C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- DoMainFrame();
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2")));
-
- run_order.clear();
- clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1000));
- PostTestTasks(&run_order, "D1 C1 D2 C2");
-
- // Compositor policy mode should have ended now that the clock has advanced.
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("D1"), std::string("C1"),
- std::string("D2"), std::string("C2")));
-}
-
-TEST_F(RendererSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2")));
-
- run_order.clear();
- clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1000));
-
- // Don't post any compositor tasks to simulate a very long running event
- // handler.
- PostTestTasks(&run_order, "D1 D2");
-
- // Touchstart policy mode should have ended now that the clock has advanced.
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("L1"), std::string("D1"),
- std::string("D2")));
-}
-
-TEST_F(RendererSchedulerImplTest,
- TestTouchstartPolicyEndsAfterConsecutiveTouchmoves) {
- std::vector<std::string> run_order;
- PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
-
- // Observation of touchstart should defer execution of idle and loading tasks.
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
- DoMainFrame();
- RunUntilIdle();
- EXPECT_THAT(run_order,
- testing::ElementsAre(std::string("C1"), std::string("C2"),
- std::string("D1"), std::string("D2")));
-
- // Receiving the first touchmove will not affect scheduler priority.
- run_order.clear();
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchMove));
- DoMainFrame();
- RunUntilIdle();
- EXPECT_TRUE(run_order.empty());
-
- // Receiving the second touchmove will kick us back into compositor priority.
- run_order.clear();
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchMove));
- RunUntilIdle();
- EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1")));
-}
-
-TEST_F(RendererSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
- bool is_anticipated_before = false;
- bool is_anticipated_after = false;
-
- bool simulate_input = false;
- default_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
- &is_anticipated_before, &is_anticipated_after));
- RunUntilIdle();
- // In its default state, without input receipt, the scheduler should indicate
- // that no high-priority is anticipated.
- EXPECT_FALSE(is_anticipated_before);
- EXPECT_FALSE(is_anticipated_after);
-
- simulate_input = true;
- default_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
- &is_anticipated_before, &is_anticipated_after));
- RunUntilIdle();
- // When input is received, the scheduler should indicate that high-priority
- // work is anticipated.
- EXPECT_FALSE(is_anticipated_before);
- EXPECT_TRUE(is_anticipated_after);
-
- clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
- simulate_input = false;
- default_task_runner_->PostTask(
- FROM_HERE,
- base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
- &is_anticipated_before, &is_anticipated_after));
- RunUntilIdle();
- // Without additional input, the scheduler should indicate that high-priority
- // work is no longer anticipated.
- EXPECT_FALSE(is_anticipated_before);
- EXPECT_FALSE(is_anticipated_after);
-}
-
-TEST_F(RendererSchedulerImplTest, TestShouldYield) {
- bool should_yield_before = false;
- bool should_yield_after = false;
-
- default_task_runner_->PostTask(
- FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
- default_task_runner_, false, &should_yield_before,
- &should_yield_after));
- RunUntilIdle();
- // Posting to default runner shouldn't cause yielding.
- EXPECT_FALSE(should_yield_before);
- EXPECT_FALSE(should_yield_after);
-
- default_task_runner_->PostTask(
- FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
- compositor_task_runner_, false,
- &should_yield_before, &should_yield_after));
- RunUntilIdle();
- // Posting while not in compositor priority shouldn't cause yielding.
- EXPECT_FALSE(should_yield_before);
- EXPECT_FALSE(should_yield_after);
-
- default_task_runner_->PostTask(
- FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
- compositor_task_runner_, true, &should_yield_before,
- &should_yield_after));
- RunUntilIdle();
- // We should be able to switch to compositor priority mid-task.
- EXPECT_FALSE(should_yield_before);
- EXPECT_TRUE(should_yield_after);
-
- // Receiving a touchstart should immediately trigger yielding, even if
- // there's no immediately pending work in the compositor queue.
- EXPECT_FALSE(scheduler_->ShouldYieldForHighPriorityWork());
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
- EXPECT_TRUE(scheduler_->ShouldYieldForHighPriorityWork());
- RunUntilIdle();
-}
-
-TEST_F(RendererSchedulerImplTest, SlowInputEvent) {
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-
- // An input event should bump us into input priority.
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // Simulate the input event being queued for a very long time. The compositor
- // task we post here represents the enqueued input task.
- clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
- compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
- RunUntilIdle();
-
- // Even though we exceeded the input priority escalation period, we should
- // still be in compositor priority since the input remains queued.
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // Simulate the input event triggering a composition. This should start the
- // countdown for going back into normal policy.
- DoMainFrame();
- RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // After the escalation period ends we should go back into normal mode.
- clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
- RunUntilIdle();
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-}
-
-TEST_F(RendererSchedulerImplTest, SlowNoOpInputEvent) {
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-
- // An input event should bump us into input priority.
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // Simulate the input event being queued for a very long time. The compositor
- // task we post here represents the enqueued input task.
- clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
- compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
- RunUntilIdle();
-
- // Even though we exceeded the input priority escalation period, we should
- // still be in compositor priority since the input remains queued.
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // If we let the compositor queue drain, we should fall out of input
- // priority.
- clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
- RunUntilIdle();
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-}
-
-TEST_F(RendererSchedulerImplTest, NoOpInputEvent) {
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-
- // An input event should bump us into input priority.
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
- RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // If nothing else happens after this, we should drop out of compositor
- // priority after the escalation period ends and stop polling.
- clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
- RunUntilIdle();
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
- EXPECT_FALSE(mock_task_runner_->HasPendingTasks());
-}
-
-TEST_F(RendererSchedulerImplTest, NoOpInputEventExtendsEscalationPeriod) {
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-
- // Simulate one handled input event.
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
- RunUntilIdle();
- DoMainFrame();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // Send a no-op input event in the middle of the escalation period.
- clock_->AdvanceNow(priority_escalation_after_input_duration() / 2);
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate));
- RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // The escalation period should have been extended by the new input event.
- clock_->AdvanceNow(3 * priority_escalation_after_input_duration() / 4);
- RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- clock_->AdvanceNow(priority_escalation_after_input_duration() / 2);
- RunUntilIdle();
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-}
-
-TEST_F(RendererSchedulerImplTest, InputArrivesAfterBeginFrame) {
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-
- cc::BeginFrameArgs args = cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL);
- clock_->AdvanceNow(priority_escalation_after_input_duration() / 2);
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
-
- // Simulate a BeginMainFrame task from the past.
- clock_->AdvanceNow(2 * priority_escalation_after_input_duration());
- scheduler_->WillBeginFrame(args);
- scheduler_->DidCommitFrameToCompositor();
-
- // This task represents the queued-up input event.
- compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
-
- // Should remain in input priority policy since the input event hasn't been
- // processed yet.
- clock_->AdvanceNow(2 * priority_escalation_after_input_duration());
- RunUntilIdle();
- EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
-
- // Process the input event with a new BeginMainFrame.
- DoMainFrame();
- clock_->AdvanceNow(2 * priority_escalation_after_input_duration());
- RunUntilIdle();
- EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
-}
-
-class RendererSchedulerImplForTest : public RendererSchedulerImpl {
- public:
- RendererSchedulerImplForTest(
- scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
- : RendererSchedulerImpl(main_task_runner), update_policy_count_(0) {}
-
- void UpdatePolicyLocked() override {
- update_policy_count_++;
- RendererSchedulerImpl::UpdatePolicyLocked();
- }
-
- int update_policy_count_;
-};
-
-TEST_F(RendererSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdatey) {
- RendererSchedulerImplForTest* mock_scheduler =
- new RendererSchedulerImplForTest(nestable_task_runner_);
- scheduler_.reset(mock_scheduler);
-
- EnsureUrgentPolicyUpdatePostedOnMainThread();
- EnsureUrgentPolicyUpdatePostedOnMainThread();
- EnsureUrgentPolicyUpdatePostedOnMainThread();
- EnsureUrgentPolicyUpdatePostedOnMainThread();
-
- RunUntilIdle();
-
- EXPECT_EQ(1, mock_scheduler->update_policy_count_);
-}
-
-TEST_F(RendererSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) {
- RendererSchedulerImplForTest* mock_scheduler =
- new RendererSchedulerImplForTest(nestable_task_runner_);
- scheduler_.reset(mock_scheduler);
- scheduler_->SetTimeSourceForTesting(clock_);
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
- ScheduleDelayedPolicyUpdate(base::TimeDelta::FromMilliseconds(1));
- EnsureUrgentPolicyUpdatePostedOnMainThread();
-
- RunUntilIdle();
-
- // We expect both the urgent and the delayed updates to run.
- EXPECT_EQ(2, mock_scheduler->update_policy_count_);
-}
-
-TEST_F(RendererSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) {
- RendererSchedulerImplForTest* mock_scheduler =
- new RendererSchedulerImplForTest(nestable_task_runner_);
- scheduler_.reset(mock_scheduler);
- scheduler_->SetTimeSourceForTesting(clock_);
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
- EnsureUrgentPolicyUpdatePostedOnMainThread();
- ScheduleDelayedPolicyUpdate(base::TimeDelta::FromMilliseconds(1));
-
- RunUntilIdle();
-
- // We expect both the urgent and the delayed updates to run.
- EXPECT_EQ(2, mock_scheduler->update_policy_count_);
-}
-
-TEST_F(RendererSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) {
- RendererSchedulerImplForTest* mock_scheduler =
- new RendererSchedulerImplForTest(nestable_task_runner_);
- scheduler_.reset(mock_scheduler);
- scheduler_->SetTimeSourceForTesting(clock_);
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
-
- RunUntilIdle();
-
- // We expect an urgent policy update followed by a delayed one 100ms later.
- EXPECT_EQ(2, mock_scheduler->update_policy_count_);
-}
-
-TEST_F(RendererSchedulerImplTest, UpdatePolicyCountTriggeredByTwoInputEvents) {
- RendererSchedulerImplForTest* mock_scheduler =
- new RendererSchedulerImplForTest(nestable_task_runner_);
- scheduler_.reset(mock_scheduler);
- scheduler_->SetTimeSourceForTesting(clock_);
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchMove));
-
- RunUntilIdle();
-
- // We expect an urgent policy update followed by a delayed one 100ms later.
- EXPECT_EQ(2, mock_scheduler->update_policy_count_);
-}
-
-TEST_F(RendererSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) {
- RendererSchedulerImplForTest* mock_scheduler =
- new RendererSchedulerImplForTest(nestable_task_runner_);
- scheduler_.reset(mock_scheduler);
- scheduler_->SetTimeSourceForTesting(clock_);
- mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchMove));
-
- // We expect the first call to IsHighPriorityWorkAnticipated to be called
- // after recieving an input event (but before the UpdateTask was processed) to
- // call UpdatePolicy.
- EXPECT_EQ(0, mock_scheduler->update_policy_count_);
- scheduler_->IsHighPriorityWorkAnticipated();
- EXPECT_EQ(1, mock_scheduler->update_policy_count_);
- // Subsequent calls should not call UpdatePolicy.
- scheduler_->IsHighPriorityWorkAnticipated();
- scheduler_->IsHighPriorityWorkAnticipated();
- scheduler_->IsHighPriorityWorkAnticipated();
- scheduler_->ShouldYieldForHighPriorityWork();
- scheduler_->ShouldYieldForHighPriorityWork();
- scheduler_->ShouldYieldForHighPriorityWork();
- scheduler_->ShouldYieldForHighPriorityWork();
-
- EXPECT_EQ(1, mock_scheduler->update_policy_count_);
-
- RunUntilIdle();
- // We expect both the urgent and the delayed updates to run in addition to the
- // earlier updated cause by IsHighPriorityWorkAnticipated.
- EXPECT_EQ(3, mock_scheduler->update_policy_count_);
-}
-
-class RendererSchedulerImplWithMessageLoopTest
- : public RendererSchedulerImplTest {
+class SchedulerHelperWithMessageLoopTest : public SchedulerHelperTest {
public:
- RendererSchedulerImplWithMessageLoopTest()
- : RendererSchedulerImplTest(new base::MessageLoop()) {}
- ~RendererSchedulerImplWithMessageLoopTest() override {}
+ SchedulerHelperWithMessageLoopTest()
+ : SchedulerHelperTest(new base::MessageLoop()) {}
+ ~SchedulerHelperWithMessageLoopTest() override {}
void PostFromNestedRunloop(std::vector<
std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) {
@@ -1054,15 +360,16 @@ class RendererSchedulerImplWithMessageLoopTest
idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first);
}
}
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
message_loop_->RunUntilIdle();
}
private:
- DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplWithMessageLoopTest);
+ DISALLOW_COPY_AND_ASSIGN(SchedulerHelperWithMessageLoopTest);
};
-TEST_F(RendererSchedulerImplWithMessageLoopTest,
+TEST_F(SchedulerHelperWithMessageLoopTest,
NonNestableIdleTaskDoesntExecuteInNestedLoop) {
std::vector<std::string> order;
idle_task_runner_->PostIdleTask(
@@ -1084,12 +391,12 @@ TEST_F(RendererSchedulerImplWithMessageLoopTest,
default_task_runner_->PostTask(
FROM_HERE,
- base::Bind(
- &RendererSchedulerImplWithMessageLoopTest::PostFromNestedRunloop,
- base::Unretained(this),
- base::Unretained(&tasks_to_post_from_nested_loop)));
+ base::Bind(&SchedulerHelperWithMessageLoopTest::PostFromNestedRunloop,
+ base::Unretained(this),
+ base::Unretained(&tasks_to_post_from_nested_loop)));
- EnableIdleTasks();
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
// Note we expect task 3 to run last because it's non-nestable.
EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"),
@@ -1097,7 +404,7 @@ TEST_F(RendererSchedulerImplWithMessageLoopTest,
std::string("3")));
}
-TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) {
+TEST_F(SchedulerHelperTest, TestLongIdlePeriod) {
base::TimeTicks expected_deadline =
clock_->Now() + maximum_idle_period_duration();
base::TimeTicks deadline_in_task;
@@ -1106,50 +413,60 @@ TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) {
idle_task_runner_->PostIdleTask(
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
+ EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(2)
+ .WillRepeatedly(Return(true));
+
RunUntilIdle();
EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period.
- scheduler_->BeginFrameNotExpectedSoon();
+ scheduler_helper_->InitiateLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(1, run_count); // Should have run in a long idle time.
EXPECT_EQ(expected_deadline, deadline_in_task);
}
-TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
+TEST_F(SchedulerHelperTest, TestLongIdlePeriodWithPendingDelayedTask) {
base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
base::TimeTicks expected_deadline = clock_->Now() + pending_task_delay;
base::TimeTicks deadline_in_task;
int run_count = 0;
+ EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(2)
+ .WillRepeatedly(Return(true));
+
idle_task_runner_->PostIdleTask(
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
- default_task_runner_->PostDelayedTask(
- FROM_HERE, base::Bind(&NullTask), pending_task_delay);
+ default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
+ pending_task_delay);
- scheduler_->BeginFrameNotExpectedSoon();
+ scheduler_helper_->InitiateLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(1, run_count); // Should have run in a long idle time.
EXPECT_EQ(expected_deadline, deadline_in_task);
}
-TEST_F(RendererSchedulerImplTest,
- TestLongIdlePeriodWithLatePendingDelayedTask) {
+TEST_F(SchedulerHelperTest, TestLongIdlePeriodWithLatePendingDelayedTask) {
base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10);
base::TimeTicks deadline_in_task;
int run_count = 0;
- default_task_runner_->PostDelayedTask(
- FROM_HERE, base::Bind(&NullTask), pending_task_delay);
+ EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(3)
+ .WillRepeatedly(Return(true));
+
+ default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
+ pending_task_delay);
// Advance clock until after delayed task was meant to be run.
clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20));
- // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle
- // period. Since there is a late pending delayed task this shouldn't actually
- // start an idle period.
+ // Post an idle task and then InitiateLongIdlePeriod. Since there is a late
+ // pending delayed task this shouldn't actually start an idle period.
idle_task_runner_->PostIdleTask(
FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
- scheduler_->BeginFrameNotExpectedSoon();
+ scheduler_helper_->InitiateLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(0, run_count);
@@ -1159,14 +476,19 @@ TEST_F(RendererSchedulerImplTest,
EXPECT_EQ(1, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) {
+TEST_F(SchedulerHelperTest, TestLongIdlePeriodRepeating) {
int run_count = 0;
+ EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(4)
+ .WillRepeatedly(Return(true));
+
+ max_idle_task_reposts = 3;
idle_task_runner_->PostIdleTask(
FROM_HERE,
base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
- scheduler_->BeginFrameNotExpectedSoon();
+ scheduler_helper_->InitiateLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(1, run_count); // Should only run once per idle period.
@@ -1176,75 +498,92 @@ TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) {
RunUntilIdle();
EXPECT_EQ(2, run_count);
- // Advance time to start of next long idle period then end idle period with a
- // new BeginMainFrame and check idle task doesn't run.
+ // Advance time to start of next long idle period and check task reposted task
+ // gets run.
clock_->AdvanceNow(maximum_idle_period_duration());
rmcilroy 2015/03/27 19:01:59 Please make this do the same as the previous test
alex clarke (OOO till 29th) 2015/03/30 12:23:30 Done.
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
RunUntilIdle();
- EXPECT_EQ(2, run_count);
+ EXPECT_EQ(3, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) {
+TEST_F(SchedulerHelperTest, TestLongIdlePeriodDoesNotWakeScheduler) {
base::TimeTicks deadline_in_task;
int run_count = 0;
+ EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(3)
+ .WillRepeatedly(Return(true));
+
// Start a long idle period and get the time it should end.
- scheduler_->BeginFrameNotExpectedSoon();
+ scheduler_helper_->InitiateLongIdlePeriod();
// The scheduler should not run the initiate_next_long_idle_period task if
// there are no idle tasks and no other task woke up the scheduler, thus
// the idle period deadline shouldn't update at the end of the current long
// idle period.
- base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadline();
+ base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
clock_->AdvanceNow(maximum_idle_period_duration());
RunUntilIdle();
- base::TimeTicks new_idle_period_deadline = CurrentIdleTaskDeadline();
+ base::TimeTicks new_idle_period_deadline =
+ CurrentIdleTaskDeadlineForTesting();
EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
// Posting a after-wakeup idle task also shouldn't wake the scheduler or
// initiate the next long idle period.
idle_task_runner_->PostIdleTaskAfterWakeup(
- FROM_HERE,
- base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
+ FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
RunUntilIdle();
- new_idle_period_deadline = CurrentIdleTaskDeadline();
+ new_idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
EXPECT_EQ(0, run_count);
// Running a normal task should initiate a new long idle period though.
default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
RunUntilIdle();
- new_idle_period_deadline = CurrentIdleTaskDeadline();
+ new_idle_period_deadline = CurrentIdleTaskDeadlineForTesting();
EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(),
new_idle_period_deadline);
EXPECT_EQ(1, run_count);
}
-TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) {
+TEST_F(SchedulerHelperTest, TestLongIdlePeriodCantEnterLongIdlePeriod) {
rmcilroy 2015/03/27 19:01:59 nit - TestLongIdlePeriodWhenNotCanEnterLongIdlePer
alex clarke (OOO till 29th) 2015/03/30 12:23:30 Done.
+ base::TimeDelta delay = base::TimeDelta::FromMilliseconds(1000);
+ base::TimeDelta halfDelay = base::TimeDelta::FromMilliseconds(500);
+ base::TimeTicks delayOver = clock_->Now() + delay;
base::TimeTicks deadline_in_task;
int run_count = 0;
+ ON_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
+ .WillByDefault(Invoke([&delay, &delayOver](
+ base::TimeTicks now,
+ base::TimeDelta* next_long_idle_period_delay_out) {
+ if (now >= delayOver)
+ return true;
+ *next_long_idle_period_delay_out = delay;
+ return false;
+ }));
+
+ EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)).Times(3);
+
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
+ FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
- // Observation of touchstart should defer the start of the long idle period.
- scheduler_->DidReceiveInputEventOnCompositorThread(
- FakeInputEvent(blink::WebInputEvent::TouchStart));
- scheduler_->BeginFrameNotExpectedSoon();
+ // Make sure Idle tasks don't run until the delay has occured.
+ scheduler_helper_->InitiateLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(0, run_count);
- // The long idle period should start after the touchstart policy has finished.
- clock_->AdvanceNow(priority_escalation_after_input_duration());
+ clock_->AdvanceNow(halfDelay);
+ RunUntilIdle();
+ EXPECT_EQ(0, run_count);
+
+ // Delay is finished, idle task should run.
+ clock_->AdvanceNow(halfDelay);
RunUntilIdle();
EXPECT_EQ(1, run_count);
}
-void TestCanExceedIdleDeadlineIfRequiredTask(RendererScheduler* scheduler,
+void TestCanExceedIdleDeadlineIfRequiredTask(SchedulerHelperForTest* scheduler,
bool* can_exceed_idle_deadline_out,
int* run_count,
base::TimeTicks deadline) {
@@ -1252,19 +591,24 @@ void TestCanExceedIdleDeadlineIfRequiredTask(RendererScheduler* scheduler,
(*run_count)++;
}
-TEST_F(RendererSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
+TEST_F(SchedulerHelperTest, CanExceedIdleDeadlineIfRequired) {
int run_count = 0;
bool can_exceed_idle_deadline = false;
+ EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _))
+ .Times(3)
+ .WillRepeatedly(Return(true));
+
// Should return false if not in an idle period.
- EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
+ EXPECT_FALSE(scheduler_helper_->CanExceedIdleDeadlineIfRequired());
// Should return false for short idle periods.
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
- &can_exceed_idle_deadline, &run_count));
- EnableIdleTasks();
+ FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask,
+ scheduler_helper_.get(), &can_exceed_idle_deadline,
+ &run_count));
+ scheduler_helper_->StartIdlePeriod(
+ SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD);
RunUntilIdle();
EXPECT_EQ(1, run_count);
EXPECT_FALSE(can_exceed_idle_deadline);
@@ -1274,10 +618,10 @@ TEST_F(RendererSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
base::TimeDelta::FromMilliseconds(10));
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
- &can_exceed_idle_deadline, &run_count));
- scheduler_->BeginFrameNotExpectedSoon();
+ FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask,
+ scheduler_helper_.get(), &can_exceed_idle_deadline,
+ &run_count));
+ scheduler_helper_->InitiateLongIdlePeriod();
RunUntilIdle();
EXPECT_EQ(2, run_count);
EXPECT_FALSE(can_exceed_idle_deadline);
@@ -1286,19 +630,19 @@ TEST_F(RendererSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
// CanExceedIdleDeadlineIfRequired should return true.
clock_->AdvanceNow(maximum_idle_period_duration());
idle_task_runner_->PostIdleTask(
- FROM_HERE,
- base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
- &can_exceed_idle_deadline, &run_count));
+ FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask,
+ scheduler_helper_.get(), &can_exceed_idle_deadline,
+ &run_count));
RunUntilIdle();
EXPECT_EQ(3, run_count);
EXPECT_TRUE(can_exceed_idle_deadline);
+}
- // Next long idle period will be for the maximum time, so
- // CanExceedIdleDeadlineIfRequired should return true.
- scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
- base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
- EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
+TEST_F(SchedulerHelperTest, IsShutdown) {
+ EXPECT_FALSE(scheduler_helper_->IsShutdown());
+
+ scheduler_helper_->Shutdown();
+ EXPECT_TRUE(scheduler_helper_->IsShutdown());
}
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698