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
diff --git a/tests/clock-fixture.cpp b/tests/clock-fixture.cpp
new file mode 100644
index 0000000..de55cf3
--- /dev/null
+++ b/tests/clock-fixture.cpp
@@ -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
diff --git a/tests/clock-fixture.hpp b/tests/clock-fixture.hpp
new file mode 100644
index 0000000..5c69334
--- /dev/null
+++ b/tests/clock-fixture.hpp
@@ -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
diff --git a/tests/daemon/rib-io-fixture.cpp b/tests/daemon/rib-io-fixture.cpp
index 251d6e9..98563a9 100644
--- a/tests/daemon/rib-io-fixture.cpp
+++ b/tests/daemon/rib-io-fixture.cpp
@@ -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 @@
}
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
diff --git a/tests/daemon/rib-io-fixture.hpp b/tests/daemon/rib-io-fixture.hpp
index 99d4387..67b803c 100644
--- a/tests/daemon/rib-io-fixture.hpp
+++ b/tests/daemon/rib-io-fixture.hpp
@@ -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 @@
~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 @@
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
diff --git a/tests/test-common.cpp b/tests/test-common.cpp
index 59060d6..236007e 100644
--- a/tests/test-common.cpp
+++ b/tests/test-common.cpp
@@ -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 @@
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)
{
diff --git a/tests/test-common.hpp b/tests/test-common.hpp
index 178502a..775c032 100644
--- a/tests/test-common.hpp
+++ b/tests/test-common.hpp
@@ -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 @@
/** \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
diff --git a/tests/tools/mock-nfd-mgmt-fixture.hpp b/tests/tools/mock-nfd-mgmt-fixture.hpp
index 9e8bd53..1e1d592 100644
--- a/tests/tools/mock-nfd-mgmt-fixture.hpp
+++ b/tests/tools/mock-nfd-mgmt-fixture.hpp
@@ -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 @@
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 @@
signData(data);
}
+private:
+ boost::asio::io_service m_io;
+
protected:
ndn::util::DummyClientFace face;
std::function<void(const Interest&)> processInterest;
diff --git a/tests/tools/nfdc/status-report.t.cpp b/tests/tools/nfdc/status-report.t.cpp
index 6b1cd20..7c8e32c 100644
--- a/tests/tools/nfdc/status-report.t.cpp
+++ b/tests/tools/nfdc/status-report.t.cpp
@@ -120,11 +120,12 @@
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 @@
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 @@
}
}
+private:
+ boost::asio::io_service m_io;
+
protected:
ndn::util::DummyClientFace face;
ValidatorNull validator;
@@ -164,7 +168,6 @@
output_test_stream statusText;
};
-
BOOST_AUTO_TEST_SUITE(Nfdc)
BOOST_FIXTURE_TEST_SUITE(TestStatusReport, StatusReportModulesFixture)