blob: b6352070014a33c83f29e28dfca4b0bee33ebf93 [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
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040032namespace nfd::tests {
Alexander Afanasyev3ecec502014-04-16 13:42:44 -070033
Davide Pesaventoe422f9e2022-06-03 01:30:23 -040034using rib::Route;
Davide Pesavento14e71f02019-03-28 17:35:25 -040035
36BOOST_FIXTURE_TEST_SUITE(TestRib, GlobalIoFixture)
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
Vince12e49462014-06-09 13:29:32 -050042 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -040043 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -050044
Vince12e49462014-06-09 13:29:32 -050045 Name name2("/hello");
Davide Pesavento22db5392017-04-14 00:56:43 -040046 rib.insert(name2, createRoute(2, 20));
Vince12e49462014-06-09 13:29:32 -050047
Vince12e49462014-06-09 13:29:32 -050048 Name name3("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -040049 rib.insert(name3, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050050
51 shared_ptr<rib::RibEntry> ribEntry = rib.findParent(name3);
Davide Pesavento22db5392017-04-14 00:56:43 -040052 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060053 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 2);
Vince12e49462014-06-09 13:29:32 -050054
55 ribEntry = rib.findParent(name2);
Davide Pesavento22db5392017-04-14 00:56:43 -040056 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060057 BOOST_CHECK_EQUAL(ribEntry->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -050058
Vince12e49462014-06-09 13:29:32 -050059 Name name4("/hello/test/foo/bar");
Davide Pesavento22db5392017-04-14 00:56:43 -040060 rib.insert(name4, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050061
62 ribEntry = rib.findParent(name4);
Davide Pesavento22db5392017-04-14 00:56:43 -040063 BOOST_REQUIRE(ribEntry != nullptr);
Vince Lehman218be0a2015-01-15 17:25:20 -060064 BOOST_CHECK(ribEntry->getRoutes().front().faceId == 2);
Vince12e49462014-06-09 13:29:32 -050065}
66
Vince Lehman4387e782014-06-19 16:57:45 -050067BOOST_AUTO_TEST_CASE(Children)
Vince12e49462014-06-09 13:29:32 -050068{
69 rib::Rib rib;
70
Vince12e49462014-06-09 13:29:32 -050071 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -040072 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -050073
Vince12e49462014-06-09 13:29:32 -050074 Name name2("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -040075 rib.insert(name2, createRoute(2, 20));
Vince12e49462014-06-09 13:29:32 -050076
Vince12e49462014-06-09 13:29:32 -050077 Name name3("/hello/test/foo/bar");
Davide Pesavento22db5392017-04-14 00:56:43 -040078 rib.insert(name3, createRoute(3, 20));
Vince12e49462014-06-09 13:29:32 -050079
80 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 2);
81 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
82 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
83
Vince12e49462014-06-09 13:29:32 -050084 Name name4("/hello");
Davide Pesavento22db5392017-04-14 00:56:43 -040085 rib.insert(name4, createRoute(4, 20));
Vince12e49462014-06-09 13:29:32 -050086
87 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().size(), 1);
88 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getChildren().size(), 0);
89 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getChildren().size(), 0);
90 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getChildren().size(), 2);
91
92 BOOST_CHECK_EQUAL((rib.find(name1)->second)->getChildren().front()->getName(), "/hello");
93 BOOST_CHECK_EQUAL((rib.find(name4)->second)->getParent()->getName(), "/");
94
95 BOOST_REQUIRE(static_cast<bool>((rib.find(name2)->second)->getParent()));
96 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getParent()->getName(), name4);
97 BOOST_REQUIRE(static_cast<bool>((rib.find(name3)->second)->getParent()));
98 BOOST_CHECK_EQUAL((rib.find(name3)->second)->getParent()->getName(), name4);
99}
100
Vince Lehman4387e782014-06-19 16:57:45 -0500101BOOST_AUTO_TEST_CASE(EraseFace)
Vince12e49462014-06-09 13:29:32 -0500102{
103 rib::Rib rib;
104
Davide Pesavento22db5392017-04-14 00:56:43 -0400105 Route route1 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500106 Name name1("/");
Vince Lehman218be0a2015-01-15 17:25:20 -0600107 rib.insert(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500108
Davide Pesavento22db5392017-04-14 00:56:43 -0400109 Route route2 = createRoute(2, 20);
Vince12e49462014-06-09 13:29:32 -0500110 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600111 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500112
Davide Pesavento22db5392017-04-14 00:56:43 -0400113 Route route3 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500114 Name name3("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600115 rib.insert(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500116
Davide Pesavento22db5392017-04-14 00:56:43 -0400117 Route route4 = createRoute(1, 20);
Vince12e49462014-06-09 13:29:32 -0500118 Name name4("/not/inserted");
Vince12e49462014-06-09 13:29:32 -0500119
Davide Pesavento22db5392017-04-14 00:56:43 -0400120 rib.erase(name4, route4);
Vince Lehman218be0a2015-01-15 17:25:20 -0600121 rib.erase(name1, route1);
Vince12e49462014-06-09 13:29:32 -0500122
123 BOOST_CHECK(rib.find(name1) == rib.end());
Vince Lehman218be0a2015-01-15 17:25:20 -0600124 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 2);
Vince12e49462014-06-09 13:29:32 -0500125
Vince Lehman218be0a2015-01-15 17:25:20 -0600126 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500127
Vince Lehman218be0a2015-01-15 17:25:20 -0600128 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().size(), 1);
129 BOOST_CHECK_EQUAL((rib.find(name2)->second)->getRoutes().front().faceId, 1);
Vince12e49462014-06-09 13:29:32 -0500130
Vince Lehman218be0a2015-01-15 17:25:20 -0600131 rib.erase(name3, route3);
Vince12e49462014-06-09 13:29:32 -0500132
133 BOOST_CHECK(rib.find(name2) == rib.end());
134
Davide Pesavento22db5392017-04-14 00:56:43 -0400135 rib.erase(name4, route4);
Vince12e49462014-06-09 13:29:32 -0500136}
137
Vince Lehman4387e782014-06-19 16:57:45 -0500138BOOST_AUTO_TEST_CASE(EraseRibEntry)
Vince12e49462014-06-09 13:29:32 -0500139{
140 rib::Rib rib;
141
Vince12e49462014-06-09 13:29:32 -0500142 Name name1("/");
Davide Pesavento22db5392017-04-14 00:56:43 -0400143 rib.insert(name1, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -0500144
Davide Pesavento22db5392017-04-14 00:56:43 -0400145 Route route2 = createRoute(2, 20);
Vince12e49462014-06-09 13:29:32 -0500146 Name name2("/hello");
Vince Lehman218be0a2015-01-15 17:25:20 -0600147 rib.insert(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500148
Vince12e49462014-06-09 13:29:32 -0500149 Name name3("/hello/world");
Davide Pesavento22db5392017-04-14 00:56:43 -0400150 rib.insert(name3, createRoute(1, 20));
Vince12e49462014-06-09 13:29:32 -0500151
152 shared_ptr<rib::RibEntry> ribEntry1 = rib.find(name1)->second;
153 shared_ptr<rib::RibEntry> ribEntry2 = rib.find(name2)->second;
154 shared_ptr<rib::RibEntry> ribEntry3 = rib.find(name3)->second;
155
156 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry2);
157 BOOST_CHECK(ribEntry3->getParent() == ribEntry2);
158
Vince Lehman218be0a2015-01-15 17:25:20 -0600159 rib.erase(name2, route2);
Vince12e49462014-06-09 13:29:32 -0500160 BOOST_CHECK(ribEntry1->getChildren().front() == ribEntry3);
161 BOOST_CHECK(ribEntry3->getParent() == ribEntry1);
162}
163
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700164BOOST_AUTO_TEST_CASE(Basic)
165{
166 rib::Rib rib;
167
Vince Lehman218be0a2015-01-15 17:25:20 -0600168 Route route1;
Vince12e49462014-06-09 13:29:32 -0500169 Name name1("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600170 route1.faceId = 1;
Vince Lehman218be0a2015-01-15 17:25:20 -0600171 route1.cost = 10;
172 route1.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT | ndn::nfd::ROUTE_FLAG_CAPTURE;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400173 route1.expires = time::steady_clock::now() + 1500_ms;
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700174
Vince Lehman218be0a2015-01-15 17:25:20 -0600175 rib.insert(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700176 BOOST_CHECK_EQUAL(rib.size(), 1);
177
Vince Lehman218be0a2015-01-15 17:25:20 -0600178 rib.insert(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700179 BOOST_CHECK_EQUAL(rib.size(), 1);
180
Vince Lehman218be0a2015-01-15 17:25:20 -0600181 Route route2;
Vince12e49462014-06-09 13:29:32 -0500182 Name name2("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600183 route2.faceId = 1;
Vince Lehman218be0a2015-01-15 17:25:20 -0600184 route2.cost = 100;
185 route2.flags = ndn::nfd::ROUTE_FLAG_CHILD_INHERIT;
Davide Pesavento14e71f02019-03-28 17:35:25 -0400186 route2.expires = time::steady_clock::now() + 0_s;
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700187
Vince Lehman218be0a2015-01-15 17:25:20 -0600188 rib.insert(name2, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700189 BOOST_CHECK_EQUAL(rib.size(), 1);
190
Vince Lehman218be0a2015-01-15 17:25:20 -0600191 route2.faceId = 2;
192 rib.insert(name2, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700193 BOOST_CHECK_EQUAL(rib.size(), 2);
194
Vince Lehman218be0a2015-01-15 17:25:20 -0600195 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route1.faceId));
196 BOOST_CHECK(rib.find(name1)->second->hasFaceId(route2.faceId));
Vince12e49462014-06-09 13:29:32 -0500197
198 Name name3("/foo/bar");
Vince Lehman218be0a2015-01-15 17:25:20 -0600199 rib.insert(name3, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700200 BOOST_CHECK_EQUAL(rib.size(), 3);
201
Davide Pesavento22db5392017-04-14 00:56:43 -0400202 route2.origin = ndn::nfd::ROUTE_ORIGIN_AUTOCONF;
Vince Lehman218be0a2015-01-15 17:25:20 -0600203 rib.insert(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700204 BOOST_CHECK_EQUAL(rib.size(), 4);
205
Vince Lehman218be0a2015-01-15 17:25:20 -0600206 rib.erase(name3, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700207 BOOST_CHECK_EQUAL(rib.size(), 3);
208
Vince12e49462014-06-09 13:29:32 -0500209 Name name4("/hello/world");
Vince Lehman218be0a2015-01-15 17:25:20 -0600210 rib.erase(name4, route2);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700211 BOOST_CHECK_EQUAL(rib.size(), 3);
212
Davide Pesavento22db5392017-04-14 00:56:43 -0400213 route2.origin = ndn::nfd::ROUTE_ORIGIN_APP;
Vince Lehman218be0a2015-01-15 17:25:20 -0600214 rib.erase(name4, route2);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700215 BOOST_CHECK_EQUAL(rib.size(), 2);
216
Davide Pesavento22db5392017-04-14 00:56:43 -0400217 BOOST_CHECK(rib.find(name2, route2) == nullptr);
218 BOOST_CHECK(rib.find(name1, route1) != nullptr);
Alexander Afanasyev20d31442014-04-19 17:00:53 -0700219
Teng Lianga4e6ec32018-10-21 09:25:00 -0700220 Name name5("/hello/world/666");
221 Name name6("/hello/world/cs/ua/edu");
222 BOOST_CHECK(rib.findLongestPrefix(name1, route1) != nullptr);
223 BOOST_CHECK(rib.findLongestPrefix(name5, route1) != nullptr);
224 BOOST_CHECK(rib.findLongestPrefix(name6, route1) != nullptr);
225
Vince Lehman218be0a2015-01-15 17:25:20 -0600226 rib.erase(name1, route1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700227 BOOST_CHECK_EQUAL(rib.size(), 1);
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700228}
229
Nick Gordon89c4cca2016-11-02 15:42:32 +0000230BOOST_AUTO_TEST_CASE(RibSignals)
231{
232 rib::Rib rib;
233
234 Route route;
235 Name name("/hello/world");
236
Davide Pesavento22db5392017-04-14 00:56:43 -0400237 Route route1 = createRoute(1, 20, 10);
238 Route route2 = createRoute(2, 30, 20);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000239
Nick Gordon89c4cca2016-11-02 15:42:32 +0000240 int nAfterInsertEntryInvocations = 0;
241 int nAfterAddRouteInvocations = 0;
242 int nBeforeRemoveRouteInvocations = 0;
243 int nAfterEraseEntryInvocations = 0;
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400244 rib.afterInsertEntry.connect([&] (const auto&) {
245 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 0);
246 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 0);
247 BOOST_CHECK(rib.find(name) != rib.end());
248 nAfterInsertEntryInvocations++;
249 });
Nick Gordon89c4cca2016-11-02 15:42:32 +0000250
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400251 rib.afterAddRoute.connect([&] (const auto&) {
252 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
253 BOOST_CHECK(rib.find(name) != rib.end());
254 BOOST_CHECK(rib.find(name, route) != nullptr);
255 nAfterAddRouteInvocations++;
256 });
Nick Gordon89c4cca2016-11-02 15:42:32 +0000257
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400258 rib.beforeRemoveRoute.connect([&] (const auto&) {
259 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
260 BOOST_CHECK(rib.find(name) != rib.end());
261 BOOST_CHECK(rib.find(name, route) != nullptr);
262 nBeforeRemoveRouteInvocations++;
263 });
Nick Gordon89c4cca2016-11-02 15:42:32 +0000264
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400265 rib.afterEraseEntry.connect([&] (const auto&) {
266 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
267 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
268 BOOST_CHECK(rib.find(name) == rib.end());
269 nAfterEraseEntryInvocations++;
270 });
Nick Gordon89c4cca2016-11-02 15:42:32 +0000271
272 route = route1;
273 rib.insert(name, route);
274 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
275 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 1);
276
277 route = route2;
278 rib.insert(name, route);
279 BOOST_CHECK_EQUAL(nAfterInsertEntryInvocations, 1);
280 BOOST_CHECK_EQUAL(nAfterAddRouteInvocations, 2);
281
282 route = route1;
283 rib.erase(name, route);
284 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 1);
285 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 0);
286
287 route = route2;
288 rib.erase(name, route);
289 BOOST_CHECK_EQUAL(nBeforeRemoveRouteInvocations, 2);
290 BOOST_CHECK_EQUAL(nAfterEraseEntryInvocations, 1);
Nick Gordon89c4cca2016-11-02 15:42:32 +0000291}
292
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700293BOOST_AUTO_TEST_CASE(Output)
294{
295 rib::Rib rib;
296
Davide Pesavento22db5392017-04-14 00:56:43 -0400297 Route root = createRoute(1, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700298 Name name1("/");
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400299 root.expires = std::nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700300 rib.insert(name1, root);
301
Davide Pesavento22db5392017-04-14 00:56:43 -0400302 Route route1 = createRoute(2, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700303 Name name2("/hello");
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400304 route1.expires = std::nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700305 rib.insert(name2, route1);
306
Davide Pesavento22db5392017-04-14 00:56:43 -0400307 Route route2 = createRoute(3, 20);
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700308 Name name3("/hello/world");
Davide Pesaventob7bfcb92022-05-22 23:55:23 -0400309 route2.expires = std::nullopt;
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700310 rib.insert(name3, route2);
311
312 const std::string ribStr = std::string(R"TEXT(
313RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000314 Name: /
315 Route(faceid: 1, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700316}
317RibEntry {
Junxiao Shi3f21e582017-05-29 15:26:32 +0000318 Name: /hello
319 Route(faceid: 2, 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/world
323 Route(faceid: 3, origin: 20, cost: 0, flags: 0x0, never expires)
Weiwei Liuaaa58a62016-11-28 23:15:15 -0700324}
325)TEXT").substr(1);
326
327 BOOST_CHECK_EQUAL(boost::lexical_cast<std::string>(rib), ribStr);
328}
329
Davide Pesavento97210d52016-10-14 15:45:48 +0200330BOOST_AUTO_TEST_SUITE_END() // TestRib
Alexander Afanasyev3ecec502014-04-16 13:42:44 -0700331
Davide Pesaventoe422f9e2022-06-03 01:30:23 -0400332} // namespace nfd::tests