blob: 0df019c1ccb3a8f830de87e4baaa2a8a2b3efd2d [file] [log] [blame]
Junxiao Shi02b73f52016-07-28 01:48:27 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014-2016, 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 "table/cleanup.hpp"
27#include "fw/forwarder.hpp"
28
29#include "tests/test-common.hpp"
30#include "tests/daemon/face/dummy-face.hpp"
31
32namespace nfd {
33namespace tests {
34
35using namespace nfd::tests;
36
37BOOST_AUTO_TEST_SUITE(Table)
38BOOST_FIXTURE_TEST_SUITE(TestCleanup, BaseFixture)
39
40BOOST_AUTO_TEST_SUITE(FaceRemoval)
41
42BOOST_AUTO_TEST_CASE(Basic)
43{
44 NameTree nameTree(16);
45 Fib fib(nameTree);
46 Pit pit(nameTree);
47 shared_ptr<Face> face1 = make_shared<DummyFace>();
48
49 for (uint64_t i = 0; i < 300; ++i) {
50 Name name = Name("/P").appendVersion(i);
51
52 fib::Entry* fibEntry = fib.insert(name).first;
53 fibEntry->addNextHop(*face1, 0);
54
55 shared_ptr<Interest> interest = makeInterest(name);
56 shared_ptr<pit::Entry> pitEntry = pit.insert(*interest).first;
57 if ((i & 0x01) != 0) {
58 pitEntry->insertOrUpdateInRecord(face1, *interest);
59 }
60 if ((i & 0x02) != 0) {
61 pitEntry->insertOrUpdateOutRecord(face1, *interest);
62 }
63 }
64 BOOST_CHECK_EQUAL(fib.size(), 300);
65 BOOST_CHECK_EQUAL(pit.size(), 300);
66
67 cleanupOnFaceRemoval(nameTree, fib, pit, *face1);
68 BOOST_CHECK_EQUAL(fib.size(), 0);
69 BOOST_CHECK_EQUAL(pit.size(), 300);
70 for (const pit::Entry& pitEntry : pit) {
71 BOOST_CHECK_EQUAL(pitEntry.hasInRecords(), false);
72 BOOST_CHECK_EQUAL(pitEntry.hasOutRecords(), false);
73 }
74}
75
76BOOST_AUTO_TEST_CASE(RemoveFibNexthops)
77{
78 Forwarder forwarder;
79 NameTree& nameTree = forwarder.getNameTree();
80 Fib& fib = forwarder.getFib();
81
82 shared_ptr<Face> face1 = make_shared<DummyFace>();
83 shared_ptr<Face> face2 = make_shared<DummyFace>();
84 forwarder.addFace(face1);
85 forwarder.addFace(face2);
86
87 // {}
88 size_t nNameTreeEntriesBefore = nameTree.size();
89 BOOST_CHECK_EQUAL(fib.size(), 0);
90
91 fib::Entry* entryA = fib.insert("/A").first;
92 entryA->addNextHop(*face1, 0);
93 entryA->addNextHop(*face2, 0);
94 // {'/A':[1,2]}
95
96 fib::Entry* entryB = fib.insert("/B").first;
97 entryB->addNextHop(*face1, 0);
98 // {'/A':[1,2], '/B':[1]}
99
100 fib::Entry* entryC = fib.insert("/C").first;
101 entryC->addNextHop(*face2, 1);
102 // {'/A':[1,2], '/B':[1], '/C':[2]}
103
104 fib::Entry* entryB1 = fib.insert("/B/1").first;
105 entryB1->addNextHop(*face1, 0);
106 // {'/A':[1,2], '/B':[1], '/B/1':[1], '/C':[2]}
107
108 fib::Entry* entryB12 = fib.insert("/B/1/2").first;
109 entryB12->addNextHop(*face1, 0);
110 // {'/A':[1,2], '/B':[1], '/B/1':[1], '/B/1/2':[1], '/C':[2]}
111
112 // ---- close face1 ----
113 face1->close();
114 BOOST_CHECK_EQUAL(face1->getState(), face::FaceState::CLOSED);
115 // {'/A':[2], '/C':[2]}
116 BOOST_CHECK_EQUAL(fib.size(), 2);
117
118 const fib::Entry& foundA = fib.findLongestPrefixMatch("/A");
119 BOOST_CHECK_EQUAL(foundA.getPrefix(), "/A");
120 BOOST_CHECK_EQUAL(foundA.getNextHops().size(), 1);
121 BOOST_CHECK_EQUAL(&foundA.getNextHops().begin()->getFace(), face2.get());
122
123 BOOST_CHECK_EQUAL(fib.findLongestPrefixMatch("/B").getPrefix(), "/");
124
125 // ---- close face2 ----
126 face2->close();
127 BOOST_CHECK_EQUAL(face2->getState(), face::FaceState::CLOSED);
128 BOOST_CHECK_EQUAL(fib.size(), 0);
129 BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntriesBefore);
130}
131
132BOOST_AUTO_TEST_CASE(DeletePitInOutRecords)
133{
134 Forwarder forwarder;
135 Pit& pit = forwarder.getPit();
136
137 shared_ptr<Face> face1 = make_shared<DummyFace>();
138 shared_ptr<Face> face2 = make_shared<DummyFace>();
139 forwarder.addFace(face1);
140 forwarder.addFace(face2);
141
142 // {}
143 BOOST_CHECK_EQUAL(pit.size(), 0);
144
145 shared_ptr<Interest> interestA = makeInterest("/A");
146 shared_ptr<pit::Entry> entryA = pit.insert(*interestA).first;
147 entryA->insertOrUpdateInRecord(face1, *interestA);
148 entryA->insertOrUpdateInRecord(face2, *interestA);
149 entryA->insertOrUpdateOutRecord(face1, *interestA);
150 entryA->insertOrUpdateOutRecord(face2, *interestA);
151 // {'/A':[1,2]}
152
153 shared_ptr<Interest> interestB = makeInterest("/B");
154 shared_ptr<pit::Entry> entryB = pit.insert(*interestB).first;
155 entryB->insertOrUpdateInRecord(face1, *interestB);
156 entryB->insertOrUpdateOutRecord(face1, *interestB);
157 // {'/A':[1,2], '/B':[1]}
158
159 shared_ptr<Interest> interestC = makeInterest("/C");
160 shared_ptr<pit::Entry> entryC = pit.insert(*interestC).first;
161 entryC->insertOrUpdateInRecord(face2, *interestC);
162 entryC->insertOrUpdateOutRecord(face2, *interestC);
163 // {'/A':[1,2], '/B':[1], '/C':[2]}
164 BOOST_CHECK_EQUAL(pit.size(), 3);
165
166 // ---- close face1 ----
167 face1->close();
168 BOOST_CHECK_EQUAL(face1->getState(), face::FaceState::CLOSED);
169 // {'/A':[2], '/B':[], '/C':[2]}
170 BOOST_CHECK_EQUAL(pit.size(), 3);
171
172 shared_ptr<pit::Entry> foundA = pit.find(*interestA);
173 BOOST_REQUIRE(foundA != nullptr);
174 BOOST_REQUIRE_EQUAL(foundA->getInRecords().size(), 1);
175 BOOST_CHECK_EQUAL(foundA->getInRecords().front().getFace(), face2);
176 BOOST_REQUIRE_EQUAL(foundA->getOutRecords().size(), 1);
177 BOOST_CHECK_EQUAL(foundA->getOutRecords().front().getFace(), face2);
178}
179
180BOOST_AUTO_TEST_SUITE_END() // FaceRemovalCleanup
181
182BOOST_AUTO_TEST_SUITE_END() // TestCleanup
183BOOST_AUTO_TEST_SUITE_END() // Table
184
185} // namespace tests
186} // namespace nfd