Home | History | Annotate | Download | only in message_loops
      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 tracked_objects::Location& from_here,
     40                          const base::Closure& task,
     41                          base::TimeDelta delay) override;
     42   using MessageLoop::PostDelayedTask;
     43   TaskId WatchFileDescriptor(const tracked_objects::Location& from_here,
     44                              int fd,
     45                              WatchMode mode,
     46                              bool persistent,
     47                              const base::Closure& task) override;
     48   using MessageLoop::WatchFileDescriptor;
     49   bool CancelTask(TaskId task_id) override;
     50   bool RunOnce(bool may_block) override;
     51 
     52   // FakeMessageLoop methods:
     53 
     54   // Pretend, for the purpose of the FakeMessageLoop watching for file
     55   // descriptors, that the file descriptor |fd| readiness to perform the
     56   // operation described by |mode| is |ready|. Initially, no file descriptor
     57   // is ready for any operation.
     58   void SetFileDescriptorReadiness(int fd, WatchMode mode, bool ready);
     59 
     60   // Return whether there are peding tasks. Useful to check that no
     61   // callbacks were leaked.
     62   bool PendingTasks();
     63 
     64  private:
     65   struct ScheduledTask {
     66     tracked_objects::Location location;
     67     bool persistent;
     68     base::Closure callback;
     69   };
     70 
     71   // The sparse list of scheduled pending callbacks.
     72   std::map<MessageLoop::TaskId, ScheduledTask> tasks_;
     73 
     74   // Using std::greater<> for the priority_queue means that the top() of the
     75   // queue is the lowest (earliest) time, and for the same time, the smallest
     76   // TaskId. This determines the order in which the tasks will be fired.
     77   std::priority_queue<
     78       std::pair<base::Time, MessageLoop::TaskId>,
     79       std::vector<std::pair<base::Time, MessageLoop::TaskId>>,
     80       std::greater<std::pair<base::Time, MessageLoop::TaskId>>> fire_order_;
     81 
     82   // The bag of watched (fd, mode) pair associated with the TaskId that's
     83   // watching them.
     84   std::multimap<std::pair<int, WatchMode>, MessageLoop::TaskId> fds_watched_;
     85 
     86   // The set of (fd, mode) pairs that are faked as ready.
     87   std::set<std::pair<int, WatchMode>> fds_ready_;
     88 
     89   base::SimpleTestClock* test_clock_ = nullptr;
     90   base::Time current_time_ = base::Time::FromDoubleT(1246996800.);
     91 
     92   MessageLoop::TaskId last_id_ = kTaskIdNull;
     93 
     94   DISALLOW_COPY_AND_ASSIGN(FakeMessageLoop);
     95 };
     96 
     97 }  // namespace brillo
     98 
     99 #endif  // LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_
    100