blob: 51a8040a8c98cbb16e56892dc9d9eece6bad5016 [file] [log] [blame]
Nick Gordon89c4cca2016-11-02 15:42:32 +00001 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -07002/**
Davide Pesavento97210d52016-10-14 15:45:48 +02003 * Copyright (c) 2014-2016, Regents of the University of California,
Alexander Afanasyev7c10b3b2015-01-20 12:24:27 -08004 * 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.
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070010 *
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/>.
Vince12e49462014-06-09 13:29:32 -050024 */
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070025
26#include "rib/rib.hpp"
27
28#include "tests/test-common.hpp"
29
Davide Pesavento97210d52016-10-14 15:45:48 +020030#include <ndn-cxx/encoding/tlv-nfd.hpp>
31
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070032namespace nfd {
33namespace rib {
34namespace tests {
35
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -080036BOOST_FIXTURE_TEST_SUITE(TestRib, nfd::tests::BaseFixture)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070037
Vince Lehman4387e782014-06-19 16:57:45 -050038BOOST_AUTO_TEST_CASE(Parent)
Vince12e49462014-06-09 13:29:32 -050039{
40 rib::Rib rib;
41
Vince Lehman218be0a2015-01-15 17:25:20 -060042 Route root;
Vince12e49462014-06-09 13:29:32 -050043 Name name1("/");
44 root.faceId = 1;
45 root.origin = 20;
46 rib.insert(name1, root);
47
Vince Lehman218be0a2015-01-15 17:25:20 -060048 Route route1;
Vince12e49462014-06-09 13:29:32 -050049 Name name2("/hello");
Vince Lehman218be0a2015-01-15 17:25:20 -060050 route1.faceId = 2;
51 route1.origin = 20;
52 rib.insert(name2, route1);
Vince12e49462014-06-09 13:29:32 -050053
Vince Lehman218be0a2015-01-15 17:25:20 -060054 Route route2;
Vince12e49462014-06-09 13:29:32 -050055 Name name3("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -060056 route2.faceId = 3;
57 route2.origin = 20;
58 rib.insert(name3, route2);
Vince12e49462014-06-09 13:29:32 -050059
60 shared_ptr<rib::RibEntry> ribEntry = rib.findParent(name3);
61 BOOST_REQUIRE(static_cast<bool>(ribEntry));
Vince Lehman218be0a2015-01-15 17:25:20 -060062 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 2);
Vince12e49462014-06-09 13:29:32 -050063
64 ribEntry = rib.findParent(name2);
65 BOOST_REQUIRE(static_cast<bool>(ribEntry));
Vince Lehman218be0a2015-01-15 17:25:20 -060066 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -050067
Vince Lehman218be0a2015-01-15 17:25:20 -060068 Route route3;
Vince12e49462014-06-09 13:29:32 -050069 Name name4("/hello/test/foo/bar");
Vince Lehman218be0a2015-01-15 17:25:20 -060070 route2.faceId = 3;
71 route2.origin = 20;
72 rib.insert(name4, route3);
Vince12e49462014-06-09 13:29:32 -050073
74 ribEntry = rib.findParent(name4);
75 BOOST_CHECK(ribEntry != shared_ptr<rib::RibEntry>());
Vince Lehman218be0a2015-01-15 17:25:20 -060076 BOOST_CHECK(ribEntry->getRoutes().front().faceId == 2);
Vince12e49462014-06-09 13:29:32 -050077}
78
Vince Lehman4387e782014-06-19 16:57:45 -050079BOOST_AUTO_TEST_CASE(Children)
Vince12e49462014-06-09 13:29:32 -050080{
81 rib::Rib rib;
82
Vince Lehman218be0a2015-01-15 17:25:20 -060083 Route route1;
Vince12e49462014-06-09 13:29:32 -050084 Name name1("/");
Vince Lehman218be0a2015-01-15 17:25:20 -060085 route1.faceId = 1;
86 route1.origin = 20;
87 rib.insert(name1, route1);
Vince12e49462014-06-09 13:29:32 -050088
Vince Lehman218be0a2015-01-15 17:25:20 -060089 Route route2;
Vince12e49462014-06-09 13:29:32 -050090 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -060091 route2.faceId = 2;
92 route2.origin = 20;
93 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -050094
Vince Lehman218be0a2015-01-15 17:25:20 -060095 Route route3;
Vince12e49462014-06-09 13:29:32 -050096 Name name3("/hello/test/foo/bar");
Vince Lehman218be0a2015-01-15 17:25:20 -060097 route3.faceId = 3;
98 route3.origin = 20;
99 rib.insert(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500100
101 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 2);
102 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
103 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
104
Vince Lehman218be0a2015-01-15 17:25:20 -0600105 Route entry4;
Vince12e49462014-06-09 13:29:32 -0500106 Name name4("/hello");
107 entry4.faceId = 4;
108 entry4.origin = 20;
109 rib.insert(name4, entry4);
110
111 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 1);
112 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
113 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
114 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getChildren().size(), 2);
115
116 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().front()->getName(), "/hello");
117 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getParent()->getName(), "/");
118
119 BOOST_REQUIRE(static_cast<bool>((rib.find(name2)->second)->getParent()));
120 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getParent()->getName(), name4);
121 BOOST_REQUIRE(static_cast<bool>((rib.find(name3)->second)->getParent()));
122 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getParent()->getName(), name4);
123}
124
Vince Lehman4387e782014-06-19 16:57:45 -0500125BOOST_AUTO_TEST_CASE(EraseFace)
Vince12e49462014-06-09 13:29:32 -0500126{
127 rib::Rib rib;
128
Vince Lehman218be0a2015-01-15 17:25:20 -0600129 Route route1;
Vince12e49462014-06-09 13:29:32 -0500130 Name name1("/");
Vince Lehman218be0a2015-01-15 17:25:20 -0600131 route1.faceId = 1;
132 route1.origin = 20;
133 rib.insert(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500134
Vince Lehman218be0a2015-01-15 17:25:20 -0600135 Route route2;
Vince12e49462014-06-09 13:29:32 -0500136 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600137 route2.faceId = 2;
138 route2.origin = 20;
139 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500140
Vince Lehman218be0a2015-01-15 17:25:20 -0600141 Route route3;
Vince12e49462014-06-09 13:29:32 -0500142 Name name3("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600143 route3.faceId = 1;
144 route3.origin = 20;
145 rib.insert(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500146
Vince Lehman218be0a2015-01-15 17:25:20 -0600147 Route entry4;
Vince12e49462014-06-09 13:29:32 -0500148 Name name4("/not/inserted");
149 entry4.faceId = 1;
150 entry4.origin = 20;
151
152 rib.erase(name4, entry4);
Vince Lehman218be0a2015-01-15 17:25:20 -0600153 rib.erase(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500154
155 BOOST_CHECK(rib.find(name1) == rib.end());
Vince Lehman218be0a2015-01-15 17:25:20 -0600156 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 2);
Vince12e49462014-06-09 13:29:32 -0500157
Vince Lehman218be0a2015-01-15 17:25:20 -0600158 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500159
Vince Lehman218be0a2015-01-15 17:25:20 -0600160 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 1);
161 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -0500162
Vince Lehman218be0a2015-01-15 17:25:20 -0600163 rib.erase(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500164
165 BOOST_CHECK(rib.find(name2) == rib.end());
166
167 rib.erase(name4, entry4);
168}
169
Vince Lehman4387e782014-06-19 16:57:45 -0500170BOOST_AUTO_TEST_CASE(EraseRibEntry)
Vince12e49462014-06-09 13:29:32 -0500171{
172 rib::Rib rib;
173
Vince Lehman218be0a2015-01-15 17:25:20 -0600174 Route route1;
Vince12e49462014-06-09 13:29:32 -0500175 Name name1("/");
Vince Lehman218be0a2015-01-15 17:25:20 -0600176 route1.faceId = 1;
177 route1.origin = 20;
178 rib.insert(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500179
Vince Lehman218be0a2015-01-15 17:25:20 -0600180 Route route2;
Vince12e49462014-06-09 13:29:32 -0500181 Name name2("/hello");
Vince Lehman218be0a2015-01-15 17:25:20 -0600182 route2.faceId = 2;
183 route2.origin = 20;
184 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500185
Vince Lehman218be0a2015-01-15 17:25:20 -0600186 Route route3;
Vince12e49462014-06-09 13:29:32 -0500187 Name name3("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600188 route3.faceId = 1;
189 route3.origin = 20;
190 rib.insert(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500191
192 shared_ptr<rib::RibEntry> ribEntry1 = rib.find(name1)->second;
193 shared_ptr<rib::RibEntry> ribEntry2 = rib.find(name2)->second;
194 shared_ptr<rib::RibEntry> ribEntry3 = rib.find(name3)->second;
195
196 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry2);
197 BOOST_CHECK(ribEntry3->getParent() == ribEntry2);
198
Vince Lehman218be0a2015-01-15 17:25:20 -0600199 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500200 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry3);
201 BOOST_CHECK(ribEntry3->getParent() == ribEntry1);
202}
203
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700204BOOST_AUTO_TEST_CASE(Basic)
205{
206 rib::Rib rib;
207
Vince Lehman218be0a2015-01-15 17:25:20 -0600208 Route route1;
Vince12e49462014-06-09 13:29:32 -0500209 Name name1("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600210 route1.faceId = 1;
211 route1.origin = 20;
212 route1.cost = 10;
213 route1.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE;
214 route1.expires = time::steady_clock::now() + time::milliseconds(1500);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700215
Vince Lehman218be0a2015-01-15 17:25:20 -0600216 rib.insert(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700217 BOOST_CHECK_EQUAL(rib.size(), 1);
218
Vince Lehman218be0a2015-01-15 17:25:20 -0600219 rib.insert(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700220 BOOST_CHECK_EQUAL(rib.size(), 1);
221
Vince Lehman218be0a2015-01-15 17:25:20 -0600222 Route route2;
Vince12e49462014-06-09 13:29:32 -0500223 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600224 route2.faceId = 1;
225 route2.origin = 20;
226 route2.cost = 100;
227 route2.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
228 route2.expires = time::steady_clock::now() + time::seconds(0);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700229
Vince Lehman218be0a2015-01-15 17:25:20 -0600230 rib.insert(name2, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700231 BOOST_CHECK_EQUAL(rib.size(), 1);
232
Vince Lehman218be0a2015-01-15 17:25:20 -0600233 route2.faceId = 2;
234 rib.insert(name2, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700235 BOOST_CHECK_EQUAL(rib.size(), 2);
236
Vince Lehman218be0a2015-01-15 17:25:20 -0600237 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route1.faceId));
238 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route2.faceId));
Vince12e49462014-06-09 13:29:32 -0500239
240 Name name3("/foo/bar");
Vince Lehman218be0a2015-01-15 17:25:20 -0600241 rib.insert(name3, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700242 BOOST_CHECK_EQUAL(rib.size(), 3);
243
Vince Lehman218be0a2015-01-15 17:25:20 -0600244 route2.origin = 1;
245 rib.insert(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700246 BOOST_CHECK_EQUAL(rib.size(), 4);
247
Vince Lehman218be0a2015-01-15 17:25:20 -0600248 rib.erase(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700249 BOOST_CHECK_EQUAL(rib.size(), 3);
250
Vince12e49462014-06-09 13:29:32 -0500251 Name name4("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600252 rib.erase(name4, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700253 BOOST_CHECK_EQUAL(rib.size(), 3);
254
Vince Lehman218be0a2015-01-15 17:25:20 -0600255 route2.origin = 20;
256 rib.erase(name4, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700257 BOOST_CHECK_EQUAL(rib.size(), 2);
258
Vince Lehman218be0a2015-01-15 17:25:20 -0600259 BOOST_CHECK_EQUAL(rib.find(name2, route2), static_cast<Route*>(0));
260 BOOST_CHECK_NE(rib.find(name1, route1), static_cast<Route*>(0));
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700261
Vince Lehman218be0a2015-01-15 17:25:20 -0600262 rib.erase(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700263 BOOST_CHECK_EQUAL(rib.size(), 1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700264}
265
Nick Gordon89c4cca2016-11-02 15:42:32 +0000266BOOST_AUTO_TEST_CASE(RibSignals)
267{
268 rib::Rib rib;
269
270 Route route;
271 Name name("/hello/world");
272
273 Route route1;
274 route1.faceId = 1;
275 route1.origin = 20;
276 route1.cost = 10;
277
278 Route route2;
279 route2.faceId = 2;
280 route2.origin = 30;
281 route2.cost = 20;
282
283 RibRouteRef routeInfo;
284
285 int nAfterInsertEntryInvocations = 0;
286 int nAfterAddRouteInvocations = 0;
287 int nBeforeRemoveRouteInvocations = 0;
288 int nAfterEraseEntryInvocations = 0;
289 rib.afterInsertEntry.connect([&] (const Name& inName) {
290 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 0);
291 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 0);
292 BOOST_CHECK(rib.find(name) != rib.end());
293 nAfterInsertEntryInvocations++;
294 });
295
296 rib.afterAddRoute.connect([&] (const RibRouteRef& rrr) {
297 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
298 BOOST_CHECK(rib.find(name) != rib.end());
299 BOOST_CHECK(rib.find(name, route) != nullptr);
300 nAfterAddRouteInvocations++;
301 });
302
303 rib.beforeRemoveRoute.connect([&] (const RibRouteRef& rrr) {
304 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
305 BOOST_CHECK(rib.find(name) != rib.end());
306 BOOST_CHECK(rib.find(name, route) != nullptr);
307 nBeforeRemoveRouteInvocations++;
308 });
309
310 rib.afterEraseEntry.connect([&] (const Name& inName) {
311 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
312 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
313 BOOST_CHECK(rib.find(name) == rib.end());
314 nAfterEraseEntryInvocations++;
315 });
316
317 route = route1;
318 rib.insert(name, route);
319 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
320 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 1);
321
322 route = route2;
323 rib.insert(name, route);
324 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
325 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 2);
326
327 route = route1;
328 rib.erase(name, route);
329 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 1);
330 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
331
332 route = route2;
333 rib.erase(name, route);
334 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
335 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 1);
336
337}
338
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700339BOOST_AUTO_TEST_CASE(Output)
340{
341 rib::Rib rib;
342
343 Route root;
344 Name name1("/");
345 root.faceId = 1;
346 root.origin = 20;
347 root.expires = time::steady_clock::TimePoint::max();
348 rib.insert(name1, root);
349
350 Route route1;
351 Name name2("/hello");
352 route1.faceId = 2;
353 route1.origin = 20;
354 route1.expires = time::steady_clock::TimePoint::max();
355 rib.insert(name2, route1);
356
357 Route route2;
358 Name name3("/hello/world");
359 route2.faceId = 3;
360 route2.origin = 20;
361 route2.expires = time::steady_clock::TimePoint::max();
362 rib.insert(name3, route2);
363
364 const std::string ribStr = std::string(R"TEXT(
365RibEntry {
366 Name: /
367 Route(faceid: 1, origin: 20, cost: 0, flags: 0, never expires)
368}
369RibEntry {
370 Name: /hello
371 Route(faceid: 2, origin: 20, cost: 0, flags: 0, never expires)
372}
373RibEntry {
374 Name: /hello/world
375 Route(faceid: 3, origin: 20, cost: 0, flags: 0, never expires)
376}
377)TEXT").substr(1);
378
379 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(rib), ribStr);
380}
381
Davide Pesavento97210d52016-10-14 15:45:48 +0200382BOOST_AUTO_TEST_SUITE_END() // TestRib
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700383
384} // namespace tests
385} // namespace rib
386} // namespace nfd