src: Implement packet statistics collection

refs: #2955, #2956

Change-Id: I57476a63562dbd378e566ad0280c89ccc5883e3e
This commit is contained in:
Alejandro Gil Torres authored and Ashlesh Gawande committed 2017-08-17 11:59:53 -07:00
1 parent f14ec357d5
commit e0d2048d5f
11 files changed
+712 -5

No files matched your search

+13 -1
View File
@@ -19,9 +19,9 @@
*
**/
#include "hello-protocol.hpp"
#include "nlsr.hpp"
#include "lsdb.hpp"
#include "hello-protocol.hpp"
#include "utility/name-helper.hpp"
#include "logger.hpp"
@@ -47,6 +47,9 @@ HelloProtocol::expressInterest(const ndn::Name& interestName, uint32_t seconds)
this, _1),
std::bind(&HelloProtocol::processInterestTimedOut,
this, _1));
// increment SENT_HELLO_INTEREST
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_INTEREST);
}
void
@@ -85,12 +88,17 @@ HelloProtocol::processInterest(const ndn::Name& name,
{
// interest name: /<neighbor>/NLSR/INFO/<router>
const ndn::Name interestName = interest.getName();
// increment RCV_HELLO_INTEREST
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_INTEREST);
_LOG_DEBUG("Interest Received for Name: " << interestName);
if (interestName.get(-2).toUri() != INFO_COMPONENT) {
_LOG_DEBUG("INFO_COMPONENT not found or interestName: " << interestName
<< " does not match expression");
return;
}
ndn::Name neighbor;
neighbor.wireDecode(interestName.get(-1).blockFromValue());
_LOG_DEBUG("Neighbor: " << neighbor);
@@ -103,6 +111,8 @@ HelloProtocol::processInterest(const ndn::Name& name,
m_nlsr.getKeyChain().sign(*data, m_nlsr.getDefaultCertName());
_LOG_DEBUG("Sending out data for name: " << interest.getName());
m_nlsr.getNlsrFace().put(*data);
// increment SENT_HELLO_DATA
hpIncrementSignal(Statistics::PacketType::SENT_HELLO_DATA);
auto adjacent = m_nlsr.getAdjacencyList().findAdjacent(neighbor);
// If this neighbor was previously inactive, send our own hello interest, too
@@ -209,6 +219,8 @@ HelloProtocol::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
}
}
}
// increment RCV_HELLO_DATA
hpIncrementSignal(Statistics::PacketType::RCV_HELLO_DATA);
}
// Simply logs a debug message that the content could not be
+4
View File
@@ -22,8 +22,10 @@
#ifndef NLSR_HELLO_PROTOCOL_HPP
#define NLSR_HELLO_PROTOCOL_HPP
#include "statistics.hpp"
#include "test-access-control.hpp"
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/face.hpp>
#include <ndn-cxx/mgmt/nfd/control-parameters.hpp>
#include <ndn-cxx/mgmt/nfd/control-response.hpp>
@@ -93,6 +95,8 @@ public:
void
processInterest(const ndn::Name& name, const ndn::Interest& interest);
ndn::util::signal::Signal<HelloProtocol, Statistics::PacketType> hpIncrementSignal;
private:
void
processInterestTimedOut(const ndn::Interest& interest);
+42 -4
View File
@@ -29,8 +29,6 @@
#include <ndn-cxx/security/signing-helpers.hpp>
#include <ndn-cxx/util/segment-fetcher.hpp>
#include <string>
namespace nlsr {
INIT_LOGGER("Lsdb");
@@ -961,6 +959,9 @@ void
Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
steady_clock::TimePoint deadline)
{
// increment SENT_LSA_INTEREST
lsaIncrementSignal(Statistics::PacketType::SENT_LSA_INTEREST);
if (deadline == DEFAULT_LSA_RETRIEVAL_DEADLINE) {
deadline = steady_clock::now() + ndn::time::seconds(static_cast<int>(LSA_REFRESH_TIME_MAX));
}
@@ -991,11 +992,28 @@ Lsdb::expressInterest(const ndn::Name& interestName, uint32_t timeoutCount,
std::bind(&Lsdb::afterFetchLsa, this, _1, interestName),
std::bind(&Lsdb::onFetchLsaError, this, _1, _2, interestName,
timeoutCount, deadline, lsaName, seqNo));
// increment a specific SENT_LSA_INTEREST
std::string typeLSA = interestName[-2].toUri();
if (typeLSA == AdjLsa::TYPE_STRING) {
lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
}
else if (typeLSA == CoordinateLsa::TYPE_STRING) {
lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_INTEREST);
}
else if (typeLSA == NameLsa::TYPE_STRING) {
lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_INTEREST);
}
else {
_LOG_ERROR("typeLSA " + typeLSA + " not recognized; failed Statistics::PacketType conversion");
}
}
void
Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
{
// increment RCV_LSA_INTEREST
lsaIncrementSignal(Statistics::PacketType::RCV_LSA_INTEREST);
const ndn::Name& interestName(interest.getName());
_LOG_DEBUG("Interest received for LSA: " << interestName);
@@ -1014,7 +1032,6 @@ Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
std::string interestedLsType = interestName[-2].toUri();
// Passes the Interest off to the appropriate subprocessor
if (interestedLsType == NameLsa::TYPE_STRING) {
processInterestForNameLsa(interest, originRouter.append(interestedLsType), seqNo);
}
@@ -1027,6 +1044,7 @@ Lsdb::processInterest(const ndn::Name& name, const ndn::Interest& interest)
else {
_LOG_WARN("Received unrecognized LSA type: " << interestedLsType);
}
lsaIncrementSignal(Statistics::PacketType::SENT_LSA_DATA);
}
}
@@ -1056,13 +1074,16 @@ Lsdb::processInterestForNameLsa(const ndn::Interest& interest,
const ndn::Name& lsaKey,
uint64_t seqNo)
{
// increment RCV_NAME_LSA_INTEREST
lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_INTEREST);
_LOG_DEBUG("nameLsa interest " << interest << " received");
NameLsa* nameLsa = m_nlsr.getLsdb().findNameLsa(lsaKey);
if (nameLsa != 0) {
if (nameLsa->getLsSeqNo() == seqNo) {
std::string content = nameLsa->getData();
putLsaData(interest,content);
// increment SENT_NAME_LSA_DATA
lsaIncrementSignal(Statistics::PacketType::SENT_NAME_LSA_DATA);
}
else {
_LOG_TRACE("SeqNo for nameLsa does not match");
@@ -1087,12 +1108,16 @@ Lsdb::processInterestForAdjacencyLsa(const ndn::Interest& interest,
_LOG_ERROR("Received interest for an adjacency LSA when hyperbolic routing is enabled");
}
// increment RCV_ADJ_LSA_INTEREST
lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_INTEREST);
_LOG_DEBUG("AdjLsa interest " << interest << " received");
AdjLsa* adjLsa = m_nlsr.getLsdb().findAdjLsa(lsaKey);
if (adjLsa != 0) {
if (adjLsa->getLsSeqNo() == seqNo) {
std::string content = adjLsa->getData();
putLsaData(interest,content);
// increment SENT_ADJ_LSA_DATA
lsaIncrementSignal(Statistics::PacketType::SENT_ADJ_LSA_DATA);
}
else {
_LOG_TRACE("SeqNo for AdjLsa does not match");
@@ -1117,12 +1142,16 @@ Lsdb::processInterestForCoordinateLsa(const ndn::Interest& interest,
_LOG_ERROR("Received Interest for a coordinate LSA when link-state routing is enabled");
}
// increment RCV_COORD_LSA_INTEREST
lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_INTEREST);
_LOG_DEBUG("CoordinateLsa interest " << interest << " received");
CoordinateLsa* corLsa = m_nlsr.getLsdb().findCoordinateLsa(lsaKey);
if (corLsa != 0) {
if (corLsa->getLsSeqNo() == seqNo) {
std::string content = corLsa->getData();
putLsaData(interest,content);
// increment SENT_COORD_LSA_DATA
lsaIncrementSignal(Statistics::PacketType::SENT_COORD_LSA_DATA);
}
else {
_LOG_TRACE("SeqNo for CoordinateLsa does not match");
@@ -1166,6 +1195,9 @@ Lsdb::onContentValidated(const std::shared_ptr<const ndn::Data>& data)
else {
_LOG_WARN("Received unrecognized LSA Type: " << interestedLsType);
}
// increment RCV_LSA_DATA
lsaIncrementSignal(Statistics::PacketType::RCV_LSA_DATA);
}
}
@@ -1173,6 +1205,8 @@ void
Lsdb::processContentNameLsa(const ndn::Name& lsaKey,
uint64_t lsSeqNo, std::string& dataContent)
{
// increment RCV_NAME_LSA_DATA
lsaIncrementSignal(Statistics::PacketType::RCV_NAME_LSA_DATA);
if (isNameLsaNew(lsaKey, lsSeqNo)) {
NameLsa nameLsa;
if (nameLsa.initializeFromContent(dataContent)) {
@@ -1188,6 +1222,8 @@ void
Lsdb::processContentAdjacencyLsa(const ndn::Name& lsaKey,
uint64_t lsSeqNo, std::string& dataContent)
{
// increment RCV_ADJ_LSA_DATA
lsaIncrementSignal(Statistics::PacketType::RCV_ADJ_LSA_DATA);
if (isAdjLsaNew(lsaKey, lsSeqNo)) {
AdjLsa adjLsa;
if (adjLsa.initializeFromContent(dataContent)) {
@@ -1203,6 +1239,8 @@ void
Lsdb::processContentCoordinateLsa(const ndn::Name& lsaKey,
uint64_t lsSeqNo, std::string& dataContent)
{
// increment RCV_COORD_LSA_DATA
lsaIncrementSignal(Statistics::PacketType::RCV_COORD_LSA_DATA);
if (isCoordinateLsaNew(lsaKey, lsSeqNo)) {
CoordinateLsa corLsa;
if (corLsa.initializeFromContent(dataContent)) {
+10
View File
@@ -27,6 +27,14 @@
#include "sequencing-manager.hpp"
#include "test-access-control.hpp"
#include "communication/sync-logic-handler.hpp"
#include "statistics.hpp"
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/util/signal.hpp>
#include <ndn-cxx/util/time.hpp>
#include <utility>
#include <boost/cstdint.hpp>
#include <utility>
#include <boost/cstdint.hpp>
@@ -374,6 +382,8 @@ private:
public:
static const ndn::Name::Component NAME_COMPONENT;
ndn::util::signal::Signal<Lsdb, Statistics::PacketType> lsaIncrementSignal;
private:
Nlsr& m_nlsr;
ndn::Scheduler& m_scheduler;
+1
View File
@@ -81,6 +81,7 @@ Nlsr::Nlsr(boost::asio::io_service& ioService, ndn::Scheduler& scheduler, ndn::F
, m_nfdRibCommandProcessor(m_localhostDispatcher,
m_namePrefixList,
m_nlsrLsdb)
, m_statsCollector(m_nlsrLsdb, m_helloProtocol)
, m_faceMonitor(m_nlsrFace)
, m_firstHelloInterval(FIRST_HELLO_INTERVAL_DEFAULT)
{
+7
View File
@@ -38,6 +38,7 @@
#include "update/prefix-update-processor.hpp"
#include "update/nfd-rib-command-processor.hpp"
#include "utility/name-helper.hpp"
#include "stats-collector.hpp"
#include <stdexcept>
@@ -376,6 +377,11 @@ public:
canonizeNeighborUris(std::list<Adjacent>::iterator currentNeighbor,
std::function<void(std::list<Adjacent>::iterator)> then);
StatsCollector&
getStatsCollector()
{
return m_statsCollector;
}
PUBLIC_WITH_TESTS_ELSE_PRIVATE:
void
@@ -470,6 +476,7 @@ private:
ndn::Name m_defaultCertName;
update::PrefixUpdateProcessor m_prefixUpdateProcessor;
update::NfdRibCommandProcessor m_nfdRibCommandProcessor;
StatsCollector m_statsCollector;
ndn::nfd::FaceMonitor m_faceMonitor;
+101
View File
@@ -0,0 +1,101 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "statistics.hpp"
#include "nlsr.hpp"
#include "utility/name-helper.hpp"
namespace nlsr {
size_t
Statistics::get(PacketType type) const
{
std::map<PacketType,int>::const_iterator it = m_packetCounter.find(type);
if(it != m_packetCounter.end())
{
return it->second;
}
else
{
return 0;
}
}
void
Statistics::increment(PacketType type)
{
m_packetCounter[type]++;
}
void
Statistics::resetAll()
{
for (auto&& it : m_packetCounter )
{
it.second = 0;
}
}
std::ostream&
operator<<(std::ostream& os, const Statistics& stats)
{
using PacketType = Statistics::PacketType;
os << "++++++++++++++++++++++++++++++++++++++++\n"
<< "+ +\n"
<< "+ Statistics +\n"
<< "+ +\n"
<< "++++++++++++++++++++++++++++++++++++++++\n"
<< "HELLO PROTOCOL\n"
<< " Sent Hello Interests: " << stats.get(PacketType::SENT_HELLO_INTEREST) << "\n"
<< " Sent Hello Data: " << stats.get(PacketType::SENT_HELLO_DATA) << "\n"
<< "\n"
<< " Received Hello Interests: " << stats.get(PacketType::RCV_HELLO_INTEREST) << "\n"
<< " Received Hello Data: " << stats.get(PacketType::RCV_HELLO_DATA) << "\n"
<< "\n"
<< "LSDB\n"
<< " Total Sent LSA Interests: " << stats.get(PacketType::SENT_LSA_INTEREST) << "\n"
<< " Total Received LSA Interests: " << stats.get(PacketType::RCV_LSA_INTEREST) << "\n"
<< "\n"
<< " Total Sent LSA Data: " << stats.get(PacketType::SENT_LSA_DATA) << "\n"
<< " Total Received LSA Data: " << stats.get(PacketType::RCV_LSA_DATA) << "\n"
<< "\n"
<< " Sent Adjacency LSA Interests: " << stats.get(PacketType::SENT_ADJ_LSA_INTEREST) << "\n"
<< " Sent Coordinate LSA Interests: " << stats.get(PacketType::SENT_COORD_LSA_INTEREST) << "\n"
<< " Sent Name LSA Interests: " << stats.get(PacketType::SENT_NAME_LSA_INTEREST) << "\n"
<< "\n"
<< " Received Adjacency LSA Interests: " << stats.get(PacketType::RCV_ADJ_LSA_INTEREST) << "\n"
<< " Received Coordinate LSA Interests: " << stats.get(PacketType::RCV_COORD_LSA_INTEREST) << "\n"
<< " Received Name LSA Interests: " << stats.get(PacketType::RCV_NAME_LSA_INTEREST) << "\n"
<< "\n"
<< " Sent Adjacency LSA Data: " << stats.get(PacketType::SENT_ADJ_LSA_DATA) << "\n"
<< " Sent Coordinate LSA Data: " << stats.get(PacketType::SENT_COORD_LSA_DATA) << "\n"
<< " Sent Name LSA Data: " << stats.get(PacketType::SENT_NAME_LSA_DATA) << "\n"
<< "\n"
<< " Received Adjacency LSA Data: " << stats.get(PacketType::RCV_ADJ_LSA_DATA) << "\n"
<< " Received Coordinate LSA Data: " << stats.get(PacketType::RCV_COORD_LSA_DATA) << "\n"
<< " Received Name LSA Data: " << stats.get(PacketType::RCV_NAME_LSA_DATA) << "\n"
<< "++++++++++++++++++++++++++++++++++++++++\n";
return os;
}
} // namespace nlsr
+80
View File
@@ -0,0 +1,80 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_STATISTICS_HPP
#define NLSR_STATISTICS_HPP
#include <map>
namespace nlsr {
class Statistics
{
public:
enum class PacketType {
SENT_HELLO_INTEREST,
SENT_HELLO_DATA,
RCV_HELLO_INTEREST,
RCV_HELLO_DATA,
SENT_LSA_INTEREST,
SENT_ADJ_LSA_INTEREST,
SENT_COORD_LSA_INTEREST,
SENT_NAME_LSA_INTEREST,
SENT_LSA_DATA,
SENT_ADJ_LSA_DATA,
SENT_COORD_LSA_DATA,
SENT_NAME_LSA_DATA,
RCV_LSA_INTEREST,
RCV_ADJ_LSA_INTEREST,
RCV_COORD_LSA_INTEREST,
RCV_NAME_LSA_INTEREST,
RCV_LSA_DATA,
RCV_ADJ_LSA_DATA,
RCV_COORD_LSA_DATA,
RCV_NAME_LSA_DATA
};
size_t
get(PacketType) const;
void
resetAll();
void
increment(PacketType);
const std::map<PacketType,int>&
getCounter() const
{
return m_packetCounter;
}
private:
std::map<PacketType,int> m_packetCounter;
};
std::ostream&
operator<<(std::ostream&, const Statistics& stats);
} // namespace nlsr
#endif // NLSR_STATISTICS_HPP
+52
View File
@@ -0,0 +1,52 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "stats-collector.hpp"
#include "logger.hpp"
#include <fstream>
namespace nlsr {
StatsCollector::StatsCollector(Lsdb& lsdb, HelloProtocol& hp)
: m_lsdb(lsdb)
, m_hp(hp)
{
m_lsaIncrementConn =
this->m_lsdb.lsaIncrementSignal.connect(std::bind(&StatsCollector::statsIncrement,
this, _1));
m_helloIncrementConn =
this->m_hp.hpIncrementSignal.connect(std::bind(&StatsCollector::statsIncrement,
this, _1));
}
StatsCollector::~StatsCollector()
{
m_lsaIncrementConn.disconnect();
m_helloIncrementConn.disconnect();
}
void
StatsCollector::statsIncrement(Statistics::PacketType pType)
{
m_stats.increment(pType);
}
} // namespace nlsr
+72
View File
@@ -0,0 +1,72 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef NLSR_STATS_COLLECTOR_HPP
#define NLSR_STATS_COLLECTOR_HPP
#include "statistics.hpp"
#include "lsdb.hpp"
#include "hello-protocol.hpp"
#include <ndn-cxx/util/signal.hpp>
namespace nlsr {
// brief: a class designed to handle statistical signals in nlsr
class StatsCollector
{
public:
StatsCollector(Lsdb& lsdb, HelloProtocol& hp);
~StatsCollector();
Statistics&
getStatistics()
{
return m_stats;
}
private:
/*!
* \brief: increments a Statistics::PacketType
*
* \param: pType is an enum value corresponding to a Statistics::PacketType
*
* This takes in a Statistics::PacketType emitted by a signal and increments
* the value in m_stats.
*/
void
statsIncrement(Statistics::PacketType pType);
private:
Lsdb& m_lsdb;
HelloProtocol& m_hp;
Statistics m_stats;
ndn::util::signal::ScopedConnection m_lsaIncrementConn;
ndn::util::signal::ScopedConnection m_helloIncrementConn;
};
} // namespace nlsr
#endif // NLSR_STATS_COLLECTOR_HPP
+330
View File
@@ -0,0 +1,330 @@
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2017, The University of Memphis,
* Regents of the University of California,
* Arizona Board of Regents.
*
* This file is part of NLSR (Named-data Link State Routing).
* See AUTHORS.md for complete list of NLSR authors and contributors.
*
* NLSR 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.
*
* NLSR 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
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
#include "statistics.hpp"
#include "test-common.hpp"
#include "hello-protocol.hpp"
#include "lsdb.hpp"
#include "nlsr.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>
namespace nlsr {
namespace test {
class StatisticsFixture : public BaseFixture
{
public:
StatisticsFixture()
: face(std::make_shared<ndn::util::DummyClientFace>(g_ioService))
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
, lsdb(nlsr.getLsdb())
, hello(nlsr.m_helloProtocol)
, conf(nlsr.getConfParameter())
, collector(nlsr.getStatsCollector())
{
conf.setNetwork("/ndn");
conf.setSiteName("/site");
conf.setRouterName("/%C1.router/this-router");
conf.buildRouterPrefix();
nlsr.initialize();
face->processEvents(ndn::time::milliseconds(1));
face->sentInterests.clear();
}
/*!
* \brief Checks if lsa interest was received and data for interest was sent
*
* \param interestPrefix is an interest name prefix
* \param lsaType indicates whether the lsa is a name, adjacency, or coordinate
* \param seqNo sequence number that will be appended to an interest name
* \param receivedInterestType is the specific Statisitcs::PacketType interest that is received
* \param sentDataType is the Statistics::PacketType data being sent upon interest process
*
* This is a general function that can be used for all three types of lsa. Calling processInterest()
* from lsdb will cause the statsCollector to increment the incoming interest type and increment the
* outgoing data type.
*/
void
receiveInterestAndCheckSentStats(const std::string& interestPrefix,
const std::string& lsaType,
uint32_t seqNo,
Statistics::PacketType receivedInterestType,
Statistics::PacketType sentDataType)
{
size_t rcvBefore = collector.getStatistics().get(receivedInterestType);
size_t sentBefore = collector.getStatistics().get(sentDataType);
ndn::Name interestName = ndn::Name(ndn::Name(interestPrefix + lsaType).appendNumber(seqNo));
lsdb.processInterest(ndn::Name(), ndn::Interest(interestName));
face->processEvents(ndn::time::milliseconds(1));
BOOST_CHECK_EQUAL(collector.getStatistics().get(receivedInterestType), rcvBefore + 1);
BOOST_CHECK_EQUAL(collector.getStatistics().get(sentDataType), sentBefore + 1);
}
/*!
* \brief Checks if statistics update after an lsa interest is sent
*
* \param prefix is an interest prefix
* \param lsaType indicates whether the lsa is a name, adjacency, or coordinate
* \param seqNo is the sequence number
* \param statsType is a statistical PacketType
*
* The function is called to initiate an expressInterest call in lsdb and to check if the
* expected statistical packetType was incremented.
*/
void
sendInterestAndCheckStats(const std::string& prefix,
const std::string& lsaType,
uint32_t seqNo,
Statistics::PacketType statsType)
{
size_t sentBefore = collector.getStatistics().get(statsType);
lsdb.expressInterest(ndn::Name(prefix + lsaType).appendNumber(seqNo), 0,
ndn::time::steady_clock::TimePoint::min());
face->processEvents(ndn::time::milliseconds(1));
BOOST_CHECK_EQUAL(collector.getStatistics().get(statsType), sentBefore + 1);
}
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
Nlsr nlsr;
Lsdb& lsdb;
HelloProtocol& hello;
ConfParameter& conf;
StatsCollector& collector;
};
BOOST_FIXTURE_TEST_SUITE(TestStatistics, StatisticsFixture)
// A statistical PacketType is directly incremented (without signals).
BOOST_AUTO_TEST_CASE(StatsIncrement)
{
Statistics stats;
BOOST_CHECK_EQUAL(stats.get(Statistics::PacketType::SENT_HELLO_INTEREST), 0);
stats.increment(Statistics::PacketType::SENT_HELLO_INTEREST);
BOOST_CHECK_EQUAL(stats.get(Statistics::PacketType::SENT_HELLO_INTEREST), 1);
}
/*
* After a PacketType has been incremented, the resetAll() function is called, which sets all
* statistical packetType counts to 0
*/
BOOST_AUTO_TEST_CASE(StatsReset)
{
Statistics stats;
stats.increment(Statistics::PacketType::SENT_HELLO_INTEREST);
stats.resetAll();
BOOST_CHECK_EQUAL(stats.get(Statistics::PacketType::SENT_HELLO_INTEREST), 0);
}
/*
* This tests hello interests and hello data statistical collection by constructing an adjacency lsa
* and calling functions that trigger the sending and receiving hello of interests/data.
*/
BOOST_AUTO_TEST_CASE(SendHelloInterest)
{
nlsr.initialize();
face->processEvents(ndn::time::milliseconds(1));
face->sentInterests.clear();
Adjacent other("/ndn/router/other", ndn::util::FaceUri("udp4://other"), 25, Adjacent::STATUS_INACTIVE, 0, 0);
// This router's Adjacency LSA
nlsr.getAdjacencyList().insert(other);
ndn::Name name(conf.getRouterPrefix());
name.append("NLSR");
name.append("INFO");
name.append(other.getName().wireEncode());
hello.expressInterest(name, 1);
face->processEvents(ndn::time::milliseconds(1));
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::SENT_HELLO_INTEREST), 1);
ndn::Interest interest(name);
hello.processInterest(ndn::Name(), interest);
face->processEvents(ndn::time::milliseconds(1));
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_HELLO_INTEREST), 1);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::SENT_HELLO_DATA), 1);
// Receive Hello Data
ndn::Name dataName = other.getName();
dataName.append("NLSR");
dataName.append("INFO");
dataName.append(conf.getRouterPrefix().wireEncode());
std::shared_ptr<ndn::Data> data = std::make_shared<ndn::Data>(dataName);
hello.onContentValidated(data);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_HELLO_DATA), 1);
}
/*
* An interest is sent for each lsa type (name, adjacency, coordinate). The respective statistics are
* totaled and checked.
*/
BOOST_AUTO_TEST_CASE(LsdbSendLsaInterest)
{
const std::string interestPrefix("/ndn/NLSR/LSA/site/%C1.Router/router/");
uint32_t seqNo = 1;
// Adjacency LSA
sendInterestAndCheckStats(interestPrefix, AdjLsa::TYPE_STRING, seqNo, Statistics::PacketType::SENT_ADJ_LSA_INTEREST);
// Coordinate LSA
sendInterestAndCheckStats(interestPrefix, CoordinateLsa::TYPE_STRING, seqNo, Statistics::PacketType::SENT_COORD_LSA_INTEREST);
// Name LSA
sendInterestAndCheckStats(interestPrefix, NameLsa::TYPE_STRING, seqNo, Statistics::PacketType::SENT_NAME_LSA_INTEREST);
// 3 total lsa interests were sent
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::SENT_LSA_INTEREST), 3);
}
/*
* Tests the statistics collected upon processing incoming lsa interests and respective outgoing data.
* This process will trigger both an increment for received lsa interest and sent lsa data.
*
* /sa receiveInterestAndCheckSentStats
*/
BOOST_AUTO_TEST_CASE(LsdbReceiveInterestSendData)
{
std::string routerName("/ndn/site/%C1.Router/router");
ndn::time::system_clock::TimePoint MAX_TIME = ndn::time::system_clock::TimePoint::max();
uint32_t seqNo = 1;
// Adjacency LSA
Adjacent adjacency("adjacency");
adjacency.setStatus(Adjacent::STATUS_ACTIVE);
AdjacencyList adjacencies;
adjacencies.insert(adjacency);
AdjLsa adjLsa(routerName, seqNo, MAX_TIME, 1, adjacencies);
lsdb.installAdjLsa(adjLsa);
const std::string interestPrefix("/ndn/NLSR/LSA/site/%C1.Router/router/");
// Receive Adjacency LSA Interest
receiveInterestAndCheckSentStats(interestPrefix,
AdjLsa::TYPE_STRING,
seqNo,
Statistics::PacketType::RCV_ADJ_LSA_INTEREST,
Statistics::PacketType::SENT_ADJ_LSA_DATA);
// Name LSA
NamePrefixList prefixes;
prefixes.insert("/ndn/name");
NameLsa nameLsa(routerName, seqNo, MAX_TIME, prefixes);
lsdb.installNameLsa(nameLsa);
// Receive Name LSA Interest
receiveInterestAndCheckSentStats(interestPrefix,
NameLsa::TYPE_STRING,
seqNo,
Statistics::PacketType::RCV_NAME_LSA_INTEREST,
Statistics::PacketType::SENT_NAME_LSA_DATA);
// Coordinate LSA
std::vector<double> angles = {20.0, 30.0};
CoordinateLsa coordLsa(routerName, seqNo, MAX_TIME, 2.5, angles);
lsdb.installCoordinateLsa(coordLsa);
// Receive Adjacency LSA Interest
receiveInterestAndCheckSentStats(interestPrefix,
CoordinateLsa::TYPE_STRING,
seqNo,
Statistics::PacketType::RCV_COORD_LSA_INTEREST,
Statistics::PacketType::SENT_COORD_LSA_DATA);
// 3 different lsa type interests should be received
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_LSA_INTEREST), 3);
// data should have been sent 3x, once per lsa type
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::SENT_LSA_DATA), 3);
}
/*
* Data for each lsa type (name, adjacency, coordinate) is sent to the lsdb and statistics are
* checked to verify the respective statistical PacketType has been received.
*/
BOOST_AUTO_TEST_CASE(LsdbReceiveData)
{
ndn::Name routerName("/ndn/cs/%C1.Router/router1");
uint32_t seqNo = 1;
ndn::time::system_clock::TimePoint MAX_TIME = ndn::time::system_clock::TimePoint::max();
// adjacency lsa
ndn::Name adjInterest("/ndn/NLSR/LSA/cs/%C1.Router/router1/adjacency/");
adjInterest.appendNumber(seqNo);
AdjLsa aLsa(routerName, seqNo, MAX_TIME, 1, nlsr.getAdjacencyList());
lsdb.installAdjLsa(aLsa);
const ndn::ConstBufferPtr aBuffer = std::make_shared<ndn::Buffer>(aLsa.getData().c_str(),
aLsa.getData().size());
lsdb.afterFetchLsa(aBuffer, adjInterest);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_ADJ_LSA_DATA), 1);
// coordinate lsa
ndn::Name coordInterest("/ndn/NLSR/LSA/cs/%C1.Router/router1/coordinate/");
coordInterest.appendNumber(seqNo);
std::vector<double> angles = {20.0, 30.0};
CoordinateLsa cLsa(routerName, seqNo, MAX_TIME, 2.5, angles);
lsdb.installCoordinateLsa(cLsa);
const ndn::ConstBufferPtr cBuffer = std::make_shared<ndn::Buffer>(cLsa.getData().c_str(),
cLsa.getData().size());
lsdb.afterFetchLsa(cBuffer, coordInterest);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_COORD_LSA_DATA), 1);
// name lsa
ndn::Name interestName("/ndn/NLSR/LSA/cs/%C1.Router/router1/name/");
interestName.appendNumber(seqNo);
NameLsa nLsa(routerName, seqNo, MAX_TIME, nlsr.getNamePrefixList());
lsdb.installNameLsa(nLsa);
const ndn::ConstBufferPtr nBuffer = std::make_shared<ndn::Buffer>(nLsa.getData().c_str(),
nLsa.getData().size());
lsdb.afterFetchLsa(nBuffer, interestName);
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_NAME_LSA_DATA), 1);
// 3 lsa data types should be received
BOOST_CHECK_EQUAL(collector.getStatistics().get(Statistics::PacketType::RCV_LSA_DATA), 3);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace test
} // namespace nlsr