OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ | 5 #ifndef BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ |
6 #define BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ | 6 #define BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ |
7 | 7 |
8 #include <queue> | 8 #include <queue> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
15 #include "base/test/test_pending_task.h" | 15 #include "base/test/test_pending_task.h" |
16 #include "base/threading/thread_checker.h" | 16 #include "base/threading/thread_checker.h" |
17 #include "base/time/tick_clock.h" | |
18 #include "base/time/time.h" | 17 #include "base/time/time.h" |
19 | 18 |
20 namespace base { | 19 namespace base { |
21 | 20 |
| 21 class Clock; |
| 22 class TickClock; |
| 23 |
22 // Runs pending tasks in the order of the tasks' post time + delay, and keeps | 24 // Runs pending tasks in the order of the tasks' post time + delay, and keeps |
23 // track of a mock (virtual) tick clock time that can be fast-forwarded. | 25 // track of a mock (virtual) tick clock time that can be fast-forwarded. |
24 // | 26 // |
25 // TestMockTimeTaskRunner has the following properties: | 27 // TestMockTimeTaskRunner has the following properties: |
26 // | 28 // |
27 // - Methods RunsTasksOnCurrentThread() and Post[Delayed]Task() can be called | 29 // - Methods RunsTasksOnCurrentThread() and Post[Delayed]Task() can be called |
28 // from any thread, but the rest of the methods must be called on the same | 30 // from any thread, but the rest of the methods must be called on the same |
29 // thread the TaskRunner was created on. | 31 // thread the TaskRunner was created on. |
30 // - It allows for reentrancy, in that it handles the running of tasks that in | 32 // - It allows for reentrancy, in that it handles the running of tasks that in |
31 // turn call back into it (e.g., to post more tasks). | 33 // turn call back into it (e.g., to post more tasks). |
32 // - Tasks are stored in a priority queue, and executed in the increasing | 34 // - Tasks are stored in a priority queue, and executed in the increasing |
33 // order of post time + delay. | 35 // order of post time + delay. |
| 36 // - It does not check for overflow when doing time arithmetic. A sufficient |
| 37 // condition for preventing overflows is to make sure that the sum of all |
| 38 // posted task delays and fast-forward increments is still representable by |
| 39 // a TimeDelta, and that adding this delta to the starting values of Time |
| 40 // and TickTime is still within their respective range. |
34 // - Non-nestable tasks are not supported. | 41 // - Non-nestable tasks are not supported. |
35 // - Tasks aren't guaranteed to be destroyed immediately after they're run. | 42 // - Tasks aren't guaranteed to be destroyed immediately after they're run. |
36 // | 43 // |
37 // This is a slightly more sophisticated version of TestSimpleTaskRunner, in | 44 // This is a slightly more sophisticated version of TestSimpleTaskRunner, in |
38 // that it supports running delayed tasks in the correct temporal order. | 45 // that it supports running delayed tasks in the correct temporal order. |
39 class TestMockTimeTaskRunner : public base::SingleThreadTaskRunner { | 46 class TestMockTimeTaskRunner : public SingleThreadTaskRunner { |
40 public: | 47 public: |
| 48 // Constructs an instance whose virtual time will start at the Unix epoch, and |
| 49 // whose time ticks will start at zero. |
41 TestMockTimeTaskRunner(); | 50 TestMockTimeTaskRunner(); |
42 | 51 |
43 // Fast-forwards virtual time by |delta|, causing all tasks with a remaining | 52 // Fast-forwards virtual time by |delta|, causing all tasks with a remaining |
44 // delay less than or equal to |delta| to be executed. | 53 // delay less than or equal to |delta| to be executed. |delta| must be |
45 void FastForwardBy(base::TimeDelta delta); | 54 // non-negative. |
| 55 void FastForwardBy(TimeDelta delta); |
46 | 56 |
47 // Fast-forwards virtual time just until all tasks are executed. | 57 // Fast-forwards virtual time just until all tasks are executed. |
48 void FastForwardUntilNoTasksRemain(); | 58 void FastForwardUntilNoTasksRemain(); |
49 | 59 |
50 // Executes all tasks that have no remaining delay. Tasks with a remaining | 60 // Executes all tasks that have no remaining delay. Tasks with a remaining |
51 // delay greater than zero will remain enqueued, and no virtual time will | 61 // delay greater than zero will remain enqueued, and no virtual time will |
52 // elapse. | 62 // elapse. |
53 void RunUntilIdle(); | 63 void RunUntilIdle(); |
54 | 64 |
55 // Returns the current virtual time. | 65 // Returns the current virtual time (initially starting at the Unix epoch). |
56 TimeTicks GetCurrentMockTime() const; | 66 Time Now() const; |
57 | 67 |
58 // Returns a TickClock that uses the mock time of |this| as its time source. | 68 // Returns the current virtual tick time (initially starting at 0). |
59 // The returned TickClock will hold a reference to |this|. | 69 TimeTicks NowTicks() const; |
| 70 |
| 71 // Returns a Clock that uses the virtual time of |this| as its time source. |
| 72 // The returned Clock will hold a reference to |this|. |
| 73 scoped_ptr<Clock> GetMockClock() const; |
| 74 |
| 75 // Returns a TickClock that uses the virtual time ticks of |this| as its tick |
| 76 // source. The returned TickClock will hold a reference to |this|. |
60 scoped_ptr<TickClock> GetMockTickClock() const; | 77 scoped_ptr<TickClock> GetMockTickClock() const; |
61 | 78 |
62 bool HasPendingTask() const; | 79 bool HasPendingTask() const; |
63 size_t GetPendingTaskCount() const; | 80 size_t GetPendingTaskCount() const; |
64 TimeDelta NextPendingTaskDelay() const; | 81 TimeDelta NextPendingTaskDelay() const; |
65 | 82 |
66 // SingleThreadTaskRunner: | 83 // SingleThreadTaskRunner: |
67 bool RunsTasksOnCurrentThread() const override; | 84 bool RunsTasksOnCurrentThread() const override; |
68 bool PostDelayedTask(const tracked_objects::Location& from_here, | 85 bool PostDelayedTask(const tracked_objects::Location& from_here, |
69 const base::Closure& task, | 86 const Closure& task, |
70 TimeDelta delay) override; | 87 TimeDelta delay) override; |
71 bool PostNonNestableDelayedTask( | 88 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
72 const tracked_objects::Location& from_here, | 89 const Closure& task, |
73 const base::Closure& task, | 90 TimeDelta delay) override; |
74 TimeDelta delay) override; | |
75 | 91 |
76 protected: | 92 protected: |
77 ~TestMockTimeTaskRunner() override; | 93 ~TestMockTimeTaskRunner() override; |
78 | 94 |
79 // Called before the next task to run is selected, so that subclasses have a | 95 // Called before the next task to run is selected, so that subclasses have a |
80 // last chance to make sure all tasks are posted. | 96 // last chance to make sure all tasks are posted. |
81 virtual void OnBeforeSelectingTask(); | 97 virtual void OnBeforeSelectingTask(); |
82 | 98 |
83 // Called after the current mock time has been incremented so that subclasses | 99 // Called after the current mock time has been incremented so that subclasses |
84 // can react to the passing of time. | 100 // can react to the passing of time. |
85 virtual void OnAfterTimePassed(); | 101 virtual void OnAfterTimePassed(); |
86 | 102 |
87 // Called after each task is run so that subclasses may perform additional | 103 // Called after each task is run so that subclasses may perform additional |
88 // activities, e.g., pump additional task runners. | 104 // activities, e.g., pump additional task runners. |
89 virtual void OnAfterTaskRun(); | 105 virtual void OnAfterTaskRun(); |
90 | 106 |
91 private: | 107 private: |
92 // Predicate that defines a strict weak temporal ordering of tasks. | 108 // Predicate that defines a strict weak temporal ordering of tasks. |
93 class TemporalOrder { | 109 class TemporalOrder { |
94 public: | 110 public: |
95 bool operator()(const TestPendingTask& first_task, | 111 bool operator()(const TestPendingTask& first_task, |
96 const TestPendingTask& second_task) const; | 112 const TestPendingTask& second_task) const; |
97 }; | 113 }; |
98 | 114 |
99 typedef std::priority_queue<TestPendingTask, | 115 typedef std::priority_queue<TestPendingTask, |
100 std::vector<TestPendingTask>, | 116 std::vector<TestPendingTask>, |
101 TemporalOrder> TaskPriorityQueue; | 117 TemporalOrder> TaskPriorityQueue; |
102 | 118 |
| 119 // Core of the implementation for all flavors of fast-forward methods. Given a |
| 120 // non-negative |max_delta|, runs all tasks with a remaining delay less than |
| 121 // or equal to |max_delta|, and moves virtual time forward as needed for each |
| 122 // processed task. Pass in TimeDelta::Max() as |max_delta| to run all tasks. |
| 123 void ProcessAllTasksNoLaterThan(TimeDelta max_delta); |
| 124 |
| 125 // Forwards |now_ticks_| until it equals |later_ticks|, and forwards |now_| by |
| 126 // the same amount. Calls OnAfterTimePassed() if |later_ticks| > |now_ticks_|. |
| 127 // Does nothing if |later_ticks| <= |now_ticks_|. |
| 128 void ForwardClocksUntilTickTime(TimeTicks later_ticks); |
| 129 |
103 // Returns the |next_task| to run if there is any with a running time that is | 130 // Returns the |next_task| to run if there is any with a running time that is |
104 // at most |reference| + |max_delta|. This additional complexity is required | 131 // at most |reference| + |max_delta|. This additional complexity is required |
105 // so that |max_delta| == TimeDelta::Max() can be supported. | 132 // so that |max_delta| == TimeDelta::Max() can be supported. |
106 bool DequeueNextTask(const base::TimeTicks& reference, | 133 bool DequeueNextTask(const TimeTicks& reference, |
107 const base::TimeDelta& max_delta, | 134 const TimeDelta& max_delta, |
108 TestPendingTask* next_task); | 135 TestPendingTask* next_task); |
109 | 136 |
110 base::ThreadChecker thread_checker_; | 137 ThreadChecker thread_checker_; |
111 base::TimeTicks now_; | 138 Time now_; |
| 139 TimeTicks now_ticks_; |
112 | 140 |
113 // Temporally ordered heap of pending tasks. Must only be accessed while the | 141 // Temporally ordered heap of pending tasks. Must only be accessed while the |
114 // |tasks_lock_| is held. | 142 // |tasks_lock_| is held. |
115 TaskPriorityQueue tasks_; | 143 TaskPriorityQueue tasks_; |
116 base::Lock tasks_lock_; | 144 Lock tasks_lock_; |
117 | 145 |
118 DISALLOW_COPY_AND_ASSIGN(TestMockTimeTaskRunner); | 146 DISALLOW_COPY_AND_ASSIGN(TestMockTimeTaskRunner); |
119 }; | 147 }; |
120 | 148 |
121 } // namespace base | 149 } // namespace base |
122 | 150 |
123 #endif // BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ | 151 #endif // BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ |
OLD | NEW |