blob: a86d5ad0b6e89829931e00cde1b6a459874fee46 [file] [log] [blame]
Junxiao Shic1e12362014-01-24 20:03:26 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "table/fib.hpp"
Junxiao Shid9ee45c2014-02-27 15:38:11 -07008#include "tests/face/dummy-face.hpp"
Junxiao Shic1e12362014-01-24 20:03:26 -07009
Junxiao Shid9ee45c2014-02-27 15:38:11 -070010#include "tests/test-common.hpp"
Junxiao Shic1e12362014-01-24 20:03:26 -070011
Alexander Afanasyev18bbf812014-01-29 01:40:23 -080012namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070013namespace tests {
Junxiao Shic1e12362014-01-24 20:03:26 -070014
Junxiao Shid9ee45c2014-02-27 15:38:11 -070015BOOST_FIXTURE_TEST_SUITE(TableFib, BaseFixture)
Junxiao Shic1e12362014-01-24 20:03:26 -070016
17BOOST_AUTO_TEST_CASE(Entry)
18{
19 Name prefix("ndn:/pxWhfFza");
Junxiao Shi8c8d2182014-01-30 22:33:00 -070020 shared_ptr<Face> face1 = make_shared<DummyFace>();
21 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shiefceadc2014-03-09 18:52:57 -070022
Junxiao Shic1e12362014-01-24 20:03:26 -070023 fib::Entry entry(prefix);
Junxiao Shiefceadc2014-03-09 18:52:57 -070024 BOOST_CHECK_EQUAL(entry.getPrefix(), prefix);
25
Junxiao Shic1e12362014-01-24 20:03:26 -070026 const fib::NextHopList& nexthops1 = entry.getNextHops();
27 // []
28 BOOST_CHECK_EQUAL(nexthops1.size(), 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -070029
Junxiao Shic1e12362014-01-24 20:03:26 -070030 entry.addNextHop(face1, 20);
31 const fib::NextHopList& nexthops2 = entry.getNextHops();
32 // [(face1,20)]
33 BOOST_CHECK_EQUAL(nexthops2.size(), 1);
34 BOOST_CHECK_EQUAL(nexthops2.begin()->getFace(), face1);
35 BOOST_CHECK_EQUAL(nexthops2.begin()->getCost(), 20);
Junxiao Shiefceadc2014-03-09 18:52:57 -070036
Junxiao Shic1e12362014-01-24 20:03:26 -070037 entry.addNextHop(face1, 30);
38 const fib::NextHopList& nexthops3 = entry.getNextHops();
39 // [(face1,30)]
40 BOOST_CHECK_EQUAL(nexthops3.size(), 1);
41 BOOST_CHECK_EQUAL(nexthops3.begin()->getFace(), face1);
42 BOOST_CHECK_EQUAL(nexthops3.begin()->getCost(), 30);
43
44 entry.addNextHop(face2, 40);
45 const fib::NextHopList& nexthops4 = entry.getNextHops();
46 // [(face1,30), (face2,40)]
47 BOOST_CHECK_EQUAL(nexthops4.size(), 2);
48 int i = -1;
49 for (fib::NextHopList::const_iterator it = nexthops4.begin();
50 it != nexthops4.end(); ++it) {
51 ++i;
52 switch (i) {
53 case 0 :
54 BOOST_CHECK_EQUAL(it->getFace(), face1);
55 BOOST_CHECK_EQUAL(it->getCost(), 30);
56 break;
57 case 1 :
58 BOOST_CHECK_EQUAL(it->getFace(), face2);
59 BOOST_CHECK_EQUAL(it->getCost(), 40);
60 break;
61 }
62 }
63
64 entry.addNextHop(face2, 10);
65 const fib::NextHopList& nexthops5 = entry.getNextHops();
66 // [(face2,10), (face1,30)]
67 BOOST_CHECK_EQUAL(nexthops5.size(), 2);
68 i = -1;
69 for (fib::NextHopList::const_iterator it = nexthops5.begin();
70 it != nexthops5.end(); ++it) {
71 ++i;
72 switch (i) {
73 case 0 :
74 BOOST_CHECK_EQUAL(it->getFace(), face2);
75 BOOST_CHECK_EQUAL(it->getCost(), 10);
76 break;
77 case 1 :
78 BOOST_CHECK_EQUAL(it->getFace(), face1);
79 BOOST_CHECK_EQUAL(it->getCost(), 30);
80 break;
81 }
82 }
Junxiao Shiefceadc2014-03-09 18:52:57 -070083
Junxiao Shic1e12362014-01-24 20:03:26 -070084 entry.removeNextHop(face1);
85 const fib::NextHopList& nexthops6 = entry.getNextHops();
86 // [(face2,10)]
87 BOOST_CHECK_EQUAL(nexthops6.size(), 1);
88 BOOST_CHECK_EQUAL(nexthops6.begin()->getFace(), face2);
89 BOOST_CHECK_EQUAL(nexthops6.begin()->getCost(), 10);
Junxiao Shiefceadc2014-03-09 18:52:57 -070090
Junxiao Shic1e12362014-01-24 20:03:26 -070091 entry.removeNextHop(face1);
92 const fib::NextHopList& nexthops7 = entry.getNextHops();
93 // [(face2,10)]
94 BOOST_CHECK_EQUAL(nexthops7.size(), 1);
95 BOOST_CHECK_EQUAL(nexthops7.begin()->getFace(), face2);
96 BOOST_CHECK_EQUAL(nexthops7.begin()->getCost(), 10);
Junxiao Shiefceadc2014-03-09 18:52:57 -070097
Junxiao Shic1e12362014-01-24 20:03:26 -070098 entry.removeNextHop(face2);
99 const fib::NextHopList& nexthops8 = entry.getNextHops();
100 // []
101 BOOST_CHECK_EQUAL(nexthops8.size(), 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700102
Junxiao Shic1e12362014-01-24 20:03:26 -0700103 entry.removeNextHop(face2);
104 const fib::NextHopList& nexthops9 = entry.getNextHops();
105 // []
106 BOOST_CHECK_EQUAL(nexthops9.size(), 0);
107}
108
109BOOST_AUTO_TEST_CASE(Insert_LongestPrefixMatch)
110{
111 Name nameEmpty;
112 Name nameA ("ndn:/A");
113 Name nameAB ("ndn:/A/B");
114 Name nameABC ("ndn:/A/B/C");
115 Name nameABCD("ndn:/A/B/C/D");
116 Name nameE ("ndn:/E");
Junxiao Shiefceadc2014-03-09 18:52:57 -0700117
Junxiao Shic1e12362014-01-24 20:03:26 -0700118 std::pair<shared_ptr<fib::Entry>, bool> insertRes;
119 shared_ptr<fib::Entry> entry;
120
HangZhangad4afd12014-03-01 11:03:08 +0800121 NameTree nameTree(1024);
122 Fib fib(nameTree);
Junxiao Shi40631842014-03-01 13:52:37 -0700123 // []
Junxiao Shiefceadc2014-03-09 18:52:57 -0700124 BOOST_CHECK_EQUAL(fib.size(), 0);
Junxiao Shi40631842014-03-01 13:52:37 -0700125
126 entry = fib.findLongestPrefixMatch(nameA);
127 BOOST_REQUIRE(static_cast<bool>(entry)); // the empty entry
Junxiao Shiefceadc2014-03-09 18:52:57 -0700128
Junxiao Shi40631842014-03-01 13:52:37 -0700129 insertRes = fib.insert(nameEmpty);
130 BOOST_CHECK_EQUAL(insertRes.second, true);
131 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700132 // ['/']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700133 BOOST_CHECK_EQUAL(fib.size(), 1);
134
Junxiao Shic1e12362014-01-24 20:03:26 -0700135 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700136 BOOST_REQUIRE(static_cast<bool>(entry));
137 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700138
Junxiao Shic1e12362014-01-24 20:03:26 -0700139 insertRes = fib.insert(nameA);
140 BOOST_CHECK_EQUAL(insertRes.second, true);
Junxiao Shi40631842014-03-01 13:52:37 -0700141 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700142 // ['/', '/A']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700143 BOOST_CHECK_EQUAL(fib.size(), 2);
144
Junxiao Shic1e12362014-01-24 20:03:26 -0700145 insertRes = fib.insert(nameA);
146 BOOST_CHECK_EQUAL(insertRes.second, false);
Junxiao Shi40631842014-03-01 13:52:37 -0700147 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700148 // ['/', '/A']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700149 BOOST_CHECK_EQUAL(fib.size(), 2);
Junxiao Shic1e12362014-01-24 20:03:26 -0700150
151 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700152 BOOST_REQUIRE(static_cast<bool>(entry));
153 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700154
Junxiao Shic1e12362014-01-24 20:03:26 -0700155 entry = fib.findLongestPrefixMatch(nameABCD);
Junxiao Shi40631842014-03-01 13:52:37 -0700156 BOOST_REQUIRE(static_cast<bool>(entry));
157 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700158
Junxiao Shic1e12362014-01-24 20:03:26 -0700159 insertRes = fib.insert(nameABC);
160 BOOST_CHECK_EQUAL(insertRes.second, true);
Junxiao Shi40631842014-03-01 13:52:37 -0700161 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameABC);
Junxiao Shic1e12362014-01-24 20:03:26 -0700162 // ['/', '/A', '/A/B/C']
Junxiao Shiefceadc2014-03-09 18:52:57 -0700163 BOOST_CHECK_EQUAL(fib.size(), 3);
Junxiao Shic1e12362014-01-24 20:03:26 -0700164
165 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700166 BOOST_REQUIRE(static_cast<bool>(entry));
167 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700168
Junxiao Shic1e12362014-01-24 20:03:26 -0700169 entry = fib.findLongestPrefixMatch(nameAB);
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(), nameABC);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700176
Junxiao Shic1e12362014-01-24 20:03:26 -0700177 entry = fib.findLongestPrefixMatch(nameE);
Junxiao Shi40631842014-03-01 13:52:37 -0700178 BOOST_REQUIRE(static_cast<bool>(entry));
179 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700180}
181
182BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
183{
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700184 shared_ptr<Face> face1 = make_shared<DummyFace>();
185 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shiefceadc2014-03-09 18:52:57 -0700186 Name nameEmpty("ndn:/");
Junxiao Shic1e12362014-01-24 20:03:26 -0700187 Name nameA("ndn:/A");
188 Name nameB("ndn:/B");
Junxiao Shiefceadc2014-03-09 18:52:57 -0700189
Junxiao Shic1e12362014-01-24 20:03:26 -0700190 std::pair<shared_ptr<fib::Entry>, bool> insertRes;
191 shared_ptr<fib::Entry> entry;
Junxiao Shiefceadc2014-03-09 18:52:57 -0700192
HangZhangad4afd12014-03-01 11:03:08 +0800193 NameTree nameTree(1024);
194 Fib fib(nameTree);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700195 // {}
196
Junxiao Shic1e12362014-01-24 20:03:26 -0700197 insertRes = fib.insert(nameA);
198 insertRes.first->addNextHop(face1, 0);
199 insertRes.first->addNextHop(face2, 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700200 // {'/A':[1,2]}
Junxiao Shic1e12362014-01-24 20:03:26 -0700201
202 insertRes = fib.insert(nameB);
203 insertRes.first->addNextHop(face1, 0);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700204 // {'/A':[1,2], '/B':[1]}
205 BOOST_CHECK_EQUAL(fib.size(), 2);
206
Junxiao Shic1e12362014-01-24 20:03:26 -0700207 fib.removeNextHopFromAllEntries(face1);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700208 // {'/A':[2]}
209 BOOST_CHECK_EQUAL(fib.size(), 1);
210
Junxiao Shic1e12362014-01-24 20:03:26 -0700211 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700212 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700213 const fib::NextHopList& nexthopsA = entry->getNextHops();
214 BOOST_CHECK_EQUAL(nexthopsA.size(), 1);
215 BOOST_CHECK_EQUAL(nexthopsA.begin()->getFace(), face2);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700216
Junxiao Shic1e12362014-01-24 20:03:26 -0700217 entry = fib.findLongestPrefixMatch(nameB);
Junxiao Shiefceadc2014-03-09 18:52:57 -0700218 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700219}
220
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700221void
222validateFindExactMatch(const Fib& fib, const Name& target)
223{
224 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
225 if (static_cast<bool>(entry))
226 {
227 BOOST_CHECK_EQUAL(entry->getPrefix(), target);
228 }
229 else
230 {
231 BOOST_FAIL("No entry found for " << target);
232 }
233}
234
235void
236validateNoExactMatch(const Fib& fib, const Name& target)
237{
238 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
239 if (static_cast<bool>(entry))
240 {
241 BOOST_FAIL("Found unexpected entry for " << target);
242 }
243}
244
245BOOST_AUTO_TEST_CASE(FindExactMatch)
246{
HangZhangad4afd12014-03-01 11:03:08 +0800247 NameTree nameTree(1024);
248 Fib fib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700249 fib.insert("/A");
250 fib.insert("/A/B");
251 fib.insert("/A/B/C");
252
253 validateFindExactMatch(fib, "/A");
254 validateFindExactMatch(fib, "/A/B");
255 validateFindExactMatch(fib, "/A/B/C");
Junxiao Shi40631842014-03-01 13:52:37 -0700256 validateNoExactMatch(fib, "/");
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700257
258 validateNoExactMatch(fib, "/does/not/exist");
259
HangZhangad4afd12014-03-01 11:03:08 +0800260 NameTree gapNameTree(1024);
261 Fib gapFib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700262 fib.insert("/X");
263 fib.insert("/X/Y/Z");
264
265 validateNoExactMatch(gapFib, "/X/Y");
266
HangZhangad4afd12014-03-01 11:03:08 +0800267 NameTree emptyNameTree(1024);
268 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700269 validateNoExactMatch(emptyFib, "/nothing/here");
270}
271
272void
273validateRemove(Fib& fib, const Name& target)
274{
HangZhangad4afd12014-03-01 11:03:08 +0800275 fib.erase(target);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700276
277 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
278 if (static_cast<bool>(entry))
279 {
280 BOOST_FAIL("Found \"removed\" entry for " << target);
281 }
282}
283
284BOOST_AUTO_TEST_CASE(Remove)
285{
HangZhangad4afd12014-03-01 11:03:08 +0800286 NameTree emptyNameTree(1024);
287 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700288
HangZhangad4afd12014-03-01 11:03:08 +0800289 emptyFib.erase("/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700290
291 validateRemove(emptyFib, "/");
292
HangZhangad4afd12014-03-01 11:03:08 +0800293 emptyFib.erase("/still/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700294
HangZhangad4afd12014-03-01 11:03:08 +0800295 NameTree nameTree(1024);
296 Fib fib(nameTree);
Junxiao Shi40631842014-03-01 13:52:37 -0700297 fib.insert("/");
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700298 fib.insert("/A");
299 fib.insert("/A/B");
300 fib.insert("/A/B/C");
301
302 // check if we remove the right thing and leave
303 // everything else alone
304
305 validateRemove(fib, "/A/B");
306 validateFindExactMatch(fib, "/A");
307 validateFindExactMatch(fib, "/A/B/C");
308 validateFindExactMatch(fib, "/");
309
310 validateRemove(fib, "/A/B/C");
311 validateFindExactMatch(fib, "/A");
312 validateFindExactMatch(fib, "/");
313
314 validateRemove(fib, "/A");
315 validateFindExactMatch(fib, "/");
316
Junxiao Shi40631842014-03-01 13:52:37 -0700317 validateRemove(fib, "/");
318 validateNoExactMatch(fib, "/");
319
HangZhangad4afd12014-03-01 11:03:08 +0800320 NameTree gapNameTree(1024);
321 Fib gapFib(gapNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700322 gapFib.insert("/X");
323 gapFib.insert("/X/Y/Z");
324
HangZhangad4afd12014-03-01 11:03:08 +0800325 gapFib.erase("/X/Y"); //should do nothing
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700326 validateFindExactMatch(gapFib, "/X");
327 validateFindExactMatch(gapFib, "/X/Y/Z");
328}
329
HangZhang5d469422014-03-12 09:26:26 +0800330BOOST_AUTO_TEST_CASE(Iterator)
331{
332 NameTree nameTree(1024);
333 Fib fib(nameTree);
334 Name nameA("/A");
335 Name nameAB("/A/B");
336 Name nameABC("/A/B/C");
337 Name nameRoot("/");
338
339 fib.insert(nameA);
340 fib.insert(nameAB);
341 fib.insert(nameABC);
342 fib.insert(nameRoot);
343
344 std::set<Name> expected;
345 expected.insert(nameA);
346 expected.insert(nameAB);
347 expected.insert(nameABC);
348 expected.insert(nameRoot);
349
350 for (Fib::const_iterator it = fib.begin(); it != fib.end(); it++)
351 {
352 bool isInSet = expected.find(it->getPrefix()) != expected.end();
353 BOOST_CHECK(isInSet);
354 expected.erase(it->getPrefix());
355 }
356
357 BOOST_CHECK_EQUAL(expected.size(), 0);
358}
359
Junxiao Shic1e12362014-01-24 20:03:26 -0700360BOOST_AUTO_TEST_SUITE_END()
361
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700362} // namespace tests
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800363} // namespace nfd