blob: dd3291bc367e6e593d45992fb6a8a78567f2bae7 [file] [log] [blame]
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -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/strategy-choice-manager.hpp"
8#include "face/face.hpp"
9#include "mgmt/internal-face.hpp"
10#include "table/name-tree.hpp"
11#include "table/strategy-choice.hpp"
12#include "fw/forwarder.hpp"
13#include "fw/strategy.hpp"
14#include "tests/face/dummy-face.hpp"
15
16
17#include "tests/test-common.hpp"
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070018#include "validation-common.hpp"
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -070019
20namespace nfd {
21namespace tests {
22
23NFD_LOG_INIT("StrategyChoiceManagerTest");
24
25class DummyStrategy : public fw::Strategy
26{
27public:
28 DummyStrategy(Forwarder& forwarder, const Name& strategyName)
29 : fw::Strategy(forwarder, strategyName)
30 {
31
32 }
33
34 virtual
35 ~DummyStrategy()
36 {
37
38 }
39
40 virtual void
41 afterReceiveInterest(const Face& inFace,
42 const Interest& interest,
43 shared_ptr<fib::Entry> fibEntry,
44 shared_ptr<pit::Entry> pitEntry)
45 {
46
47 }
48};
49
50class TestStrategyA : public DummyStrategy
51{
52public:
53 TestStrategyA(Forwarder& forwarder)
54 : DummyStrategy(forwarder, "/localhost/nfd/strategy/test-strategy-a")
55 {
56 }
57
58 virtual
59 ~TestStrategyA()
60 {
61
62 }
63};
64
65class TestStrategyB : public DummyStrategy
66{
67public:
68 TestStrategyB(Forwarder& forwarder)
69 : DummyStrategy(forwarder, "/localhost/nfd/strategy/test-strategy-b")
70 {
71 }
72
73 virtual
74 ~TestStrategyB()
75 {
76
77 }
78};
79
80class StrategyChoiceManagerFixture : protected BaseFixture
81{
82public:
83
84 StrategyChoiceManagerFixture()
85 : m_nameTree(1024)
86 , m_strategyChoice(m_nameTree, make_shared<TestStrategyA>(boost::ref(m_forwarder)))
87 , m_face(make_shared<InternalFace>())
88 , m_manager(m_strategyChoice, m_face)
89 , m_callbackFired(false)
90 {
91
92 }
93
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070094 virtual
95 ~StrategyChoiceManagerFixture()
96 {
97
98 }
99
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700100 void
101 validateControlResponseCommon(const Data& response,
102 const Name& expectedName,
103 uint32_t expectedCode,
104 const std::string& expectedText,
105 ControlResponse& control)
106 {
107 m_callbackFired = true;
108 Block controlRaw = response.getContent().blockFromValue();
109
110 control.wireDecode(controlRaw);
111
112 NFD_LOG_DEBUG("received control response"
113 << " Name: " << response.getName()
114 << " code: " << control.getCode()
115 << " text: " << control.getText());
116
117 BOOST_CHECK_EQUAL(response.getName(), expectedName);
118 BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
119 BOOST_CHECK_EQUAL(control.getText(), expectedText);
120 }
121
122 void
123 validateControlResponse(const Data& response,
124 const Name& expectedName,
125 uint32_t expectedCode,
126 const std::string& expectedText)
127 {
128 ControlResponse control;
129 validateControlResponseCommon(response, expectedName,
130 expectedCode, expectedText, control);
131
132 if (!control.getBody().empty())
133 {
134 BOOST_FAIL("found unexpected control response body");
135 }
136 }
137
138 void
139 validateControlResponse(const Data& response,
140 const Name& expectedName,
141 uint32_t expectedCode,
142 const std::string& expectedText,
143 const Block& expectedBody)
144 {
145 ControlResponse control;
146 validateControlResponseCommon(response, expectedName,
147 expectedCode, expectedText, control);
148
149 BOOST_REQUIRE(!control.getBody().empty());
150 BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
151
152 BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
153 expectedBody.value_size()) == 0);
154
155 }
156
157 bool
158 didCallbackFire()
159 {
160 return m_callbackFired;
161 }
162
163 void
164 resetCallbackFired()
165 {
166 m_callbackFired = false;
167 }
168
169 shared_ptr<InternalFace>&
170 getFace()
171 {
172 return m_face;
173 }
174
175 StrategyChoiceManager&
176 getManager()
177 {
178 return m_manager;
179 }
180
181 StrategyChoice&
182 getStrategyChoice()
183 {
184 return m_strategyChoice;
185 }
186
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700187 void
188 addInterestRule(const std::string& regex,
189 ndn::IdentityCertificate& certificate)
190 {
191 m_manager.addInterestRule(regex, certificate);
192 }
193
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700194protected:
195 Forwarder m_forwarder;
196 NameTree m_nameTree;
197 StrategyChoice m_strategyChoice;
198 shared_ptr<InternalFace> m_face;
199 StrategyChoiceManager m_manager;
200
201private:
202 bool m_callbackFired;
203};
204
205class AllStrategiesFixture : public StrategyChoiceManagerFixture
206{
207public:
208 AllStrategiesFixture()
209 {
210 m_strategyChoice.install(make_shared<TestStrategyB>(boost::ref(m_forwarder)));
211 }
212
213 virtual
214 ~AllStrategiesFixture()
215 {
216
217 }
218};
219
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700220template <typename T> class AuthorizedCommandFixture : public CommandFixture<T>
221{
222public:
223 AuthorizedCommandFixture()
224 {
225 const std::string regex = "^<localhost><nfd><strategy-choice>";
226 T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
227 }
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700228
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700229 virtual
230 ~AuthorizedCommandFixture()
231 {
232
233 }
234};
235
236BOOST_FIXTURE_TEST_SUITE(MgmtStrategyChoiceManager,
237 AuthorizedCommandFixture<AllStrategiesFixture>)
238
239BOOST_FIXTURE_TEST_CASE(TestFireInterestFilter, AllStrategiesFixture)
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700240{
241 shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
242
243 getFace()->onReceiveData +=
244 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
245 command->getName(), 400, "Malformed command");
246
247 getFace()->sendInterest(*command);
248
249 BOOST_REQUIRE(didCallbackFire());
250}
251
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700252BOOST_FIXTURE_TEST_CASE(MalformedCommmand, AllStrategiesFixture)
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700253{
254 shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/strategy-choice"));
255
256 getFace()->onReceiveData +=
257 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
258 command->getName(), 400, "Malformed command");
259
260 getManager().onStrategyChoiceRequest(*command);
261
262 BOOST_REQUIRE(didCallbackFire());
263}
264
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700265BOOST_FIXTURE_TEST_CASE(UnsignedCommand, AllStrategiesFixture)
266{
267 ndn::nfd::FibManagementOptions options;
268 options.setName("/test");
269 options.setStrategy("/localhost/nfd/strategy/best-route");
270
271 Block encodedOptions(options.wireEncode());
272
273 Name commandName("/localhost/nfd/strategy-choice");
274 commandName.append("set");
275 commandName.append(encodedOptions);
276
277 shared_ptr<Interest> command(make_shared<Interest>(commandName));
278
279 getFace()->onReceiveData +=
280 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
281 command->getName(), 401, "Signature required");
282
283 getManager().onStrategyChoiceRequest(*command);
284
285 BOOST_REQUIRE(didCallbackFire());
286}
287
288BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand,
289 UnauthorizedCommandFixture<StrategyChoiceManagerFixture>)
290{
291 ndn::nfd::FibManagementOptions options;
292 options.setName("/test");
293 options.setStrategy("/localhost/nfd/strategy/best-route");
294
295 Block encodedOptions(options.wireEncode());
296
297 Name commandName("/localhost/nfd/strategy-choice");
298 commandName.append("set");
299 commandName.append(encodedOptions);
300
301 shared_ptr<Interest> command(make_shared<Interest>(commandName));
302 generateCommand(*command);
303
304 getFace()->onReceiveData +=
305 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
306 command->getName(), 403, "Unauthorized command");
307
308 getManager().onStrategyChoiceRequest(*command);
309
310 BOOST_REQUIRE(didCallbackFire());
311}
312
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700313BOOST_AUTO_TEST_CASE(UnsupportedVerb)
314{
315 ndn::nfd::FibManagementOptions options;
316 options.setStrategy("/localhost/nfd/strategy/test-strategy-b");
317
318 Block encodedOptions(options.wireEncode());
319
320 Name commandName("/localhost/nfd/strategy-choice");
321 commandName.append("unsupported");
322 commandName.append(encodedOptions);
323
324 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700325 generateCommand(*command);
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700326
327 getFace()->onReceiveData +=
328 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
329 command->getName(), 501, "Unsupported command");
330
331 getManager().onValidatedStrategyChoiceRequest(command);
332
333 BOOST_REQUIRE(didCallbackFire());
334}
335
336BOOST_AUTO_TEST_CASE(BadOptionParse)
337{
338 Name commandName("/localhost/nfd/strategy-choice");
339 commandName.append("set");
340 commandName.append("NotReallyOptions");
341
342 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700343 generateCommand(*command);
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700344
345 getFace()->onReceiveData +=
346 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
347 command->getName(), 400, "Malformed command");
348
349 getManager().onValidatedStrategyChoiceRequest(command);
350
351 BOOST_REQUIRE(didCallbackFire());
352}
353
354BOOST_AUTO_TEST_CASE(SetStrategies)
355{
356 ndn::nfd::FibManagementOptions options;
357 options.setName("/test");
358 options.setStrategy("/localhost/nfd/strategy/test-strategy-b");
359
360 Block encodedOptions(options.wireEncode());
361
362 Name commandName("/localhost/nfd/strategy-choice");
363 commandName.append("set");
364 commandName.append(encodedOptions);
365
366 shared_ptr<Interest> command(make_shared<Interest>(commandName));
367
368 getFace()->onReceiveData +=
369 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
370 command->getName(), 200, "Success", encodedOptions);
371
372 getManager().onValidatedStrategyChoiceRequest(command);
373
374 BOOST_REQUIRE(didCallbackFire());
375 fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
376 BOOST_REQUIRE_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-b");
377
378 resetCallbackFired();
379 getFace()->onReceiveData.clear();
380}
381
382BOOST_AUTO_TEST_CASE(SetUnsupportedStrategy)
383{
384 ndn::nfd::FibManagementOptions options;
385 options.setName("/test");
386 options.setStrategy("/localhost/nfd/strategy/unit-test-doesnotexist");
387
388 Block encodedOptions(options.wireEncode());
389
390 Name commandName("/localhost/nfd/strategy-choice");
391 commandName.append("set");
392 commandName.append(encodedOptions);
393
394 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700395 generateCommand(*command);
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700396
397 getFace()->onReceiveData +=
398 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
399 command->getName(), 504, "Unsupported strategy");
400
401 getManager().onValidatedStrategyChoiceRequest(command);
402
403 BOOST_REQUIRE(didCallbackFire());
404 fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
405 BOOST_CHECK_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
406}
407
408class DefaultStrategyOnlyFixture : public StrategyChoiceManagerFixture
409{
410public:
411 DefaultStrategyOnlyFixture()
412 : StrategyChoiceManagerFixture()
413 {
414
415 }
416
417 virtual
418 ~DefaultStrategyOnlyFixture()
419 {
420
421 }
422};
423
424
425/// \todo I'm not sure this code branch (code 405) can happen. The manager tests for the strategy first and will return 504.
426// BOOST_FIXTURE_TEST_CASE(SetNotInstalled, DefaultStrategyOnlyFixture)
427// {
428// BOOST_REQUIRE(!getStrategyChoice().hasStrategy("/localhost/nfd/strategy/test-strategy-b"));
429// ndn::nfd::FibManagementOptions options;
430// options.setName("/test");
431// options.setStrategy("/localhost/nfd/strategy/test-strategy-b");
432
433// Block encodedOptions(options.wireEncode());
434
435// Name commandName("/localhost/nfd/strategy-choice");
436// commandName.append("set");
437// commandName.append(encodedOptions);
438
439// shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700440// generateCommand(*command);
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700441
442// getFace()->onReceiveData +=
443// bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
444// command->getName(), 405, "Strategy not installed");
445
446// getManager().onValidatedStrategyChoiceRequest(command);
447
448// BOOST_REQUIRE(didCallbackFire());
449// fw::Strategy& strategy = getStrategyChoice().findEffectiveStrategy("/test");
450// BOOST_CHECK_EQUAL(strategy.getName(), "/localhost/nfd/strategy/test-strategy-a");
451// }
452
453BOOST_AUTO_TEST_CASE(Unset)
454{
455 ndn::nfd::FibManagementOptions options;
456 options.setName("/test");
457
458 BOOST_REQUIRE(m_strategyChoice.insert("/test", "/localhost/nfd/strategy/test-strategy-b"));
459 BOOST_REQUIRE_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
460 "/localhost/nfd/strategy/test-strategy-b");
461
462 Block encodedOptions(options.wireEncode());
463
464 Name commandName("/localhost/nfd/strategy-choice");
465 commandName.append("unset");
466 commandName.append(encodedOptions);
467
468 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700469 generateCommand(*command);
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700470
471 getFace()->onReceiveData +=
472 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
473 command->getName(), 200, "Success", encodedOptions);
474
475 getManager().onValidatedStrategyChoiceRequest(command);
476
477 BOOST_REQUIRE(didCallbackFire());
478
479 BOOST_CHECK_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
480 "/localhost/nfd/strategy/test-strategy-a");
481}
482
483BOOST_AUTO_TEST_CASE(UnsetRoot)
484{
485 ndn::nfd::FibManagementOptions options;
486 options.setName("/");
487
488 Block encodedOptions(options.wireEncode());
489
490 Name commandName("/localhost/nfd/strategy-choice");
491 commandName.append("unset");
492 commandName.append(encodedOptions);
493
494 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700495 generateCommand(*command);
Steve DiBenedetto5330e0d2014-03-05 21:52:51 -0700496
497 getFace()->onReceiveData +=
498 bind(&StrategyChoiceManagerFixture::validateControlResponse, this, _1,
499 command->getName(), 403, "Cannot unset root prefix strategy");
500
501 getManager().onValidatedStrategyChoiceRequest(command);
502
503 BOOST_REQUIRE(didCallbackFire());
504
505 BOOST_CHECK_EQUAL(m_strategyChoice.findEffectiveStrategy("/test").getName(),
506 "/localhost/nfd/strategy/test-strategy-a");
507}
508
509BOOST_AUTO_TEST_SUITE_END()
510
511} // namespace tests
512} // namespace nfd