1ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// Copyright 2015 The Chromium OS Authors. All rights reserved. 2ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// Use of this source code is governed by a BSD-style license that can be 3ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// found in the LICENSE file. 4ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 5fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#ifndef LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_ 6fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#define LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_ 7ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 8ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo#include <functional> 9ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo#include <map> 10ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo#include <queue> 113845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo#include <set> 12ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo#include <utility> 13ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo#include <vector> 14ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 15106edd138a59b2fa3856028baa15201d4f7f3ffdAlex Deymo#include <base/location.h> 16ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo#include <base/test/simple_test_clock.h> 17ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo#include <base/time/time.h> 18ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 199ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/brillo_export.h> 209ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko#include <brillo/message_loops/message_loop.h> 21ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 229ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkonamespace brillo { 23ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 24ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// The FakeMessageLoop implements a message loop that doesn't block or wait for 25ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// time based tasks to be ready. The tasks are executed in the order they should 26ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// be executed in a real message loop implementation, but the time is advanced 27ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// to the time when the first task should be executed instead of blocking. 28ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// To keep a consistent notion of time for other classes, FakeMessageLoop 29ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// optionally updates a SimpleTestClock instance when it needs to advance the 30ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// clock. 31ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo// This message loop implementation is useful for unittests. 329ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenkoclass BRILLO_EXPORT FakeMessageLoop : public MessageLoop { 33ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo public: 34ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // Create a FakeMessageLoop optionally using a SimpleTestClock to update the 35ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // time when Run() or RunOnce(true) are called and should block. 36ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo explicit FakeMessageLoop(base::SimpleTestClock* clock); 37ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo ~FakeMessageLoop() override = default; 38ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 393845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo TaskId PostDelayedTask(const tracked_objects::Location& from_here, 40a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const base::Closure& task, 413845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo base::TimeDelta delay) override; 42106edd138a59b2fa3856028baa15201d4f7f3ffdAlex Deymo using MessageLoop::PostDelayedTask; 433845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo TaskId WatchFileDescriptor(const tracked_objects::Location& from_here, 443845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo int fd, 453845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo WatchMode mode, 463845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo bool persistent, 47a8632e4a671d44cffa7b1f079baa0b9fdb48c5e3Alex Deymo const base::Closure& task) override; 483845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo using MessageLoop::WatchFileDescriptor; 49ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo bool CancelTask(TaskId task_id) override; 50ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo bool RunOnce(bool may_block) override; 51ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 52ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // FakeMessageLoop methods: 53ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 543845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // Pretend, for the purpose of the FakeMessageLoop watching for file 553845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // descriptors, that the file descriptor |fd| readiness to perform the 563845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // operation described by |mode| is |ready|. Initially, no file descriptor 573845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // is ready for any operation. 583845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo void SetFileDescriptorReadiness(int fd, WatchMode mode, bool ready); 593845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo 60ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // Return whether there are peding tasks. Useful to check that no 61ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // callbacks were leaked. 62ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo bool PendingTasks(); 63ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 64ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo private: 653845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo struct ScheduledTask { 663845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo tracked_objects::Location location; 673845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo bool persistent; 683845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo base::Closure callback; 693845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo }; 703845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo 713845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // The sparse list of scheduled pending callbacks. 723845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo std::map<MessageLoop::TaskId, ScheduledTask> tasks_; 733845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo 74ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // Using std::greater<> for the priority_queue means that the top() of the 75ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // queue is the lowest (earliest) time, and for the same time, the smallest 76ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo // TaskId. This determines the order in which the tasks will be fired. 77ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo std::priority_queue< 78ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo std::pair<base::Time, MessageLoop::TaskId>, 79ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo std::vector<std::pair<base::Time, MessageLoop::TaskId>>, 80ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo std::greater<std::pair<base::Time, MessageLoop::TaskId>>> fire_order_; 813845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo 823845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // The bag of watched (fd, mode) pair associated with the TaskId that's 833845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // watching them. 843845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo std::multimap<std::pair<int, WatchMode>, MessageLoop::TaskId> fds_watched_; 853845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo 863845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo // The set of (fd, mode) pairs that are faked as ready. 873845c6dfdf6c1edb45271e691990c12ef92f77c7Alex Deymo std::set<std::pair<int, WatchMode>> fds_ready_; 88ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 89ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo base::SimpleTestClock* test_clock_ = nullptr; 90ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo base::Time current_time_ = base::Time::FromDoubleT(1246996800.); 91ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 92ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo MessageLoop::TaskId last_id_ = kTaskIdNull; 93ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 94ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo DISALLOW_COPY_AND_ASSIGN(FakeMessageLoop); 95ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo}; 96ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 979ed0cab99f18acb3570a35e9408f24355f6b8324Alex Vakulenko} // namespace brillo 98ef3955af0d6b1baa7df93604c2d47b9e5af4de43Alex Deymo 99fed60b0c640828b320f56293c8bebc43fd2b1da8Alex Vakulenko#endif // LIBBRILLO_BRILLO_MESSAGE_LOOPS_FAKE_MESSAGE_LOOP_H_ 100