chromium/base/test/test_mock_time_task_runner.h

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_
#define BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_

#include <stddef.h>

#include <memory>
#include <queue>
#include <vector>

#include "base/containers/circular_deque.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/test_pending_task.h"
#include "base/threading/thread_checker_impl.h"
#include "base/time/clock.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"

namespace base {

// ATTENTION: Prefer using base::test::SingleThreadTaskEnvironment with a
// base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME trait instead.
// The only case where TestMockTimeTaskRunner is necessary is when instantiating
// multiple TestMockTimeTaskRunners in the same test to deterministically
// exercise the result of a race between two simulated threads.
//
// Runs pending tasks in the order of the tasks' post time + delay, and keeps
// track of a mock (virtual) tick clock time that can be fast-forwarded.
//
// TestMockTimeTaskRunner has the following properties:
//
//   - Methods RunsTasksInCurrentSequence() and Post[Delayed]Task() can be
//     called from any thread, but the rest of the methods must be called on
//     the same thread the TestMockTimeTaskRunner was created on unless a call
//     is made to DetachFromThread(), in which case usage can switch to a
//     different thread.
//   - It allows for reentrancy, in that it handles the running of tasks that in
//     turn call back into it (e.g., to post more tasks).
//   - Tasks are stored in a priority queue, and executed in the increasing
//     order of post time + delay, but ignoring nestability.
//   - It does not check for overflow when doing time arithmetic. A sufficient
//     condition for preventing overflows is to make sure that the sum of all
//     posted task delays and fast-forward increments is still representable by
//     a TimeDelta, and that adding this delta to the starting values of Time
//     and TickTime is still within their respective range.
//
// A TestMockTimeTaskRunner of Type::kBoundToThread has the following additional
// properties:
//   - Thread/SequencedTaskRunner::CurrentDefaultHandle refers to it on its
//     thread.
//   - It can be driven by a RunLoop on the thread it was created on.
//     RunLoop::Run() will result in running non-delayed tasks until idle and
//     then, if RunLoop::QuitWhenIdle() wasn't invoked, fast-forwarding time to
//     the next delayed task and looping again. And so on, until either
//     RunLoop::Quit() is invoked (quits immediately after the current task) or
//     RunLoop::QuitWhenIdle() is invoked (quits before having to fast forward
//     time once again). Should RunLoop::Run() process all tasks (including
//     delayed ones), it will block until more are posted. As usual,
//     RunLoop::RunUntilIdle() is equivalent to RunLoop::Run() followed by an
//     immediate RunLoop::QuitWhenIdle().
//
// This is a slightly more sophisticated version of TestSimpleTaskRunner, in
// that it supports running delayed tasks in the correct temporal order.
class TestMockTimeTaskRunner : public SingleThreadTaskRunner,
                               public RunLoop::Delegate {};

}  // namespace base

#endif  // BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_