• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium OS Authors. All rights reserved.
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 LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_
6 #define LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_
7 
8 #include <functional>
9 #include <map>
10 #include <queue>
11 #include <set>
12 #include <utility>
13 #include <vector>
14 
15 #include <base/location.h>
16 #include <base/test/simple_test_clock.h>
17 #include <base/time/time.h>
18 
19 #include <brillo/brillo_export.h>
20 #include <brillo/message_loops/message_loop.h>
21 
22 namespace brillo {
23 
24 // The FakeMessageLoop implements a message loop that doesn't block or wait for
25 // time based tasks to be ready. The tasks are executed in the order they should
26 // be executed in a real message loop implementation, but the time is advanced
27 // to the time when the first task should be executed instead of blocking.
28 // To keep a consistent notion of time for other classes, FakeMessageLoop
29 // optionally updates a SimpleTestClock instance when it needs to advance the
30 // clock.
31 // This message loop implementation is useful for unittests.
32 class BRILLO_EXPORT FakeMessageLoop : public MessageLoop {
33  public:
34   // Create a FakeMessageLoop optionally using a SimpleTestClock to update the
35   // time when Run() or RunOnce(true) are called and should block.
36   explicit FakeMessageLoop(base::SimpleTestClock* clock);
37   ~FakeMessageLoop() override = default;
38 
39   TaskId PostDelayedTask(const base::Location& from_here,
40                          base::OnceClosure task,
41                          base::TimeDelta delay) override;
42   using MessageLoop::PostDelayedTask;
43   bool CancelTask(TaskId task_id) override;
44   bool RunOnce(bool may_block) override;
45 
46   // FakeMessageLoop methods:
47 
48   // Return whether there are peding tasks. Useful to check that no
49   // callbacks were leaked.
50   bool PendingTasks();
51 
52  private:
53   struct ScheduledTask {
54     base::Location location;
55     base::OnceClosure callback;
56   };
57 
58   // The sparse list of scheduled pending callbacks.
59   std::map<MessageLoop::TaskId, ScheduledTask> tasks_;
60 
61   // Using std::greater<> for the priority_queue means that the top() of the
62   // queue is the lowest (earliest) time, and for the same time, the smallest
63   // TaskId. This determines the order in which the tasks will be fired.
64   std::priority_queue<
65       std::pair<base::Time, MessageLoop::TaskId>,
66       std::vector<std::pair<base::Time, MessageLoop::TaskId>>,
67       std::greater<std::pair<base::Time, MessageLoop::TaskId>>> fire_order_;
68 
69   base::SimpleTestClock* test_clock_ = nullptr;
70   base::Time current_time_ = base::Time::FromDoubleT(1246996800.);
71 
72   MessageLoop::TaskId last_id_ = kTaskIdNull;
73 
74   DISALLOW_COPY_AND_ASSIGN(FakeMessageLoop);
75 };
76 
77 }  // namespace brillo
78 
79 #endif  // LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_
80