blob: bdd8a3ec6b40c464e3f8bea0827e97f26c520d67 [file] [log] [blame]
Ashlesh Gawande85998a12017-12-07 22:22:13 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Saurab Dulal427e0122019-11-28 11:58:02 -06003 * Copyright (c) 2014-2020, The University of Memphis,
Ashlesh Gawande85998a12017-12-07 22:22:13 -06004 * Regents of the University of California,
5 * Arizona Board of Regents.
6 *
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/>.
20 **/
21
22#include "communication/sync-logic-handler.hpp"
Saurab Dulal427e0122019-11-28 11:58:02 -060023#include "tests/test-common.hpp"
Ashlesh Gawande85998a12017-12-07 22:22:13 -060024#include "common.hpp"
25#include "nlsr.hpp"
Ashlesh Gawande85998a12017-12-07 22:22:13 -060026
27#include <ndn-cxx/util/dummy-client-face.hpp>
28
29namespace nlsr {
30namespace test {
31
32using std::shared_ptr;
33
34template<int32_t Protocol>
35class SyncLogicFixture : public UnitTestTimeFixture
36{
37public:
38 SyncLogicFixture()
39 : face(m_ioService, m_keyChain)
Saurab Dulal427e0122019-11-28 11:58:02 -060040 , conf(face, m_keyChain)
Ashlesh Gawande85998a12017-12-07 22:22:13 -060041 , confProcessor(conf, Protocol)
42 , testIsLsaNew([] (const ndn::Name& name, const Lsa::Type& lsaType,
43 const uint64_t sequenceNumber) {
44 return true;
45 })
46 , sync(face, testIsLsaNew, conf)
47 , updateNamePrefix(this->conf.getLsaPrefix().toUri() +
48 this->conf.getSiteName().toUri() +
49 "/%C1.Router/other-router/")
50 {
51 addIdentity(conf.getRouterPrefix());
52 }
53
54 void
55 receiveUpdate(const std::string& prefix, uint64_t seqNo)
56 {
57 this->advanceClocks(ndn::time::milliseconds(1), 10);
58 face.sentInterests.clear();
59
60 if (Protocol == SYNC_PROTOCOL_CHRONOSYNC) {
61 std::vector<chronosync::MissingDataInfo> updates;
62 updates.push_back({ndn::Name(prefix).appendNumber(1), 0, seqNo});
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -050063 sync.m_syncLogic.onChronoSyncUpdate(updates);
Ashlesh Gawande85998a12017-12-07 22:22:13 -060064 }
65 else {
66 std::vector<psync::MissingDataInfo> updates;
67 updates.push_back({ndn::Name(prefix), 0, seqNo});
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -050068 sync.m_syncLogic.onPSyncUpdate(updates);
Ashlesh Gawande85998a12017-12-07 22:22:13 -060069 }
70
71 this->advanceClocks(ndn::time::milliseconds(1), 10);
72 }
73
74public:
75 ndn::util::DummyClientFace face;
76 ConfParameter conf;
77 DummyConfFileProcessor confProcessor;
78 SyncLogicHandler::IsLsaNew testIsLsaNew;
79 SyncLogicHandler sync;
80
81 const std::string updateNamePrefix;
82 const std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::ADJACENCY,
83 Lsa::Type::COORDINATE};
84};
85
86using mpl_::int_;
87using Protocols = boost::mpl::vector<int_<SYNC_PROTOCOL_CHRONOSYNC>,
88 int_<SYNC_PROTOCOL_PSYNC>>;
89
90BOOST_AUTO_TEST_SUITE(TestSyncLogicHandler)
91
92/* Tests that when SyncLogicHandler receives an LSA of either Name or
93 Adjacency type that appears to be newer, it will emit to its signal
94 with those LSA details.
95 */
96BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherLS, T, Protocols, SyncLogicFixture<T::value>)
97{
98 std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::ADJACENCY};
99
100 uint64_t syncSeqNo = 1;
101
102 for (const Lsa::Type& lsaType : lsaTypes) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800103 std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(lsaType);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600104
105 // Actual testing done here -- signal function callback
106 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500107 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
108 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600109 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
110 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
111 });
112
113 this->receiveUpdate(updateName, syncSeqNo);
114 }
115}
116
117/* Tests that when SyncLogicHandler in HR mode receives an LSA of
118 either Coordinate or Name type that appears to be newer, it will
119 emit to its signal with those LSA details.
120 */
121BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherHR, T, Protocols, SyncLogicFixture<T::value>)
122{
123 this->conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
124
125 uint64_t syncSeqNo = 1;
126 std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::COORDINATE};
127
128 for (const Lsa::Type& lsaType : lsaTypes) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800129 std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(lsaType);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600130
131 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500132 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
133 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600134 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
135 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
136 });
137
138 this->receiveUpdate(updateName, syncSeqNo);
139 }
140}
141
142/* Tests that when SyncLogicHandler in HR-dry mode receives an LSA of
143 any type that appears to be newer, it will emit to its signal with
144 those LSA details.
145 */
146BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherHRDry, T, Protocols, SyncLogicFixture<T::value>)
147{
148 this->conf.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
149
150 uint64_t syncSeqNo = 1;
151
152 for (const Lsa::Type& lsaType : this->lsaTypes) {
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800153 std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(lsaType);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600154
155 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500156 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
157 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600158 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
159 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
160 });
161
162 this->receiveUpdate(updateName, syncSeqNo);
163 }
164}
165
166/* Tests that when SyncLogicHandler receives an update for an LSA with
167 details matching this router's details, it will *not* emit to its
168 signal those LSA details.
169 */
170BOOST_FIXTURE_TEST_CASE_TEMPLATE(NoUpdateForSelf, T, Protocols, SyncLogicFixture<T::value>)
171{
172 const uint64_t sequenceNumber = 1;
173
174 for (const Lsa::Type& lsaType : this->lsaTypes) {
175 // To ensure that we get correctly-separated components, create
176 // and modify a Name to hand off.
177 ndn::Name updateName = ndn::Name{this->conf.getLsaPrefix()};
178 updateName.append(this->conf.getSiteName())
179 .append(this->conf.getRouterName())
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800180 .append(boost::lexical_cast<std::string>(lsaType));
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600181
182 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500183 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
184 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600185 BOOST_FAIL("Updates for self should not be emitted!");
186 });
187
188 this->receiveUpdate(updateName.toUri(), sequenceNumber);
189 }
190}
191
192/* Tests that when SyncLogicHandler receives an update for an LSA with
193 details that do not match the expected format, it will *not* emit
194 to its signal those LSA details.
195 */
196BOOST_FIXTURE_TEST_CASE_TEMPLATE(MalformedUpdate, T, Protocols, SyncLogicFixture<T::value>)
197{
198 const uint64_t sequenceNumber = 1;
199
200 for (const Lsa::Type& lsaType : this->lsaTypes) {
201 ndn::Name updateName{this->conf.getSiteName()};
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800202 updateName.append(this->conf.getRouterName()).append(boost::lexical_cast<std::string>(lsaType));
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600203
204 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500205 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
206 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600207 BOOST_FAIL("Malformed updates should not be emitted!");
208 });
209
210 this->receiveUpdate(updateName.toUri(), sequenceNumber);
211 }
212}
213
214/* Tests that when SyncLogicHandler receives an update for an LSA with
215 details that do not appear to be new, it will *not* emit to its
216 signal those LSA details.
217 */
218BOOST_FIXTURE_TEST_CASE_TEMPLATE(LsaNotNew, T, Protocols, SyncLogicFixture<T::value>)
219{
220 auto testLsaAlwaysFalse = [] (const ndn::Name& routerName, const Lsa::Type& lsaType,
221 const uint64_t& sequenceNumber) {
222 return false;
223 };
224
225 const uint64_t sequenceNumber = 1;
226 SyncLogicHandler sync{this->face, testLsaAlwaysFalse, this->conf};
227 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500228 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
229 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600230 BOOST_FAIL("An update for an LSA with non-new sequence number should not emit!");
231 });
232
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800233 std::string updateName = this->updateNamePrefix + boost::lexical_cast<std::string>(Lsa::Type::NAME);
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600234
235 this->receiveUpdate(updateName, sequenceNumber);
236}
237
238/* Tests that SyncLogicHandler successfully concatenates configured
239 variables together to form the necessary prefixes to advertise
240 through ChronoSync.
241 */
242BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdatePrefix, T, Protocols, SyncLogicFixture<T::value>)
243{
244 ndn::Name expectedPrefix = this->conf.getLsaPrefix();
245 expectedPrefix.append(this->conf.getSiteName());
246 expectedPrefix.append(this->conf.getRouterName());
247
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600248 BOOST_CHECK_EQUAL(this->sync.m_nameLsaUserPrefix,
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800249 ndn::Name(expectedPrefix).append(boost::lexical_cast<std::string>(Lsa::Type::NAME)));
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600250 BOOST_CHECK_EQUAL(this->sync.m_adjLsaUserPrefix,
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800251 ndn::Name(expectedPrefix).append(boost::lexical_cast<std::string>(Lsa::Type::ADJACENCY)));
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600252 BOOST_CHECK_EQUAL(this->sync.m_coorLsaUserPrefix,
Ashlesh Gawande0db4d4d2020-02-05 20:30:02 -0800253 ndn::Name(expectedPrefix).append(boost::lexical_cast<std::string>(Lsa::Type::COORDINATE)));
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600254}
255
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600256BOOST_AUTO_TEST_SUITE_END()
257
258} // namespace test
259} // namespace nlsr