1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TEST_TEST_SIMPLE_TASK_RUNNER_H_ 6 #define BASE_TEST_TEST_SIMPLE_TASK_RUNNER_H_ 7 8 #include "base/compiler_specific.h" 9 #include "base/containers/circular_deque.h" 10 #include "base/functional/callback.h" 11 #include "base/synchronization/lock.h" 12 #include "base/task/single_thread_task_runner.h" 13 #include "base/test/test_pending_task.h" 14 #include "base/threading/platform_thread.h" 15 16 namespace base { 17 18 class TimeDelta; 19 20 // ATTENTION: Prefer using base::test::TaskEnvironment and a task runner 21 // obtained from base/task/thread_pool.h over this class. This class isn't as 22 // "simple" as it seems specifically because it runs tasks in a surprising order 23 // (delays aren't respected and nesting doesn't behave as usual). Should you 24 // prefer to flush all tasks regardless of delays, 25 // TaskEnvironment::TimeSource::MOCK_TIME and 26 // TaskEnvironment::FastForwardUntilNoTasksRemain() have you covered. 27 // 28 // TestSimpleTaskRunner is a simple TaskRunner implementation that can 29 // be used for testing. It implements SingleThreadTaskRunner as that 30 // interface implements SequencedTaskRunner, which in turn implements 31 // TaskRunner, so TestSimpleTaskRunner can be passed in to a function 32 // that accepts any *TaskRunner object. 33 // 34 // TestSimpleTaskRunner has the following properties which make it simple: 35 // 36 // - Tasks are simply stored in a queue in FIFO order, ignoring delay 37 // and nestability. 38 // - Tasks aren't guaranteed to be destroyed immediately after 39 // they're run. 40 // 41 // However, TestSimpleTaskRunner allows for reentrancy, in that it 42 // handles the running of tasks that in turn call back into itself 43 // (e.g., to post more tasks). 44 // 45 // Note that, like any TaskRunner, TestSimpleTaskRunner is 46 // ref-counted. 47 class TestSimpleTaskRunner : public SingleThreadTaskRunner { 48 public: 49 TestSimpleTaskRunner(); 50 51 TestSimpleTaskRunner(const TestSimpleTaskRunner&) = delete; 52 TestSimpleTaskRunner& operator=(const TestSimpleTaskRunner&) = delete; 53 54 // SingleThreadTaskRunner implementation. 55 bool PostDelayedTask(const Location& from_here, 56 OnceClosure task, 57 TimeDelta delay) override; 58 bool PostNonNestableDelayedTask(const Location& from_here, 59 OnceClosure task, 60 TimeDelta delay) override; 61 62 bool RunsTasksInCurrentSequence() const override; 63 64 base::circular_deque<TestPendingTask> TakePendingTasks(); 65 size_t NumPendingTasks() const; 66 bool HasPendingTask() const; 67 base::TimeDelta NextPendingTaskDelay() const; 68 base::TimeDelta FinalPendingTaskDelay() const; 69 70 // Clears the queue of pending tasks without running them. 71 void ClearPendingTasks(); 72 73 // Runs each current pending task in order and clears the queue. Tasks posted 74 // by the tasks that run within this call do not run within this call. Can 75 // only be called on the thread that created this TestSimpleTaskRunner. 76 void RunPendingTasks(); 77 78 // Runs pending tasks until the queue is empty. Can only be called on the 79 // thread that created this TestSimpleTaskRunner. 80 void RunUntilIdle(); 81 82 protected: 83 ~TestSimpleTaskRunner() override; 84 85 private: 86 // Thread on which this was instantiated. 87 const PlatformThreadRef thread_ref_ = PlatformThread::CurrentRef(); 88 89 // Synchronizes access to |pending_tasks_|. 90 mutable Lock lock_; 91 92 base::circular_deque<TestPendingTask> pending_tasks_; 93 }; 94 95 } // namespace base 96 97 #endif // BASE_TEST_TEST_SIMPLE_TASK_RUNNER_H_ 98