1 // Copyright 2019 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_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_ 6 #define BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_ 7 8 #include "base/functional/callback.h" 9 #include "base/memory/raw_ptr.h" 10 #include "base/message_loop/message_pump.h" 11 #include "base/synchronization/waitable_event.h" 12 #include "base/time/time.h" 13 14 namespace base { 15 16 class SimpleTestTickClock; 17 18 namespace sequence_manager { 19 20 // MessagePump implementation that uses a SimpleTestTickClock to keep track of 21 // time and will advance it as needed to keep running tasks. 22 // 23 // This pump will actually check fail if it ever has to go to sleep as this 24 // would indicate that the unit test might block indefinitely. 25 // TODO(carlscab): In the future we could consider sleeping if there is no 26 // outstanding |delayed_work_time_|, because we could be woken up by concurrent 27 // ScheduleWork() calls. 28 class MockTimeMessagePump : public MessagePump { 29 public: 30 explicit MockTimeMessagePump(SimpleTestTickClock* clock); 31 ~MockTimeMessagePump() override; 32 33 // MessagePump implementation 34 void Run(Delegate* delegate) override; 35 void Quit() override; 36 void ScheduleWork() override; 37 void ScheduleDelayedWork( 38 const Delegate::NextWorkInfo& next_work_info) override; 39 40 // Returns the time at which the pump would have to wake up to be perform 41 // work. next_wake_up_time()42 TimeTicks next_wake_up_time() const { return next_wake_up_time_; } 43 44 // Quits after the first call to Delegate::DoWork(). Useful 45 // for tests that want to make sure certain things happen during a DoWork 46 // call. SetQuitAfterDoWork(bool quit_after_do_some_work)47 void SetQuitAfterDoWork(bool quit_after_do_some_work) { 48 quit_after_do_some_work_ = quit_after_do_some_work; 49 } 50 51 // Allows this instance to advance the SimpleTestTickClock up to but not over 52 // |advance_until| when idle (i.e. when a regular pump would go to sleep). 53 // The clock will allways be advanced to |advance_until|, even if there are no 54 // tasks requiring it (i.e. delayed tasks to be run after 55 // |advance_until|) except for a value of TimeTicks::Max() which will advance 56 // the clock as long as there is pending delayed work. SetAllowTimeToAutoAdvanceUntil(TimeTicks advance_until)57 void SetAllowTimeToAutoAdvanceUntil(TimeTicks advance_until) { 58 allow_advance_until_ = advance_until; 59 } 60 61 // Quit when this pump's Delegate is out of work (i.e. when a regular pump 62 // would go to sleep) and we are not allowed to advance the clock anymore. SetStopWhenMessagePumpIsIdle(bool stop_when_message_pump_is_idle)63 void SetStopWhenMessagePumpIsIdle(bool stop_when_message_pump_is_idle) { 64 stop_when_message_pump_is_idle_ = stop_when_message_pump_is_idle; 65 } 66 67 private: 68 // Returns true if the clock was indeed advanced and thus we should attempt 69 // another iteration of the DoWork-DoIdleWork-loop. 70 bool MaybeAdvanceTime(TimeTicks target_time); 71 72 const raw_ptr<SimpleTestTickClock> clock_; 73 // This flag is set to false when Run should return. 74 bool keep_running_ = true; 75 76 bool stop_when_message_pump_is_idle_ = false; 77 bool quit_after_do_some_work_ = false; 78 79 TimeTicks next_wake_up_time_{TimeTicks::Max()}; 80 81 TimeTicks allow_advance_until_ = TimeTicks::Min(); 82 }; 83 84 } // namespace sequence_manager 85 } // namespace base 86 87 #endif // BASE_TASK_SEQUENCE_MANAGER_TEST_MOCK_TIME_MESSAGE_PUMP_H_ 88