tests: introduce ClockFixture

Identical to UnitTestTimeFixture, except that it does not derive
from BaseFixture, and thus does not depend on a global io_service.

Refs: #4528
Change-Id: Ia2e6c4835a1e461c73281e103109d5cc85be355e
This commit is contained in:
Davide Pesavento committed 2019-03-26 22:51:04 -04:00
1 parent 1d12d2fe4e
commit b7703adb88
8 files changed
+196 -136

No files matched your search

+69
View File
@@ -0,0 +1,69 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tests/clock-fixture.hpp"
namespace nfd {
namespace tests {
ClockFixture::ClockFixture(boost::asio::io_service& io)
: m_steadyClock(make_shared<time::UnitTestSteadyClock>())
, m_systemClock(make_shared<time::UnitTestSystemClock>())
, m_io(io)
{
time::setCustomClocks(m_steadyClock, m_systemClock);
}
ClockFixture::~ClockFixture()
{
time::setCustomClocks(nullptr, nullptr);
}
void
ClockFixture::advanceClocks(time::nanoseconds tick, time::nanoseconds total)
{
BOOST_ASSERT(tick > time::nanoseconds::zero());
BOOST_ASSERT(total >= time::nanoseconds::zero());
while (total > time::nanoseconds::zero()) {
auto t = std::min(tick, total);
m_steadyClock->advance(t);
m_systemClock->advance(t);
total -= t;
pollAfterClockTick();
}
}
void
ClockFixture::pollAfterClockTick()
{
if (m_io.stopped())
m_io.reset();
m_io.poll();
}
} // namespace tests
} // namespace nfd
+91
View File
@@ -0,0 +1,91 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2014-2019, Regents of the University of California,
* Arizona Board of Regents,
* Colorado State University,
* University Pierre & Marie Curie, Sorbonne University,
* Washington University in St. Louis,
* Beijing Institute of Technology,
* The University of Memphis.
*
* This file is part of NFD (Named Data Networking Forwarding Daemon).
* See AUTHORS.md for complete list of NFD authors and contributors.
*
* NFD is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef NFD_TESTS_CLOCK_FIXTURE_HPP
#define NFD_TESTS_CLOCK_FIXTURE_HPP
#include "core/common.hpp"
#include <ndn-cxx/util/time-unit-test-clock.hpp>
namespace nfd {
namespace tests {
/** \brief A test fixture that overrides steady clock and system clock.
*/
class ClockFixture
{
public:
virtual
~ClockFixture();
/** \brief Advance steady and system clocks.
*
* Clocks are advanced in increments of \p tick for \p nTicks ticks.
* After each tick, global io_service is polled to process pending I/O events.
*
* Exceptions thrown during I/O events are propagated to the caller.
* Clock advancing would stop in case of an exception.
*/
void
advanceClocks(time::nanoseconds tick, size_t nTicks = 1)
{
advanceClocks(tick, tick * nTicks);
}
/** \brief Advance steady and system clocks.
*
* Clocks are advanced in increments of \p tick for \p total time.
* The last increment might be shorter than \p tick.
* After each tick, global io_service is polled to process pending I/O events.
*
* Exceptions thrown during I/O events are propagated to the caller.
* Clock advancing would stop in case of an exception.
*/
void
advanceClocks(time::nanoseconds tick, time::nanoseconds total);
protected:
explicit
ClockFixture(boost::asio::io_service& io);
private:
/** \brief Called by advanceClocks() after each clock advancement (tick).
*/
virtual void
pollAfterClockTick();
protected:
shared_ptr<time::UnitTestSteadyClock> m_steadyClock;
shared_ptr<time::UnitTestSystemClock> m_systemClock;
private:
boost::asio::io_service& m_io;
};
} // namespace tests
} // namespace nfd
#endif // NFD_TESTS_CLOCK_FIXTURE_HPP
+3 -20
View File
@@ -23,7 +23,7 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "rib-io-fixture.hpp"
#include "tests/daemon/rib-io-fixture.hpp"
#include "daemon/global.hpp"
#include <boost/exception/diagnostic_information.hpp>
@@ -122,26 +122,9 @@ RibIoFixture::poll()
}
void
RibIoTimeFixture::advanceClocks(time::nanoseconds tick, time::nanoseconds total)
RibIoTimeFixture::pollAfterClockTick()
{
BOOST_ASSERT(tick > time::nanoseconds::zero());
BOOST_ASSERT(total >= time::nanoseconds::zero());
time::nanoseconds remaining = total;
while (remaining > time::nanoseconds::zero()) {
if (remaining >= tick) {
steadyClock->advance(tick);
systemClock->advance(tick);
remaining -= tick;
}
else {
steadyClock->advance(remaining);
systemClock->advance(remaining);
remaining = time::nanoseconds::zero();
}
poll();
}
poll();
}
} // namespace tests
+6 -19
View File
@@ -35,7 +35,7 @@
namespace nfd {
namespace tests {
/** \brief a base test fixture that provides both main and RIB io_service
/** \brief A base test fixture that provides both main and RIB io_service.
*/
class RibIoFixture : public virtual BaseFixture
{
@@ -45,13 +45,13 @@ protected:
~RibIoFixture();
protected:
/** \brief Poll main and RIB thread io_service to process all pending I/O events
/** \brief Poll main and RIB thread io_service to process all pending I/O events.
*
* This call will execute all pending I/O events, including events that are posted
* inside the processing event, i.e., main and RIB thread io_service will be polled
* repeatedly until all pending events are processed.
*
* \note Must be called from the main thread
* \warning Must be called from the main thread
*/
void
poll();
@@ -77,26 +77,13 @@ private:
std::condition_variable m_ribPollEndCv;
};
/** \brief RibIoFixture that also overrides steady clock and system clock
/** \brief RibIoFixture that also overrides steady clock and system clock.
*/
class RibIoTimeFixture : public RibIoFixture, public UnitTestTimeFixture
{
protected:
using UnitTestTimeFixture::advanceClocks;
/** \brief advance steady and system clocks in the main and RIB threads
*
* Clocks are advanced in increments of \p tick for \p total time.
* The last increment might be shorter than \p tick.
* After each tick, the main and RIB thread io_service is polled to process pending I/O events.
*
* Exceptions thrown during I/O events are propagated to the caller.
* Clock advancing would stop in case of an exception.
*
* \note Must be called from the main thread
*/
private:
void
advanceClocks(time::nanoseconds tick, time::nanoseconds total) override;
pollAfterClockTick() override;
};
} // namespace tests
+1 -44
View File
@@ -23,7 +23,7 @@
* NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "test-common.hpp"
#include "tests/test-common.hpp"
#include "daemon/global.hpp"
#include <ndn-cxx/security/signature-sha256-with-rsa.hpp>
@@ -41,49 +41,6 @@ BaseFixture::~BaseFixture()
resetGlobalIoService();
}
UnitTestTimeFixture::UnitTestTimeFixture()
: steadyClock(make_shared<time::UnitTestSteadyClock>())
, systemClock(make_shared<time::UnitTestSystemClock>())
{
time::setCustomClocks(steadyClock, systemClock);
}
UnitTestTimeFixture::~UnitTestTimeFixture()
{
time::setCustomClocks(nullptr, nullptr);
}
void
UnitTestTimeFixture::advanceClocks(time::nanoseconds tick, size_t nTicks)
{
advanceClocks(tick, tick * nTicks);
}
void
UnitTestTimeFixture::advanceClocks(time::nanoseconds tick, time::nanoseconds total)
{
BOOST_ASSERT(tick > time::nanoseconds::zero());
BOOST_ASSERT(total >= time::nanoseconds::zero());
time::nanoseconds remaining = total;
while (remaining > time::nanoseconds::zero()) {
if (remaining >= tick) {
steadyClock->advance(tick);
systemClock->advance(tick);
remaining -= tick;
}
else {
steadyClock->advance(remaining);
systemClock->advance(remaining);
remaining = time::nanoseconds::zero();
}
if (g_io.stopped())
g_io.reset();
g_io.poll();
}
}
shared_ptr<Interest>
makeInterest(const Name& name, uint32_t nonce)
{
+6 -36
View File
@@ -28,10 +28,9 @@
#include "boost-test.hpp"
#include "core/common.hpp"
#include "tests/clock-fixture.hpp"
#include <ndn-cxx/prefix-announcement.hpp>
#include <ndn-cxx/util/time-unit-test-clock.hpp>
#ifdef HAVE_PRIVILEGE_DROP_AND_ELEVATE
#include <unistd.h>
@@ -70,42 +69,13 @@ protected:
/** \brief a base test fixture that overrides steady clock and system clock
*/
class UnitTestTimeFixture : public virtual BaseFixture
class UnitTestTimeFixture : public virtual BaseFixture, public ClockFixture
{
protected:
UnitTestTimeFixture();
virtual
~UnitTestTimeFixture();
/** \brief advance steady and system clocks
*
* Clocks are advanced in increments of \p tick for \p nTicks ticks.
* After each tick, global io_service is polled to process pending I/O events.
*
* Exceptions thrown during I/O events are propagated to the caller.
* Clock advancing would stop in case of an exception.
*/
virtual void
advanceClocks(time::nanoseconds tick, size_t nTicks = 1);
/** \brief advance steady and system clocks
*
* Clocks are advanced in increments of \p tick for \p total time.
* The last increment might be shorter than \p tick.
* After each tick, global io_service is polled to process pending I/O events.
*
* Exceptions thrown during I/O events are propagated to the caller.
* Clock advancing would stop in case of an exception.
*/
virtual void
advanceClocks(time::nanoseconds tick, time::nanoseconds total);
protected:
shared_ptr<time::UnitTestSteadyClock> steadyClock;
shared_ptr<time::UnitTestSystemClock> systemClock;
friend class LimitedIo;
UnitTestTimeFixture()
: ClockFixture(g_io)
{
}
};
/** \brief create an Interest
+13 -13
View File
@@ -26,8 +26,9 @@
#ifndef NFD_TESTS_TOOLS_MOCK_NFD_MGMT_FIXTURE_HPP
#define NFD_TESTS_TOOLS_MOCK_NFD_MGMT_FIXTURE_HPP
#include "tests/test-common.hpp"
#include "tests/clock-fixture.hpp"
#include "tests/key-chain-fixture.hpp"
#include "tests/test-common.hpp"
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
@@ -40,27 +41,23 @@ namespace tests {
using namespace nfd::tests;
using ndn::nfd::ControlParameters;
/** \brief fixture to emulate NFD management
/** \brief Fixture to emulate NFD management.
*/
class MockNfdMgmtFixture : public UnitTestTimeFixture, public KeyChainFixture
class MockNfdMgmtFixture : public ClockFixture, public KeyChainFixture
{
protected:
MockNfdMgmtFixture()
: face(g_io, m_keyChain,
: ClockFixture(m_io)
, face(m_io, m_keyChain,
{true, false, bind(&MockNfdMgmtFixture::processEventsOverride, this, _1)})
{
face.onSendInterest.connect([=] (const Interest& interest) {
g_io.post([=] {
if (processInterest != nullptr) {
processInterest(interest);
}
});
face.onSendInterest.connect([this] (const Interest& interest) {
if (processInterest) {
m_io.post([=] { processInterest(interest); });
}
});
}
virtual
~MockNfdMgmtFixture() = default;
protected: // ControlCommand
/** \brief check the Interest is a command with specified prefix
* \retval nullopt last Interest is not the expected command
@@ -206,6 +203,9 @@ private:
signData(data);
}
private:
boost::asio::io_service m_io;
protected:
ndn::util::DummyClientFace face;
std::function<void(const Interest&)> processInterest;
+7 -4
View File
@@ -120,11 +120,12 @@ public:
std::function<void()> processEventsFunc;
};
class StatusReportModulesFixture : public UnitTestTimeFixture, public KeyChainFixture
class StatusReportModulesFixture : public ClockFixture, public KeyChainFixture
{
protected:
StatusReportModulesFixture()
: face(g_io, m_keyChain)
: ClockFixture(m_io)
, face(m_io, m_keyChain)
, controller(face, m_keyChain, validator)
, res(0)
{
@@ -133,7 +134,7 @@ protected:
DummyModule&
addModule(const std::string& moduleName)
{
report.sections.push_back(make_unique<DummyModule>(moduleName, g_io));
report.sections.push_back(make_unique<DummyModule>(moduleName, m_io));
return static_cast<DummyModule&>(*report.sections.back());
}
@@ -153,6 +154,9 @@ protected:
}
}
private:
boost::asio::io_service m_io;
protected:
ndn::util::DummyClientFace face;
ValidatorNull validator;
@@ -164,7 +168,6 @@ protected:
output_test_stream statusText;
};
BOOST_AUTO_TEST_SUITE(Nfdc)
BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)