blob: 4d9d05f09f505076cdf137bf4be3a1d20b535856 [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 Shic1e12362014-01-24 20:03:26 -070022
23 fib::Entry entry(prefix);
24 BOOST_CHECK(entry.getPrefix().equals(prefix));
25
26 const fib::NextHopList& nexthops1 = entry.getNextHops();
27 // []
28 BOOST_CHECK_EQUAL(nexthops1.size(), 0);
29
30 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);
36
37 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 }
83
84 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);
90
91 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);
97
98 entry.removeNextHop(face2);
99 const fib::NextHopList& nexthops8 = entry.getNextHops();
100 // []
101 BOOST_CHECK_EQUAL(nexthops8.size(), 0);
102
103 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");
117
118 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 // []
124
125 entry = fib.findLongestPrefixMatch(nameA);
126 BOOST_REQUIRE(static_cast<bool>(entry)); // the empty entry
127
128 insertRes = fib.insert(nameEmpty);
129 BOOST_CHECK_EQUAL(insertRes.second, true);
130 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700131 // ['/']
132
133 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700134 BOOST_REQUIRE(static_cast<bool>(entry));
135 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700136
137 insertRes = fib.insert(nameA);
138 BOOST_CHECK_EQUAL(insertRes.second, true);
Junxiao Shi40631842014-03-01 13:52:37 -0700139 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700140 // ['/', '/A']
141
142 insertRes = fib.insert(nameA);
143 BOOST_CHECK_EQUAL(insertRes.second, false);
Junxiao Shi40631842014-03-01 13:52:37 -0700144 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700145 // ['/', '/A']
146
147 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700148 BOOST_REQUIRE(static_cast<bool>(entry));
149 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700150
151 entry = fib.findLongestPrefixMatch(nameABCD);
Junxiao Shi40631842014-03-01 13:52:37 -0700152 BOOST_REQUIRE(static_cast<bool>(entry));
153 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700154
155 insertRes = fib.insert(nameABC);
156 BOOST_CHECK_EQUAL(insertRes.second, true);
Junxiao Shi40631842014-03-01 13:52:37 -0700157 BOOST_CHECK_EQUAL(insertRes.first->getPrefix(), nameABC);
Junxiao Shic1e12362014-01-24 20:03:26 -0700158 // ['/', '/A', '/A/B/C']
159
160 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700161 BOOST_REQUIRE(static_cast<bool>(entry));
162 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700163
164 entry = fib.findLongestPrefixMatch(nameAB);
Junxiao Shi40631842014-03-01 13:52:37 -0700165 BOOST_REQUIRE(static_cast<bool>(entry));
166 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700167
168 entry = fib.findLongestPrefixMatch(nameABCD);
Junxiao Shi40631842014-03-01 13:52:37 -0700169 BOOST_REQUIRE(static_cast<bool>(entry));
170 BOOST_CHECK_EQUAL(entry->getPrefix(), nameABC);
Junxiao Shic1e12362014-01-24 20:03:26 -0700171
172 entry = fib.findLongestPrefixMatch(nameE);
Junxiao Shi40631842014-03-01 13:52:37 -0700173 BOOST_REQUIRE(static_cast<bool>(entry));
174 BOOST_CHECK_EQUAL(entry->getPrefix(), nameEmpty);
Junxiao Shic1e12362014-01-24 20:03:26 -0700175}
176
177BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
178{
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700179 shared_ptr<Face> face1 = make_shared<DummyFace>();
180 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shic1e12362014-01-24 20:03:26 -0700181 Name nameA("ndn:/A");
182 Name nameB("ndn:/B");
183
184 std::pair<shared_ptr<fib::Entry>, bool> insertRes;
185 shared_ptr<fib::Entry> entry;
186
HangZhangad4afd12014-03-01 11:03:08 +0800187 NameTree nameTree(1024);
188 Fib fib(nameTree);
Junxiao Shic1e12362014-01-24 20:03:26 -0700189 // {'/':[]}
190
191 insertRes = fib.insert(nameA);
192 insertRes.first->addNextHop(face1, 0);
193 insertRes.first->addNextHop(face2, 0);
194 // {'/':[], '/A':[1,2]}
195
196 insertRes = fib.insert(nameB);
197 insertRes.first->addNextHop(face1, 0);
198 // {'/':[], '/A':[1,2], '/B':[1]}
199
200 fib.removeNextHopFromAllEntries(face1);
201 // {'/':[], '/A':[2], '/B':[]}
202
203 entry = fib.findLongestPrefixMatch(nameA);
Junxiao Shi40631842014-03-01 13:52:37 -0700204 BOOST_CHECK_EQUAL(entry->getPrefix(), nameA);
Junxiao Shic1e12362014-01-24 20:03:26 -0700205 const fib::NextHopList& nexthopsA = entry->getNextHops();
206 BOOST_CHECK_EQUAL(nexthopsA.size(), 1);
207 BOOST_CHECK_EQUAL(nexthopsA.begin()->getFace(), face2);
208
209 entry = fib.findLongestPrefixMatch(nameB);
Junxiao Shi40631842014-03-01 13:52:37 -0700210 BOOST_CHECK_EQUAL(entry->getPrefix(), nameB);
Junxiao Shic1e12362014-01-24 20:03:26 -0700211 const fib::NextHopList& nexthopsB = entry->getNextHops();
212 BOOST_CHECK_EQUAL(nexthopsB.size(), 0);
213}
214
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700215void
216validateFindExactMatch(const Fib& fib, const Name& target)
217{
218 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
219 if (static_cast<bool>(entry))
220 {
221 BOOST_CHECK_EQUAL(entry->getPrefix(), target);
222 }
223 else
224 {
225 BOOST_FAIL("No entry found for " << target);
226 }
227}
228
229void
230validateNoExactMatch(const Fib& fib, const Name& target)
231{
232 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
233 if (static_cast<bool>(entry))
234 {
235 BOOST_FAIL("Found unexpected entry for " << target);
236 }
237}
238
239BOOST_AUTO_TEST_CASE(FindExactMatch)
240{
HangZhangad4afd12014-03-01 11:03:08 +0800241 NameTree nameTree(1024);
242 Fib fib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700243 fib.insert("/A");
244 fib.insert("/A/B");
245 fib.insert("/A/B/C");
246
247 validateFindExactMatch(fib, "/A");
248 validateFindExactMatch(fib, "/A/B");
249 validateFindExactMatch(fib, "/A/B/C");
Junxiao Shi40631842014-03-01 13:52:37 -0700250 validateNoExactMatch(fib, "/");
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700251
252 validateNoExactMatch(fib, "/does/not/exist");
253
HangZhangad4afd12014-03-01 11:03:08 +0800254 NameTree gapNameTree(1024);
255 Fib gapFib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700256 fib.insert("/X");
257 fib.insert("/X/Y/Z");
258
259 validateNoExactMatch(gapFib, "/X/Y");
260
HangZhangad4afd12014-03-01 11:03:08 +0800261 NameTree emptyNameTree(1024);
262 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700263 validateNoExactMatch(emptyFib, "/nothing/here");
264}
265
266void
267validateRemove(Fib& fib, const Name& target)
268{
HangZhangad4afd12014-03-01 11:03:08 +0800269 fib.erase(target);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700270
271 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
272 if (static_cast<bool>(entry))
273 {
274 BOOST_FAIL("Found \"removed\" entry for " << target);
275 }
276}
277
278BOOST_AUTO_TEST_CASE(Remove)
279{
HangZhangad4afd12014-03-01 11:03:08 +0800280 NameTree emptyNameTree(1024);
281 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700282
HangZhangad4afd12014-03-01 11:03:08 +0800283 emptyFib.erase("/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700284
285 validateRemove(emptyFib, "/");
286
HangZhangad4afd12014-03-01 11:03:08 +0800287 emptyFib.erase("/still/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700288
HangZhangad4afd12014-03-01 11:03:08 +0800289 NameTree nameTree(1024);
290 Fib fib(nameTree);
Junxiao Shi40631842014-03-01 13:52:37 -0700291 fib.insert("/");
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700292 fib.insert("/A");
293 fib.insert("/A/B");
294 fib.insert("/A/B/C");
295
296 // check if we remove the right thing and leave
297 // everything else alone
298
299 validateRemove(fib, "/A/B");
300 validateFindExactMatch(fib, "/A");
301 validateFindExactMatch(fib, "/A/B/C");
302 validateFindExactMatch(fib, "/");
303
304 validateRemove(fib, "/A/B/C");
305 validateFindExactMatch(fib, "/A");
306 validateFindExactMatch(fib, "/");
307
308 validateRemove(fib, "/A");
309 validateFindExactMatch(fib, "/");
310
Junxiao Shi40631842014-03-01 13:52:37 -0700311 validateRemove(fib, "/");
312 validateNoExactMatch(fib, "/");
313
HangZhangad4afd12014-03-01 11:03:08 +0800314 NameTree gapNameTree(1024);
315 Fib gapFib(gapNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700316 gapFib.insert("/X");
317 gapFib.insert("/X/Y/Z");
318
HangZhangad4afd12014-03-01 11:03:08 +0800319 gapFib.erase("/X/Y"); //should do nothing
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700320 validateFindExactMatch(gapFib, "/X");
321 validateFindExactMatch(gapFib, "/X/Y/Z");
322}
323
Junxiao Shic1e12362014-01-24 20:03:26 -0700324BOOST_AUTO_TEST_SUITE_END()
325
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700326} // namespace tests
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800327} // namespace nfd