blob: 4e4f587ae38497730509d240295bcc4ddd5a21e2 [file] [log] [blame]
Steve DiBenedetto042bfe92014-01-30 15:05:08 -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 "mgmt/fib-manager.hpp"
8#include "fw/forwarder.hpp"
9#include "table/fib.hpp"
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070010#include "table/fib-nexthop.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070011#include "face/face.hpp"
Steve DiBenedetto3970c892014-01-31 23:31:13 -070012#include "mgmt/internal-face.hpp"
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070013#include "../face/dummy-face.hpp"
14
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070015#include <algorithm>
16
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070017#include <ndn-cpp-dev/management/fib-management-options.hpp>
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070018#include <ndn-cpp-dev/management/control-response.hpp>
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070019
20#include <boost/test/unit_test.hpp>
21
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070022namespace nfd {
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070023
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070024NFD_LOG_INIT("FibManagerTest");
25
26class FibManagerFixture
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070027{
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070028public:
29
30 shared_ptr<Face>
31 getFace(FaceId id)
32 {
33 if (m_faces.size() < id)
34 {
35 BOOST_FAIL("Attempted to access invalid FaceId: " << id);
36 }
37 return m_faces[id-1];
38 }
39
40 void
41 addFace(shared_ptr<Face> face)
42 {
43 m_faces.push_back(face);
44 }
45
46private:
47 std::vector<shared_ptr<Face> > m_faces;
48};
49
50
51BOOST_AUTO_TEST_SUITE(MgmtFibManager)
52
53void
54validateControlResponse(const Data& response,
55 uint32_t expectedCode,
56 const std::string& expectedText)
57{
58 Block controlRaw = response.getContent().blockFromValue();
59
60 ndn::ControlResponse control;
61 control.wireDecode(controlRaw);
62
63 NFD_LOG_DEBUG("received control response"
64 << " Name: " << response.getName()
65 << " code: " << control.getCode()
66 << " text: " << control.getText());
67
68 BOOST_REQUIRE(control.getCode() == expectedCode);
69 BOOST_REQUIRE(control.getText() == expectedText);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070070}
71
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070072BOOST_AUTO_TEST_CASE(MalformedCommmand)
73{
74 FibManagerFixture fixture;
75 shared_ptr<InternalFace> face(new InternalFace);
76 Fib fib;
77 FibManager manager(fib,
78 bind(&FibManagerFixture::getFace,
79 &fixture, _1),
80 face);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070081
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070082 face->onReceiveData +=
83 bind(&validateControlResponse, _1, 404, "MALFORMED");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070084
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070085 Interest command("/localhost/nfd/fib");
86 manager.onFibRequest(command);
87}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -070088
Steve DiBenedetto43cd0372014-02-01 17:05:07 -070089BOOST_AUTO_TEST_CASE(UnsupportedVerb)
90{
91 FibManagerFixture fixture;
92 shared_ptr<InternalFace> face(new InternalFace);
93 Fib fib;
94 FibManager manager(fib,
95 bind(&FibManagerFixture::getFace,
96 &fixture, _1),
97 face);
98 face->onReceiveData +=
99 bind(&validateControlResponse, _1, 404, "UNSUPPORTED");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700100
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700101 ndn::FibManagementOptions options;
102 options.setName("/hello");
103 options.setFaceId(1);
104 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700105
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700106 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700107
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700108 Name commandName("/localhost/nfd/fib");
109 commandName.append("unsupported");
110 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700111
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700112 Interest command(commandName);
113 manager.onFibRequest(command);
114}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700115
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700116bool
117foundNextHop(FaceId id, uint32_t cost, const fib::NextHop& next)
118{
119 return id == next.getFace()->getId() && next.getCost() == cost;
120}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700121
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700122BOOST_AUTO_TEST_CASE(AddNextHopVerbInitialAdd)
123{
124 FibManagerFixture fixture;
125 fixture.addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700126
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700127 shared_ptr<InternalFace> face(new InternalFace);
128 Fib fib;
129 FibManager manager(fib,
130 bind(&FibManagerFixture::getFace,
131 &fixture, _1),
132 face);
133 face->onReceiveData +=
134 bind(&validateControlResponse, _1, 200, "OK");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700135
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700136
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700137
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700138 ndn::FibManagementOptions options;
139 options.setName("/hello");
140 options.setFaceId(1);
141 options.setCost(101);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700142
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700143 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700144
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700145 Name commandName("/localhost/nfd/fib");
146 commandName.append("add-nexthop");
147 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700148
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700149 Interest command(commandName);
150 manager.onFibRequest(command);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700151
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700152 shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700153
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700154 if (entry)
155 {
156 const fib::NextHopList& hops = entry->getNextHops();
157 NFD_LOG_DEBUG("FaceId: " << hops[0].getFace()->getId());
158 BOOST_REQUIRE(hops.size() == 1);
159 BOOST_REQUIRE(std::find_if(hops.begin(),
160 hops.end(),
161 bind(&foundNextHop, -1, 101, _1)) != hops.end());
162 }
163 else
164 {
165 BOOST_FAIL("Failed to find expected fib entry");
166 }
167}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700168
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700169BOOST_AUTO_TEST_CASE(AddNextHopVerbAddToExisting)
170{
171 FibManagerFixture fixture;
172 fixture.addFace(make_shared<DummyFace>());
173 fixture.addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700174
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700175 shared_ptr<InternalFace> face(new InternalFace);
176 Fib fib;
177 FibManager manager(fib,
178 bind(&FibManagerFixture::getFace,
179 &fixture, _1),
180 face);
181 face->onReceiveData +=
182 bind(&validateControlResponse, _1, 200, "OK");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700183
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700184 // Add faces with cost == FaceID for the name /hello
185 // This test assumes:
186 // FaceIDs are -1 because we don't add them to a forwarder
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700187
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700188 for (int i = 1; i <= 2; i++)
189 {
190 ndn::FibManagementOptions options;
191 options.setName("/hello");
192 options.setFaceId(i);
193 options.setCost(100 + i);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700194
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700195 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700196
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700197 Name commandName("/localhost/nfd/fib");
198 commandName.append("add-nexthop");
199 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700200
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700201 Interest command(commandName);
202 manager.onFibRequest(command);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700203
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700204 shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700205
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700206 if (entry)
207 {
208 const fib::NextHopList& hops = entry->getNextHops();
209 for (int j = 1; j <= i; j++)
210 {
211 BOOST_REQUIRE(hops.size() == i);
212 // BOOST_REQUIRE(hops[j-1].getCost() == j);
213 BOOST_REQUIRE(std::find_if(hops.begin(),
214 hops.end(),
215 bind(&foundNextHop, -1, 100 + j, _1)) != hops.end());
216 }
217 }
218 else
219 {
220 BOOST_FAIL("Failed to find expected fib entry");
221 }
222 }
223}
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700224
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700225BOOST_AUTO_TEST_CASE(AddNextHopVerbUpdateFaceCost)
226{
227 FibManagerFixture fixture;
228 fixture.addFace(make_shared<DummyFace>());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700229
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700230 shared_ptr<InternalFace> face(new InternalFace);
231 Fib fib;
232 FibManager manager(fib,
233 bind(&FibManagerFixture::getFace,
234 &fixture, _1),
235 face);
236 face->onReceiveData +=
237 bind(&validateControlResponse, _1, 200, "OK");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700238
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700239 ndn::FibManagementOptions options;
240 options.setName("/hello");
241 options.setFaceId(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700242
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700243 {
244 options.setCost(1);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700245
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700246 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700247
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700248 Name commandName("/localhost/nfd/fib");
249 commandName.append("add-nexthop");
250 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700251
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700252 Interest command(commandName);
253 manager.onFibRequest(command);
254 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700255
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700256 {
257 options.setCost(102);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700258
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700259 Block encodedOptions(options.wireEncode());
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700260
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700261 Name commandName("/localhost/nfd/fib");
262 commandName.append("add-nexthop");
263 commandName.append(encodedOptions);
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700264
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700265 Interest command(commandName);
266 manager.onFibRequest(command);
267 }
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700268
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700269 shared_ptr<fib::Entry> entry = fib.findLongestPrefixMatch("/hello");
Steve DiBenedetto042bfe92014-01-30 15:05:08 -0700270
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700271 // Add faces with cost == FaceID for the name /hello
272 // This test assumes:
273 // FaceIDs are -1 because we don't add them to a forwarder
274 if (entry)
275 {
276 const fib::NextHopList& hops = entry->getNextHops();
277 BOOST_REQUIRE(hops.size() == 1);
278 BOOST_REQUIRE(std::find_if(hops.begin(),
279 hops.end(),
280 bind(&foundNextHop, -1, 102, _1)) != hops.end());
281 }
282 else
283 {
284 BOOST_FAIL("Failed to find expected fib entry");
285 }
286}
Steve DiBenedetto3970c892014-01-31 23:31:13 -0700287
Steve DiBenedetto43cd0372014-02-01 17:05:07 -0700288BOOST_AUTO_TEST_SUITE_END()
289
290} // namespace nfd