blob: 629a10f8521d6b09edfc5964bfca73d19e98c96a [file] [log] [blame]
Junxiao Shic1e12362014-01-24 20:03:26 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev9bcbc7c2014-04-06 19:37:37 -07003 * Copyright (c) 2014 Regents of the University of California,
4 * 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 *
10 * This file is part of NFD (Named Data Networking Forwarding Daemon).
11 * See AUTHORS.md for complete list of NFD authors and contributors.
12 *
13 * NFD is free software: you can redistribute it and/or modify it under the terms
14 * of the GNU General Public License as published by the Free Software Foundation,
15 * either version 3 of the License, or (at your option) any later version.
16 *
17 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
18 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
19 * PURPOSE. See the GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along with
22 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
23 **/
Junxiao Shic1e12362014-01-24 20:03:26 -070024
25#include "table/fib.hpp"
Junxiao Shid9ee45c2014-02-27 15:38:11 -070026#include "tests/face/dummy-face.hpp"
Junxiao Shic1e12362014-01-24 20:03:26 -070027
Junxiao Shid9ee45c2014-02-27 15:38:11 -070028#include "tests/test-common.hpp"
Junxiao Shic1e12362014-01-24 20:03:26 -070029
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080030namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070031namespace tests {
Junxiao Shic1e12362014-01-24 20:03:26 -070032
Junxiao Shid9ee45c2014-02-27 15:38:11 -070033BOOST_FIXTURE_TEST_SUITE(TableFib, BaseFixture)
Junxiao Shic1e12362014-01-24 20:03:26 -070034
35BOOST_AUTO_TEST_CASE(Entry)
36{
37 Name prefix("ndn:/pxWhfFza");
Junxiao Shi8c8d2182014-01-30 22:33:00 -070038 shared_ptr<Face> face1 = make_shared<DummyFace>();
39 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shiefceadc2014-03-09 18:52:57 -070040
Junxiao Shic1e12362014-01-24 20:03:26 -070041 fib::Entry entry(prefix);
Junxiao Shiefceadc2014-03-09 18:52:57 -070042 BOOST_CHECK_EQUAL(entry.getPrefix(), prefix);
43
Junxiao Shic1e12362014-01-24 20:03:26 -070044 const fib::NextHopList& nexthops1 = entry.getNextHops();
45 // []
46 BOOST_CHECK_EQUAL(nexthops1.size(), 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -070047
Junxiao Shic1e12362014-01-24 20:03:26 -070048 entry.addNextHop(face1, 20);
49 const fib::NextHopList& nexthops2 = entry.getNextHops();
50 // [(face1,20)]
51 BOOST_CHECK_EQUAL(nexthops2.size(), 1);
52 BOOST_CHECK_EQUAL(nexthops2.begin()->getFace(), face1);
53 BOOST_CHECK_EQUAL(nexthops2.begin()->getCost(), 20);
Junxiao Shiefceadc2014-03-09 18:52:57 -070054
Junxiao Shic1e12362014-01-24 20:03:26 -070055 entry.addNextHop(face1, 30);
56 const fib::NextHopList& nexthops3 = entry.getNextHops();
57 // [(face1,30)]
58 BOOST_CHECK_EQUAL(nexthops3.size(), 1);
59 BOOST_CHECK_EQUAL(nexthops3.begin()->getFace(), face1);
60 BOOST_CHECK_EQUAL(nexthops3.begin()->getCost(), 30);
61
62 entry.addNextHop(face2, 40);
63 const fib::NextHopList& nexthops4 = entry.getNextHops();
64 // [(face1,30), (face2,40)]
65 BOOST_CHECK_EQUAL(nexthops4.size(), 2);
66 int i = -1;
67 for (fib::NextHopList::const_iterator it = nexthops4.begin();
68 it != nexthops4.end(); ++it) {
69 ++i;
70 switch (i) {
71 case 0 :
72 BOOST_CHECK_EQUAL(it->getFace(), face1);
73 BOOST_CHECK_EQUAL(it->getCost(), 30);
74 break;
75 case 1 :
76 BOOST_CHECK_EQUAL(it->getFace(), face2);
77 BOOST_CHECK_EQUAL(it->getCost(), 40);
78 break;
79 }
80 }
81
82 entry.addNextHop(face2, 10);
83 const fib::NextHopList& nexthops5 = entry.getNextHops();
84 // [(face2,10), (face1,30)]
85 BOOST_CHECK_EQUAL(nexthops5.size(), 2);
86 i = -1;
87 for (fib::NextHopList::const_iterator it = nexthops5.begin();
88 it != nexthops5.end(); ++it) {
89 ++i;
90 switch (i) {
91 case 0 :
92 BOOST_CHECK_EQUAL(it->getFace(), face2);
93 BOOST_CHECK_EQUAL(it->getCost(), 10);
94 break;
95 case 1 :
96 BOOST_CHECK_EQUAL(it->getFace(), face1);
97 BOOST_CHECK_EQUAL(it->getCost(), 30);
98 break;
99 }
100 }
Junxiao Shiefceadc2014-03-09 18:52:57 -0700101
Junxiao Shic1e12362014-01-24 20:03:26 -0700102 entry.removeNextHop(face1);
103 const fib::NextHopList& nexthops6 = entry.getNextHops();
104 // [(face2,10)]
105 BOOST_CHECK_EQUAL(nexthops6.size(), 1);
106 BOOST_CHECK_EQUAL(nexthops6.begin()->getFace(), face2);
107 BOOST_CHECK_EQUAL(nexthops6.begin()->getCost(), 10);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700108
Junxiao Shic1e12362014-01-24 20:03:26 -0700109 entry.removeNextHop(face1);
110 const fib::NextHopList& nexthops7 = entry.getNextHops();
111 // [(face2,10)]
112 BOOST_CHECK_EQUAL(nexthops7.size(), 1);
113 BOOST_CHECK_EQUAL(nexthops7.begin()->getFace(), face2);
114 BOOST_CHECK_EQUAL(nexthops7.begin()->getCost(), 10);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700115
Junxiao Shic1e12362014-01-24 20:03:26 -0700116 entry.removeNextHop(face2);
117 const fib::NextHopList& nexthops8 = entry.getNextHops();
118 // []
119 BOOST_CHECK_EQUAL(nexthops8.size(), 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700120
Junxiao Shic1e12362014-01-24 20:03:26 -0700121 entry.removeNextHop(face2);
122 const fib::NextHopList& nexthops9 = entry.getNextHops();
123 // []
124 BOOST_CHECK_EQUAL(nexthops9.size(), 0);
125}
126
127BOOST_AUTO_TEST_CASE(Insert_LongestPrefixMatch)
128{
129 Name nameEmpty;
130 Name nameA ("ndn:/A");
131 Name nameAB ("ndn:/A/B");
132 Name nameABC ("ndn:/A/B/C");
133 Name nameABCD("ndn:/A/B/C/D");
134 Name nameE ("ndn:/E");
Junxiao Shiefceadc2014-03-09 18:52:57 -0700135
Junxiao Shic1e12362014-01-24 20:03:26 -0700136 std::pair<shared_ptr<fib::Entry>, bool> insertRes;
137 shared_ptr<fib::Entry> entry;
138
Haowei Yuanf52dac72014-03-24 23:35:03 -0500139 NameTree nameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800140 Fib fib(nameTree);
Junxiao Shi40631842014-03-01 13:52:37 -0700141 // []
Junxiao Shiefceadc2014-03-09 18:52:57 -0700142 BOOST_CHECK_EQUAL(fib.size(), 0);
Junxiao Shi40631842014-03-01 13:52:37 -0700143
144 entry = fib.findLongestPrefixMatch(nameA);
145 BOOST_REQUIRE(static_cast<bool>(entry)); // the empty entry
Junxiao Shiefceadc2014-03-09 18:52:57 -0700146
Junxiao Shi40631842014-03-01 13:52:37 -0700147 insertRes = fib.insert(nameEmpty);
148 BOOST_CHECK_EQUAL(insertRes.second, true);
149 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700150 // ['/']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700151 BOOST_CHECK_EQUAL(fib.size(), 1);
152
Junxiao Shic1e12362014-01-24 20:03:26 -0700153 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700154 BOOST_REQUIRE(static_cast<bool>(entry));
155 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700156
Junxiao Shic1e12362014-01-24 20:03:26 -0700157 insertRes = fib.insert(nameA);
158 BOOST_CHECK_EQUAL(insertRes.second, true);
Junxiao Shi40631842014-03-01 13:52:37 -0700159 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700160 // ['/', '/A']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700161 BOOST_CHECK_EQUAL(fib.size(), 2);
162
Junxiao Shic1e12362014-01-24 20:03:26 -0700163 insertRes = fib.insert(nameA);
164 BOOST_CHECK_EQUAL(insertRes.second, false);
Junxiao Shi40631842014-03-01 13:52:37 -0700165 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700166 // ['/', '/A']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700167 BOOST_CHECK_EQUAL(fib.size(), 2);
Junxiao Shic1e12362014-01-24 20:03:26 -0700168
169 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700170 BOOST_REQUIRE(static_cast<bool>(entry));
171 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700172
Junxiao Shic1e12362014-01-24 20:03:26 -0700173 entry = fib.findLongestPrefixMatch(nameABCD);
Junxiao Shi40631842014-03-01 13:52:37 -0700174 BOOST_REQUIRE(static_cast<bool>(entry));
175 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700176
Junxiao Shic1e12362014-01-24 20:03:26 -0700177 insertRes = fib.insert(nameABC);
178 BOOST_CHECK_EQUAL(insertRes.second, true);
Junxiao Shi40631842014-03-01 13:52:37 -0700179 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameABC);
Junxiao Shic1e12362014-01-24 20:03:26 -0700180 // ['/', '/A', '/A/B/C']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700181 BOOST_CHECK_EQUAL(fib.size(), 3);
Junxiao Shic1e12362014-01-24 20:03:26 -0700182
183 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700184 BOOST_REQUIRE(static_cast<bool>(entry));
185 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700186
Junxiao Shic1e12362014-01-24 20:03:26 -0700187 entry = fib.findLongestPrefixMatch(nameAB);
Junxiao Shi40631842014-03-01 13:52:37 -0700188 BOOST_REQUIRE(static_cast<bool>(entry));
189 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700190
Junxiao Shic1e12362014-01-24 20:03:26 -0700191 entry = fib.findLongestPrefixMatch(nameABCD);
Junxiao Shi40631842014-03-01 13:52:37 -0700192 BOOST_REQUIRE(static_cast<bool>(entry));
193 BOOST_CHECK_EQUAL(entry->getPrefix(), nameABC);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700194
Junxiao Shic1e12362014-01-24 20:03:26 -0700195 entry = fib.findLongestPrefixMatch(nameE);
Junxiao Shi40631842014-03-01 13:52:37 -0700196 BOOST_REQUIRE(static_cast<bool>(entry));
197 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700198}
199
200BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
201{
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700202 shared_ptr<Face> face1 = make_shared<DummyFace>();
203 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shiefceadc2014-03-09 18:52:57 -0700204 Name nameEmpty("ndn:/");
Junxiao Shic1e12362014-01-24 20:03:26 -0700205 Name nameA("ndn:/A");
206 Name nameB("ndn:/B");
Junxiao Shiefceadc2014-03-09 18:52:57 -0700207
Junxiao Shic1e12362014-01-24 20:03:26 -0700208 std::pair<shared_ptr<fib::Entry>, bool> insertRes;
209 shared_ptr<fib::Entry> entry;
Junxiao Shiefceadc2014-03-09 18:52:57 -0700210
Haowei Yuanf52dac72014-03-24 23:35:03 -0500211 NameTree nameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800212 Fib fib(nameTree);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700213 // {}
214
Junxiao Shic1e12362014-01-24 20:03:26 -0700215 insertRes = fib.insert(nameA);
216 insertRes.first->addNextHop(face1, 0);
217 insertRes.first->addNextHop(face2, 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700218 // {'/A':[1,2]}
Junxiao Shic1e12362014-01-24 20:03:26 -0700219
220 insertRes = fib.insert(nameB);
221 insertRes.first->addNextHop(face1, 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700222 // {'/A':[1,2], '/B':[1]}
223 BOOST_CHECK_EQUAL(fib.size(), 2);
224
Junxiao Shic1e12362014-01-24 20:03:26 -0700225 fib.removeNextHopFromAllEntries(face1);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700226 // {'/A':[2]}
227 BOOST_CHECK_EQUAL(fib.size(), 1);
228
Junxiao Shic1e12362014-01-24 20:03:26 -0700229 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700230 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700231 const fib::NextHopList& nexthopsA = entry->getNextHops();
232 BOOST_CHECK_EQUAL(nexthopsA.size(), 1);
233 BOOST_CHECK_EQUAL(nexthopsA.begin()->getFace(), face2);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700234
Junxiao Shic1e12362014-01-24 20:03:26 -0700235 entry = fib.findLongestPrefixMatch(nameB);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700236 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700237}
238
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700239void
240validateFindExactMatch(const Fib& fib, const Name& target)
241{
242 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
243 if (static_cast<bool>(entry))
244 {
245 BOOST_CHECK_EQUAL(entry->getPrefix(), target);
246 }
247 else
248 {
249 BOOST_FAIL("No entry found for " << target);
250 }
251}
252
253void
254validateNoExactMatch(const Fib& fib, const Name& target)
255{
256 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
257 if (static_cast<bool>(entry))
258 {
259 BOOST_FAIL("Found unexpected entry for " << target);
260 }
261}
262
263BOOST_AUTO_TEST_CASE(FindExactMatch)
264{
Haowei Yuanf52dac72014-03-24 23:35:03 -0500265 NameTree nameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800266 Fib fib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700267 fib.insert("/A");
268 fib.insert("/A/B");
269 fib.insert("/A/B/C");
270
271 validateFindExactMatch(fib, "/A");
272 validateFindExactMatch(fib, "/A/B");
273 validateFindExactMatch(fib, "/A/B/C");
Junxiao Shi40631842014-03-01 13:52:37 -0700274 validateNoExactMatch(fib, "/");
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700275
276 validateNoExactMatch(fib, "/does/not/exist");
277
Haowei Yuanf52dac72014-03-24 23:35:03 -0500278 NameTree gapNameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800279 Fib gapFib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700280 fib.insert("/X");
281 fib.insert("/X/Y/Z");
282
283 validateNoExactMatch(gapFib, "/X/Y");
284
Haowei Yuanf52dac72014-03-24 23:35:03 -0500285 NameTree emptyNameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800286 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700287 validateNoExactMatch(emptyFib, "/nothing/here");
288}
289
290void
291validateRemove(Fib& fib, const Name& target)
292{
HangZhangad4afd12014-03-01 11:03:08 +0800293 fib.erase(target);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700294
295 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
296 if (static_cast<bool>(entry))
297 {
298 BOOST_FAIL("Found \"removed\" entry for " << target);
299 }
300}
301
302BOOST_AUTO_TEST_CASE(Remove)
303{
Haowei Yuanf52dac72014-03-24 23:35:03 -0500304 NameTree emptyNameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800305 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700306
HangZhangad4afd12014-03-01 11:03:08 +0800307 emptyFib.erase("/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700308
309 validateRemove(emptyFib, "/");
310
HangZhangad4afd12014-03-01 11:03:08 +0800311 emptyFib.erase("/still/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700312
Haowei Yuanf52dac72014-03-24 23:35:03 -0500313 NameTree nameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800314 Fib fib(nameTree);
Junxiao Shi40631842014-03-01 13:52:37 -0700315 fib.insert("/");
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700316 fib.insert("/A");
317 fib.insert("/A/B");
318 fib.insert("/A/B/C");
319
320 // check if we remove the right thing and leave
321 // everything else alone
322
323 validateRemove(fib, "/A/B");
324 validateFindExactMatch(fib, "/A");
325 validateFindExactMatch(fib, "/A/B/C");
326 validateFindExactMatch(fib, "/");
327
328 validateRemove(fib, "/A/B/C");
329 validateFindExactMatch(fib, "/A");
330 validateFindExactMatch(fib, "/");
331
332 validateRemove(fib, "/A");
333 validateFindExactMatch(fib, "/");
334
Junxiao Shi40631842014-03-01 13:52:37 -0700335 validateRemove(fib, "/");
336 validateNoExactMatch(fib, "/");
337
Haowei Yuanf52dac72014-03-24 23:35:03 -0500338 NameTree gapNameTree;
HangZhangad4afd12014-03-01 11:03:08 +0800339 Fib gapFib(gapNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700340 gapFib.insert("/X");
341 gapFib.insert("/X/Y/Z");
342
HangZhangad4afd12014-03-01 11:03:08 +0800343 gapFib.erase("/X/Y"); //should do nothing
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700344 validateFindExactMatch(gapFib, "/X");
345 validateFindExactMatch(gapFib, "/X/Y/Z");
346}
347
HangZhang5d469422014-03-12 09:26:26 +0800348BOOST_AUTO_TEST_CASE(Iterator)
349{
Haowei Yuanf52dac72014-03-24 23:35:03 -0500350 NameTree nameTree;
HangZhang5d469422014-03-12 09:26:26 +0800351 Fib fib(nameTree);
352 Name nameA("/A");
353 Name nameAB("/A/B");
354 Name nameABC("/A/B/C");
355 Name nameRoot("/");
356
357 fib.insert(nameA);
358 fib.insert(nameAB);
359 fib.insert(nameABC);
360 fib.insert(nameRoot);
361
362 std::set<Name> expected;
363 expected.insert(nameA);
364 expected.insert(nameAB);
365 expected.insert(nameABC);
366 expected.insert(nameRoot);
367
368 for (Fib::const_iterator it = fib.begin(); it != fib.end(); it++)
369 {
370 bool isInSet = expected.find(it->getPrefix()) != expected.end();
371 BOOST_CHECK(isInSet);
372 expected.erase(it->getPrefix());
373 }
374
375 BOOST_CHECK_EQUAL(expected.size(), 0);
376}
377
Junxiao Shic1e12362014-01-24 20:03:26 -0700378BOOST_AUTO_TEST_SUITE_END()
379
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700380} // namespace tests
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800381} // namespace nfd