blob: c8c13133d8b0a94a57ad8ec32964a6bbcc0f5294 [file] [log] [blame]
Alex Deymoef3955a2015-06-09 10:14:01 -07001// 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
Alex Vakulenkofed60b02015-10-27 09:53:05 -07005#ifndef LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_
6#define LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_
Alex Deymoef3955a2015-06-09 10:14:01 -07007
8#include <functional>
9#include <map>
10#include <queue>
Alex Deymo3845c6d2015-06-25 11:08:30 -070011#include <set>
Alex Deymoef3955a2015-06-09 10:14:01 -070012#include <utility>
13#include <vector>
14
Alex Deymo106edd12015-06-18 20:15:11 -070015#include <base/location.h>
Alex Deymoef3955a2015-06-09 10:14:01 -070016#include <base/test/simple_test_clock.h>
17#include <base/time/time.h>
18
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070019#include <brillo/brillo_export.h>
20#include <brillo/message_loops/message_loop.h>
Alex Deymoef3955a2015-06-09 10:14:01 -070021
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070022namespace brillo {
Alex Deymoef3955a2015-06-09 10:14:01 -070023
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.
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070032class BRILLO_EXPORT FakeMessageLoop : public MessageLoop {
Alex Deymoef3955a2015-06-09 10:14:01 -070033 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
Alex Deymo3845c6d2015-06-25 11:08:30 -070039 TaskId PostDelayedTask(const tracked_objects::Location& from_here,
Alex Deymoa8632e42015-07-14 08:38:28 -070040 const base::Closure& task,
Alex Deymo3845c6d2015-06-25 11:08:30 -070041 base::TimeDelta delay) override;
Alex Deymo106edd12015-06-18 20:15:11 -070042 using MessageLoop::PostDelayedTask;
Alex Deymo3845c6d2015-06-25 11:08:30 -070043 TaskId WatchFileDescriptor(const tracked_objects::Location& from_here,
44 int fd,
45 WatchMode mode,
46 bool persistent,
Alex Deymoa8632e42015-07-14 08:38:28 -070047 const base::Closure& task) override;
Alex Deymo3845c6d2015-06-25 11:08:30 -070048 using MessageLoop::WatchFileDescriptor;
Alex Deymoef3955a2015-06-09 10:14:01 -070049 bool CancelTask(TaskId task_id) override;
50 bool RunOnce(bool may_block) override;
51
52 // FakeMessageLoop methods:
53
Alex Deymo3845c6d2015-06-25 11:08:30 -070054 // 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
Alex Deymoef3955a2015-06-09 10:14:01 -070060 // Return whether there are peding tasks. Useful to check that no
61 // callbacks were leaked.
62 bool PendingTasks();
63
64 private:
Alex Deymo3845c6d2015-06-25 11:08:30 -070065 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
Alex Deymoef3955a2015-06-09 10:14:01 -070074 // 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_;
Alex Deymo3845c6d2015-06-25 11:08:30 -070081
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_;
Alex Deymoef3955a2015-06-09 10:14:01 -070088
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
Alex Vakulenko9ed0cab2015-10-12 15:21:28 -070097} // namespace brillo
Alex Deymoef3955a2015-06-09 10:14:01 -070098
Alex Vakulenkofed60b02015-10-27 09:53:05 -070099#endif // LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_