blob: 2352735c0bec1d3295ac5b94c6035c2ebbdc02f2 [file] [log] [blame]
Ashlesh Gawande85998a12017-12-07 22:22:13 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2019, The University of Memphis,
4 * 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"
23#include "../test-common.hpp"
24#include "common.hpp"
25#include "nlsr.hpp"
26#include "lsa.hpp"
27
28#include <ndn-cxx/util/dummy-client-face.hpp>
29
30namespace nlsr {
31namespace test {
32
33using std::shared_ptr;
34
35template<int32_t Protocol>
36class SyncLogicFixture : public UnitTestTimeFixture
37{
38public:
39 SyncLogicFixture()
40 : face(m_ioService, m_keyChain)
41 , conf(face)
42 , confProcessor(conf, Protocol)
43 , testIsLsaNew([] (const ndn::Name& name, const Lsa::Type& lsaType,
44 const uint64_t sequenceNumber) {
45 return true;
46 })
47 , sync(face, testIsLsaNew, conf)
48 , updateNamePrefix(this->conf.getLsaPrefix().toUri() +
49 this->conf.getSiteName().toUri() +
50 "/%C1.Router/other-router/")
51 {
52 addIdentity(conf.getRouterPrefix());
53 }
54
55 void
56 receiveUpdate(const std::string& prefix, uint64_t seqNo)
57 {
58 this->advanceClocks(ndn::time::milliseconds(1), 10);
59 face.sentInterests.clear();
60
61 if (Protocol == SYNC_PROTOCOL_CHRONOSYNC) {
62 std::vector<chronosync::MissingDataInfo> updates;
63 updates.push_back({ndn::Name(prefix).appendNumber(1), 0, seqNo});
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -050064 sync.m_syncLogic.onChronoSyncUpdate(updates);
Ashlesh Gawande85998a12017-12-07 22:22:13 -060065 }
66 else {
67 std::vector<psync::MissingDataInfo> updates;
68 updates.push_back({ndn::Name(prefix), 0, seqNo});
Ashlesh Gawande6b388fc2019-09-30 10:14:41 -050069 sync.m_syncLogic.onPSyncUpdate(updates);
Ashlesh Gawande85998a12017-12-07 22:22:13 -060070 }
71
72 this->advanceClocks(ndn::time::milliseconds(1), 10);
73 }
74
75public:
76 ndn::util::DummyClientFace face;
77 ConfParameter conf;
78 DummyConfFileProcessor confProcessor;
79 SyncLogicHandler::IsLsaNew testIsLsaNew;
80 SyncLogicHandler sync;
81
82 const std::string updateNamePrefix;
83 const std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::ADJACENCY,
84 Lsa::Type::COORDINATE};
85};
86
87using mpl_::int_;
88using Protocols = boost::mpl::vector<int_<SYNC_PROTOCOL_CHRONOSYNC>,
89 int_<SYNC_PROTOCOL_PSYNC>>;
90
91BOOST_AUTO_TEST_SUITE(TestSyncLogicHandler)
92
93/* Tests that when SyncLogicHandler receives an LSA of either Name or
94 Adjacency type that appears to be newer, it will emit to its signal
95 with those LSA details.
96 */
97BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherLS, T, Protocols, SyncLogicFixture<T::value>)
98{
99 std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::ADJACENCY};
100
101 uint64_t syncSeqNo = 1;
102
103 for (const Lsa::Type& lsaType : lsaTypes) {
104 std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
105
106 // Actual testing done here -- signal function callback
107 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500108 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
109 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600110 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
111 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
112 });
113
114 this->receiveUpdate(updateName, syncSeqNo);
115 }
116}
117
118/* Tests that when SyncLogicHandler in HR mode receives an LSA of
119 either Coordinate or Name type that appears to be newer, it will
120 emit to its signal with those LSA details.
121 */
122BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherHR, T, Protocols, SyncLogicFixture<T::value>)
123{
124 this->conf.setHyperbolicState(HYPERBOLIC_STATE_ON);
125
126 uint64_t syncSeqNo = 1;
127 std::vector<Lsa::Type> lsaTypes = {Lsa::Type::NAME, Lsa::Type::COORDINATE};
128
129 for (const Lsa::Type& lsaType : lsaTypes) {
130 std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
131
132 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500133 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
134 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600135 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
136 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
137 });
138
139 this->receiveUpdate(updateName, syncSeqNo);
140 }
141}
142
143/* Tests that when SyncLogicHandler in HR-dry mode receives an LSA of
144 any type that appears to be newer, it will emit to its signal with
145 those LSA details.
146 */
147BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdateForOtherHRDry, T, Protocols, SyncLogicFixture<T::value>)
148{
149 this->conf.setHyperbolicState(HYPERBOLIC_STATE_DRY_RUN);
150
151 uint64_t syncSeqNo = 1;
152
153 for (const Lsa::Type& lsaType : this->lsaTypes) {
154 std::string updateName = this->updateNamePrefix + std::to_string(lsaType);
155
156 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500157 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
158 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600159 BOOST_CHECK_EQUAL(ndn::Name{updateName}, routerName);
160 BOOST_CHECK_EQUAL(sequenceNumber, syncSeqNo);
161 });
162
163 this->receiveUpdate(updateName, syncSeqNo);
164 }
165}
166
167/* Tests that when SyncLogicHandler receives an update for an LSA with
168 details matching this router's details, it will *not* emit to its
169 signal those LSA details.
170 */
171BOOST_FIXTURE_TEST_CASE_TEMPLATE(NoUpdateForSelf, T, Protocols, SyncLogicFixture<T::value>)
172{
173 const uint64_t sequenceNumber = 1;
174
175 for (const Lsa::Type& lsaType : this->lsaTypes) {
176 // To ensure that we get correctly-separated components, create
177 // and modify a Name to hand off.
178 ndn::Name updateName = ndn::Name{this->conf.getLsaPrefix()};
179 updateName.append(this->conf.getSiteName())
180 .append(this->conf.getRouterName())
181 .append(std::to_string(lsaType));
182
183 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500184 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
185 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600186 BOOST_FAIL("Updates for self should not be emitted!");
187 });
188
189 this->receiveUpdate(updateName.toUri(), sequenceNumber);
190 }
191}
192
193/* Tests that when SyncLogicHandler receives an update for an LSA with
194 details that do not match the expected format, it will *not* emit
195 to its signal those LSA details.
196 */
197BOOST_FIXTURE_TEST_CASE_TEMPLATE(MalformedUpdate, T, Protocols, SyncLogicFixture<T::value>)
198{
199 const uint64_t sequenceNumber = 1;
200
201 for (const Lsa::Type& lsaType : this->lsaTypes) {
202 ndn::Name updateName{this->conf.getSiteName()};
203 updateName.append(this->conf.getRouterName()).append(std::to_string(lsaType));
204
205 ndn::util::signal::ScopedConnection connection = this->sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500206 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
207 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600208 BOOST_FAIL("Malformed updates should not be emitted!");
209 });
210
211 this->receiveUpdate(updateName.toUri(), sequenceNumber);
212 }
213}
214
215/* Tests that when SyncLogicHandler receives an update for an LSA with
216 details that do not appear to be new, it will *not* emit to its
217 signal those LSA details.
218 */
219BOOST_FIXTURE_TEST_CASE_TEMPLATE(LsaNotNew, T, Protocols, SyncLogicFixture<T::value>)
220{
221 auto testLsaAlwaysFalse = [] (const ndn::Name& routerName, const Lsa::Type& lsaType,
222 const uint64_t& sequenceNumber) {
223 return false;
224 };
225
226 const uint64_t sequenceNumber = 1;
227 SyncLogicHandler sync{this->face, testLsaAlwaysFalse, this->conf};
228 ndn::util::signal::ScopedConnection connection = sync.onNewLsa->connect(
Ashlesh Gawande08bce9c2019-04-05 11:08:07 -0500229 [&] (const ndn::Name& routerName, const uint64_t& sequenceNumber,
230 const ndn::Name& originRouter) {
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600231 BOOST_FAIL("An update for an LSA with non-new sequence number should not emit!");
232 });
233
234 std::string updateName = this->updateNamePrefix + std::to_string(Lsa::Type::NAME);
235
236 this->receiveUpdate(updateName, sequenceNumber);
237}
238
239/* Tests that SyncLogicHandler successfully concatenates configured
240 variables together to form the necessary prefixes to advertise
241 through ChronoSync.
242 */
243BOOST_FIXTURE_TEST_CASE_TEMPLATE(UpdatePrefix, T, Protocols, SyncLogicFixture<T::value>)
244{
245 ndn::Name expectedPrefix = this->conf.getLsaPrefix();
246 expectedPrefix.append(this->conf.getSiteName());
247 expectedPrefix.append(this->conf.getRouterName());
248
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600249 BOOST_CHECK_EQUAL(this->sync.m_nameLsaUserPrefix,
250 ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::NAME)));
251 BOOST_CHECK_EQUAL(this->sync.m_adjLsaUserPrefix,
252 ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::ADJACENCY)));
253 BOOST_CHECK_EQUAL(this->sync.m_coorLsaUserPrefix,
254 ndn::Name(expectedPrefix).append(std::to_string(Lsa::Type::COORDINATE)));
255}
256
Ashlesh Gawande85998a12017-12-07 22:22:13 -0600257BOOST_AUTO_TEST_SUITE_END()
258
259} // namespace test
260} // namespace nlsr