blob: 3b9840c14ff425cad3d131b3dadda459e5732e28 [file] [log] [blame]
Davide Pesavento22db5392017-04-14 00:56:43 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento87fc0f82018-04-11 23:43:51 -04002/*
3 * Copyright (c) 2014-2018, 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
Davide Pesavento22db5392017-04-14 00:56:43 -040028#include "rib-test-common.hpp"
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070029#include "tests/test-common.hpp"
30
31namespace nfd {
32namespace rib {
33namespace tests {
34
Spyridon Mastorakisd0381c02015-02-19 10:29:41 -080035BOOST_FIXTURE_TEST_SUITE(TestRib, nfd::tests::BaseFixture)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070036
Vince Lehman4387e782014-06-19 16:57:45 -050037BOOST_AUTO_TEST_CASE(Parent)
Vince12e49462014-06-09 13:29:32 -050038{
39 rib::Rib rib;
40
Vince12e49462014-06-09 13:29:32 -050041 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -040042 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -050043
Vince12e49462014-06-09 13:29:32 -050044 Name name2("/hello");
Davide Pesavento22db5392017-04-14 00:56:43 -040045 rib.insert(name2, createRoute(2, 20));
Vince12e49462014-06-09 13:29:32 -050046
Vince12e49462014-06-09 13:29:32 -050047 Name name3("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -040048 rib.insert(name3, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050049
50 shared_ptr<rib::RibEntry> ribEntry = rib.findParent(name3);
Davide Pesavento22db5392017-04-14 00:56:43 -040051 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060052 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 2);
Vince12e49462014-06-09 13:29:32 -050053
54 ribEntry = rib.findParent(name2);
Davide Pesavento22db5392017-04-14 00:56:43 -040055 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060056 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -050057
Vince12e49462014-06-09 13:29:32 -050058 Name name4("/hello/test/foo/bar");
Davide Pesavento22db5392017-04-14 00:56:43 -040059 rib.insert(name4, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050060
61 ribEntry = rib.findParent(name4);
Davide Pesavento22db5392017-04-14 00:56:43 -040062 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060063 BOOST_CHECK(ribEntry->getRoutes().front().faceId == 2);
Vince12e49462014-06-09 13:29:32 -050064}
65
Vince Lehman4387e782014-06-19 16:57:45 -050066BOOST_AUTO_TEST_CASE(Children)
Vince12e49462014-06-09 13:29:32 -050067{
68 rib::Rib rib;
69
Vince12e49462014-06-09 13:29:32 -050070 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -040071 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -050072
Vince12e49462014-06-09 13:29:32 -050073 Name name2("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -040074 rib.insert(name2, createRoute(2, 20));
Vince12e49462014-06-09 13:29:32 -050075
Vince12e49462014-06-09 13:29:32 -050076 Name name3("/hello/test/foo/bar");
Davide Pesavento22db5392017-04-14 00:56:43 -040077 rib.insert(name3, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050078
79 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 2);
80 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
81 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
82
Vince12e49462014-06-09 13:29:32 -050083 Name name4("/hello");
Davide Pesavento22db5392017-04-14 00:56:43 -040084 rib.insert(name4, createRoute(4, 20));
Vince12e49462014-06-09 13:29:32 -050085
86 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 1);
87 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
88 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
89 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getChildren().size(), 2);
90
91 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().front()->getName(), "/hello");
92 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getParent()->getName(), "/");
93
94 BOOST_REQUIRE(static_cast<bool>((rib.find(name2)->second)->getParent()));
95 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getParent()->getName(), name4);
96 BOOST_REQUIRE(static_cast<bool>((rib.find(name3)->second)->getParent()));
97 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getParent()->getName(), name4);
98}
99
Vince Lehman4387e782014-06-19 16:57:45 -0500100BOOST_AUTO_TEST_CASE(EraseFace)
Vince12e49462014-06-09 13:29:32 -0500101{
102 rib::Rib rib;
103
Davide Pesavento22db5392017-04-14 00:56:43 -0400104 Route route1 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500105 Name name1("/");
Vince Lehman218be0a2015-01-15 17:25:20 -0600106 rib.insert(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500107
Davide Pesavento22db5392017-04-14 00:56:43 -0400108 Route route2 = createRoute(2, 20);
Vince12e49462014-06-09 13:29:32 -0500109 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600110 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500111
Davide Pesavento22db5392017-04-14 00:56:43 -0400112 Route route3 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500113 Name name3("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600114 rib.insert(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500115
Davide Pesavento22db5392017-04-14 00:56:43 -0400116 Route route4 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500117 Name name4("/not/inserted");
Vince12e49462014-06-09 13:29:32 -0500118
Davide Pesavento22db5392017-04-14 00:56:43 -0400119 rib.erase(name4, route4);
Vince Lehman218be0a2015-01-15 17:25:20 -0600120 rib.erase(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500121
122 BOOST_CHECK(rib.find(name1) == rib.end());
Vince Lehman218be0a2015-01-15 17:25:20 -0600123 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 2);
Vince12e49462014-06-09 13:29:32 -0500124
Vince Lehman218be0a2015-01-15 17:25:20 -0600125 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500126
Vince Lehman218be0a2015-01-15 17:25:20 -0600127 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 1);
128 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -0500129
Vince Lehman218be0a2015-01-15 17:25:20 -0600130 rib.erase(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500131
132 BOOST_CHECK(rib.find(name2) == rib.end());
133
Davide Pesavento22db5392017-04-14 00:56:43 -0400134 rib.erase(name4, route4);
Vince12e49462014-06-09 13:29:32 -0500135}
136
Vince Lehman4387e782014-06-19 16:57:45 -0500137BOOST_AUTO_TEST_CASE(EraseRibEntry)
Vince12e49462014-06-09 13:29:32 -0500138{
139 rib::Rib rib;
140
Vince12e49462014-06-09 13:29:32 -0500141 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -0400142 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -0500143
Davide Pesavento22db5392017-04-14 00:56:43 -0400144 Route route2 = createRoute(2, 20);
Vince12e49462014-06-09 13:29:32 -0500145 Name name2("/hello");
Vince Lehman218be0a2015-01-15 17:25:20 -0600146 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500147
Vince12e49462014-06-09 13:29:32 -0500148 Name name3("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -0400149 rib.insert(name3, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -0500150
151 shared_ptr<rib::RibEntry> ribEntry1 = rib.find(name1)->second;
152 shared_ptr<rib::RibEntry> ribEntry2 = rib.find(name2)->second;
153 shared_ptr<rib::RibEntry> ribEntry3 = rib.find(name3)->second;
154
155 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry2);
156 BOOST_CHECK(ribEntry3->getParent() == ribEntry2);
157
Vince Lehman218be0a2015-01-15 17:25:20 -0600158 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500159 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry3);
160 BOOST_CHECK(ribEntry3->getParent() == ribEntry1);
161}
162
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700163BOOST_AUTO_TEST_CASE(Basic)
164{
165 rib::Rib rib;
166
Vince Lehman218be0a2015-01-15 17:25:20 -0600167 Route route1;
Vince12e49462014-06-09 13:29:32 -0500168 Name name1("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600169 route1.faceId = 1;
Vince Lehman218be0a2015-01-15 17:25:20 -0600170 route1.cost = 10;
171 route1.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE;
172 route1.expires = time::steady_clock::now() + time::milliseconds(1500);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700173
Vince Lehman218be0a2015-01-15 17:25:20 -0600174 rib.insert(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700175 BOOST_CHECK_EQUAL(rib.size(), 1);
176
Vince Lehman218be0a2015-01-15 17:25:20 -0600177 rib.insert(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700178 BOOST_CHECK_EQUAL(rib.size(), 1);
179
Vince Lehman218be0a2015-01-15 17:25:20 -0600180 Route route2;
Vince12e49462014-06-09 13:29:32 -0500181 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600182 route2.faceId = 1;
Vince Lehman218be0a2015-01-15 17:25:20 -0600183 route2.cost = 100;
184 route2.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
185 route2.expires = time::steady_clock::now() + time::seconds(0);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700186
Vince Lehman218be0a2015-01-15 17:25:20 -0600187 rib.insert(name2, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700188 BOOST_CHECK_EQUAL(rib.size(), 1);
189
Vince Lehman218be0a2015-01-15 17:25:20 -0600190 route2.faceId = 2;
191 rib.insert(name2, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700192 BOOST_CHECK_EQUAL(rib.size(), 2);
193
Vince Lehman218be0a2015-01-15 17:25:20 -0600194 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route1.faceId));
195 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route2.faceId));
Vince12e49462014-06-09 13:29:32 -0500196
197 Name name3("/foo/bar");
Vince Lehman218be0a2015-01-15 17:25:20 -0600198 rib.insert(name3, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700199 BOOST_CHECK_EQUAL(rib.size(), 3);
200
Davide Pesavento22db5392017-04-14 00:56:43 -0400201 route2.origin = ndn::nfd::ROUTE_ORIGIN_AUTOCONF;
Vince Lehman218be0a2015-01-15 17:25:20 -0600202 rib.insert(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700203 BOOST_CHECK_EQUAL(rib.size(), 4);
204
Vince Lehman218be0a2015-01-15 17:25:20 -0600205 rib.erase(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700206 BOOST_CHECK_EQUAL(rib.size(), 3);
207
Vince12e49462014-06-09 13:29:32 -0500208 Name name4("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600209 rib.erase(name4, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700210 BOOST_CHECK_EQUAL(rib.size(), 3);
211
Davide Pesavento22db5392017-04-14 00:56:43 -0400212 route2.origin = ndn::nfd::ROUTE_ORIGIN_APP;
Vince Lehman218be0a2015-01-15 17:25:20 -0600213 rib.erase(name4, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700214 BOOST_CHECK_EQUAL(rib.size(), 2);
215
Davide Pesavento22db5392017-04-14 00:56:43 -0400216 BOOST_CHECK(rib.find(name2, route2) == nullptr);
217 BOOST_CHECK(rib.find(name1, route1) != nullptr);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700218
Teng Lianga4e6ec32018-10-21 09:25:00 -0700219 Name name5("/hello/world/666");
220 Name name6("/hello/world/cs/ua/edu");
221 BOOST_CHECK(rib.findLongestPrefix(name1, route1) != nullptr);
222 BOOST_CHECK(rib.findLongestPrefix(name5, route1) != nullptr);
223 BOOST_CHECK(rib.findLongestPrefix(name6, route1) != nullptr);
224
Vince Lehman218be0a2015-01-15 17:25:20 -0600225 rib.erase(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700226 BOOST_CHECK_EQUAL(rib.size(), 1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700227}
228
Nick Gordon89c4cca2016-11-02 15:42:32 +0000229BOOST_AUTO_TEST_CASE(RibSignals)
230{
231 rib::Rib rib;
232
233 Route route;
234 Name name("/hello/world");
235
Davide Pesavento22db5392017-04-14 00:56:43 -0400236 Route route1 = createRoute(1, 20, 10);
237 Route route2 = createRoute(2, 30, 20);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000238
239 RibRouteRef routeInfo;
240
241 int nAfterInsertEntryInvocations = 0;
242 int nAfterAddRouteInvocations = 0;
243 int nBeforeRemoveRouteInvocations = 0;
244 int nAfterEraseEntryInvocations = 0;
245 rib.afterInsertEntry.connect([&] (const Name& inName) {
246 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 0);
247 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 0);
248 BOOST_CHECK(rib.find(name) != rib.end());
249 nAfterInsertEntryInvocations++;
250 });
251
252 rib.afterAddRoute.connect([&] (const RibRouteRef& rrr) {
253 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
254 BOOST_CHECK(rib.find(name) != rib.end());
255 BOOST_CHECK(rib.find(name, route) != nullptr);
256 nAfterAddRouteInvocations++;
257 });
258
259 rib.beforeRemoveRoute.connect([&] (const RibRouteRef& rrr) {
260 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
261 BOOST_CHECK(rib.find(name) != rib.end());
262 BOOST_CHECK(rib.find(name, route) != nullptr);
263 nBeforeRemoveRouteInvocations++;
264 });
265
266 rib.afterEraseEntry.connect([&] (const Name& inName) {
267 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
268 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
269 BOOST_CHECK(rib.find(name) == rib.end());
270 nAfterEraseEntryInvocations++;
271 });
272
273 route = route1;
274 rib.insert(name, route);
275 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
276 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 1);
277
278 route = route2;
279 rib.insert(name, route);
280 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
281 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 2);
282
283 route = route1;
284 rib.erase(name, route);
285 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 1);
286 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
287
288 route = route2;
289 rib.erase(name, route);
290 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
291 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 1);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000292}
293
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700294BOOST_AUTO_TEST_CASE(Output)
295{
296 rib::Rib rib;
297
Davide Pesavento22db5392017-04-14 00:56:43 -0400298 Route root = createRoute(1, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700299 Name name1("/");
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400300 root.expires = nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700301 rib.insert(name1, root);
302
Davide Pesavento22db5392017-04-14 00:56:43 -0400303 Route route1 = createRoute(2, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700304 Name name2("/hello");
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400305 route1.expires = nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700306 rib.insert(name2, route1);
307
Davide Pesavento22db5392017-04-14 00:56:43 -0400308 Route route2 = createRoute(3, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700309 Name name3("/hello/world");
Davide Pesavento87fc0f82018-04-11 23:43:51 -0400310 route2.expires = nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700311 rib.insert(name3, route2);
312
313 const std::string ribStr = std::string(R"TEXT(
314RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000315 Name: /
316 Route(faceid: 1, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700317}
318RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000319 Name: /hello
320 Route(faceid: 2, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700321}
322RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000323 Name: /hello/world
324 Route(faceid: 3, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700325}
326)TEXT").substr(1);
327
328 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(rib), ribStr);
329}
330
Davide Pesavento97210d52016-10-14 15:45:48 +0200331BOOST_AUTO_TEST_SUITE_END() // TestRib
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700332
333} // namespace tests
334} // namespace rib
335} // namespace nfd