blob: 73108dc73ceb5a79161761ff89d886da5585a9cc [file] [log] [blame]
akmhoque3d06e792014-05-27 16:23:20 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Ashlesh Gawande0421bc62020-05-08 20:42:19 -07002/*
Ashlesh Gawande6f0f35d2021-08-21 23:52:14 -07003 * Copyright (c) 2014-2021, The University of Memphis,
Vince Lehmancec38852015-03-31 13:21:38 -05004 * Regents of the University of California,
5 * Arizona Board of Regents.
akmhoque3d06e792014-05-27 16:23:20 -05006 *
7 * This file is part of NLSR (Named-data Link State Routing).
8 * See AUTHORS.md for complete list of NLSR authors and contributors.
9 *
10 * NLSR is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * NLSR is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * NLSR, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Ashlesh Gawande0421bc62020-05-08 20:42:19 -070020 */
Vince Lehmancec38852015-03-31 13:21:38 -050021
Ashlesh Gawandeeb582eb2014-05-01 14:25:20 -050022#include "route/nexthop-list.hpp"
23#include "route/nexthop.hpp"
Ashlesh Gawande6f0f35d2021-08-21 23:52:14 -070024#include "route/fib.hpp"
Davide Pesaventocb065f12019-12-27 01:03:34 -050025#include "tests/boost-test.hpp"
Ashlesh Gawandeeb582eb2014-05-01 14:25:20 -050026
27namespace nlsr {
Ashlesh Gawandeeb582eb2014-05-01 14:25:20 -050028namespace test {
29
30BOOST_AUTO_TEST_SUITE(TestNhl)
31
32BOOST_AUTO_TEST_CASE(NhlAddNextHop)
33{
34 NextHop np1;
35
36 NexthopList nhl1;
37
38 nhl1.addNextHop(np1);
Nick Gordonff9a6272017-10-12 13:38:29 -050039 BOOST_CHECK_EQUAL(nhl1.size(), (uint32_t)1);
Ashlesh Gawandeeb582eb2014-05-01 14:25:20 -050040
41 nhl1.removeNextHop(np1);
Nick Gordonff9a6272017-10-12 13:38:29 -050042 BOOST_CHECK_EQUAL(nhl1.size(), (uint32_t)0);
Ashlesh Gawandeeb582eb2014-05-01 14:25:20 -050043}
44
Vince Lehman20fe4a92014-09-09 15:57:59 -050045BOOST_AUTO_TEST_CASE(LinkStateRemoveNextHop)
Vince Lehman145064a2014-08-23 11:44:16 -050046{
47 NextHop hop1;
48 hop1.setRouteCost(12.34);
49
50 NexthopList hopList;
51 hopList.addNextHop(hop1);
52
53 NextHop hop2;
Vince Lehman20fe4a92014-09-09 15:57:59 -050054 hop2.setRouteCost(13.01);
55
Nick Gordonff9a6272017-10-12 13:38:29 -050056 BOOST_REQUIRE_EQUAL(hopList.size(), 1);
Vince Lehman20fe4a92014-09-09 15:57:59 -050057
58 hopList.removeNextHop(hop2);
Nick Gordonff9a6272017-10-12 13:38:29 -050059 BOOST_CHECK_EQUAL(hopList.size(), 1);
Vince Lehman20fe4a92014-09-09 15:57:59 -050060
61 hopList.removeNextHop(hop1);
Nick Gordonff9a6272017-10-12 13:38:29 -050062 BOOST_CHECK_EQUAL(hopList.size(), 0);
Vince Lehman20fe4a92014-09-09 15:57:59 -050063}
64
65BOOST_AUTO_TEST_CASE(HyperbolicRemoveNextHop)
66{
67 NextHop hop1;
68 hop1.setHyperbolic(true);
69 hop1.setRouteCost(12.34);
70
71 NexthopList hopList;
72 hopList.addNextHop(hop1);
73
74 NextHop hop2;
75 hop2.setHyperbolic(true);
Vince Lehman145064a2014-08-23 11:44:16 -050076 hop2.setRouteCost(12.35);
77
Nick Gordonff9a6272017-10-12 13:38:29 -050078 BOOST_REQUIRE_EQUAL(hopList.size(), 1);
Vince Lehman145064a2014-08-23 11:44:16 -050079
80 hopList.removeNextHop(hop2);
Nick Gordonff9a6272017-10-12 13:38:29 -050081 BOOST_CHECK_EQUAL(hopList.size(), 1);
Vince Lehman145064a2014-08-23 11:44:16 -050082
83 hopList.removeNextHop(hop1);
Nick Gordonff9a6272017-10-12 13:38:29 -050084 BOOST_CHECK_EQUAL(hopList.size(), 0);
Vince Lehman145064a2014-08-23 11:44:16 -050085}
86
Vince Lehmancec38852015-03-31 13:21:38 -050087BOOST_AUTO_TEST_CASE(TieBreaker)
88{
Vince Lehmanef21d8e2015-04-01 15:59:39 -050089 // equal-cost hops are sorted lexicographically
Vince Lehmancec38852015-03-31 13:21:38 -050090 NextHop hopA;
91 hopA.setRouteCost(25);
Vince Lehmanef21d8e2015-04-01 15:59:39 -050092 hopA.setConnectingFaceUri("AAAZZ");
Vince Lehmancec38852015-03-31 13:21:38 -050093
94 NextHop hopZ;
95 hopZ.setRouteCost(25);
Vince Lehmanef21d8e2015-04-01 15:59:39 -050096 hopZ.setConnectingFaceUri("ZZA");
Vince Lehmancec38852015-03-31 13:21:38 -050097
98 NexthopList list;
99 list.addNextHop(hopA);
100 list.addNextHop(hopZ);
101
Vince Lehmancec38852015-03-31 13:21:38 -0500102 NexthopList::iterator it = list.begin();
103 BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), hopA.getConnectingFaceUri());
104
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700105 list.clear();
Vince Lehmancec38852015-03-31 13:21:38 -0500106 list.addNextHop(hopZ);
107 list.addNextHop(hopA);
108
Vince Lehmancec38852015-03-31 13:21:38 -0500109 it = list.begin();
110 BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), hopA.getConnectingFaceUri());
Vince Lehmanef21d8e2015-04-01 15:59:39 -0500111
112
113 // equal-cost and lexicographically equal hops are sorted by the length of their face uris
114 NextHop longUriHop;
115 longUriHop.setRouteCost(25);
116 longUriHop.setConnectingFaceUri("AAAAAA");
117
118 NextHop shortUriHop;
119 shortUriHop.setRouteCost(25);
120 shortUriHop.setConnectingFaceUri("AAA");
121
Ashlesh Gawande0421bc62020-05-08 20:42:19 -0700122 list.clear();
Vince Lehmanef21d8e2015-04-01 15:59:39 -0500123 list.addNextHop(longUriHop);
124 list.addNextHop(shortUriHop);
125
126 it = list.begin();
127 BOOST_CHECK_EQUAL(it->getConnectingFaceUri(), shortUriHop.getConnectingFaceUri());
128}
129
130BOOST_AUTO_TEST_CASE(SortOnAddAndRemove)
131{
132 NexthopList list;
133
134 NextHop hopA("A", 10);
135 NextHop hopB("B", 5);
136 NextHop hopC("C", 25);
137
138 list.addNextHop(hopA);
139 list.addNextHop(hopB);
140 list.addNextHop(hopC);
141
Nick Gordonff9a6272017-10-12 13:38:29 -0500142 BOOST_REQUIRE_EQUAL(list.size(), 3);
Vince Lehmanef21d8e2015-04-01 15:59:39 -0500143
144 double lastCost = 0;
145 for (const auto& hop : list) {
146 BOOST_CHECK(hop.getRouteCost() > lastCost);
147 lastCost = hop.getRouteCost();
148 }
149
150 // removing a hop keep the list sorted
151 list.removeNextHop(hopA);
152
Nick Gordonff9a6272017-10-12 13:38:29 -0500153 BOOST_REQUIRE_EQUAL(list.size(), 2);
Vince Lehmanef21d8e2015-04-01 15:59:39 -0500154
155 lastCost = 0;
156 for (const auto& hop : list) {
157 BOOST_CHECK(hop.getRouteCost() > lastCost);
158 lastCost = hop.getRouteCost();
159 }
Vince Lehmancec38852015-03-31 13:21:38 -0500160}
161
Nick Gordon608061b2017-07-06 12:45:04 -0500162/* If there are two NextHops going to the same neighbor, then the list
163 should always select the one with the cheaper cost. This would be
164 caused by a Name being advertised by two different routers, which
165 are reachable through the same neighbor.
166 */
167BOOST_AUTO_TEST_CASE(UseCheaperNextHop)
168{
169 NexthopList list;
170
171 NextHop hopA("udp4://10.0.0.1:6363", 10);
172 NextHop hopB("udp4://10.0.0.1:6363", 5);
173
174 list.addNextHop(hopA);
175 list.addNextHop(hopB);
176
Nick Gordonff9a6272017-10-12 13:38:29 -0500177 BOOST_REQUIRE_EQUAL(list.size(), 1);
Nick Gordon608061b2017-07-06 12:45:04 -0500178
179 for (const auto& hop : list) {
180 BOOST_CHECK_EQUAL(hop, hopB);
181 }
182}
183
Ashlesh Gawande6f0f35d2021-08-21 23:52:14 -0700184/* Fib needs a NexthopList to be sorted by FaceUri when updating
185 to avoid removing prefixes that were just installed. The above
186 test does not apply to this scenario as the NexthopList
187 sorted by cost is given to the Fib::update.
188 */
189BOOST_AUTO_TEST_CASE(NextHopListDiffForFibUpdate) // #5179
190{
191 // If default sorter is used then difference results in
192 // the same hops to remove as those that were added
193 NexthopList nhl1;
194 nhl1.addNextHop(NextHop("udp4://10.0.0.13:6363", 28));
195 nhl1.addNextHop(NextHop("udp4://10.0.0.9:6363", 38));
196 nhl1.addNextHop(NextHop("udp4://10.0.0.26:6363", 44));
197
198 NexthopList nhl2;
199 nhl2.addNextHop(NextHop("udp4://10.0.0.9:6363", 21));
200 nhl2.addNextHop(NextHop("udp4://10.0.0.13:6363", 26));
201 nhl2.addNextHop(NextHop("udp4://10.0.0.26:6363", 42));
202
203 std::set<NextHop, NextHopComparator> hopsToRemove;
204 std::set_difference(nhl2.begin(), nhl2.end(),
205 nhl1.begin(), nhl1.end(),
206 std::inserter(hopsToRemove, hopsToRemove.begin()),
207 NextHopComparator());
208
209 BOOST_CHECK_EQUAL(hopsToRemove.size(), 3);
210
211 // Sorted by FaceUri
212 NextHopsUriSortedSet nhs1;
213 nhs1.addNextHop(NextHop("udp4://10.0.0.13:6363", 28));
214 nhs1.addNextHop(NextHop("udp4://10.0.0.9:6363", 38));
215 nhs1.addNextHop(NextHop("udp4://10.0.0.26:6363", 44));
216
217 NextHopsUriSortedSet nhs2;
218 nhs2.addNextHop(NextHop("udp4://10.0.0.9:6363", 21));
219 nhs2.addNextHop(NextHop("udp4://10.0.0.13:6363", 26));
220 nhs2.addNextHop(NextHop("udp4://10.0.0.26:6363", 42));
221
222 std::set<NextHop, NextHopUriSortedComparator> hopsToRemove2;
223 std::set_difference(nhs2.begin(), nhs2.end(),
224 nhs1.begin(), nhs1.end(),
225 std::inserter(hopsToRemove2, hopsToRemove2.begin()),
226 NextHopUriSortedComparator());
227
228 BOOST_CHECK_EQUAL(hopsToRemove2.size(), 0);
229}
230
Ashlesh Gawandeeb582eb2014-05-01 14:25:20 -0500231BOOST_AUTO_TEST_SUITE_END()
232
Nick Gordonfad8e252016-08-11 14:21:38 -0500233} // namespace test
234} // namespace nlsr