/* * Copyright (c) 2021 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef NET_DCSCTP_TIMER_FAKE_TIMEOUT_H_ #define NET_DCSCTP_TIMER_FAKE_TIMEOUT_H_ #include #include #include #include #include #include #include #include "net/dcsctp/public/timeout.h" namespace dcsctp { // A timeout used in tests. class FakeTimeout : public Timeout { public: explicit FakeTimeout(std::function get_time, std::function on_delete) : get_time_(std::move(get_time)), on_delete_(std::move(on_delete)) {} ~FakeTimeout() override { on_delete_(this); } void Start(DurationMs duration_ms, TimeoutID timeout_id) override { timeout_id_ = timeout_id; expiry_ = get_time_() + duration_ms; } void Stop() override { expiry_ = InfiniteFuture(); } bool EvaluateHasExpired(TimeMs now) { if (now >= expiry_) { expiry_ = InfiniteFuture(); return true; } return false; } TimeoutID timeout_id() const { return timeout_id_; } private: static constexpr TimeMs InfiniteFuture() { return TimeMs(std::numeric_limits::max()); } const std::function get_time_; const std::function on_delete_; TimeoutID timeout_id_ = TimeoutID(0); TimeMs expiry_ = InfiniteFuture(); }; class FakeTimeoutManager { public: // The `get_time` function must return the current time, relative to any // epoch. explicit FakeTimeoutManager(std::function get_time) : get_time_(std::move(get_time)) {} std::unique_ptr CreateTimeout() { auto timer = std::make_unique( get_time_, [this](FakeTimeout* timer) { timers_.erase(timer); }); timers_.insert(timer.get()); return timer; } std::vector RunTimers() { TimeMs now = get_time_(); std::vector expired_timers; for (auto& timer : timers_) { if (timer->EvaluateHasExpired(now)) { expired_timers.push_back(timer->timeout_id()); } } return expired_timers; } private: const std::function get_time_; std::unordered_set timers_; }; } // namespace dcsctp #endif // NET_DCSCTP_TIMER_FAKE_TIMEOUT_H_