blob: 0e347562f1d457b5584936df238a0f2344ebf52c [file] [log] [blame]
Alexander Afanasyev85b17b82014-11-10 16:22:05 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi5bcab562017-07-16 17:19:14 +00002/*
Davide Pesavento5afbb0b2018-01-01 17:24:18 -05003 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyev85b17b82014-11-10 16:22:05 -08004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "time-unit-test-clock.hpp"
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050023#include "detail/steady-timer.hpp"
24
25#include <chrono>
Alexander Afanasyeveabffdf2014-11-13 13:50:33 -080026#include <thread>
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080027
28namespace ndn {
29namespace time {
30
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050031template<class BaseClock, class ClockTraits>
32UnitTestClock<BaseClock, ClockTraits>::UnitTestClock(nanoseconds startTime)
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080033 : m_currentTime(startTime)
34{
35}
36
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050037template<class BaseClock, class ClockTraits>
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080038std::string
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050039UnitTestClock<BaseClock, ClockTraits>::getSince() const
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080040{
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050041 return " since unit test beginning";
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080042}
43
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050044template<class BaseClock, class ClockTraits>
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080045typename BaseClock::time_point
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050046UnitTestClock<BaseClock, ClockTraits>::getNow() const
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080047{
48 return typename BaseClock::time_point(duration_cast<typename BaseClock::duration>(m_currentTime));
49}
50
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050051template<class BaseClock, class ClockTraits>
52typename BaseClock::duration
53UnitTestClock<BaseClock, ClockTraits>::toWaitDuration(typename BaseClock::duration) const
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080054{
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050055 return typename BaseClock::duration(1);
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080056}
57
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050058template<class BaseClock, class ClockTraits>
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080059void
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050060UnitTestClock<BaseClock, ClockTraits>::advance(nanoseconds duration)
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080061{
62 m_currentTime += duration;
Alexander Afanasyeveabffdf2014-11-13 13:50:33 -080063
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050064 // When UnitTestClock is used with Asio timers (e.g. basic_waitable_timer), and
65 // an async wait operation on a timer is already in progress, Asio won't look
66 // at the clock again until the earliest timer has expired, so it won't know that
67 // the current time has changed.
Alexander Afanasyeveabffdf2014-11-13 13:50:33 -080068 //
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050069 // Therefore, in order for the clock advancement to be effective, we must sleep
70 // for a period greater than wait_traits::to_wait_duration().
Alexander Afanasyeveabffdf2014-11-13 13:50:33 -080071 //
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050072 // See also http://blog.think-async.com/2007/08/time-travel.html - "Jumping Through Time"
73 //
74 std::this_thread::sleep_for(std::chrono::nanoseconds(duration_cast<nanoseconds>(
75 boost::asio::wait_traits<steady_clock>::to_wait_duration(duration) +
76 typename BaseClock::duration(1)).count()));
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080077}
78
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050079template<class BaseClock, class ClockTraits>
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080080void
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050081UnitTestClock<BaseClock, ClockTraits>::setNow(nanoseconds timeSinceEpoch)
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080082{
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050083 BOOST_ASSERT(!BaseClock::is_steady || timeSinceEpoch >= m_currentTime);
84
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080085 m_currentTime = timeSinceEpoch;
Davide Pesavento5afbb0b2018-01-01 17:24:18 -050086
87 // See comment in advance()
88 auto delta = timeSinceEpoch - m_currentTime;
89 std::this_thread::sleep_for(std::chrono::nanoseconds(duration_cast<nanoseconds>(
90 boost::asio::wait_traits<steady_clock>::to_wait_duration(delta) +
91 typename BaseClock::duration(1)).count()));
Alexander Afanasyev85b17b82014-11-10 16:22:05 -080092}
93
94template
95class UnitTestClock<system_clock>;
96
97template
98class UnitTestClock<steady_clock>;
99
100} // namespace time
101} // namespace ndn