mgmt: add face/list support and general purpose data segementer
refs: #1245
Change-Id: I3769941022b7ed6e2a8d39622032e4e16909f645
diff --git a/tests/mgmt/face-status-publisher-common.hpp b/tests/mgmt/face-status-publisher-common.hpp
new file mode 100644
index 0000000..e6ff706
--- /dev/null
+++ b/tests/mgmt/face-status-publisher-common.hpp
@@ -0,0 +1,219 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Named Data Networking Project
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef NFD_TESTS_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP
+#define NFD_TESTS_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP
+
+#include "mgmt/face-status-publisher.hpp"
+#include "mgmt/app-face.hpp"
+#include "mgmt/internal-face.hpp"
+#include "fw/forwarder.hpp"
+#include "../face/dummy-face.hpp"
+
+#include "tests/test-common.hpp"
+
+#include <ndn-cpp-dev/encoding/tlv.hpp>
+
+namespace nfd {
+namespace tests {
+
+class TestCountersFace : public DummyFace
+{
+public:
+
+ TestCountersFace()
+ {
+ }
+
+ virtual
+ ~TestCountersFace()
+ {
+ }
+
+ void
+ setCounters(FaceCounter inInterest,
+ FaceCounter inData,
+ FaceCounter outInterest,
+ FaceCounter outData)
+ {
+ FaceCounters& counters = getMutableCounters();
+ counters.getInInterest() = inInterest;
+ counters.getInData() = inData;
+ counters.getOutInterest() = outInterest;
+ counters.getOutData() = outData;
+ }
+
+
+};
+
+static inline uint64_t
+readNonNegativeIntegerType(const Block& block,
+ uint32_t type)
+{
+ if (block.type() == type)
+ {
+ return readNonNegativeInteger(block);
+ }
+ std::stringstream error;
+ error << "expected type " << type << " got " << block.type();
+ throw ndn::Tlv::Error(error.str());
+}
+
+static inline uint64_t
+checkedReadNonNegativeIntegerType(Block::element_const_iterator& i,
+ Block::element_const_iterator end,
+ uint32_t type)
+{
+ if (i != end)
+ {
+ const Block& block = *i;
+ ++i;
+ return readNonNegativeIntegerType(block, type);
+ }
+ throw ndn::Tlv::Error("Unexpected end of FaceStatus");
+}
+
+class FaceStatusPublisherFixture : public BaseFixture
+{
+public:
+
+ FaceStatusPublisherFixture()
+ : m_table(m_forwarder)
+ , m_face(make_shared<InternalFace>())
+ , m_publisher(m_table, m_face, "/localhost/nfd/FaceStatusPublisherFixture")
+ , m_finished(false)
+ {
+
+ }
+
+ virtual
+ ~FaceStatusPublisherFixture()
+ {
+
+ }
+
+ void
+ add(shared_ptr<Face> face)
+ {
+ m_table.add(face);
+ }
+
+ void
+ validateFaceStatus(const Block& status, const shared_ptr<Face>& reference)
+ {
+ const FaceCounters& counters = reference->getCounters();
+
+ FaceId faceId = INVALID_FACEID;
+ std::string uri;
+ FaceCounter inInterest = 0;
+ FaceCounter inData = 0;
+ FaceCounter outInterest = 0;
+ FaceCounter outData = 0;
+
+ status.parse();
+
+ for (Block::element_const_iterator i = status.elements_begin();
+ i != status.elements_end();
+ ++i)
+ {
+ // parse a full set of FaceStatus sub-blocks
+ faceId =
+ checkedReadNonNegativeIntegerType(i,
+ status.elements_end(),
+ ndn::tlv::nfd::FaceId);
+
+ BOOST_REQUIRE_EQUAL(faceId, reference->getId());
+
+ BOOST_REQUIRE(i->type() == ndn::tlv::nfd::Uri);
+
+ uri.append(reinterpret_cast<const char*>(i->value()), i->value_size());
+ ++i;
+
+ BOOST_REQUIRE(i != status.elements_end());
+
+ BOOST_REQUIRE_EQUAL(uri, reference->getUri().toString());
+
+ inInterest =
+ checkedReadNonNegativeIntegerType(i,
+ status.elements_end(),
+ ndn::tlv::nfd::TotalIncomingInterestCounter);
+
+ BOOST_REQUIRE_EQUAL(inInterest, counters.getInInterest());
+
+ inData =
+ checkedReadNonNegativeIntegerType(i,
+ status.elements_end(),
+ ndn::tlv::nfd::TotalIncomingDataCounter);
+
+ BOOST_REQUIRE_EQUAL(inData, counters.getInData());
+
+ outInterest =
+ checkedReadNonNegativeIntegerType(i,
+ status.elements_end(),
+ ndn::tlv::nfd::TotalOutgoingInterestCounter);
+ BOOST_REQUIRE_EQUAL(outInterest, counters.getOutInterest());
+
+ outData =
+ readNonNegativeIntegerType(*i,
+ ndn::tlv::nfd::TotalOutgoingDataCounter);
+
+ BOOST_REQUIRE_EQUAL(outData, counters.getOutData());
+ }
+ }
+
+ void
+ decodeFaceStatusBlock(const Data& data)
+ {
+ Block payload = data.getContent();
+
+ m_buffer.appendByteArray(payload.value(), payload.value_size());
+
+ uint64_t segmentNo = data.getName()[-1].toSegment();
+ if (data.getFinalBlockId() != data.getName()[-1])
+ {
+ return;
+ }
+
+ // wrap the Face Statuses in a single Content TLV for easy parsing
+ m_buffer.prependVarNumber(m_buffer.size());
+ m_buffer.prependVarNumber(ndn::Tlv::Content);
+
+ ndn::Block parser(m_buffer.buf(), m_buffer.size());
+ parser.parse();
+
+ BOOST_REQUIRE_EQUAL(parser.elements_size(), m_referenceFaces.size());
+
+ std::list<shared_ptr<Face> >::const_iterator iReference = m_referenceFaces.begin();
+ for (Block::element_const_iterator i = parser.elements_begin();
+ i != parser.elements_end();
+ ++i)
+ {
+ if (i->type() != ndn::tlv::nfd::FaceStatus)
+ {
+ BOOST_FAIL("expected face status, got type #" << i->type());
+ }
+ validateFaceStatus(*i, *iReference);
+ ++iReference;
+ }
+ m_finished = true;
+ }
+
+protected:
+ Forwarder m_forwarder;
+ FaceTable m_table;
+ shared_ptr<InternalFace> m_face;
+ FaceStatusPublisher m_publisher;
+ ndn::EncodingBuffer m_buffer;
+ std::list<shared_ptr<Face> > m_referenceFaces;
+
+protected:
+ bool m_finished;
+};
+
+} // namespace tests
+} // namespace nfd
+
+#endif // NFD_TESTS_MGMT_FACE_STATUS_PUBLISHER_COMMON_HPP