blob: 1615876385fbea7c167cab0d34d5d1b0ee632738 [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
121 Fib fib;
122 // ['/']
123
124 entry = fib.findLongestPrefixMatch(nameA);
125 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
126 BOOST_CHECK(entry->getPrefix().equals(nameEmpty));
127
128 insertRes = fib.insert(nameA);
129 BOOST_CHECK_EQUAL(insertRes.second, true);
130 BOOST_CHECK(insertRes.first->getPrefix().equals(nameA));
131 // ['/', '/A']
132
133 insertRes = fib.insert(nameA);
134 BOOST_CHECK_EQUAL(insertRes.second, false);
135 BOOST_CHECK(insertRes.first->getPrefix().equals(nameA));
136 // ['/', '/A']
137
138 entry = fib.findLongestPrefixMatch(nameA);
139 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
140 BOOST_CHECK(entry->getPrefix().equals(nameA));
141
142 entry = fib.findLongestPrefixMatch(nameABCD);
143 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
144 BOOST_CHECK(entry->getPrefix().equals(nameA));
145
146 insertRes = fib.insert(nameABC);
147 BOOST_CHECK_EQUAL(insertRes.second, true);
148 BOOST_CHECK(insertRes.first->getPrefix().equals(nameABC));
149 // ['/', '/A', '/A/B/C']
150
151 entry = fib.findLongestPrefixMatch(nameA);
152 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
153 BOOST_CHECK(entry->getPrefix().equals(nameA));
154
155 entry = fib.findLongestPrefixMatch(nameAB);
156 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
157 BOOST_CHECK(entry->getPrefix().equals(nameA));
158
159 entry = fib.findLongestPrefixMatch(nameABCD);
160 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
161 BOOST_CHECK(entry->getPrefix().equals(nameABC));
162
163 entry = fib.findLongestPrefixMatch(nameE);
164 BOOST_CHECK_NE(entry.get(), static_cast<fib::Entry*>(0));
165 BOOST_CHECK(entry->getPrefix().equals(nameEmpty));
166}
167
168BOOST_AUTO_TEST_CASE(RemoveNextHopFromAllEntries)
169{
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700170 shared_ptr<Face> face1 = make_shared<DummyFace>();
171 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shic1e12362014-01-24 20:03:26 -0700172 Name nameA("ndn:/A");
173 Name nameB("ndn:/B");
174
175 std::pair<shared_ptr<fib::Entry>, bool> insertRes;
176 shared_ptr<fib::Entry> entry;
177
178 Fib fib;
179 // {'/':[]}
180
181 insertRes = fib.insert(nameA);
182 insertRes.first->addNextHop(face1, 0);
183 insertRes.first->addNextHop(face2, 0);
184 // {'/':[], '/A':[1,2]}
185
186 insertRes = fib.insert(nameB);
187 insertRes.first->addNextHop(face1, 0);
188 // {'/':[], '/A':[1,2], '/B':[1]}
189
190 fib.removeNextHopFromAllEntries(face1);
191 // {'/':[], '/A':[2], '/B':[]}
192
193 entry = fib.findLongestPrefixMatch(nameA);
194 BOOST_CHECK(entry->getPrefix().equals(nameA));
195 const fib::NextHopList& nexthopsA = entry->getNextHops();
196 BOOST_CHECK_EQUAL(nexthopsA.size(), 1);
197 BOOST_CHECK_EQUAL(nexthopsA.begin()->getFace(), face2);
198
199 entry = fib.findLongestPrefixMatch(nameB);
200 BOOST_CHECK(entry->getPrefix().equals(nameB));
201 const fib::NextHopList& nexthopsB = entry->getNextHops();
202 BOOST_CHECK_EQUAL(nexthopsB.size(), 0);
203}
204
Steve DiBenedettod5f87932014-02-05 15:11:39 -0700205void
206validateFindExactMatch(const Fib& fib, const Name& target)
207{
208 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
209 if (static_cast<bool>(entry))
210 {
211 BOOST_CHECK_EQUAL(entry->getPrefix(), target);
212 }
213 else
214 {
215 BOOST_FAIL("No entry found for " << target);
216 }
217}
218
219void
220validateNoExactMatch(const Fib& fib, const Name& target)
221{
222 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
223 if (static_cast<bool>(entry))
224 {
225 BOOST_FAIL("Found unexpected entry for " << target);
226 }
227}
228
229BOOST_AUTO_TEST_CASE(FindExactMatch)
230{
231 Fib fib;
232 fib.insert("/A");
233 fib.insert("/A/B");
234 fib.insert("/A/B/C");
235
236 validateFindExactMatch(fib, "/A");
237 validateFindExactMatch(fib, "/A/B");
238 validateFindExactMatch(fib, "/A/B/C");
239 validateFindExactMatch(fib, "/");
240
241 validateNoExactMatch(fib, "/does/not/exist");
242
243 Fib gapFib;
244 fib.insert("/X");
245 fib.insert("/X/Y/Z");
246
247 validateNoExactMatch(gapFib, "/X/Y");
248
249 Fib emptyFib;
250 validateNoExactMatch(emptyFib, "/nothing/here");
251}
252
253void
254validateRemove(Fib& fib, const Name& target)
255{
256 fib.remove(target);
257
258 shared_ptr<fib::Entry> entry = fib.findExactMatch(target);
259 if (static_cast<bool>(entry))
260 {
261 BOOST_FAIL("Found \"removed\" entry for " << target);
262 }
263}
264
265BOOST_AUTO_TEST_CASE(Remove)
266{
267 Fib emptyFib;
268
269 emptyFib.remove("/does/not/exist"); // crash test
270
271 validateRemove(emptyFib, "/");
272
273 emptyFib.remove("/still/does/not/exist"); // crash test
274
275 Fib fib;
276 fib.insert("/A");
277 fib.insert("/A/B");
278 fib.insert("/A/B/C");
279
280 // check if we remove the right thing and leave
281 // everything else alone
282
283 validateRemove(fib, "/A/B");
284 validateFindExactMatch(fib, "/A");
285 validateFindExactMatch(fib, "/A/B/C");
286 validateFindExactMatch(fib, "/");
287
288 validateRemove(fib, "/A/B/C");
289 validateFindExactMatch(fib, "/A");
290 validateFindExactMatch(fib, "/");
291
292 validateRemove(fib, "/A");
293 validateFindExactMatch(fib, "/");
294
295 Fib gapFib;
296 gapFib.insert("/X");
297 gapFib.insert("/X/Y/Z");
298
299 gapFib.remove("/X/Y"); //should do nothing
300 validateFindExactMatch(gapFib, "/X");
301 validateFindExactMatch(gapFib, "/X/Y/Z");
302}
303
Junxiao Shic1e12362014-01-24 20:03:26 -0700304BOOST_AUTO_TEST_SUITE_END()
305
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700306} // namespace tests
Alexander Afanasyev18bbf812014-01-29 01:40:23 -0800307} // namespace nfd