blob: cc96e79774edeee98c2672c47c1b607b757ee555 [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/*
Davide Pesaventob7bfcb92022-05-22 23:55:23 -04003 * Copyright (c) 2014-2022, 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"
Davide Pesaventocf7db2f2019-03-24 23:17:28 -040029#include "tests/daemon/global-io-fixture.hpp"
Davide Pesavento1b077f62019-02-19 19:19:44 -050030#include "tests/daemon/rib/create-route.hpp"
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070031
32namespace nfd {
33namespace rib {
34namespace tests {
35
Davide Pesavento14e71f02019-03-28 17:35:25 -040036using namespace nfd::tests;
37
38BOOST_FIXTURE_TEST_SUITE(TestRib, GlobalIoFixture)
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070039
Vince Lehman4387e782014-06-19 16:57:45 -050040BOOST_AUTO_TEST_CASE(Parent)
Vince12e49462014-06-09 13:29:32 -050041{
42 rib::Rib rib;
43
Vince12e49462014-06-09 13:29:32 -050044 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -040045 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -050046
Vince12e49462014-06-09 13:29:32 -050047 Name name2("/hello");
Davide Pesavento22db5392017-04-14 00:56:43 -040048 rib.insert(name2, createRoute(2, 20));
Vince12e49462014-06-09 13:29:32 -050049
Vince12e49462014-06-09 13:29:32 -050050 Name name3("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -040051 rib.insert(name3, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050052
53 shared_ptr<rib::RibEntry> ribEntry = rib.findParent(name3);
Davide Pesavento22db5392017-04-14 00:56:43 -040054 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060055 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 2);
Vince12e49462014-06-09 13:29:32 -050056
57 ribEntry = rib.findParent(name2);
Davide Pesavento22db5392017-04-14 00:56:43 -040058 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060059 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -050060
Vince12e49462014-06-09 13:29:32 -050061 Name name4("/hello/test/foo/bar");
Davide Pesavento22db5392017-04-14 00:56:43 -040062 rib.insert(name4, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050063
64 ribEntry = rib.findParent(name4);
Davide Pesavento22db5392017-04-14 00:56:43 -040065 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060066 BOOST_CHECK(ribEntry->getRoutes().front().faceId == 2);
Vince12e49462014-06-09 13:29:32 -050067}
68
Vince Lehman4387e782014-06-19 16:57:45 -050069BOOST_AUTO_TEST_CASE(Children)
Vince12e49462014-06-09 13:29:32 -050070{
71 rib::Rib rib;
72
Vince12e49462014-06-09 13:29:32 -050073 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -040074 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -050075
Vince12e49462014-06-09 13:29:32 -050076 Name name2("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -040077 rib.insert(name2, createRoute(2, 20));
Vince12e49462014-06-09 13:29:32 -050078
Vince12e49462014-06-09 13:29:32 -050079 Name name3("/hello/test/foo/bar");
Davide Pesavento22db5392017-04-14 00:56:43 -040080 rib.insert(name3, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050081
82 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 2);
83 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
84 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
85
Vince12e49462014-06-09 13:29:32 -050086 Name name4("/hello");
Davide Pesavento22db5392017-04-14 00:56:43 -040087 rib.insert(name4, createRoute(4, 20));
Vince12e49462014-06-09 13:29:32 -050088
89 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 1);
90 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
91 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
92 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getChildren().size(), 2);
93
94 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().front()->getName(), "/hello");
95 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getParent()->getName(), "/");
96
97 BOOST_REQUIRE(static_cast<bool>((rib.find(name2)->second)->getParent()));
98 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getParent()->getName(), name4);
99 BOOST_REQUIRE(static_cast<bool>((rib.find(name3)->second)->getParent()));
100 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getParent()->getName(), name4);
101}
102
Vince Lehman4387e782014-06-19 16:57:45 -0500103BOOST_AUTO_TEST_CASE(EraseFace)
Vince12e49462014-06-09 13:29:32 -0500104{
105 rib::Rib rib;
106
Davide Pesavento22db5392017-04-14 00:56:43 -0400107 Route route1 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500108 Name name1("/");
Vince Lehman218be0a2015-01-15 17:25:20 -0600109 rib.insert(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500110
Davide Pesavento22db5392017-04-14 00:56:43 -0400111 Route route2 = createRoute(2, 20);
Vince12e49462014-06-09 13:29:32 -0500112 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600113 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500114
Davide Pesavento22db5392017-04-14 00:56:43 -0400115 Route route3 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500116 Name name3("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600117 rib.insert(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500118
Davide Pesavento22db5392017-04-14 00:56:43 -0400119 Route route4 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500120 Name name4("/not/inserted");
Vince12e49462014-06-09 13:29:32 -0500121
Davide Pesavento22db5392017-04-14 00:56:43 -0400122 rib.erase(name4, route4);
Vince Lehman218be0a2015-01-15 17:25:20 -0600123 rib.erase(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500124
125 BOOST_CHECK(rib.find(name1) == rib.end());
Vince Lehman218be0a2015-01-15 17:25:20 -0600126 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 2);
Vince12e49462014-06-09 13:29:32 -0500127
Vince Lehman218be0a2015-01-15 17:25:20 -0600128 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500129
Vince Lehman218be0a2015-01-15 17:25:20 -0600130 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 1);
131 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -0500132
Vince Lehman218be0a2015-01-15 17:25:20 -0600133 rib.erase(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500134
135 BOOST_CHECK(rib.find(name2) == rib.end());
136
Davide Pesavento22db5392017-04-14 00:56:43 -0400137 rib.erase(name4, route4);
Vince12e49462014-06-09 13:29:32 -0500138}
139
Vince Lehman4387e782014-06-19 16:57:45 -0500140BOOST_AUTO_TEST_CASE(EraseRibEntry)
Vince12e49462014-06-09 13:29:32 -0500141{
142 rib::Rib rib;
143
Vince12e49462014-06-09 13:29:32 -0500144 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -0400145 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -0500146
Davide Pesavento22db5392017-04-14 00:56:43 -0400147 Route route2 = createRoute(2, 20);
Vince12e49462014-06-09 13:29:32 -0500148 Name name2("/hello");
Vince Lehman218be0a2015-01-15 17:25:20 -0600149 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500150
Vince12e49462014-06-09 13:29:32 -0500151 Name name3("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -0400152 rib.insert(name3, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -0500153
154 shared_ptr<rib::RibEntry> ribEntry1 = rib.find(name1)->second;
155 shared_ptr<rib::RibEntry> ribEntry2 = rib.find(name2)->second;
156 shared_ptr<rib::RibEntry> ribEntry3 = rib.find(name3)->second;
157
158 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry2);
159 BOOST_CHECK(ribEntry3->getParent() == ribEntry2);
160
Vince Lehman218be0a2015-01-15 17:25:20 -0600161 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500162 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry3);
163 BOOST_CHECK(ribEntry3->getParent() == ribEntry1);
164}
165
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700166BOOST_AUTO_TEST_CASE(Basic)
167{
168 rib::Rib rib;
169
Vince Lehman218be0a2015-01-15 17:25:20 -0600170 Route route1;
Vince12e49462014-06-09 13:29:32 -0500171 Name name1("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600172 route1.faceId = 1;
Vince Lehman218be0a2015-01-15 17:25:20 -0600173 route1.cost = 10;
174 route1.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400175 route1.expires = time::steady_clock::now() + 1500_ms;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700176
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 rib.insert(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700181 BOOST_CHECK_EQUAL(rib.size(), 1);
182
Vince Lehman218be0a2015-01-15 17:25:20 -0600183 Route route2;
Vince12e49462014-06-09 13:29:32 -0500184 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600185 route2.faceId = 1;
Vince Lehman218be0a2015-01-15 17:25:20 -0600186 route2.cost = 100;
187 route2.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400188 route2.expires = time::steady_clock::now() + 0_s;
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700189
Vince Lehman218be0a2015-01-15 17:25:20 -0600190 rib.insert(name2, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700191 BOOST_CHECK_EQUAL(rib.size(), 1);
192
Vince Lehman218be0a2015-01-15 17:25:20 -0600193 route2.faceId = 2;
194 rib.insert(name2, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700195 BOOST_CHECK_EQUAL(rib.size(), 2);
196
Vince Lehman218be0a2015-01-15 17:25:20 -0600197 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route1.faceId));
198 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route2.faceId));
Vince12e49462014-06-09 13:29:32 -0500199
200 Name name3("/foo/bar");
Vince Lehman218be0a2015-01-15 17:25:20 -0600201 rib.insert(name3, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700202 BOOST_CHECK_EQUAL(rib.size(), 3);
203
Davide Pesavento22db5392017-04-14 00:56:43 -0400204 route2.origin = ndn::nfd::ROUTE_ORIGIN_AUTOCONF;
Vince Lehman218be0a2015-01-15 17:25:20 -0600205 rib.insert(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700206 BOOST_CHECK_EQUAL(rib.size(), 4);
207
Vince Lehman218be0a2015-01-15 17:25:20 -0600208 rib.erase(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700209 BOOST_CHECK_EQUAL(rib.size(), 3);
210
Vince12e49462014-06-09 13:29:32 -0500211 Name name4("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600212 rib.erase(name4, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700213 BOOST_CHECK_EQUAL(rib.size(), 3);
214
Davide Pesavento22db5392017-04-14 00:56:43 -0400215 route2.origin = ndn::nfd::ROUTE_ORIGIN_APP;
Vince Lehman218be0a2015-01-15 17:25:20 -0600216 rib.erase(name4, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700217 BOOST_CHECK_EQUAL(rib.size(), 2);
218
Davide Pesavento22db5392017-04-14 00:56:43 -0400219 BOOST_CHECK(rib.find(name2, route2) == nullptr);
220 BOOST_CHECK(rib.find(name1, route1) != nullptr);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700221
Teng Lianga4e6ec32018-10-21 09:25:00 -0700222 Name name5("/hello/world/666");
223 Name name6("/hello/world/cs/ua/edu");
224 BOOST_CHECK(rib.findLongestPrefix(name1, route1) != nullptr);
225 BOOST_CHECK(rib.findLongestPrefix(name5, route1) != nullptr);
226 BOOST_CHECK(rib.findLongestPrefix(name6, route1) != nullptr);
227
Vince Lehman218be0a2015-01-15 17:25:20 -0600228 rib.erase(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700229 BOOST_CHECK_EQUAL(rib.size(), 1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700230}
231
Nick Gordon89c4cca2016-11-02 15:42:32 +0000232BOOST_AUTO_TEST_CASE(RibSignals)
233{
234 rib::Rib rib;
235
236 Route route;
237 Name name("/hello/world");
238
Davide Pesavento22db5392017-04-14 00:56:43 -0400239 Route route1 = createRoute(1, 20, 10);
240 Route route2 = createRoute(2, 30, 20);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000241
242 RibRouteRef routeInfo;
243
244 int nAfterInsertEntryInvocations = 0;
245 int nAfterAddRouteInvocations = 0;
246 int nBeforeRemoveRouteInvocations = 0;
247 int nAfterEraseEntryInvocations = 0;
248 rib.afterInsertEntry.connect([&] (const Name& inName) {
249 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 0);
250 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 0);
251 BOOST_CHECK(rib.find(name) != rib.end());
252 nAfterInsertEntryInvocations++;
253 });
254
255 rib.afterAddRoute.connect([&] (const RibRouteRef& rrr) {
256 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
257 BOOST_CHECK(rib.find(name) != rib.end());
258 BOOST_CHECK(rib.find(name, route) != nullptr);
259 nAfterAddRouteInvocations++;
260 });
261
262 rib.beforeRemoveRoute.connect([&] (const RibRouteRef& rrr) {
263 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
264 BOOST_CHECK(rib.find(name) != rib.end());
265 BOOST_CHECK(rib.find(name, route) != nullptr);
266 nBeforeRemoveRouteInvocations++;
267 });
268
269 rib.afterEraseEntry.connect([&] (const Name& inName) {
270 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
271 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
272 BOOST_CHECK(rib.find(name) == rib.end());
273 nAfterEraseEntryInvocations++;
274 });
275
276 route = route1;
277 rib.insert(name, route);
278 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
279 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 1);
280
281 route = route2;
282 rib.insert(name, route);
283 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
284 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 2);
285
286 route = route1;
287 rib.erase(name, route);
288 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 1);
289 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
290
291 route = route2;
292 rib.erase(name, route);
293 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
294 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 1);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000295}
296
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700297BOOST_AUTO_TEST_CASE(Output)
298{
299 rib::Rib rib;
300
Davide Pesavento22db5392017-04-14 00:56:43 -0400301 Route root = createRoute(1, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700302 Name name1("/");
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400303 root.expires = std::nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700304 rib.insert(name1, root);
305
Davide Pesavento22db5392017-04-14 00:56:43 -0400306 Route route1 = createRoute(2, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700307 Name name2("/hello");
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400308 route1.expires = std::nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700309 rib.insert(name2, route1);
310
Davide Pesavento22db5392017-04-14 00:56:43 -0400311 Route route2 = createRoute(3, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700312 Name name3("/hello/world");
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400313 route2.expires = std::nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700314 rib.insert(name3, route2);
315
316 const std::string ribStr = std::string(R"TEXT(
317RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000318 Name: /
319 Route(faceid: 1, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700320}
321RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000322 Name: /hello
323 Route(faceid: 2, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700324}
325RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000326 Name: /hello/world
327 Route(faceid: 3, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700328}
329)TEXT").substr(1);
330
331 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(rib), ribStr);
332}
333
Davide Pesavento97210d52016-10-14 15:45:48 +0200334BOOST_AUTO_TEST_SUITE_END() // TestRib
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700335
336} // namespace tests
337} // namespace rib
338} // namespace nfd