blob: bb6a6db50827be86bb29ffdfc56c5e5b3398219a [file] [log] [blame]
Vince Lehman904c2412014-09-23 19:36:11 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Nick Gordonfeae5572017-01-13 12:06:26 -06003 * Copyright (c) 2014-2017, The University of Memphis,
Vince Lehmanc2e51f62015-01-20 15:03:11 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
Vince Lehman904c2412014-09-23 19:36:11 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Vince Lehman904c2412014-09-23 19:36:11 -050020 **/
21
Vince Lehman904c2412014-09-23 19:36:11 -050022#include "communication/sync-logic-handler.hpp"
Nick Gordon8f23b5d2017-08-31 17:53:07 -050023#include "test-common.hpp"
24#include "common.hpp"
25#include "nlsr.hpp"
26#include "logger.hpp"
Vince Lehman904c2412014-09-23 19:36:11 -050027
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060028#include <ndn-cxx/util/dummy-client-face.hpp>
29
Vince Lehman904c2412014-09-23 19:36:11 -050030namespace nlsr {
31namespace test {
32
dmcoomes9f936662017-03-02 10:33:09 -060033using std::shared_ptr;
Vince Lehman904c2412014-09-23 19:36:11 -050034
35class SyncLogicFixture : public BaseFixture
36{
37public:
38 SyncLogicFixture()
dmcoomes9f936662017-03-02 10:33:09 -060039 : face(std::make_shared<ndn::util::DummyClientFace>())
40 , nlsr(g_ioService, g_scheduler, std::ref(*face), g_keyChain)
Nick Gordon8f23b5d2017-08-31 17:53:07 -050041 , testIsLsaNew([] (const ndn::Name& name, const std::string& lsaType,
42 const uint64_t sequenceNumber) {
43 return true;
44 })
Vince Lehman904c2412014-09-23 19:36:11 -050045 , CONFIG_NETWORK("/ndn")
46 , CONFIG_SITE("/site")
47 , CONFIG_ROUTER_NAME("/%C1.Router/this-router")
Nick Gordon8f23b5d2017-08-31 17:53:07 -050048 , OTHER_ROUTER_NAME("/%C1.Router/other-router/")
Vince Lehman904c2412014-09-23 19:36:11 -050049 {
50 nlsr.getConfParameter().setNetwork(CONFIG_NETWORK);
51 nlsr.getConfParameter().setSiteName(CONFIG_SITE);
52 nlsr.getConfParameter().setRouterName(CONFIG_ROUTER_NAME);
53 nlsr.getConfParameter().buildRouterPrefix();
Nick Gordon8f23b5d2017-08-31 17:53:07 -050054
55 conf.setNetwork(CONFIG_NETWORK);
56 conf.setSiteName(CONFIG_SITE);
57 conf.setRouterName(CONFIG_ROUTER_NAME);
58 conf.buildRouterPrefix();
59 INIT_LOGGERS("/tmp", "TRACE");
Vince Lehman904c2412014-09-23 19:36:11 -050060 }
61
62 void
Nick Gordon5c467f02016-07-13 13:40:10 -050063 receiveUpdate(std::string prefix, uint64_t seqNo, SyncLogicHandler& p_sync)
Vince Lehman904c2412014-09-23 19:36:11 -050064 {
Ashlesh Gawande415676b2016-12-22 00:26:23 -060065 chronosync::MissingDataInfo info = {ndn::Name(prefix).appendNumber(1), 0, seqNo};
Vince Lehman904c2412014-09-23 19:36:11 -050066
Ashlesh Gawande415676b2016-12-22 00:26:23 -060067 std::vector<chronosync::MissingDataInfo> updates;
Vince Lehman904c2412014-09-23 19:36:11 -050068 updates.push_back(info);
69
70 face->processEvents(ndn::time::milliseconds(1));
Muktadir R Chowdhuryc69da0a2015-12-18 13:24:38 -060071 face->sentInterests.clear();
Vince Lehman904c2412014-09-23 19:36:11 -050072
Ashlesh Gawande7600c902017-06-21 13:28:35 -050073 p_sync.onChronoSyncUpdate(updates);
Vince Lehman904c2412014-09-23 19:36:11 -050074
75 face->processEvents(ndn::time::milliseconds(1));
76 }
77
78public:
dmcoomes9f936662017-03-02 10:33:09 -060079 std::shared_ptr<ndn::util::DummyClientFace> face;
Vince Lehman904c2412014-09-23 19:36:11 -050080 Nlsr nlsr;
Nick Gordon8f23b5d2017-08-31 17:53:07 -050081 ConfParameter conf;
82 IsLsaNew testIsLsaNew;
Vince Lehman904c2412014-09-23 19:36:11 -050083
84 const std::string CONFIG_NETWORK;
85 const std::string CONFIG_SITE;
86 const std::string CONFIG_ROUTER_NAME;
Nick Gordon8f23b5d2017-08-31 17:53:07 -050087 const std::string OTHER_ROUTER_NAME;
Ashlesh Gawande3e105a02017-05-16 17:36:56 -050088 const std::vector<std::string> lsaTypes = {NameLsa::TYPE_STRING, AdjLsa::TYPE_STRING,
89 CoordinateLsa::TYPE_STRING};
Vince Lehman904c2412014-09-23 19:36:11 -050090};
91
92BOOST_FIXTURE_TEST_SUITE(TestSyncLogicHandler, SyncLogicFixture)
93
Nick Gordon8f23b5d2017-08-31 17:53:07 -050094/* Tests that when SyncLogicHandler receives an LSA of either Name or
95 Adjacency type that appears to be newer, it will emit to its signal
96 with those LSA details.
97 */
Nick Gordon5c467f02016-07-13 13:40:10 -050098BOOST_AUTO_TEST_CASE(UpdateForOtherLS)
Vince Lehman904c2412014-09-23 19:36:11 -050099{
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500100 SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
101 sync.createSyncSocket(conf.getChronosyncPrefix());
102
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500103 std::vector<std::string> lsaTypes = {NameLsa::TYPE_STRING, AdjLsa::TYPE_STRING};
Vince Lehman904c2412014-09-23 19:36:11 -0500104
Nick Gordon5c467f02016-07-13 13:40:10 -0500105 uint64_t syncSeqNo = 1;
Vince Lehman904c2412014-09-23 19:36:11 -0500106
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500107 for (const std::string& lsaType : lsaTypes) {
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500108 std::string updateName = conf.getLsaPrefix().toUri() + CONFIG_SITE
109 + OTHER_ROUTER_NAME + lsaType;
110
111 // Actual testing done here -- signal function callback
112 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
113 [&, this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
114 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
115 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
116 });
Nick Gordone8e03ac2016-07-07 14:24:38 -0500117
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500118 receiveUpdate(updateName, syncSeqNo, sync);
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500119 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500120}
121
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500122/* Tests that when SyncLogicHandler in HR mode receives an LSA of
123 either Coordinate or Name type that appears to be newer, it will
124 emit to its signal with those LSA details.
125 */
Nick Gordon5c467f02016-07-13 13:40:10 -0500126BOOST_AUTO_TEST_CASE(UpdateForOtherHR)
127{
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500128 conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
Nick Gordon5c467f02016-07-13 13:40:10 -0500129
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500130 SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
131 sync.createSyncSocket(conf.getChronosyncPrefix());
Nick Gordon5c467f02016-07-13 13:40:10 -0500132
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500133 uint64_t syncSeqNo = 1;
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500134 std::vector<std::string> lsaTypes = {NameLsa::TYPE_STRING, CoordinateLsa::TYPE_STRING};
Nick Gordon5c467f02016-07-13 13:40:10 -0500135
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500136 for (const std::string& lsaType : lsaTypes) {
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500137 std::string updateName = conf.getLsaPrefix().toUri() + CONFIG_SITE
138 + OTHER_ROUTER_NAME + lsaType;
Nick Gordon5c467f02016-07-13 13:40:10 -0500139
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500140 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
141 [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
142 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
143 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
144 });
Nick Gordon5c467f02016-07-13 13:40:10 -0500145
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500146 receiveUpdate(updateName, syncSeqNo, sync);
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500147 }
Nick Gordon5c467f02016-07-13 13:40:10 -0500148}
149
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500150/* Tests that when SyncLogicHandler in HR-dry mode receives an LSA of
151 any type that appears to be newer, it will emit to its signal with
152 those LSA details.
153 */
Nick Gordon5c467f02016-07-13 13:40:10 -0500154BOOST_AUTO_TEST_CASE(UpdateForOtherHRDry)
155{
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500156 conf.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
Nick Gordon5c467f02016-07-13 13:40:10 -0500157
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500158 SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
159 sync.createSyncSocket(conf.getChronosyncPrefix());
Nick Gordon5c467f02016-07-13 13:40:10 -0500160
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500161 for (const std::string& lsaType : lsaTypes) {
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500162 uint64_t syncSeqNo = 1;
Nick Gordon5c467f02016-07-13 13:40:10 -0500163
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500164 std::string updateName = conf.getLsaPrefix().toUri() + CONFIG_SITE
165 + OTHER_ROUTER_NAME + lsaType;
Nick Gordon5c467f02016-07-13 13:40:10 -0500166
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500167 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
168 [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
169 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
170 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
171 });
172
173 receiveUpdate(updateName, syncSeqNo, sync);
Nick Gordone8e03ac2016-07-07 14:24:38 -0500174 }
Vince Lehman904c2412014-09-23 19:36:11 -0500175}
176
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500177/* Tests that when SyncLogicHandler receives an update for an LSA with
178 details matching this router's details, it will *not* emit to its
179 signal those LSA details.
180 */
Nick Gordon0f1bf1d2017-06-22 15:40:27 -0500181BOOST_AUTO_TEST_CASE(NoUpdateForSelf)
182{
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500183 const uint64_t sequenceNumber = 1;
184
185 SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
186 sync.createSyncSocket(conf.getChronosyncPrefix());
187
Nick Gordon0f1bf1d2017-06-22 15:40:27 -0500188 for (const std::string& lsaType : lsaTypes) {
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500189 // To ensure that we get correctly-separated components, create
190 // and modify a Name to hand off.
191 ndn::Name updateName = ndn::Name{conf.getLsaPrefix()};
192 updateName.append(CONFIG_SITE).append(CONFIG_ROUTER_NAME).append(lsaType);
Nick Gordon0f1bf1d2017-06-22 15:40:27 -0500193
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500194 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
195 [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
196 BOOST_FAIL("Updates for self should not be emitted!");
197 });
Nick Gordon0f1bf1d2017-06-22 15:40:27 -0500198
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500199 receiveUpdate(updateName.toUri(), sequenceNumber, sync);
Nick Gordon0f1bf1d2017-06-22 15:40:27 -0500200 }
201}
202
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500203/* Tests that when SyncLogicHandler receives an update for an LSA with
204 details that do not match the expected format, it will *not* emit
205 to its signal those LSA details.
206 */
Vince Lehman904c2412014-09-23 19:36:11 -0500207BOOST_AUTO_TEST_CASE(MalformedUpdate)
208{
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500209 const uint64_t sequenceNumber = 1;
Vince Lehman904c2412014-09-23 19:36:11 -0500210
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500211 SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
212 sync.createSyncSocket(conf.getChronosyncPrefix());
213
214 for (const std::string& lsaType : lsaTypes) {
215 ndn::Name updateName{CONFIG_SITE};
216 updateName.append(CONFIG_ROUTER_NAME).append(lsaType);
217
218 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
219 [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
220 BOOST_FAIL("Malformed updates should not be emitted!");
221 });
222
223 receiveUpdate(updateName.toUri(), sequenceNumber, sync);
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500224 }
Vince Lehman904c2412014-09-23 19:36:11 -0500225}
226
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500227/* Tests that when SyncLogicHandler receives an update for an LSA with
228 details that do not appear to be new, it will *not* emit to its
229 signal those LSA details.
230 */
231BOOST_AUTO_TEST_CASE(LsaNotNew)
Vince Lehman904c2412014-09-23 19:36:11 -0500232{
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500233 auto testLsaAlwaysFalse = [] (const ndn::Name& routerName, const std::string& lsaType,
234 const uint64_t& sequenceNumber) {
235 return false;
236 };
Vince Lehman904c2412014-09-23 19:36:11 -0500237
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500238 const uint64_t sequenceNumber = 1;
239 SyncLogicHandler sync{std::ref(*face), testLsaAlwaysFalse, conf};
240 sync.createSyncSocket(conf.getChronosyncPrefix());
241 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
242 [& ,this] (const ndn::Name& routerName, const uint64_t& sequenceNumber) {
243 BOOST_FAIL("An update for an LSA with non-new sequence number should not emit!");
244 });
Vince Lehman904c2412014-09-23 19:36:11 -0500245
246 std::string updateName = nlsr.getConfParameter().getLsaPrefix().toUri() +
Ashlesh Gawande3e105a02017-05-16 17:36:56 -0500247 CONFIG_SITE + "/%C1.Router/other-router/" + NameLsa::TYPE_STRING;
Vince Lehman904c2412014-09-23 19:36:11 -0500248
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500249 receiveUpdate(updateName, sequenceNumber, sync);
Vince Lehman904c2412014-09-23 19:36:11 -0500250}
251
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500252/* Tests that SyncLogicHandler successfully concatenates configured
253 variables together to form the necessary prefixes to advertise
254 through ChronoSync.
255 */
Vince Lehmanc11cc202015-01-20 11:41:33 -0600256BOOST_AUTO_TEST_CASE(UpdatePrefix)
257{
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500258
259 SyncLogicHandler sync{std::ref(*face), testIsLsaNew, conf};
260
Vince Lehmanc11cc202015-01-20 11:41:33 -0600261 ndn::Name expectedPrefix = nlsr.getConfParameter().getLsaPrefix();
262 expectedPrefix.append(CONFIG_SITE);
263 expectedPrefix.append(CONFIG_ROUTER_NAME);
264
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500265 sync.buildUpdatePrefix();
Vince Lehmanc11cc202015-01-20 11:41:33 -0600266
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500267 BOOST_CHECK_EQUAL(sync.m_nameLsaUserPrefix,
268 ndn::Name(expectedPrefix).append(NameLsa::TYPE_STRING));
269 BOOST_CHECK_EQUAL(sync.m_adjLsaUserPrefix,
270 ndn::Name(expectedPrefix).append(AdjLsa::TYPE_STRING));
271 BOOST_CHECK_EQUAL(sync.m_coorLsaUserPrefix,
272 ndn::Name(expectedPrefix).append(CoordinateLsa::TYPE_STRING));
Vince Lehmanc11cc202015-01-20 11:41:33 -0600273}
274
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500275/* Tests that SyncLogicHandler's socket will be created when
276 Nlsr::initialize is called, preventing use of sync before the
277 socket is created.
278
279 NB: This test is as much an Nlsr class test as a SyncLogicHandler
280 class test, but it rides the line and ends up here.
281 */
Vince Lehman9d097802015-03-16 17:55:59 -0500282BOOST_AUTO_TEST_CASE(CreateSyncSocketOnInitialization) // Bug #2649
283{
284 nlsr.initialize();
285
286 // Make sure an adjacency LSA has not been built yet
287 ndn::Name key = ndn::Name(nlsr.getConfParameter().getRouterPrefix()).append(AdjLsa::TYPE_STRING);
288 AdjLsa* lsa = nlsr.getLsdb().findAdjLsa(key);
289 BOOST_REQUIRE(lsa == nullptr);
290
291 // Publish a routing update before an Adjacency LSA is built
Nick Gordon8f23b5d2017-08-31 17:53:07 -0500292 BOOST_CHECK_NO_THROW(nlsr.getLsdb().getSyncLogicHandler()
293 .publishRoutingUpdate(AdjLsa::TYPE_STRING, 0));
Vince Lehman9d097802015-03-16 17:55:59 -0500294}
295
Vince Lehman904c2412014-09-23 19:36:11 -0500296BOOST_AUTO_TEST_SUITE_END()
297
298} // namespace test
299} // namespace nlsr