blob: e56c0d3bb0d42d711addf187df8ab1c0f1079ffa [file] [log] [blame]
Vince Lehman4387e782014-06-19 16:57:45 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * 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 * The University of Memphis
10 *
11 * This file is part of NFD (Named Data Networking Forwarding Daemon).
12 * See AUTHORS.md for complete list of NFD authors and contributors.
13 *
14 * NFD is free software: you can redistribute it and/or modify it under the terms
15 * of the GNU General Public License as published by the Free Software Foundation,
16 * either version 3 of the License, or (at your option) any later version.
17 *
18 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20 * PURPOSE. See the GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License along with
23 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26#include "rib/rib.hpp"
27
28#include "tests/test-common.hpp"
29#include "fib-updates-common.hpp"
30
31namespace nfd {
32namespace rib {
33namespace tests {
34
35BOOST_FIXTURE_TEST_SUITE(FibUpdates, FibUpdatesFixture)
36
37BOOST_AUTO_TEST_SUITE(EraseFace)
38
39BOOST_AUTO_TEST_CASE(WithInheritedFace_Root)
40{
41 insertFaceEntry("/", 1, 0, 10, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
42 insertFaceEntry("/a", 1, 0, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
43 insertFaceEntry("/a/b", 2, 0, 75, 0);
44
45 // Clear updates generated from previous insertions
46 rib.clearFibUpdates();
47
48 // Should generate 1 updates: 1 to remove face 1 from /
49 eraseFaceEntry("/", 1, 0);
50
51 Rib::FibUpdateList updates = getSortedFibUpdates();
52 BOOST_REQUIRE_EQUAL(updates.size(), 1);
53
54 Rib::FibUpdateList::const_iterator update = updates.begin();
55 BOOST_CHECK_EQUAL((*update)->name, "/");
56 BOOST_CHECK_EQUAL((*update)->faceId, 1);
57 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
58}
59
60BOOST_AUTO_TEST_CASE(WithInheritedFace)
61{
62 insertFaceEntry("/a", 5, 0, 10, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
63 insertFaceEntry("/a", 5, 255, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
64 insertFaceEntry("/a", 2, 0, 20, 0);
65 insertFaceEntry("/a/b", 3, 0, 5, 0);
66
67 // /a should have face 5 with cost 10; /a/b should have face 3 with cost 5 and
68 // face 5 with cost 10
69 eraseFaceEntry("/a", 5, 255);
70
71 // Clear updates generated from previous insertions
72 rib.clearFibUpdates();
73
74 // Should generate 2 updates: 1 to remove face 3 from /a/b and one to remove inherited face.
75 eraseFaceEntry("/a/b", 3, 0);
76
77 Rib::FibUpdateList updates = getSortedFibUpdates();
78 BOOST_REQUIRE_EQUAL(updates.size(), 2);
79
80 Rib::FibUpdateList::const_iterator update = updates.begin();
81 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
82 BOOST_CHECK_EQUAL((*update)->faceId, 3);
83 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
84
85 ++update;
86 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
87 BOOST_CHECK_EQUAL((*update)->faceId, 5);
88 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
89}
90
91BOOST_AUTO_TEST_CASE(MultipleFaces)
92{
93 insertFaceEntry("/a", 5, 0, 10, 0);
94 insertFaceEntry("/a", 5, 255, 5, 0);
95
96 // Clear updates generated from previous insertions
97 rib.clearFibUpdates();
98
99 // Should generate 1 updates: 1 to update cost to 10 for /a
100 eraseFaceEntry("/a", 5, 255);
101
102 Rib::FibUpdateList updates = getSortedFibUpdates();
103 BOOST_REQUIRE_EQUAL(updates.size(), 1);
104
105 Rib::FibUpdateList::const_iterator update = updates.begin();
106 BOOST_CHECK_EQUAL((*update)->name, "/a");
107 BOOST_CHECK_EQUAL((*update)->faceId, 5);
108 BOOST_CHECK_EQUAL((*update)->cost, 10);
109 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
110}
111
112BOOST_AUTO_TEST_CASE(NoFlags_NoCaptureChange_NoCaptureOnRoute)
113{
114 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
115 insertFaceEntry("/a", 2, 0, 10, 0);
116 insertFaceEntry("/a/b", 3, 0, 10, 0);
117 insertFaceEntry("/a/c", 1, 0, 100, 0);
118 insertFaceEntry("/a", 1, 128, 50, 0);
119
120 // Clear updates generated from previous insertions
121 rib.clearFibUpdates();
122
123 // Should generate 1 updates: 1 to update cost for /a
124 eraseFaceEntry("/a", 1, 128);
125
126 Rib::FibUpdateList updates = getSortedFibUpdates();
127 BOOST_REQUIRE_EQUAL(updates.size(), 1);
128
129 Rib::FibUpdateList::const_iterator update = updates.begin();
130 BOOST_CHECK_EQUAL((*update)->name, "/a");
131 BOOST_CHECK_EQUAL((*update)->faceId, 1);
132 BOOST_CHECK_EQUAL((*update)->cost, 5);
133 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
134}
135
136BOOST_AUTO_TEST_CASE(MakeRibEmpty)
137{
138 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
139
140 // Clear updates generated from previous insertions
141 rib.clearFibUpdates();
142
143 // Should generate 1 updates: 1 to remove face from /
144 eraseFaceEntry("/", 1, 0);
145
146 Rib::FibUpdateList updates = getSortedFibUpdates();
147 BOOST_REQUIRE_EQUAL(updates.size(), 1);
148
149 Rib::FibUpdateList::const_iterator update = updates.begin();
150 BOOST_CHECK_EQUAL((*update)->name, "/");
151 BOOST_CHECK_EQUAL((*update)->faceId, 1);
152 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
153}
154
155BOOST_AUTO_TEST_CASE(NoFlags_NoCaptureChange_CaptureOnRoute)
156{
157 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
158 insertFaceEntry("/a", 2, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
159 insertFaceEntry("/a/b", 3, 0, 10, 0);
160 insertFaceEntry("/a/c", 1, 0, 100, 0);
161 insertFaceEntry("/a", 1, 128, 50, 0);
162
163 // Clear updates generated from previous insertions
164 rib.clearFibUpdates();
165
166 // Should generate 1 updates: 1 to remove face from /a
167 eraseFaceEntry("/a", 1, 128);
168
169 Rib::FibUpdateList updates = getSortedFibUpdates();
170 BOOST_REQUIRE_EQUAL(updates.size(), 1);
171
172 Rib::FibUpdateList::const_iterator update = updates.begin();
173 BOOST_CHECK_EQUAL((*update)->name, "/a");
174 BOOST_CHECK_EQUAL((*update)->faceId, 1);
175 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
176}
177
178BOOST_AUTO_TEST_CASE(BothFlags_NoCaptureChange_CaptureOnRoute)
179{
180 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
181 insertFaceEntry("/a", 2, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
182 insertFaceEntry("/a/b", 3, 0, 10, 0);
183 insertFaceEntry("/a/c", 1, 0, 100, 0);
184 insertFaceEntry("/a", 1, 128, 50, (ndn::nfd::ROUTE_FLAG_CHILD_INHERIT |
185 ndn::nfd::ROUTE_FLAG_CAPTURE));
186
187 // Clear updates generated from previous insertions
188 rib.clearFibUpdates();
189
190 // Should generate 2 updates: 1 to remove face1 from /a and
191 // 1 to remove face1 to /a/b
192 eraseFaceEntry("/a", 1, 128);
193
194 Rib::FibUpdateList updates = getSortedFibUpdates();
195 BOOST_REQUIRE_EQUAL(updates.size(), 2);
196
197 Rib::FibUpdateList::const_iterator update = updates.begin();
198 BOOST_CHECK_EQUAL((*update)->name, "/a");
199 BOOST_CHECK_EQUAL((*update)->faceId, 1);
200 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
201
202 ++update;
203 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
204 BOOST_CHECK_EQUAL((*update)->faceId, 1);
205 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
206}
207
208BOOST_AUTO_TEST_CASE(BothFlags_CaptureChange_NoCaptureOnRoute)
209{
210 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
211 insertFaceEntry("/a", 2, 0, 10, 0);
212 insertFaceEntry("/a/b", 3, 0, 10, 0);
213 insertFaceEntry("/a/c", 1, 0, 100, 0);
214 insertFaceEntry("/a", 1, 128, 50, (ndn::nfd::ROUTE_FLAG_CHILD_INHERIT |
215 ndn::nfd::ROUTE_FLAG_CAPTURE));
216
217 // Clear updates generated from previous insertions
218 rib.clearFibUpdates();
219
220 // Should generate 2 updates: 1 to add face1 to /a and
221 // 1 to add face1 to /a/b
222 eraseFaceEntry("/a", 1, 128);
223
224 Rib::FibUpdateList updates = getSortedFibUpdates();
225 BOOST_REQUIRE_EQUAL(updates.size(), 2);
226
227 Rib::FibUpdateList::const_iterator update = updates.begin();
228 BOOST_CHECK_EQUAL((*update)->name, "/a");
229 BOOST_CHECK_EQUAL((*update)->faceId, 1);
230 BOOST_CHECK_EQUAL((*update)->cost, 5);
231 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
232
233 ++update;
234 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
235 BOOST_CHECK_EQUAL((*update)->faceId, 1);
236 BOOST_CHECK_EQUAL((*update)->cost, 5);
237 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
238}
239
240BOOST_AUTO_TEST_CASE(ChildInherit_NoCaptureChange_NoCaptureOnRoute)
241{
242 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
243 insertFaceEntry("/a", 2, 0, 10, 0);
244 insertFaceEntry("/a/b", 3, 0, 10, 0);
245 insertFaceEntry("/a/c", 1, 0, 100, 0);
246 insertFaceEntry("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
247
248 // Clear updates generated from previous insertions
249 rib.clearFibUpdates();
250
251 // Should generate 2 updates: 2 to add face1 to /a and /a/b
252 eraseFaceEntry("/a", 1, 128);
253
254 Rib::FibUpdateList updates = getSortedFibUpdates();
255 BOOST_REQUIRE_EQUAL(updates.size(), 2);
256
257 Rib::FibUpdateList::const_iterator update = updates.begin();
258 BOOST_CHECK_EQUAL((*update)->name, "/a");
259 BOOST_CHECK_EQUAL((*update)->faceId, 1);
260 BOOST_CHECK_EQUAL((*update)->cost, 5);
261 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
262
263 ++update;
264 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
265 BOOST_CHECK_EQUAL((*update)->faceId, 1);
266 BOOST_CHECK_EQUAL((*update)->cost, 5);
267 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
268}
269
270BOOST_AUTO_TEST_CASE(ChildInherit_NoCaptureChange_CaptureOnRoute)
271{
272 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
273 insertFaceEntry("/a", 2, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
274 insertFaceEntry("/a/b", 3, 0, 10, 0);
275 insertFaceEntry("/a/c", 1, 0, 100, 0);
276 insertFaceEntry("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
277
278 // Clear updates generated from previous insertions
279 rib.clearFibUpdates();
280
281 // Should generate 2 updates: 2 to remove face 1 from /a and /a/b
282 eraseFaceEntry("/a", 1, 128);
283
284 Rib::FibUpdateList updates = getSortedFibUpdates();
285 BOOST_REQUIRE_EQUAL(updates.size(), 2);
286
287 Rib::FibUpdateList::const_iterator update = updates.begin();
288 BOOST_CHECK_EQUAL((*update)->name, "/a");
289 BOOST_CHECK_EQUAL((*update)->faceId, 1);
290 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
291
292 ++update;
293 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
294 BOOST_CHECK_EQUAL((*update)->faceId, 1);
295 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
296}
297
298BOOST_AUTO_TEST_CASE(Capture_CaptureChange_NoCaptureOnRoute)
299{
300 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
301 insertFaceEntry("/a", 2, 0, 10, 0);
302 insertFaceEntry("/a/b", 3, 0, 10, 0);
303 insertFaceEntry("/a/c", 1, 0, 100, 0);
304 insertFaceEntry("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CAPTURE);
305
306 // Clear updates generated from previous insertions
307 rib.clearFibUpdates();
308
309 // Should generate 2 updates: 1 to update cost on /a and
310 // 1 to add face1 to /a/b
311 eraseFaceEntry("/a", 1 ,128);
312
313 Rib::FibUpdateList updates = getSortedFibUpdates();
314 BOOST_REQUIRE_EQUAL(updates.size(), 2);
315
316 Rib::FibUpdateList::const_iterator update = updates.begin();
317 BOOST_CHECK_EQUAL((*update)->name, "/a");
318 BOOST_CHECK_EQUAL((*update)->faceId, 1);
319 BOOST_CHECK_EQUAL((*update)->cost, 5);
320 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
321
322 ++update;
323 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
324 BOOST_CHECK_EQUAL((*update)->faceId, 1);
325 BOOST_CHECK_EQUAL((*update)->cost, 5);
326 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::ADD_NEXTHOP);
327}
328
329BOOST_AUTO_TEST_CASE(Capture_NoCaptureChange_CaptureOnRoute)
330{
331 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
332 insertFaceEntry("/a", 2, 0, 10, ndn::nfd::ROUTE_FLAG_CAPTURE);
333 insertFaceEntry("/a/b", 3, 0, 10, 0);
334 insertFaceEntry("/a/c", 1, 0, 100, 0);
335 insertFaceEntry("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CAPTURE);
336
337 // Clear updates generated from previous insertions
338 rib.clearFibUpdates();
339
340 // Should generate 1 updates: 1 to remove face from /a
341 eraseFaceEntry("/a", 1, 128);
342
343 Rib::FibUpdateList updates = getSortedFibUpdates();
344 BOOST_REQUIRE_EQUAL(updates.size(), 1);
345
346 Rib::FibUpdateList::const_iterator update = updates.begin();
347 BOOST_CHECK_EQUAL((*update)->name, "/a");
348 BOOST_CHECK_EQUAL((*update)->faceId, 1);
349 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
350}
351
352BOOST_AUTO_TEST_CASE(EraseFaceById)
353{
354 insertFaceEntry("/", 1, 0, 5, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
355 insertFaceEntry("/a", 2, 0, 10, 0);
356 insertFaceEntry("/a/b", 3, 0, 10, 0);
357 insertFaceEntry("/a/c", 4, 0, 100, 0);
358 insertFaceEntry("/a", 1, 128, 50, ndn::nfd::ROUTE_FLAG_CHILD_INHERIT);
359
360 // Clear updates generated from previous insertions
361 rib.clearFibUpdates();
362
363 // Should generate 4 updates: 4 to remove face ID 1 from /, /a, /a/b, and /a/c
364 rib.erase(1);
365
366 Rib::FibUpdateList updates = getSortedFibUpdates();
367 BOOST_REQUIRE_EQUAL(updates.size(), 4);
368
369 Rib::FibUpdateList::const_iterator update = updates.begin();
370 BOOST_CHECK_EQUAL((*update)->name, "/");
371 BOOST_CHECK_EQUAL((*update)->faceId, 1);
372 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
373
374 ++update;
375 BOOST_CHECK_EQUAL((*update)->name, "/a");
376 BOOST_CHECK_EQUAL((*update)->faceId, 1);
377 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
378
379 ++update;
380 BOOST_CHECK_EQUAL((*update)->name, "/a/b");
381 BOOST_CHECK_EQUAL((*update)->faceId, 1);
382 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
383
384 ++update;
385 BOOST_CHECK_EQUAL((*update)->name, "/a/c");
386 BOOST_CHECK_EQUAL((*update)->faceId, 1);
387 BOOST_CHECK_EQUAL((*update)->action, FibUpdate::REMOVE_NEXTHOP);
388}
389
390BOOST_AUTO_TEST_SUITE_END() // EraseFace
391
392BOOST_AUTO_TEST_SUITE_END() // FibUpdates
393
394} // namespace tests
395} // namespace rib
396} // namespace nfd