// 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_