• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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