Commit f42de30a authored by Greg Kraynov's avatar Greg Kraynov Committed by Commit Bot

Refactor WorkerThreadScheduler unit tests.

Bug: 841735
Change-Id: I86007d80dd719cd00c4b224d9f88479daa1bb422
Reviewed-on: https://chromium-review.googlesource.com/1101019Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Commit-Queue: Greg Kraynov <kraynov@chromium.org>
Cr-Commit-Position: refs/heads/master@{#567263}
parent c111e749
......@@ -8,8 +8,7 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_tick_clock.h"
#include "components/viz/test/ordered_simple_task_runner.h"
#include "base/test/scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h"
......@@ -28,7 +27,7 @@ int TimeTicksToIntMs(const base::TimeTicks& time) {
}
void RecordTimelineTask(std::vector<std::string>* timeline,
base::SimpleTestTickClock* clock) {
const base::TickClock* clock) {
timeline->push_back(base::StringPrintf("run RecordTimelineTask @ %d",
TimeTicksToIntMs(clock->NowTicks())));
}
......@@ -54,16 +53,13 @@ class WorkerThreadSchedulerForTest : public WorkerThreadScheduler {
public:
WorkerThreadSchedulerForTest(
std::unique_ptr<base::sequence_manager::TaskQueueManager> manager,
base::SimpleTestTickClock* clock_)
const base::TickClock* clock_,
std::vector<std::string>* timeline)
: WorkerThreadScheduler(WebThreadType::kTestThread,
std::move(manager),
nullptr),
clock_(clock_),
timeline_(nullptr) {}
void RecordTimelineEvents(std::vector<std::string>* timeline) {
timeline_ = timeline;
}
timeline_(timeline) {}
private:
bool CanEnterLongIdlePeriod(
......@@ -85,54 +81,45 @@ class WorkerThreadSchedulerForTest : public WorkerThreadScheduler {
WorkerThreadScheduler::IsNotQuiescent();
}
base::SimpleTestTickClock* clock_; // NOT OWNED
std::vector<std::string>* timeline_; // NOT OWNED
const base::TickClock* clock_; // Not owned.
std::vector<std::string>* timeline_; // Not owned.
};
class WorkerThreadSchedulerTest : public testing::Test {
public:
WorkerThreadSchedulerTest()
: mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)),
: task_environment_(
base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED),
scheduler_(new WorkerThreadSchedulerForTest(
base::sequence_manager::TaskQueueManagerForTest::Create(
nullptr,
mock_task_runner_,
&clock_),
&clock_)),
timeline_(nullptr) {
clock_.Advance(base::TimeDelta::FromMicroseconds(5000));
}
~WorkerThreadSchedulerTest() override = default;
void TearDown() override {
// Check that all tests stop posting tasks.
while (mock_task_runner_->RunUntilIdle()) {
}
}
void Init() {
task_environment_.GetMainThreadTaskRunner(),
task_environment_.GetMockTickClock()),
task_environment_.GetMockTickClock(),
&timeline_)) {
// Null clock might trigger some assertions.
task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5));
scheduler_->Init();
default_task_runner_ = scheduler_->CreateTaskRunner();
idle_task_runner_ = scheduler_->IdleTaskRunner();
timeline_ = nullptr;
}
void RecordTimelineEvents(std::vector<std::string>* timeline) {
timeline_ = timeline;
scheduler_->RecordTimelineEvents(timeline);
~WorkerThreadSchedulerTest() override = default;
void TearDown() override {
task_environment_.FastForwardUntilNoTasksRemain();
}
void RunUntilIdle() {
if (timeline_) {
timeline_->push_back(base::StringPrintf(
"RunUntilIdle begin @ %d", TimeTicksToIntMs(clock_.NowTicks())));
}
mock_task_runner_->RunUntilIdle();
if (timeline_) {
timeline_->push_back(base::StringPrintf(
"RunUntilIdle end @ %d", TimeTicksToIntMs(clock_.NowTicks())));
}
timeline_.push_back(base::StringPrintf(
"RunUntilIdle begin @ %d",
TimeTicksToIntMs(task_environment_.GetMockTickClock()->NowTicks())));
// RunUntilIdle with auto-advancing for the mock clock.
task_environment_.FastForwardUntilNoTasksRemain();
timeline_.push_back(base::StringPrintf(
"RunUntilIdle end @ %d",
TimeTicksToIntMs(task_environment_.GetMockTickClock()->NowTicks())));
}
// Helper for posting several tasks of specific types. |task_descriptor| is a
......@@ -169,21 +156,16 @@ class WorkerThreadSchedulerTest : public testing::Test {
}
protected:
base::SimpleTestTickClock clock_;
// Only one of mock_task_runner_ or message_loop_ will be set.
scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
base::test::ScopedTaskEnvironment task_environment_;
std::vector<std::string> timeline_;
std::unique_ptr<WorkerThreadSchedulerForTest> scheduler_;
scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
std::vector<std::string>* timeline_; // NOT OWNED
DISALLOW_COPY_AND_ASSIGN(WorkerThreadSchedulerTest);
};
TEST_F(WorkerThreadSchedulerTest, TestPostDefaultTask) {
Init();
std::vector<std::string> run_order;
PostTestTasks(&run_order, "D1 D2 D3 D4");
......@@ -194,8 +176,6 @@ TEST_F(WorkerThreadSchedulerTest, TestPostDefaultTask) {
}
TEST_F(WorkerThreadSchedulerTest, TestPostIdleTask) {
Init();
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1");
......@@ -204,8 +184,6 @@ TEST_F(WorkerThreadSchedulerTest, TestPostIdleTask) {
}
TEST_F(WorkerThreadSchedulerTest, TestPostDefaultAndIdleTasks) {
Init();
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D2 D3 D4");
......@@ -216,8 +194,6 @@ TEST_F(WorkerThreadSchedulerTest, TestPostDefaultAndIdleTasks) {
}
TEST_F(WorkerThreadSchedulerTest, TestPostDefaultDelayedAndIdleTasks) {
Init();
std::vector<std::string> run_order;
PostTestTasks(&run_order, "I1 D2 D3 D4");
......@@ -233,91 +209,86 @@ TEST_F(WorkerThreadSchedulerTest, TestPostDefaultDelayedAndIdleTasks) {
}
TEST_F(WorkerThreadSchedulerTest, TestIdleTaskWhenIsNotQuiescent) {
std::vector<std::string> timeline;
RecordTimelineEvents(&timeline);
Init();
timeline.push_back("Post default task");
timeline_.push_back("Post default task");
// Post a delayed task timed to occur mid way during the long idle period.
default_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline),
base::Unretained(&clock_)));
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline_),
base::Unretained(task_environment_.GetMockTickClock())));
RunUntilIdle();
timeline.push_back("Post idle task");
timeline_.push_back("Post idle task");
idle_task_runner_->PostIdleTask(
FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline));
FROM_HERE,
base::BindOnce(&TimelineIdleTestTask, base::Unretained(&timeline_)));
RunUntilIdle();
std::string expected_timeline[] = {"CanEnterLongIdlePeriod @ 5",
"Post default task",
"run RecordTimelineTask @ 5",
"Post idle task",
"IsNotQuiescent @ 5",
"CanEnterLongIdlePeriod @ 305",
"run TimelineIdleTestTask deadline 355"};
EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
std::string expected_timeline[] = {
"CanEnterLongIdlePeriod @ 5", "Post default task",
"RunUntilIdle begin @ 5", "run RecordTimelineTask @ 5",
"RunUntilIdle end @ 5", "Post idle task",
"RunUntilIdle begin @ 5", "IsNotQuiescent @ 5",
"CanEnterLongIdlePeriod @ 305", "run TimelineIdleTestTask deadline 355",
"RunUntilIdle end @ 305"};
EXPECT_THAT(timeline_, ElementsAreArray(expected_timeline));
}
TEST_F(WorkerThreadSchedulerTest, TestIdleDeadlineWithPendingDelayedTask) {
std::vector<std::string> timeline;
RecordTimelineEvents(&timeline);
Init();
timeline.push_back("Post delayed and idle tasks");
timeline_.push_back("Post delayed and idle tasks");
// Post a delayed task timed to occur mid way during the long idle period.
default_task_runner_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline),
base::Unretained(&clock_)),
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline_),
base::Unretained(task_environment_.GetMockTickClock())),
base::TimeDelta::FromMilliseconds(20));
idle_task_runner_->PostIdleTask(
FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline));
FROM_HERE,
base::BindOnce(&TimelineIdleTestTask, base::Unretained(&timeline_)));
RunUntilIdle();
std::string expected_timeline[] = {
"CanEnterLongIdlePeriod @ 5", "Post delayed and idle tasks",
"CanEnterLongIdlePeriod @ 5",
"Post delayed and idle tasks",
"RunUntilIdle begin @ 5",
"CanEnterLongIdlePeriod @ 5",
"run TimelineIdleTestTask deadline 25", // Note the short 20ms deadline.
"run RecordTimelineTask @ 25"};
"run RecordTimelineTask @ 25",
"RunUntilIdle end @ 25"};
EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
EXPECT_THAT(timeline_, ElementsAreArray(expected_timeline));
}
TEST_F(WorkerThreadSchedulerTest,
TestIdleDeadlineWithPendingDelayedTaskFarInTheFuture) {
std::vector<std::string> timeline;
RecordTimelineEvents(&timeline);
Init();
timeline.push_back("Post delayed and idle tasks");
timeline_.push_back("Post delayed and idle tasks");
// Post a delayed task timed to occur well after the long idle period.
default_task_runner_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline),
base::Unretained(&clock_)),
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline_),
base::Unretained(task_environment_.GetMockTickClock())),
base::TimeDelta::FromMilliseconds(500));
idle_task_runner_->PostIdleTask(
FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline));
FROM_HERE,
base::BindOnce(&TimelineIdleTestTask, base::Unretained(&timeline_)));
RunUntilIdle();
std::string expected_timeline[] = {
"CanEnterLongIdlePeriod @ 5", "Post delayed and idle tasks",
"CanEnterLongIdlePeriod @ 5",
"Post delayed and idle tasks",
"RunUntilIdle begin @ 5",
"CanEnterLongIdlePeriod @ 5",
"run TimelineIdleTestTask deadline 55", // Note the full 50ms deadline.
"run RecordTimelineTask @ 505"};
"run RecordTimelineTask @ 505",
"RunUntilIdle end @ 505"};
EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
EXPECT_THAT(timeline_, ElementsAreArray(expected_timeline));
}
TEST_F(WorkerThreadSchedulerTest, TestPostIdleTaskAfterRunningUntilIdle) {
Init();
default_task_runner_->PostDelayedTask(
FROM_HERE, base::BindOnce(&NopTask),
base::TimeDelta::FromMilliseconds(1000));
......@@ -333,7 +304,7 @@ TEST_F(WorkerThreadSchedulerTest, TestPostIdleTaskAfterRunningUntilIdle) {
}
void PostIdleTask(std::vector<std::string>* timeline,
base::SimpleTestTickClock* clock,
const base::TickClock* clock,
SingleThreadIdleTaskRunner* idle_task_runner) {
timeline->push_back(base::StringPrintf("run PostIdleTask @ %d",
TimeTicksToIntMs(clock->NowTicks())));
......@@ -343,19 +314,14 @@ void PostIdleTask(std::vector<std::string>* timeline,
}
TEST_F(WorkerThreadSchedulerTest, TestLongIdlePeriodTimeline) {
Init();
std::vector<std::string> timeline;
RecordTimelineEvents(&timeline);
// 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 =
scheduler_->CurrentIdleTaskDeadlineForTesting();
clock_.Advance(maximum_idle_period_duration());
RunUntilIdle();
// Not printed in the timeline.
task_environment_.FastForwardBy(maximum_idle_period_duration());
base::TimeTicks new_idle_period_deadline =
scheduler_->CurrentIdleTaskDeadlineForTesting();
......@@ -366,27 +332,27 @@ TEST_F(WorkerThreadSchedulerTest, TestLongIdlePeriodTimeline) {
// the idle task run.
default_task_runner_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&PostIdleTask, base::Unretained(&timeline),
base::Unretained(&clock_),
base::BindOnce(&PostIdleTask, base::Unretained(&timeline_),
base::Unretained(task_environment_.GetMockTickClock()),
base::Unretained(idle_task_runner_.get())),
base::TimeDelta::FromMilliseconds(30));
timeline.push_back("PostFirstIdleTask");
timeline_.push_back("PostFirstIdleTask");
idle_task_runner_->PostIdleTask(
FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline));
FROM_HERE,
base::BindOnce(&TimelineIdleTestTask, base::Unretained(&timeline_)));
RunUntilIdle();
new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
// Running a normal task will mark the system as non-quiescent.
timeline.push_back("Post RecordTimelineTask");
timeline_.push_back("Post RecordTimelineTask");
default_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline),
base::Unretained(&clock_)));
base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline_),
base::Unretained(task_environment_.GetMockTickClock())));
RunUntilIdle();
std::string expected_timeline[] = {"RunUntilIdle begin @ 55",
"RunUntilIdle end @ 55",
std::string expected_timeline[] = {"CanEnterLongIdlePeriod @ 5",
"PostFirstIdleTask",
"RunUntilIdle begin @ 55",
"CanEnterLongIdlePeriod @ 55",
......@@ -401,7 +367,7 @@ TEST_F(WorkerThreadSchedulerTest, TestLongIdlePeriodTimeline) {
"run RecordTimelineTask @ 385",
"RunUntilIdle end @ 385"};
EXPECT_THAT(timeline, ElementsAreArray(expected_timeline));
EXPECT_THAT(timeline_, ElementsAreArray(expected_timeline));
}
} // namespace worker_thread_scheduler_unittest
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment