blob: 0be649212a409a059245fc156c4b0a8c24af0b5a [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 Shic1e12362014-01-24 20:03:26 -0700123 // ['/']
124
125 entry = fib.findLongestPrefixMatch(nameA);
126 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
127 BOOST_CHECK(entry->getPrefix().equals(nameEmpty));
128
129 insertRes = fib.insert(nameA);
130 BOOST_CHECK_EQUAL(insertRes.second, true);
131 BOOST_CHECK(insertRes.first->getPrefix().equals(nameA));
132 // ['/', '/A']
133
134 insertRes = fib.insert(nameA);
135 BOOST_CHECK_EQUAL(insertRes.second, false);
136 BOOST_CHECK(insertRes.first->getPrefix().equals(nameA));
137 // ['/', '/A']
138
139 entry = fib.findLongestPrefixMatch(nameA);
140 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
141 BOOST_CHECK(entry->getPrefix().equals(nameA));
142
143 entry = fib.findLongestPrefixMatch(nameABCD);
144 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
145 BOOST_CHECK(entry->getPrefix().equals(nameA));
146
147 insertRes = fib.insert(nameABC);
148 BOOST_CHECK_EQUAL(insertRes.second, true);
149 BOOST_CHECK(insertRes.first->getPrefix().equals(nameABC));
150 // ['/', '/A', '/A/B/C']
151
152 entry = fib.findLongestPrefixMatch(nameA);
153 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
154 BOOST_CHECK(entry->getPrefix().equals(nameA));
155
156 entry = fib.findLongestPrefixMatch(nameAB);
157 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
158 BOOST_CHECK(entry->getPrefix().equals(nameA));
159
160 entry = fib.findLongestPrefixMatch(nameABCD);
161 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
162 BOOST_CHECK(entry->getPrefix().equals(nameABC));
163
164 entry = fib.findLongestPrefixMatch(nameE);
165 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
166 BOOST_CHECK(entry->getPrefix().equals(nameEmpty));
167}
168
169BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
170{
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700171 shared_ptr<Face> face1 = make_shared<DummyFace>();
172 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shic1e12362014-01-24 20:03:26 -0700173 Name nameA("ndn:/A");
174 Name nameB("ndn:/B");
175
176 std::pair<shared_ptr<fib::Entry>, bool> insertRes;
177 shared_ptr<fib::Entry> entry;
178
HangZhangad4afd12014-03-01 11:03:08 +0800179 NameTree nameTree(1024);
180 Fib fib(nameTree);
Junxiao Shic1e12362014-01-24 20:03:26 -0700181 // {'/':[]}
182
183 insertRes = fib.insert(nameA);
184 insertRes.first->addNextHop(face1, 0);
185 insertRes.first->addNextHop(face2, 0);
186 // {'/':[], '/A':[1,2]}
187
188 insertRes = fib.insert(nameB);
189 insertRes.first->addNextHop(face1, 0);
190 // {'/':[], '/A':[1,2], '/B':[1]}
191
192 fib.removeNextHopFromAllEntries(face1);
193 // {'/':[], '/A':[2], '/B':[]}
194
195 entry = fib.findLongestPrefixMatch(nameA);
196 BOOST_CHECK(entry->getPrefix().equals(nameA));
197 const fib::NextHopList& nexthopsA = entry->getNextHops();
198 BOOST_CHECK_EQUAL(nexthopsA.size(), 1);
199 BOOST_CHECK_EQUAL(nexthopsA.begin()->getFace(), face2);
200
201 entry = fib.findLongestPrefixMatch(nameB);
202 BOOST_CHECK(entry->getPrefix().equals(nameB));
203 const fib::NextHopList& nexthopsB = entry->getNextHops();
204 BOOST_CHECK_EQUAL(nexthopsB.size(), 0);
205}
206
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700207void
208validateFindExactMatch(const Fib& fib, const Name& target)
209{
210 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
211 if (static_cast<bool>(entry))
212 {
213 BOOST_CHECK_EQUAL(entry->getPrefix(), target);
214 }
215 else
216 {
217 BOOST_FAIL("No entry found for " << target);
218 }
219}
220
221void
222validateNoExactMatch(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_FAIL("Found unexpected entry for " << target);
228 }
229}
230
231BOOST_AUTO_TEST_CASE(FindExactMatch)
232{
HangZhangad4afd12014-03-01 11:03:08 +0800233 NameTree nameTree(1024);
234 Fib fib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700235 fib.insert("/A");
236 fib.insert("/A/B");
237 fib.insert("/A/B/C");
238
239 validateFindExactMatch(fib, "/A");
240 validateFindExactMatch(fib, "/A/B");
241 validateFindExactMatch(fib, "/A/B/C");
242 validateFindExactMatch(fib, "/");
243
244 validateNoExactMatch(fib, "/does/not/exist");
245
HangZhangad4afd12014-03-01 11:03:08 +0800246 NameTree gapNameTree(1024);
247 Fib gapFib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700248 fib.insert("/X");
249 fib.insert("/X/Y/Z");
250
251 validateNoExactMatch(gapFib, "/X/Y");
252
HangZhangad4afd12014-03-01 11:03:08 +0800253 NameTree emptyNameTree(1024);
254 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700255 validateNoExactMatch(emptyFib, "/nothing/here");
256}
257
258void
259validateRemove(Fib& fib, const Name& target)
260{
HangZhangad4afd12014-03-01 11:03:08 +0800261 fib.erase(target);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700262
263 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
264 if (static_cast<bool>(entry))
265 {
266 BOOST_FAIL("Found \"removed\" entry for " << target);
267 }
268}
269
270BOOST_AUTO_TEST_CASE(Remove)
271{
HangZhangad4afd12014-03-01 11:03:08 +0800272 NameTree emptyNameTree(1024);
273 Fib emptyFib(emptyNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700274
HangZhangad4afd12014-03-01 11:03:08 +0800275 emptyFib.erase("/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700276
277 validateRemove(emptyFib, "/");
278
HangZhangad4afd12014-03-01 11:03:08 +0800279 emptyFib.erase("/still/does/not/exist"); // crash test
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700280
HangZhangad4afd12014-03-01 11:03:08 +0800281 NameTree nameTree(1024);
282 Fib fib(nameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700283 fib.insert("/A");
284 fib.insert("/A/B");
285 fib.insert("/A/B/C");
286
287 // check if we remove the right thing and leave
288 // everything else alone
289
290 validateRemove(fib, "/A/B");
291 validateFindExactMatch(fib, "/A");
292 validateFindExactMatch(fib, "/A/B/C");
293 validateFindExactMatch(fib, "/");
294
295 validateRemove(fib, "/A/B/C");
296 validateFindExactMatch(fib, "/A");
297 validateFindExactMatch(fib, "/");
298
299 validateRemove(fib, "/A");
300 validateFindExactMatch(fib, "/");
301
HangZhangad4afd12014-03-01 11:03:08 +0800302 NameTree gapNameTree(1024);
303 Fib gapFib(gapNameTree);
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700304 gapFib.insert("/X");
305 gapFib.insert("/X/Y/Z");
306
HangZhangad4afd12014-03-01 11:03:08 +0800307 gapFib.erase("/X/Y"); //should do nothing
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700308 validateFindExactMatch(gapFib, "/X");
309 validateFindExactMatch(gapFib, "/X/Y/Z");
310}
311
Junxiao Shic1e12362014-01-24 20:03:26 -0700312BOOST_AUTO_TEST_SUITE_END()
313
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700314} // namespace tests
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800315} // namespace nfd