blob: 83d7a646047d43a9c7297d050c9a43061d869dfb [file] [log] [blame]
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesavento8a05c7f2019-02-28 02:26:19 -05003 * Copyright (c) 2014-2019, Regents of the University of California,
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +00004 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050026#include "mgmt/rib-manager.hpp"
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000027
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040028#include "tests/test-common.hpp"
Davide Pesavento1d12d2f2019-03-22 12:44:14 -040029#include "tests/key-chain-fixture.hpp"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040030#include "tests/daemon/global-io-fixture.hpp"
Junxiao Shidf1dc652019-08-30 19:03:19 +000031#include "tests/daemon/rib/fib-updates-common.hpp"
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040032
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000033#include <ndn-cxx/util/dummy-client-face.hpp>
34
35namespace nfd {
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000036namespace tests {
37
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050038using rib::Route;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000039
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040040class RibManagerSlAnnounceFixture : public GlobalIoTimeFixture, public KeyChainFixture
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000041{
42public:
43 using SlAnnounceResult = RibManager::SlAnnounceResult;
44
45 RibManagerSlAnnounceFixture()
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040046 : m_face(g_io, m_keyChain)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000047 , m_nfdController(m_face, m_keyChain)
48 , m_dispatcher(m_face, m_keyChain)
49 , m_fibUpdater(rib, m_nfdController)
50 , m_trustedSigner(m_keyChain.createIdentity("/trusted", ndn::RsaKeyParams()))
51 , m_untrustedSigner(m_keyChain.createIdentity("/untrusted", ndn::RsaKeyParams()))
52 {
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000053 // Face, Controller, Dispatcher are irrelevant to SlAnnounce functions but required by
54 // RibManager construction, so they are private. RibManager is a pointer to avoid code style
55 // rule 1.4 violation.
Davide Pesavento0a71dd32019-03-17 20:36:18 -040056 manager = make_unique<RibManager>(rib, m_face, m_keyChain, m_nfdController, m_dispatcher);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000057
58 loadTrustSchema();
59 }
60
61 template<typename ...T>
62 ndn::PrefixAnnouncement
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050063 makeTrustedAnn(T&&... args)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000064 {
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050065 return signPrefixAnn(makePrefixAnn(std::forward<T>(args)...), m_keyChain, m_trustedSigner);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000066 }
67
68 template<typename ...T>
69 ndn::PrefixAnnouncement
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050070 makeUntrustedAnn(T&&... args)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000071 {
Davide Pesavento8a05c7f2019-02-28 02:26:19 -050072 return signPrefixAnn(makePrefixAnn(std::forward<T>(args)...), m_keyChain, m_untrustedSigner);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000073 }
74
75 /** \brief Invoke manager->slAnnounce and wait for result.
76 */
77 SlAnnounceResult
78 slAnnounceSync(const ndn::PrefixAnnouncement& pa, uint64_t faceId, time::milliseconds maxLifetime)
79 {
80 optional<SlAnnounceResult> result;
81 manager->slAnnounce(pa, faceId, maxLifetime,
82 [&] (RibManager::SlAnnounceResult res) {
83 BOOST_CHECK(!result);
84 result = res;
85 });
86
Davide Pesaventoe1bdc082018-10-11 21:20:23 -040087 g_io.poll();
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +000088 BOOST_CHECK(result);
89 return result.value_or(SlAnnounceResult::ERROR);
90 }
91
92 /** \brief Invoke manager->slRenew and wait for result.
93 */
94 SlAnnounceResult
95 slRenewSync(const Name& name, uint64_t faceId, time::milliseconds maxLifetime)
96 {
97 optional<SlAnnounceResult> result;
98 manager->slRenew(name, faceId, maxLifetime,
99 [&] (RibManager::SlAnnounceResult res) {
100 BOOST_CHECK(!result);
101 result = res;
102 });
103
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400104 g_io.poll();
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000105 BOOST_CHECK(result);
106 return result.value_or(SlAnnounceResult::ERROR);
107 }
108
109 /** \brief Invoke manager->slFindAnn and wait for result.
110 */
111 optional<ndn::PrefixAnnouncement>
112 slFindAnnSync(const Name& name)
113 {
114 optional<optional<ndn::PrefixAnnouncement>> result;
115 manager->slFindAnn(name,
116 [&] (optional<ndn::PrefixAnnouncement> found) {
117 BOOST_CHECK(!result);
118 result = found;
119 });
120
Davide Pesaventoe1bdc082018-10-11 21:20:23 -0400121 g_io.poll();
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000122 BOOST_CHECK(result);
123 return result.value_or(nullopt);
124 }
125
126 /** \brief Lookup a route with PREFIXANN origin.
127 */
128 Route*
129 findAnnRoute(const Name& name, uint64_t faceId)
130 {
131 Route routeQuery;
132 routeQuery.faceId = faceId;
133 routeQuery.origin = ndn::nfd::ROUTE_ORIGIN_PREFIXANN;
134 return rib.find(name, routeQuery);
135 }
136
137private:
138 /** \brief Prepare a trust schema and load as localhop_security.
139 *
140 * Test case may revert this operation with ribManager->disableLocalhop().
141 */
142 void
143 loadTrustSchema()
144 {
145 ConfigSection section;
146 section.put("rule.id", "PA");
147 section.put("rule.for", "data");
148 section.put("rule.checker.type", "customized");
149 section.put("rule.checker.sig-type", "rsa-sha256");
150 section.put("rule.checker.key-locator.type", "name");
151 section.put("rule.checker.key-locator.name", "/trusted");
152 section.put("rule.checker.key-locator.relation", "is-prefix-of");
153 section.put("trust-anchor.type", "base64");
154 section.put("trust-anchor.base64-string", getIdentityCertificateBase64("/trusted"));
155 manager->enableLocalhop(section, "trust-schema.section");
156 }
157
158public:
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500159 rib::Rib rib;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000160 unique_ptr<RibManager> manager;
161
162private:
163 ndn::util::DummyClientFace m_face;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000164 ndn::nfd::Controller m_nfdController;
Davide Pesavento78ddcab2019-02-28 22:00:03 -0500165 Dispatcher m_dispatcher;
Junxiao Shidf1dc652019-08-30 19:03:19 +0000166 rib::tests::MockFibUpdater m_fibUpdater;
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000167
168 ndn::security::SigningInfo m_trustedSigner;
169 ndn::security::SigningInfo m_untrustedSigner;
170};
171
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500172BOOST_AUTO_TEST_SUITE(Mgmt)
173BOOST_AUTO_TEST_SUITE(TestRibManager)
174BOOST_FIXTURE_TEST_SUITE(SlAnnounce, RibManagerSlAnnounceFixture)
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000175
176BOOST_AUTO_TEST_CASE(AnnounceUnconfigured)
177{
178 manager->disableLocalhop();
179 auto pa = makeTrustedAnn("/fMXN7UeB", 1_h);
180 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 3275, 1_h), SlAnnounceResult::VALIDATION_FAILURE);
181
182 BOOST_CHECK(findAnnRoute("/fMXN7UeB", 3275) == nullptr);
183}
184
185BOOST_AUTO_TEST_CASE(AnnounceValidationError)
186{
187 auto pa = makeUntrustedAnn("/1nzAe0Y4", 1_h);
188 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2959, 1_h), SlAnnounceResult::VALIDATION_FAILURE);
189
190 BOOST_CHECK(findAnnRoute("/1nzAe0Y4", 2959) == nullptr);
191}
192
193BOOST_AUTO_TEST_CASE(AnnounceInsert_AnnLifetime)
194{
195 auto pa = makeTrustedAnn("/EHJYmJz9", 1_h);
196 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 1641, 2_h), SlAnnounceResult::OK);
197
198 Route* route = findAnnRoute("/EHJYmJz9", 1641);
199 BOOST_REQUIRE(route != nullptr);
200 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 1_h);
201 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 1_h);
202}
203
204BOOST_AUTO_TEST_CASE(AnnounceInsert_ArgLifetime)
205{
206 auto pa = makeTrustedAnn("/BU9Fec9E", 2_h);
207 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 1282, 1_h), SlAnnounceResult::OK);
208
209 Route* route = findAnnRoute("/BU9Fec9E", 1282);
210 BOOST_REQUIRE(route != nullptr);
211 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 2_h);
212 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 1_h);
213}
214
215BOOST_AUTO_TEST_CASE(AnnounceReplace)
216{
217 auto pa = makeTrustedAnn("/HsBFGvL3", 1_h);
218 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2813, 1_h), SlAnnounceResult::OK);
219
220 pa = makeTrustedAnn("/HsBFGvL3", 2_h);
221 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2813, 2_h), SlAnnounceResult::OK);
222
223 Route* route = findAnnRoute("/HsBFGvL3", 2813);
224 BOOST_REQUIRE(route != nullptr);
225 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 2_h);
226 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 2_h);
227}
228
229BOOST_AUTO_TEST_CASE(AnnounceExpired)
230{
231 auto pa = makeTrustedAnn("/awrVv6V7", 1_h, std::make_pair(-3_h, -1_h));
232 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 9087, 1_h), SlAnnounceResult::EXPIRED);
233
234 BOOST_CHECK(findAnnRoute("/awrVv6V7", 9087) == nullptr);
235}
236
237BOOST_AUTO_TEST_CASE(RenewNotFound)
238{
239 BOOST_CHECK_EQUAL(slRenewSync("IAYigN73", 1070, 1_h), SlAnnounceResult::NOT_FOUND);
240
241 BOOST_CHECK(findAnnRoute("/IAYigN73", 1070) == nullptr);
242}
243
244BOOST_AUTO_TEST_CASE(RenewProlong_ArgLifetime)
245{
246 auto pa = makeTrustedAnn("/P2IYFqtr", 4_h);
247 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 4506, 2_h), SlAnnounceResult::OK);
248 advanceClocks(1_h); // Route has 1_h remaining lifetime
249
Teng Lianga4e6ec32018-10-21 09:25:00 -0700250 BOOST_CHECK_EQUAL(slRenewSync("/P2IYFqtr/2321", 4506, 2_h), SlAnnounceResult::OK);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000251
252 Route* route = findAnnRoute("/P2IYFqtr", 4506);
253 BOOST_REQUIRE(route != nullptr);
254 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 3_h);
255 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 2_h); // set by slRenew
256}
257
258BOOST_AUTO_TEST_CASE(RenewProlong_AnnLifetime)
259{
260 auto pa = makeTrustedAnn("/be01Yiba", 4_h);
261 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 1589, 2_h), SlAnnounceResult::OK);
262 advanceClocks(1_h); // Route has 1_h remaining lifetime
263
Teng Lianga4e6ec32018-10-21 09:25:00 -0700264 BOOST_CHECK_EQUAL(slRenewSync("/be01Yiba/4324", 1589, 5_h), SlAnnounceResult::OK);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000265
266 Route* route = findAnnRoute("/be01Yiba", 1589);
267 BOOST_REQUIRE(route != nullptr);
268 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 3_h);
269 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 3_h); // capped by annExpires
270}
271
272BOOST_AUTO_TEST_CASE(RenewShorten)
273{
274 auto pa = makeTrustedAnn("/5XCHYCAd", 4_h);
275 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 3851, 4_h), SlAnnounceResult::OK);
276 advanceClocks(1_h); // Route has 3_h remaining lifetime
277
Teng Lianga4e6ec32018-10-21 09:25:00 -0700278 BOOST_CHECK_EQUAL(slRenewSync("/5XCHYCAd/98934", 3851, 1_h), SlAnnounceResult::OK);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000279
280 Route* route = findAnnRoute("/5XCHYCAd", 3851);
281 BOOST_REQUIRE(route != nullptr);
282 BOOST_CHECK_EQUAL(route->annExpires, time::steady_clock::now() + 3_h);
283 BOOST_CHECK_EQUAL(route->expires.value(), time::steady_clock::now() + 1_h); // set by slRenew
284}
285
286BOOST_AUTO_TEST_CASE(RenewShorten_Zero)
287{
288 auto pa = makeTrustedAnn("/cdQ7KPNw", 4_h);
289 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 8031, 4_h), SlAnnounceResult::OK);
290 advanceClocks(1_h); // Route has 3_h remaining lifetime
291
Teng Lianga4e6ec32018-10-21 09:25:00 -0700292 BOOST_CHECK_EQUAL(slRenewSync("/cdQ7KPNw/8023", 8031, 0_s), SlAnnounceResult::EXPIRED);
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000293
294 BOOST_CHECK(findAnnRoute("/cdQ7KPNw", 8031) == nullptr);
295}
296
297BOOST_AUTO_TEST_CASE(FindExisting)
298{
299 auto pa = makeTrustedAnn("/JHugsjjr", 1_h);
300 BOOST_CHECK_EQUAL(slAnnounceSync(pa, 2363, 1_h), SlAnnounceResult::OK);
301
302 auto found = slFindAnnSync("/JHugsjjr");
303 BOOST_REQUIRE(found);
304 BOOST_CHECK_EQUAL(found->getAnnouncedName(), "/JHugsjjr");
305 BOOST_CHECK(found->getData());
306
307 auto found2 = slFindAnnSync("/JHugsjjr/StvXhKR5");
308 BOOST_CHECK(found == found2);
309}
310
311BOOST_AUTO_TEST_CASE(FindNew)
312{
313 Route route;
314 route.faceId = 1367;
315 route.origin = ndn::nfd::ROUTE_ORIGIN_APP;
316 rib.insert("/dLY1pRhR", route);
317
318 auto pa = slFindAnnSync("/dLY1pRhR/3qNK9Ngn");
319 BOOST_REQUIRE(pa);
320 BOOST_CHECK_EQUAL(pa->getAnnouncedName(), "/dLY1pRhR");
321}
322
323BOOST_AUTO_TEST_CASE(FindNone)
324{
325 auto pa = slFindAnnSync("/2YNeYuV2");
326 BOOST_CHECK(!pa);
327}
328
Davide Pesavento8a05c7f2019-02-28 02:26:19 -0500329BOOST_AUTO_TEST_SUITE_END() // SlAnnounce
330BOOST_AUTO_TEST_SUITE_END() // TestRibManager
331BOOST_AUTO_TEST_SUITE_END() // Mgmt
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000332
333} // namespace tests
Junxiao Shi5ba7dfc2018-09-26 14:24:05 +0000334} // namespace nfd