sync: improved unit tests
refs: #4264
Change-Id: I981f3d8f653e4750ee6f9d77f2c89188f11d8ebb
diff --git a/tests/test-sync-logic-handler.cpp b/tests/test-sync-logic-handler.cpp
index 5ebe679..bb6a6db 100644
--- a/tests/test-sync-logic-handler.cpp
+++ b/tests/test-sync-logic-handler.cpp
@@ -19,10 +19,11 @@
* NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
**/
-#include "test-common.hpp"
-
-#include "nlsr.hpp"
#include "communication/sync-logic-handler.hpp"
+#include "test-common.hpp"
+#include "common.hpp"
+#include "nlsr.hpp"
+#include "logger.hpp"
#include <ndn-cxx/util/dummy-client-face.hpp>
@@ -37,15 +38,25 @@
SyncLogicFixture()
: face(std::make_shared<ndn::util::DummyClientFace>())
, nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
- , sync(nlsr.getLsdb().getSyncLogicHandler())
+ , testIsLsaNew([] (const ndn::Name& name, const std::string& lsaType,
+ const uint64_t sequenceNumber) {
+ return true;
+ })
, CONFIG_NETWORK("/ndn")
, CONFIG_SITE("/site")
, CONFIG_ROUTER_NAME("/%C1.Router/this-router")
+ , OTHER_ROUTER_NAME("/%C1.Router/other-router/")
{
nlsr.getConfParameter().setNetwork(CONFIG_NETWORK);
nlsr.getConfParameter().setSiteName(CONFIG_SITE);
nlsr.getConfParameter().setRouterName(CONFIG_ROUTER_NAME);
nlsr.getConfParameter().buildRouterPrefix();
+
+ conf.setNetwork(CONFIG_NETWORK);
+ conf.setSiteName(CONFIG_SITE);
+ conf.setRouterName(CONFIG_ROUTER_NAME);
+ conf.buildRouterPrefix();
+ INIT_LOGGERS("/tmp", "TRACE");
}
void
@@ -67,193 +78,207 @@
public:
std::shared_ptr<ndn::util::DummyClientFace> face;
Nlsr nlsr;
- SyncLogicHandler& sync;
+ ConfParameter conf;
+ IsLsaNew testIsLsaNew;
const std::string CONFIG_NETWORK;
const std::string CONFIG_SITE;
const std::string CONFIG_ROUTER_NAME;
+ const std::string OTHER_ROUTER_NAME;
const std::vector<std::string> lsaTypes = {NameLsa::TYPE_STRING, AdjLsa::TYPE_STRING,
CoordinateLsa::TYPE_STRING};
};
BOOST_FIXTURE_TEST_SUITE(TestSyncLogicHandler, SyncLogicFixture)
+/* Tests that when SyncLogicHandler receives an LSA of either Name or
+ Adjacency type that appears to be newer, it will emit to its signal
+ with those LSA details.
+ */
BOOST_AUTO_TEST_CASE(UpdateForOtherLS)
{
+ SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
+ sync.createSyncSocket(conf.getChronosyncPrefix());
+
std::vector<std::string> lsaTypes = {NameLsa::TYPE_STRING, AdjLsa::TYPE_STRING};
uint64_t syncSeqNo = 1;
for (const std::string& lsaType : lsaTypes) {
- std::string updateName = nlsr.getConfParameter().getLsaPrefix().toUri() +
- CONFIG_SITE + "/%C1.Router/other-router/" + lsaType;
+ std::string updateName = conf.getLsaPrefix().toUri() + CONFIG_SITE
+ + OTHER_ROUTER_NAME + lsaType;
+
+ // Actual testing done here -- signal function callback
+ ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
+ [&, this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+ BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
+ BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
+ });
receiveUpdate(updateName, syncSeqNo, sync);
-
- const auto& it = std::find_if(face->sentInterests.begin(), face->sentInterests.end(),
- [updateName] (const ndn::Interest& interest) {
- return interest.getName().getPrefix(-1) == updateName + "/";
- });
- BOOST_REQUIRE(it != face->sentInterests.end());
}
}
+/* Tests that when SyncLogicHandler in HR mode receives an LSA of
+ either Coordinate or Name type that appears to be newer, it will
+ emit to its signal with those LSA details.
+ */
BOOST_AUTO_TEST_CASE(UpdateForOtherHR)
{
- Nlsr nlsr_hr(g_ioService, g_scheduler, std::ref(*face), g_keyChain);
- SyncLogicHandler& sync_hr(nlsr_hr.getLsdb().getSyncLogicHandler());
+ conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
- nlsr_hr.getConfParameter().setNetwork(CONFIG_NETWORK);
- nlsr_hr.getConfParameter().setSiteName(CONFIG_SITE);
- nlsr_hr.getConfParameter().setRouterName(CONFIG_ROUTER_NAME);
- nlsr_hr.getConfParameter().buildRouterPrefix();
-
- nlsr_hr.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_ON);
-
- nlsr_hr.initialize();
+ SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
+ sync.createSyncSocket(conf.getChronosyncPrefix());
uint64_t syncSeqNo = 1;
-
std::vector<std::string> lsaTypes = {NameLsa::TYPE_STRING, CoordinateLsa::TYPE_STRING};
for (const std::string& lsaType : lsaTypes) {
- std::string updateName = nlsr_hr.getConfParameter().getLsaPrefix().toUri() +
- CONFIG_SITE + "/%C1.Router/other-router/" + lsaType;
+ std::string updateName = conf.getLsaPrefix().toUri() + CONFIG_SITE
+ + OTHER_ROUTER_NAME + lsaType;
- receiveUpdate(updateName, syncSeqNo, sync_hr);
+ ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
+ [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+ BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
+ BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
+ });
- const auto& it = std::find_if(face->sentInterests.begin(), face->sentInterests.end(),
- [updateName] (const ndn::Interest& interest) {
- return interest.getName().getPrefix(-1) == updateName + "/";
- });
-
- BOOST_REQUIRE(it != face->sentInterests.end());
+ receiveUpdate(updateName, syncSeqNo, sync);
}
}
+/* Tests that when SyncLogicHandler in HR-dry mode receives an LSA of
+ any type that appears to be newer, it will emit to its signal with
+ those LSA details.
+ */
BOOST_AUTO_TEST_CASE(UpdateForOtherHRDry)
{
+ conf.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
- Nlsr nlsr_hrdry(g_ioService, g_scheduler, std::ref(*face),g_keyChain);
- SyncLogicHandler& sync_hrdry(nlsr_hrdry.getLsdb().getSyncLogicHandler());
-
- nlsr_hrdry.getConfParameter().setNetwork(CONFIG_NETWORK);
- nlsr_hrdry.getConfParameter().setSiteName(CONFIG_SITE);
- nlsr_hrdry.getConfParameter().setRouterName(CONFIG_ROUTER_NAME);
- nlsr_hrdry.getConfParameter().buildRouterPrefix();
-
- nlsr_hrdry.getConfParameter().setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
-
- nlsr_hrdry.initialize();
+ SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
+ sync.createSyncSocket(conf.getChronosyncPrefix());
for (const std::string& lsaType : lsaTypes) {
-
- std::string updateName = nlsr.getConfParameter().getLsaPrefix().toUri() +
- CONFIG_SITE + "/%C1.Router/other-router/" + lsaType;
-
-
uint64_t syncSeqNo = 1;
- receiveUpdate(updateName, syncSeqNo, sync_hrdry);
+ std::string updateName = conf.getLsaPrefix().toUri() + CONFIG_SITE
+ + OTHER_ROUTER_NAME + lsaType;
- // In HR dry-state all LSA's should be published
- const auto& it = std::find_if(face->sentInterests.begin(), face->sentInterests.end(),
- [updateName] (const ndn::Interest& interest) {
- return interest.getName().getPrefix(-1) == updateName + "/";
- });
- BOOST_REQUIRE(it != face->sentInterests.end());
+ ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
+ [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+ BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
+ BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
+ });
+
+ receiveUpdate(updateName, syncSeqNo, sync);
}
}
+/* Tests that when SyncLogicHandler receives an update for an LSA with
+ details matching this router's details, it will *not* emit to its
+ signal those LSA details.
+ */
BOOST_AUTO_TEST_CASE(NoUpdateForSelf)
{
+ const uint64_t sequenceNumber = 1;
+
+ SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
+ sync.createSyncSocket(conf.getChronosyncPrefix());
+
for (const std::string& lsaType : lsaTypes) {
- std::string updateName = nlsr.getConfParameter().getLsaPrefix().toUri() +
- CONFIG_SITE + CONFIG_ROUTER_NAME + lsaType;
+ // To ensure that we get correctly-separated components, create
+ // and modify a Name to hand off.
+ ndn::Name updateName = ndn::Name{conf.getLsaPrefix()};
+ updateName.append(CONFIG_SITE).append(CONFIG_ROUTER_NAME).append(lsaType);
- receiveUpdate(updateName, 1, sync);
+ ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
+ [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+ BOOST_FAIL("Updates for self should not be emitted!");
+ });
- std::vector<ndn::Interest>& interests = face->sentInterests;
- BOOST_CHECK_EQUAL(interests.size(), 0);
+ receiveUpdate(updateName.toUri(), sequenceNumber, sync);
}
}
+/* Tests that when SyncLogicHandler receives an update for an LSA with
+ details that do not match the expected format, it will *not* emit
+ to its signal those LSA details.
+ */
BOOST_AUTO_TEST_CASE(MalformedUpdate)
{
- for (const std::string& lsaType : lsaTypes) {
- std::string updateName = CONFIG_SITE + nlsr.getConfParameter().getLsaPrefix().toUri() +
- CONFIG_ROUTER_NAME + lsaType;
+ const uint64_t sequenceNumber = 1;
- std::vector<ndn::Interest>& interests = face->sentInterests;
- BOOST_CHECK_EQUAL(interests.size(), 0);
+ SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
+ sync.createSyncSocket(conf.getChronosyncPrefix());
+
+ for (const std::string& lsaType : lsaTypes) {
+ ndn::Name updateName{CONFIG_SITE};
+ updateName.append(CONFIG_ROUTER_NAME).append(lsaType);
+
+ ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
+ [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+ BOOST_FAIL("Malformed updates should not be emitted!");
+ });
+
+ receiveUpdate(updateName.toUri(), sequenceNumber, sync);
}
}
-BOOST_AUTO_TEST_CASE(SequenceNumber)
+/* Tests that when SyncLogicHandler receives an update for an LSA with
+ details that do not appear to be new, it will *not* emit to its
+ signal those LSA details.
+ */
+BOOST_AUTO_TEST_CASE(LsaNotNew)
{
- std::string originRouter = CONFIG_NETWORK + CONFIG_SITE + "/%C1.Router/other-router/";
+ auto testLsaAlwaysFalse = [] (const ndn::Name& routerName, const std::string& lsaType,
+ const uint64_t& sequenceNumber) {
+ return false;
+ };
- Lsdb& lsdb = nlsr.getLsdb();
-
- // Install Name LSA
- NamePrefixList nameList;
- NameLsa lsa(originRouter, 999, ndn::time::system_clock::TimePoint::max(), nameList);
- lsdb.installNameLsa(lsa);
-
- // Install Adj LSA
- AdjacencyList adjList;
- AdjLsa adjLsa(originRouter, 1000, ndn::time::system_clock::TimePoint::max(),
- 3 , adjList);
- lsdb.installAdjLsa(adjLsa);
-
- std::vector<double> angles = {0.0};
-
- // Install Cor LSA
- CoordinateLsa corLsa(originRouter, 1000, ndn::time::system_clock::TimePoint::max(),
- 0, angles);
- lsdb.installCoordinateLsa(corLsa);
+ const uint64_t sequenceNumber = 1;
+ SyncLogicHandler sync{std::ref(*face), testLsaAlwaysFalse, conf};
+ sync.createSyncSocket(conf.getChronosyncPrefix());
+ ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
+ [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
+ BOOST_FAIL("An update for an LSA with non-new sequence number should not emit!");
+ });
std::string updateName = nlsr.getConfParameter().getLsaPrefix().toUri() +
CONFIG_SITE + "/%C1.Router/other-router/" + NameLsa::TYPE_STRING;
- // Lower NameLSA sequence number
- uint64_t lowerSeqNo = 998;
- receiveUpdate(updateName, lowerSeqNo, sync);
-
- std::vector<ndn::Interest>& interests = face->sentInterests;
- BOOST_REQUIRE_EQUAL(interests.size(), 0);
-
- // Same NameLSA sequence number
- uint64_t sameSeqNo = 999;
- receiveUpdate(updateName, sameSeqNo, sync);
-
- interests = face->sentInterests;
- BOOST_REQUIRE_EQUAL(interests.size(), 0);
-
- // Higher NameLSA sequence number
- uint64_t higherSeqNo = 1000;
- receiveUpdate(updateName, higherSeqNo, sync);
-
- interests = face->sentInterests;
- BOOST_REQUIRE_EQUAL(interests.size(), 1);
-
- std::vector<ndn::Interest>::iterator it = interests.begin();
- BOOST_CHECK_EQUAL(it->getName().getPrefix(-1), updateName + "/");
+ receiveUpdate(updateName, sequenceNumber, sync);
}
+/* Tests that SyncLogicHandler successfully concatenates configured
+ variables together to form the necessary prefixes to advertise
+ through ChronoSync.
+ */
BOOST_AUTO_TEST_CASE(UpdatePrefix)
{
+
+ SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
+
ndn::Name expectedPrefix = nlsr.getConfParameter().getLsaPrefix();
expectedPrefix.append(CONFIG_SITE);
expectedPrefix.append(CONFIG_ROUTER_NAME);
- nlsr.initialize();
+ sync.buildUpdatePrefix();
- BOOST_CHECK_EQUAL(sync.m_nameLsaUserPrefix, ndn::Name(expectedPrefix).append(NameLsa::TYPE_STRING));
- BOOST_CHECK_EQUAL(sync.m_adjLsaUserPrefix, ndn::Name(expectedPrefix).append(AdjLsa::TYPE_STRING));
- BOOST_CHECK_EQUAL(sync.m_coorLsaUserPrefix, ndn::Name(expectedPrefix).append(CoordinateLsa::TYPE_STRING));
+ BOOST_CHECK_EQUAL(sync.m_nameLsaUserPrefix,
+ ndn::Name(expectedPrefix).append(NameLsa::TYPE_STRING));
+ BOOST_CHECK_EQUAL(sync.m_adjLsaUserPrefix,
+ ndn::Name(expectedPrefix).append(AdjLsa::TYPE_STRING));
+ BOOST_CHECK_EQUAL(sync.m_coorLsaUserPrefix,
+ ndn::Name(expectedPrefix).append(CoordinateLsa::TYPE_STRING));
}
+/* Tests that SyncLogicHandler's socket will be created when
+ Nlsr::initialize is called, preventing use of sync before the
+ socket is created.
+
+ NB: This test is as much an Nlsr class test as a SyncLogicHandler
+ class test, but it rides the line and ends up here.
+ */
BOOST_AUTO_TEST_CASE(CreateSyncSocketOnInitialization) // Bug #2649
{
nlsr.initialize();
@@ -264,7 +289,8 @@
BOOST_REQUIRE(lsa == nullptr);
// Publish a routing update before an Adjacency LSA is built
- BOOST_CHECK_NO_THROW(sync.publishRoutingUpdate(AdjLsa::TYPE_STRING, 0));
+ BOOST_CHECK_NO_THROW(nlsr.getLsdb().getSyncLogicHandler()
+ .publishRoutingUpdate(AdjLsa::TYPE_STRING, 0));
}
BOOST_AUTO_TEST_SUITE_END()