blob: 7f0f68e70cccc94d531ee8c3c1fd0816fa4d8990 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h"
#include "base/bind.h"
#include "base/task/sequence_manager/test/sequence_manager_for_test.h"
#include "base/test/test_mock_time_task_runner.h"
#include "third_party/blink/public/platform/scheduler/child/webthread_base.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/waitable_event.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
TestingPlatformSupportWithMockScheduler::
TestingPlatformSupportWithMockScheduler()
: test_task_runner_(base::MakeRefCounted<base::TestMockTimeTaskRunner>(
base::TestMockTimeTaskRunner::Type::kStandalone)) {
DCHECK(IsMainThread());
test_task_runner_->AdvanceMockTickClock(base::TimeDelta::FromSeconds(1));
std::unique_ptr<base::sequence_manager::SequenceManagerForTest>
sequence_manager = base::sequence_manager::SequenceManagerForTest::Create(
nullptr, test_task_runner_, test_task_runner_->GetMockTickClock());
sequence_manager_ = sequence_manager.get();
scheduler_ = std::make_unique<scheduler::MainThreadSchedulerImpl>(
std::move(sequence_manager), base::nullopt);
main_thread_overrider_ = std::make_unique<ScopedMainThreadOverrider>(
scheduler_->CreateMainThread());
// Set the work batch size to one so TakePendingTasks behaves as expected.
scheduler_->GetSchedulerHelperForTesting()->SetWorkBatchSizeForTesting(1);
WTF::SetTimeFunctionsForTesting(GetTestTime);
}
TestingPlatformSupportWithMockScheduler::
~TestingPlatformSupportWithMockScheduler() {
WTF::SetTimeFunctionsForTesting(nullptr);
scheduler_->Shutdown();
}
void TestingPlatformSupportWithMockScheduler::RunSingleTask() {
base::circular_deque<base::TestPendingTask> tasks =
test_task_runner_->TakePendingTasks();
if (tasks.empty())
return;
// Scheduler doesn't post more than one task.
DCHECK_EQ(tasks.size(), 1u);
base::TestPendingTask task = std::move(tasks.front());
tasks.clear();
// Set clock to the beginning of task and run it.
test_task_runner_->AdvanceMockTickClock(task.GetTimeToRun() -
test_task_runner_->NowTicks());
std::move(task.task).Run();
}
void TestingPlatformSupportWithMockScheduler::RunUntilIdle() {
if (auto_advance_) {
test_task_runner_->FastForwardUntilNoTasksRemain();
} else {
test_task_runner_->RunUntilIdle();
}
}
void TestingPlatformSupportWithMockScheduler::RunForPeriodSeconds(
double seconds) {
RunForPeriod(base::TimeDelta::FromSecondsD(seconds));
}
void TestingPlatformSupportWithMockScheduler::RunForPeriod(
base::TimeDelta period) {
test_task_runner_->FastForwardBy(period);
}
void TestingPlatformSupportWithMockScheduler::AdvanceClockSeconds(
double seconds) {
AdvanceClock(base::TimeDelta::FromSecondsD(seconds));
}
void TestingPlatformSupportWithMockScheduler::AdvanceClock(
base::TimeDelta duration) {
test_task_runner_->AdvanceMockTickClock(duration);
}
void TestingPlatformSupportWithMockScheduler::SetAutoAdvanceNowToPendingTasks(
bool auto_advance) {
auto_advance_ = auto_advance;
}
scheduler::MainThreadSchedulerImpl*
TestingPlatformSupportWithMockScheduler::GetMainThreadScheduler() const {
return scheduler_.get();
}
// static
double TestingPlatformSupportWithMockScheduler::GetTestTime() {
TestingPlatformSupportWithMockScheduler* platform =
static_cast<TestingPlatformSupportWithMockScheduler*>(
Platform::Current());
return (platform->test_task_runner_->NowTicks() - base::TimeTicks())
.InSecondsF();
}
} // namespace blink