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 arithmetics. 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 still 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| >= 0, causing all tasks with a |
44 // delay less than or equal to |delta| to be executed. | 53 // remaining delay less than or equal to |delta| to be executed. |
45 void FastForwardBy(base::TimeDelta delta); | 54 void FastForwardBy(TimeDelta delta); |
46 | 55 |
47 // Fast-forwards virtual time just until all tasks are executed. | 56 // Fast-forwards virtual time just until all tasks are executed. |
48 void FastForwardUntilNoTasksRemain(); | 57 void FastForwardUntilNoTasksRemain(); |
49 | 58 |
50 // Executes all tasks that have no remaining delay. Tasks with a remaining | 59 // 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 | 60 // delay greater than zero will remain enqueued, and no virtual time will |
52 // elapse. | 61 // elapse. |
53 void RunUntilIdle(); | 62 void RunUntilIdle(); |
54 | 63 |
55 // Returns the current virtual time. | 64 // Returns the current virtual time (initially starting at the Unix epoch). |
56 TimeTicks GetCurrentMockTime() const; | 65 Time Now() const; |
57 | 66 |
58 // Returns a TickClock that uses the mock time of |this| as its time source. | 67 // Returns the current virtual tick time (initially starting at 0). |
59 // The returned TickClock will hold a reference to |this|. | 68 TimeTicks NowTicks() const; |
69 | |
70 // Returns a Clock that uses the virtual time of |this| as its time source. | |
71 // The returned Clock will hold a reference to |this|. | |
72 scoped_ptr<Clock> GetMockClock() const; | |
73 | |
74 // Returns a TickClock that uses the virtual time ticks of |this| as its tick | |
75 // source. The returned TickClock will hold a reference to |this|. | |
60 scoped_ptr<TickClock> GetMockTickClock() const; | 76 scoped_ptr<TickClock> GetMockTickClock() const; |
61 | 77 |
62 bool HasPendingTask() const; | 78 bool HasPendingTask() const; |
63 size_t GetPendingTaskCount() const; | 79 size_t GetPendingTaskCount() const; |
64 TimeDelta NextPendingTaskDelay() const; | 80 TimeDelta NextPendingTaskDelay() const; |
65 | 81 |
66 // SingleThreadTaskRunner: | 82 // SingleThreadTaskRunner: |
67 bool RunsTasksOnCurrentThread() const override; | 83 bool RunsTasksOnCurrentThread() const override; |
68 bool PostDelayedTask(const tracked_objects::Location& from_here, | 84 bool PostDelayedTask(const tracked_objects::Location& from_here, |
69 const base::Closure& task, | 85 const Closure& task, |
70 TimeDelta delay) override; | 86 TimeDelta delay) override; |
71 bool PostNonNestableDelayedTask( | 87 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
72 const tracked_objects::Location& from_here, | 88 const Closure& task, |
73 const base::Closure& task, | 89 TimeDelta delay) override; |
74 TimeDelta delay) override; | |
75 | 90 |
76 protected: | 91 protected: |
77 ~TestMockTimeTaskRunner() override; | 92 ~TestMockTimeTaskRunner() override; |
78 | 93 |
79 // Called before the next task to run is selected, so that subclasses have a | 94 // Called before the next task to run is selected, so that subclasses have a |
80 // last chance to make sure all tasks are posted. | 95 // last chance to make sure all tasks are posted. |
81 virtual void OnBeforeSelectingTask(); | 96 virtual void OnBeforeSelectingTask(); |
82 | 97 |
83 // Called after the current mock time has been incremented so that subclasses | 98 // Called after the current mock time has been incremented so that subclasses |
84 // can react to the passing of time. | 99 // can react to the passing of time. |
85 virtual void OnAfterTimePassed(); | 100 virtual void OnAfterTimePassed(); |
86 | 101 |
87 // Called after each task is run so that subclasses may perform additional | 102 // Called after each task is run so that subclasses may perform additional |
88 // activities, e.g., pump additional task runners. | 103 // activities, e.g., pump additional task runners. |
89 virtual void OnAfterTaskRun(); | 104 virtual void OnAfterTaskRun(); |
90 | 105 |
91 private: | 106 private: |
92 // Predicate that defines a strict weak temporal ordering of tasks. | 107 // Predicate that defines a strict weak temporal ordering of tasks. |
93 class TemporalOrder { | 108 class TemporalOrder { |
94 public: | 109 public: |
95 bool operator()(const TestPendingTask& first_task, | 110 bool operator()(const TestPendingTask& first_task, |
96 const TestPendingTask& second_task) const; | 111 const TestPendingTask& second_task) const; |
97 }; | 112 }; |
98 | 113 |
99 typedef std::priority_queue<TestPendingTask, | 114 typedef std::priority_queue<TestPendingTask, |
100 std::vector<TestPendingTask>, | 115 std::vector<TestPendingTask>, |
101 TemporalOrder> TaskPriorityQueue; | 116 TemporalOrder> TaskPriorityQueue; |
102 | 117 |
118 // Core of the implementation for all flavors of fast-forward methods. Runs | |
119 // all tasks with a remaining delay less than or equal to |max_delta| >= 0, | |
Lei Zhang
2015/02/05 18:25:26
nit: phrasing is still a bit weird. How about:
Gi
engedy
2015/02/05 18:31:54
Done. Also one place above.
| |
120 // and moves virtual time forward as needed for each processed task. Pass in | |
121 // TimeDelta::Max() as |max_delta| to run all tasks. | |
122 void ProcessAllTasksNoLaterThan(TimeDelta max_delta); | |
123 | |
124 // Forwards |now_ticks_| until it equals |later_ticks|, and forwards |now_| by | |
125 // the same amount. Calls OnAfterTimePassed() if |now_ticks_| < |later_ticks|. | |
126 // Does nothing if |later_ticks| <= |now_ticks_|. | |
127 void ForwardClocksUntilTickTime(TimeTicks later_ticks); | |
128 | |
103 // Returns the |next_task| to run if there is any with a running time that is | 129 // 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 | 130 // at most |reference| + |max_delta|. This additional complexity is required |
105 // so that |max_delta| == TimeDelta::Max() can be supported. | 131 // so that |max_delta| == TimeDelta::Max() can be supported. |
106 bool DequeueNextTask(const base::TimeTicks& reference, | 132 bool DequeueNextTask(const TimeTicks& reference, |
107 const base::TimeDelta& max_delta, | 133 const TimeDelta& max_delta, |
108 TestPendingTask* next_task); | 134 TestPendingTask* next_task); |
109 | 135 |
110 base::ThreadChecker thread_checker_; | 136 ThreadChecker thread_checker_; |
111 base::TimeTicks now_; | 137 Time now_; |
138 TimeTicks now_ticks_; | |
112 | 139 |
113 // Temporally ordered heap of pending tasks. Must only be accessed while the | 140 // Temporally ordered heap of pending tasks. Must only be accessed while the |
114 // |tasks_lock_| is held. | 141 // |tasks_lock_| is held. |
115 TaskPriorityQueue tasks_; | 142 TaskPriorityQueue tasks_; |
116 base::Lock tasks_lock_; | 143 Lock tasks_lock_; |
117 | 144 |
118 DISALLOW_COPY_AND_ASSIGN(TestMockTimeTaskRunner); | 145 DISALLOW_COPY_AND_ASSIGN(TestMockTimeTaskRunner); |
119 }; | 146 }; |
120 | 147 |
121 } // namespace base | 148 } // namespace base |
122 | 149 |
123 #endif // BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ | 150 #endif // BASE_TEST_TEST_MOCK_TIME_TASK_RUNNER_H_ |
OLD | NEW |