blob: 169839124d9e29f7ea60ab4f356020ebcb5fb0f0 [file] [log] [blame]
// Copyright 2015 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 "base/test/test_mock_time_task_runner.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
namespace base {
namespace {
// TickClock that always returns the then-current mock time of |task_runner| as
// the current time.
class MockTickClock : public TickClock {
public:
explicit MockTickClock(
scoped_refptr<const TestMockTimeTaskRunner> task_runner);
~MockTickClock() override;
// TickClock:
TimeTicks NowTicks() override;
private:
scoped_refptr<const TestMockTimeTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(MockTickClock);
};
MockTickClock::MockTickClock(
scoped_refptr<const TestMockTimeTaskRunner> task_runner)
: task_runner_(task_runner) {
}
MockTickClock::~MockTickClock() {
}
TimeTicks MockTickClock::NowTicks() {
return task_runner_->GetCurrentMockTime();
}
} // namespace
bool TestMockTimeTaskRunner::TemporalOrder::operator()(
const TestPendingTask& first_task,
const TestPendingTask& second_task) const {
return first_task.GetTimeToRun() > second_task.GetTimeToRun();
}
TestMockTimeTaskRunner::TestMockTimeTaskRunner() {
}
TestMockTimeTaskRunner::~TestMockTimeTaskRunner() {
}
void TestMockTimeTaskRunner::FastForwardBy(TimeDelta delta) {
DCHECK(thread_checker_.CalledOnValidThread());
OnBeforeSelectingTask();
const base::TimeTicks original_now = now_;
TestPendingTask task_info;
while (DequeueNextTask(original_now, delta, &task_info)) {
if (task_info.GetTimeToRun() - now_ > base::TimeDelta()) {
now_ = task_info.GetTimeToRun();
OnAfterTimePassed();
}
task_info.task.Run();
OnAfterTaskRun();
OnBeforeSelectingTask();
}
if (!delta.is_max() && now_ - original_now < delta) {
now_ = original_now + delta;
OnAfterTimePassed();
}
}
void TestMockTimeTaskRunner::RunUntilIdle() {
FastForwardBy(TimeDelta());
}
void TestMockTimeTaskRunner::FastForwardUntilNoTasksRemain() {
FastForwardBy(TimeDelta::Max());
}
TimeTicks TestMockTimeTaskRunner::GetCurrentMockTime() const {
DCHECK(thread_checker_.CalledOnValidThread());
return now_;
}
scoped_ptr<TickClock> TestMockTimeTaskRunner::GetMockTickClock() const {
DCHECK(thread_checker_.CalledOnValidThread());
return make_scoped_ptr(new MockTickClock(this));
}
bool TestMockTimeTaskRunner::HasPendingTask() const {
DCHECK(thread_checker_.CalledOnValidThread());
return !tasks_.empty();
}
TimeDelta TestMockTimeTaskRunner::NextPendingTaskDelay() const {
DCHECK(thread_checker_.CalledOnValidThread());
return tasks_.empty() ? TimeDelta::Max() : tasks_.top().GetTimeToRun() - now_;
}
bool TestMockTimeTaskRunner::RunsTasksOnCurrentThread() const {
return thread_checker_.CalledOnValidThread();
}
bool TestMockTimeTaskRunner::PostDelayedTask(
const tracked_objects::Location& from_here,
const Closure& task,
TimeDelta delay) {
base::AutoLock scoped_lock(tasks_lock_);
tasks_.push(
TestPendingTask(from_here, task, now_, delay, TestPendingTask::NESTABLE));
return true;
}
bool TestMockTimeTaskRunner::PostNonNestableDelayedTask(
const tracked_objects::Location& from_here,
const Closure& task,
TimeDelta delay) {
NOTREACHED();
return false;
}
void TestMockTimeTaskRunner::OnBeforeSelectingTask() {
// Empty default implementation.
}
void TestMockTimeTaskRunner::OnAfterTimePassed() {
// Empty default implementation.
}
void TestMockTimeTaskRunner::OnAfterTaskRun() {
// Empty default implementation.
}
bool TestMockTimeTaskRunner::DequeueNextTask(const base::TimeTicks& reference,
const base::TimeDelta& max_delta,
TestPendingTask* next_task) {
base::AutoLock scoped_lock(tasks_lock_);
if (!tasks_.empty() &&
(tasks_.top().GetTimeToRun() - reference) <= max_delta) {
*next_task = tasks_.top();
tasks_.pop();
return true;
}
return false;
}
} // namespace base