util: DummyClientFace can override processEvents
refs #3769
Change-Id: Idf8b674ed238f296c7c4293b19a6f769cbd7e332
diff --git a/src/face.cpp b/src/face.cpp
index bbb9f08..d20f57c 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -439,7 +439,7 @@
}
void
-Face::processEvents(const time::milliseconds& timeout, bool keepThread)
+Face::doProcessEvents(const time::milliseconds& timeout, bool keepThread)
{
if (m_ioService.stopped()) {
m_ioService.reset(); // ensure that run()/poll() will do some work
diff --git a/src/face.hpp b/src/face.hpp
index 27af415..6c6c957 100644
--- a/src/face.hpp
+++ b/src/face.hpp
@@ -676,7 +676,10 @@
*/
void
processEvents(const time::milliseconds& timeout = time::milliseconds::zero(),
- bool keepThread = false);
+ bool keepThread = false)
+ {
+ this->doProcessEvents(timeout, keepThread);
+ }
/**
* @brief Shutdown face operations
@@ -705,6 +708,10 @@
shared_ptr<Transport>
getTransport();
+protected:
+ virtual void
+ doProcessEvents(const time::milliseconds& timeout, bool keepThread);
+
private:
/**
* @throw ConfigFile::Error on parse error and unsupported protocols
diff --git a/src/util/dummy-client-face.cpp b/src/util/dummy-client-face.cpp
index a1c6408..43efff9 100644
--- a/src/util/dummy-client-face.cpp
+++ b/src/util/dummy-client-face.cpp
@@ -20,6 +20,7 @@
*/
#include "dummy-client-face.hpp"
+#include "../lp/packet.hpp"
#include "../lp/tags.hpp"
#include "../mgmt/nfd/controller.hpp"
#include "../mgmt/nfd/control-response.hpp"
@@ -30,8 +31,6 @@
namespace ndn {
namespace util {
-const DummyClientFace::Options DummyClientFace::DEFAULT_OPTIONS{true, false};
-
class DummyClientFace::Transport : public ndn::Transport
{
public:
@@ -163,6 +162,8 @@
if (options.enableRegistrationReply)
this->enableRegistrationReply();
+
+ m_processEventsOverride = options.processEventsOverride;
}
void
@@ -250,5 +251,16 @@
static_pointer_cast<Transport>(getTransport())->receive(lpPacket.wireEncode());
}
+void
+DummyClientFace::doProcessEvents(const time::milliseconds& timeout, bool keepThread)
+{
+ if (m_processEventsOverride != nullptr) {
+ m_processEventsOverride(timeout);
+ }
+ else {
+ this->Face::doProcessEvents(timeout, keepThread);
+ }
+}
+
} // namespace util
} // namespace ndn
diff --git a/src/util/dummy-client-face.hpp b/src/util/dummy-client-face.hpp
index ae32e14..7d661a7 100644
--- a/src/util/dummy-client-face.hpp
+++ b/src/util/dummy-client-face.hpp
@@ -24,7 +24,7 @@
#include "../face.hpp"
#include "signal.hpp"
-#include "../lp/packet.hpp"
+#include "../security/key-chain.hpp"
namespace ndn {
namespace util {
@@ -36,8 +36,28 @@
public:
/** \brief options for DummyClientFace
*/
- struct Options
+ class Options
{
+ public:
+ Options(bool enablePacketLogging, bool enableRegistrationReply,
+ const std::function<void(time::milliseconds)>& processEventsOverride)
+ : enablePacketLogging(enablePacketLogging)
+ , enableRegistrationReply(enableRegistrationReply)
+ , processEventsOverride(processEventsOverride)
+ {
+ }
+
+ Options(bool enablePacketLogging, bool enableRegistrationReply)
+ : Options(enablePacketLogging, enableRegistrationReply, nullptr)
+ {
+ }
+
+ Options()
+ : Options(true, false)
+ {
+ }
+
+ public:
/** \brief if true, packets sent out of DummyClientFace will be appended to a container
*/
bool enablePacketLogging;
@@ -46,29 +66,31 @@
* replied with a successful response
*/
bool enableRegistrationReply;
+
+ /** \brief if not empty, face.processEvents() will be overridden by this function
+ */
+ std::function<void(time::milliseconds)> processEventsOverride;
};
- /**
- * @brief Create a dummy face with internal IO service
+ /** \brief Create a dummy face with internal IO service
*/
- DummyClientFace(const Options& options = DummyClientFace::DEFAULT_OPTIONS);
+ explicit
+ DummyClientFace(const Options& options = Options());
- /**
- * @brief Create a dummy face with internal IO service and the specified KeyChain
+ /** \brief Create a dummy face with internal IO service and the specified KeyChain
*/
- DummyClientFace(KeyChain& keyChain, const Options& options = DummyClientFace::DEFAULT_OPTIONS);
+ explicit
+ DummyClientFace(KeyChain& keyChain, const Options& options = Options());
- /**
- * @brief Create a dummy face with the provided IO service
+ /** \brief Create a dummy face with the provided IO service
*/
- DummyClientFace(boost::asio::io_service& ioService,
- const Options& options = DummyClientFace::DEFAULT_OPTIONS);
+ explicit
+ DummyClientFace(boost::asio::io_service& ioService, const Options& options = Options());
- /**
- * @brief Create a dummy face with the provided IO service and the specified KeyChain
+ /** \brief Create a dummy face with the provided IO service and the specified KeyChain
*/
DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain,
- const Options& options = DummyClientFace::DEFAULT_OPTIONS);
+ const Options& options = Options());
/** \brief cause the Face to receive a packet
* \tparam Packet either Interest or Data
@@ -77,27 +99,22 @@
void
receive(const Packet& packet);
-private: // constructors
+private:
class Transport;
void
construct(const Options& options);
-private:
void
enablePacketLogging();
void
enableRegistrationReply();
-public:
- /** \brief default options
- *
- * enablePacketLogging=true
- * enableRegistrationReply=false
- */
- static const Options DEFAULT_OPTIONS;
+ virtual void
+ doProcessEvents(const time::milliseconds& timeout, bool keepThread) override;
+public:
/** \brief Interests sent out of this DummyClientFace
*
* Sent Interests are appended to this container if options.enablePacketLogger is true.
@@ -114,9 +131,9 @@
*/
std::vector<Data> sentData;
- /** \brief NACKs sent out of this DummyClientFace
+ /** \brief Nacks sent out of this DummyClientFace
*
- * Sent NACKs are appended to this container if options.enablePacketLogger is true.
+ * Sent Nacks are appended to this container if options.enablePacketLogger is true.
* User of this class is responsible for cleaning up the container, if necessary.
* After .put, .processEvents must be called before the NACK would show up here.
*/
@@ -134,7 +151,7 @@
*/
Signal<DummyClientFace, Data> onSendData;
- /** \brief emits whenever a NACK is sent
+ /** \brief emits whenever a Nack is sent
*
* After .put, .processEvents must be called before this signal would be emitted.
*/
@@ -143,6 +160,7 @@
private:
std::unique_ptr<KeyChain> m_internalKeyChain;
KeyChain& m_keyChain;
+ std::function<void(time::milliseconds)> m_processEventsOverride;
};
template<>
diff --git a/tests/unit-tests/util/dummy-client-face.t.cpp b/tests/unit-tests/util/dummy-client-face.t.cpp
new file mode 100644
index 0000000..2e7368d
--- /dev/null
+++ b/tests/unit-tests/util/dummy-client-face.t.cpp
@@ -0,0 +1,51 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2016 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "util/dummy-client-face.hpp"
+
+#include "boost-test.hpp"
+
+namespace ndn {
+namespace util {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(Util)
+BOOST_AUTO_TEST_SUITE(TestDummyClientFace)
+
+BOOST_AUTO_TEST_CASE(ProcessEventsOverride)
+{
+ bool isOverrideInvoked = false;
+ auto override = [&] (time::milliseconds timeout) {
+ isOverrideInvoked = true;
+ BOOST_CHECK_EQUAL(timeout, time::milliseconds(200));
+ };
+
+ DummyClientFace face({false, false, override});
+ face.processEvents(time::milliseconds(200));
+ BOOST_CHECK(isOverrideInvoked);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestDummyClientFace
+BOOST_AUTO_TEST_SUITE_END() // Util
+
+} // namespace tests
+} // namespace util
+} // namespace ndn