blob: 45a609fcbb18caae5d95e442f7350218d46a74b8 [file] [log] [blame]
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001/* -*- 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 */
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07006
7#include "mgmt/face-manager.hpp"
8#include "mgmt/internal-face.hpp"
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06009#include "mgmt/face-status-publisher.hpp"
Steve DiBenedettofbb40a82014-03-11 19:40:15 -060010
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070011#include "face/face.hpp"
12#include "../face/dummy-face.hpp"
13#include "fw/face-table.hpp"
14#include "fw/forwarder.hpp"
15
16#include "common.hpp"
17#include "tests/test-common.hpp"
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -070018#include "validation-common.hpp"
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060019#include "face-status-publisher-common.hpp"
20
21#include <ndn-cpp-dev/encoding/tlv.hpp>
Steve DiBenedettofbb40a82014-03-11 19:40:15 -060022#include <ndn-cpp-dev/management/nfd-face-event-notification.hpp>
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070023
24namespace nfd {
25namespace tests {
26
27NFD_LOG_INIT("FaceManagerTest");
28
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060029class FaceManagerTestFace : public DummyFace
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070030{
31public:
32
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060033 FaceManagerTestFace()
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070034 : m_closeFired(false)
35 {
36
37 }
38
39 virtual
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060040 ~FaceManagerTestFace()
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070041 {
42
43 }
44
45 virtual void
46 close()
47 {
48 m_closeFired = true;
49 }
50
51 bool
52 didCloseFire() const
53 {
54 return m_closeFired;
55 }
56
57private:
58 bool m_closeFired;
59};
60
61class TestFaceTable : public FaceTable
62{
63public:
64 TestFaceTable(Forwarder& forwarder)
65 : FaceTable(forwarder),
66 m_addFired(false),
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070067 m_getFired(false),
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -060068 m_dummy(make_shared<FaceManagerTestFace>())
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070069 {
70
71 }
72
73 virtual
74 ~TestFaceTable()
75 {
76
77 }
78
79 virtual void
80 add(shared_ptr<Face> face)
81 {
82 m_addFired = true;
83 }
84
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070085 virtual shared_ptr<Face>
86 get(FaceId id) const
87 {
88 m_getFired = true;
89 return m_dummy;
90 }
91
92 bool
93 didAddFire() const
94 {
95 return m_addFired;
96 }
97
Steve DiBenedettoabe9e972014-02-20 15:37:04 -070098 bool
99 didGetFire() const
100 {
101 return m_getFired;
102 }
103
104 void
105 reset()
106 {
107 m_addFired = false;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700108 m_getFired = false;
109 }
110
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600111 shared_ptr<FaceManagerTestFace>&
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700112 getDummyFace()
113 {
114 return m_dummy;
115 }
116
117private:
118 bool m_addFired;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700119 mutable bool m_getFired;
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600120 shared_ptr<FaceManagerTestFace> m_dummy;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700121};
122
123
124class TestFaceTableFixture : public BaseFixture
125{
126public:
127 TestFaceTableFixture()
128 : m_faceTable(m_forwarder)
129 {
130
131 }
132
133 virtual
134 ~TestFaceTableFixture()
135 {
136
137 }
138
139protected:
140 Forwarder m_forwarder;
141 TestFaceTable m_faceTable;
142};
143
144class TestFaceManagerCommon
145{
146public:
147 TestFaceManagerCommon()
148 : m_face(make_shared<InternalFace>()),
149 m_callbackFired(false)
150 {
151
152 }
153
154 virtual
155 ~TestFaceManagerCommon()
156 {
157
158 }
159
160 shared_ptr<InternalFace>&
161 getFace()
162 {
163 return m_face;
164 }
165
166 void
167 validateControlResponseCommon(const Data& response,
168 const Name& expectedName,
169 uint32_t expectedCode,
170 const std::string& expectedText,
171 ControlResponse& control)
172 {
173 m_callbackFired = true;
174 Block controlRaw = response.getContent().blockFromValue();
175
176 control.wireDecode(controlRaw);
177
178 // NFD_LOG_DEBUG("received control response"
179 // << " Name: " << response.getName()
180 // << " code: " << control.getCode()
181 // << " text: " << control.getText());
182
183 BOOST_CHECK_EQUAL(response.getName(), expectedName);
184 BOOST_CHECK_EQUAL(control.getCode(), expectedCode);
185 BOOST_CHECK_EQUAL(control.getText(), expectedText);
186 }
187
188 void
189 validateControlResponse(const Data& response,
190 const Name& expectedName,
191 uint32_t expectedCode,
192 const std::string& expectedText)
193 {
194 ControlResponse control;
195 validateControlResponseCommon(response, expectedName,
196 expectedCode, expectedText, control);
197
198 if (!control.getBody().empty())
199 {
200 BOOST_FAIL("found unexpected control response body");
201 }
202 }
203
204 void
205 validateControlResponse(const Data& response,
206 const Name& expectedName,
207 uint32_t expectedCode,
208 const std::string& expectedText,
209 const Block& expectedBody)
210 {
211 ControlResponse control;
212 validateControlResponseCommon(response, expectedName,
213 expectedCode, expectedText, control);
214
215 BOOST_REQUIRE(!control.getBody().empty());
216 BOOST_REQUIRE(control.getBody().value_size() == expectedBody.value_size());
217
218 BOOST_CHECK(memcmp(control.getBody().value(), expectedBody.value(),
219 expectedBody.value_size()) == 0);
220
221 }
222
223 bool
224 didCallbackFire() const
225 {
226 return m_callbackFired;
227 }
228
229 void
230 resetCallbackFired()
231 {
232 m_callbackFired = false;
233 }
234
235protected:
236 shared_ptr<InternalFace> m_face;
237
238private:
239 bool m_callbackFired;
240};
241
242class FaceManagerFixture : public TestFaceTableFixture, public TestFaceManagerCommon
243{
244public:
245 FaceManagerFixture()
246 : m_manager(m_faceTable, m_face)
247 {
248 m_manager.setConfigFile(m_config);
249 }
250
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700251 virtual
252 ~FaceManagerFixture()
253 {
254
255 }
256
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -0600257 void
258 parseConfig(const std::string configuration, bool isDryRun)
259 {
260 m_config.parse(configuration, isDryRun, "dummy-config");
261 }
262
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700263 FaceManager&
264 getManager()
265 {
266 return m_manager;
267 }
268
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700269 void
270 addInterestRule(const std::string& regex,
271 ndn::IdentityCertificate& certificate)
272 {
273 m_manager.addInterestRule(regex, certificate);
274 }
275
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700276 bool
277 didFaceTableAddFire() const
278 {
279 return m_faceTable.didAddFire();
280 }
281
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700282 bool
283 didFaceTableGetFire() const
284 {
285 return m_faceTable.didGetFire();
286 }
287
288 void
289 resetFaceTable()
290 {
291 m_faceTable.reset();
292 }
293
294private:
295 FaceManager m_manager;
296 ConfigFile m_config;
297};
298
299BOOST_FIXTURE_TEST_SUITE(MgmtFaceManager, FaceManagerFixture)
300
301bool
302isExpectedException(const ConfigFile::Error& error, const std::string& expectedMessage)
303{
304 if (error.what() != expectedMessage)
305 {
306 NFD_LOG_ERROR("expected: " << expectedMessage << "\tgot: " << error.what());
307 }
308 return error.what() == expectedMessage;
309}
310
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600311#ifdef HAVE_UNIX_SOCKETS
312
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700313BOOST_AUTO_TEST_CASE(TestProcessSectionUnix)
314{
315 const std::string CONFIG =
316 "face_system\n"
317 "{\n"
318 " unix\n"
319 " {\n"
320 " listen yes\n"
321 " path /tmp/nfd.sock\n"
322 " }\n"
323 "}\n";
324 BOOST_TEST_CHECKPOINT("Calling parse");
325 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
326}
327
328BOOST_AUTO_TEST_CASE(TestProcessSectionUnixDryRun)
329{
330 const std::string CONFIG =
331 "face_system\n"
332 "{\n"
333 " unix\n"
334 " {\n"
335 " listen yes\n"
336 " path /var/run/nfd.sock\n"
337 " }\n"
338 "}\n";
339
340 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
341}
342
343BOOST_AUTO_TEST_CASE(TestProcessSectionUnixBadListen)
344{
345 const std::string CONFIG =
346 "face_system\n"
347 "{\n"
348 " unix\n"
349 " {\n"
350 " listen hello\n"
351 " }\n"
352 "}\n";
353 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
354 bind(&isExpectedException, _1,
355 "Invalid value for option \"listen\" in \"unix\" section"));
356}
357
358BOOST_AUTO_TEST_CASE(TestProcessSectionUnixUnknownOption)
359{
360 const std::string CONFIG =
361 "face_system\n"
362 "{\n"
363 " unix\n"
364 " {\n"
365 " hello\n"
366 " }\n"
367 "}\n";
368 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
369 bind(&isExpectedException, _1,
370 "Unrecognized option \"hello\" in \"unix\" section"));
371}
372
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600373#endif // HAVE_UNIX_SOCKETS
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700374
375
376BOOST_AUTO_TEST_CASE(TestProcessSectionTcp)
377{
378 const std::string CONFIG =
379 "face_system\n"
380 "{\n"
381 " tcp\n"
382 " {\n"
383 " listen yes\n"
384 " port 6363\n"
385 " }\n"
386 "}\n";
387 try
388 {
389 parseConfig(CONFIG, false);
390 }
391 catch (const std::runtime_error& e)
392 {
393 const std::string reason = e.what();
394 if (reason.find("Address in use") != std::string::npos)
395 {
396 BOOST_FAIL(reason);
397 }
398 }
399}
400
401BOOST_AUTO_TEST_CASE(TestProcessSectionTcpDryRun)
402{
403 const std::string CONFIG =
404 "face_system\n"
405 "{\n"
406 " tcp\n"
407 " {\n"
408 " listen yes\n"
409 " port 6363\n"
410 " }\n"
411 "}\n";
412 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
413}
414
415BOOST_AUTO_TEST_CASE(TestProcessSectionTcpBadListen)
416{
417 const std::string CONFIG =
418 "face_system\n"
419 "{\n"
420 " tcp\n"
421 " {\n"
422 " listen hello\n"
423 " }\n"
424 "}\n";
425 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
426 bind(&isExpectedException, _1,
427 "Invalid value for option \"listen\" in \"tcp\" section"));
428}
429
430BOOST_AUTO_TEST_CASE(TestProcessSectionTcpUnknownOption)
431{
432 const std::string CONFIG =
433 "face_system\n"
434 "{\n"
435 " tcp\n"
436 " {\n"
437 " hello\n"
438 " }\n"
439 "}\n";
440 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
441 bind(&isExpectedException, _1,
442 "Unrecognized option \"hello\" in \"tcp\" section"));
443}
444
445BOOST_AUTO_TEST_CASE(TestProcessSectionUdp)
446{
447 const std::string CONFIG =
448 "face_system\n"
449 "{\n"
450 " udp\n"
451 " {\n"
452 " port 6363\n"
453 " idle_timeout 30\n"
454 " keep_alive_interval 25\n"
455 " mcast yes\n"
456 " mcast_port 56363\n"
457 " mcast_group 224.0.23.170\n"
458 " }\n"
459 "}\n";
460 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
461}
462
463BOOST_AUTO_TEST_CASE(TestProcessSectionUdpDryRun)
464{
465 const std::string CONFIG =
466 "face_system\n"
467 "{\n"
468 " udp\n"
469 " {\n"
470 " port 6363\n"
471 " idle_timeout 30\n"
472 " keep_alive_interval 25\n"
473 " mcast yes\n"
474 " mcast_port 56363\n"
475 " mcast_group 224.0.23.170\n"
476 " }\n"
477 "}\n";
478 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
479}
480
481BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadIdleTimeout)
482{
483 const std::string CONFIG =
484 "face_system\n"
485 "{\n"
486 " udp\n"
487 " {\n"
488 " idle_timeout hello\n"
489 " }\n"
490 "}\n";
491
492 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
493 bind(&isExpectedException, _1,
494 "Invalid value for option \"idle_timeout\" in \"udp\" section"));
495}
496
497BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcast)
498{
499 const std::string CONFIG =
500 "face_system\n"
501 "{\n"
502 " udp\n"
503 " {\n"
504 " mcast hello\n"
505 " }\n"
506 "}\n";
507
508 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
509 bind(&isExpectedException, _1,
510 "Invalid value for option \"mcast\" in \"udp\" section"));
511}
512
513BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcastGroup)
514{
515 const std::string CONFIG =
516 "face_system\n"
517 "{\n"
518 " udp\n"
519 " {\n"
520 " mcast no\n"
521 " mcast_port 50\n"
522 " mcast_group hello\n"
523 " }\n"
524 "}\n";
525
526 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
527 bind(&isExpectedException, _1,
528 "Invalid value for option \"mcast_group\" in \"udp\" section"));
529}
530
531BOOST_AUTO_TEST_CASE(TestProcessSectionUdpBadMcastGroupV6)
532{
533 const std::string CONFIG =
534 "face_system\n"
535 "{\n"
536 " udp\n"
537 " {\n"
538 " mcast no\n"
539 " mcast_port 50\n"
540 " mcast_group ::1\n"
541 " }\n"
542 "}\n";
543
544 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
545 bind(&isExpectedException, _1,
546 "Invalid value for option \"mcast_group\" in \"udp\" section"));
547}
548
549BOOST_AUTO_TEST_CASE(TestProcessSectionUdpUnknownOption)
550{
551 const std::string CONFIG =
552 "face_system\n"
553 "{\n"
554 " udp\n"
555 " {\n"
556 " hello\n"
557 " }\n"
558 "}\n";
559 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
560 bind(&isExpectedException, _1,
561 "Unrecognized option \"hello\" in \"udp\" section"));
562}
563
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600564#ifdef HAVE_PCAP
565
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700566BOOST_AUTO_TEST_CASE(TestProcessSectionEther)
567{
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600568
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700569 const std::string CONFIG =
570 "face_system\n"
571 "{\n"
572 " ether\n"
573 " {\n"
574 " mcast yes\n"
575 " mcast_group 01:00:5E:00:17:AA\n"
576 " }\n"
577 "}\n";
578
579 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
580}
581
582BOOST_AUTO_TEST_CASE(TestProcessSectionEtherDryRun)
583{
584 const std::string CONFIG =
585 "face_system\n"
586 "{\n"
587 " ether\n"
588 " {\n"
589 " mcast yes\n"
590 " mcast_group 01:00:5E:00:17:AA\n"
591 " }\n"
592 "}\n";
593
594 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
595}
596
597BOOST_AUTO_TEST_CASE(TestProcessSectionEtherBadMcast)
598{
599 const std::string CONFIG =
600 "face_system\n"
601 "{\n"
602 " ether\n"
603 " {\n"
604 " mcast hello\n"
605 " }\n"
606 "}\n";
607
608 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
609 bind(&isExpectedException, _1,
610 "Invalid value for option \"mcast\" in \"ether\" section"));
611}
612
613BOOST_AUTO_TEST_CASE(TestProcessSectionEtherBadMcastGroup)
614{
615 const std::string CONFIG =
616 "face_system\n"
617 "{\n"
618 " ether\n"
619 " {\n"
620 " mcast yes\n"
621 " mcast_group\n"
622 " }\n"
623 "}\n";
624
625 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
626 bind(&isExpectedException, _1,
627 "Invalid value for option \"mcast_group\" in \"ether\" section"));
628}
629
630BOOST_AUTO_TEST_CASE(TestProcessSectionEtherUnknownOption)
631{
632 const std::string CONFIG =
633 "face_system\n"
634 "{\n"
635 " ether\n"
636 " {\n"
637 " hello\n"
638 " }\n"
639 "}\n";
640 BOOST_CHECK_EXCEPTION(parseConfig(CONFIG, false), ConfigFile::Error,
641 bind(&isExpectedException, _1,
642 "Unrecognized option \"hello\" in \"ether\" section"));
643}
644
Steve DiBenedetto4aca99c2014-03-11 11:27:54 -0600645#endif
646
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700647BOOST_AUTO_TEST_CASE(TestFireInterestFilter)
648{
649 shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
650
651 getFace()->onReceiveData +=
652 bind(&FaceManagerFixture::validateControlResponse, this, _1,
653 command->getName(), 400, "Malformed command");
654
655 getFace()->sendInterest(*command);
656
657 BOOST_REQUIRE(didCallbackFire());
658}
659
660BOOST_AUTO_TEST_CASE(MalformedCommmand)
661{
662 shared_ptr<Interest> command(make_shared<Interest>("/localhost/nfd/faces"));
663
664 getFace()->onReceiveData +=
665 bind(&FaceManagerFixture::validateControlResponse, this, _1,
666 command->getName(), 400, "Malformed command");
667
668 getManager().onFaceRequest(*command);
669
670 BOOST_REQUIRE(didCallbackFire());
671}
672
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700673BOOST_AUTO_TEST_CASE(UnsignedCommand)
674{
675 ndn::nfd::FaceManagementOptions options;
676 options.setUri("tcp://127.0.0.1");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700677
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700678 Block encodedOptions(options.wireEncode());
679
680 Name commandName("/localhost/nfd/faces");
681 commandName.append("create");
682 commandName.append(encodedOptions);
683
684 shared_ptr<Interest> command(make_shared<Interest>(commandName));
685
686 getFace()->onReceiveData +=
687 bind(&FaceManagerFixture::validateControlResponse, this, _1,
688 command->getName(), 401, "Signature required");
689
690 getManager().onFaceRequest(*command);
691
692 BOOST_REQUIRE(didCallbackFire());
693}
694
695BOOST_FIXTURE_TEST_CASE(UnauthorizedCommand, UnauthorizedCommandFixture<FaceManagerFixture>)
696{
697 ndn::nfd::FaceManagementOptions options;
698 options.setUri("tcp://127.0.0.1");
699
700 Block encodedOptions(options.wireEncode());
701
702 Name commandName("/localhost/nfd/faces");
703 commandName.append("create");
704 commandName.append(encodedOptions);
705
706 shared_ptr<Interest> command(make_shared<Interest>(commandName));
707 generateCommand(*command);
708
709 getFace()->onReceiveData +=
710 bind(&FaceManagerFixture::validateControlResponse, this, _1,
711 command->getName(), 403, "Unauthorized command");
712
713 getManager().onFaceRequest(*command);
714
715 BOOST_REQUIRE(didCallbackFire());
716}
717
718template <typename T> class AuthorizedCommandFixture : public CommandFixture<T>
719{
720public:
721 AuthorizedCommandFixture()
722 {
723 const std::string regex = "^<localhost><nfd><faces>";
724 T::addInterestRule(regex, *CommandFixture<T>::m_certificate);
725 }
726
727 virtual
728 ~AuthorizedCommandFixture()
729 {
730
731 }
732};
733
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700734BOOST_FIXTURE_TEST_CASE(UnsupportedCommand, AuthorizedCommandFixture<FaceManagerFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700735{
736 ndn::nfd::FaceManagementOptions options;
737
738 Block encodedOptions(options.wireEncode());
739
740 Name commandName("/localhost/nfd/faces");
741 commandName.append("unsupported");
742 commandName.append(encodedOptions);
743
744 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700745 generateCommand(*command);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700746
747 getFace()->onReceiveData +=
748 bind(&FaceManagerFixture::validateControlResponse, this, _1,
749 command->getName(), 501, "Unsupported command");
750
751 getManager().onFaceRequest(*command);
752
753 BOOST_REQUIRE(didCallbackFire());
754}
755
756class ValidatedFaceRequestFixture : public TestFaceTableFixture,
757 public TestFaceManagerCommon,
758 public FaceManager
759{
760public:
761
762 ValidatedFaceRequestFixture()
763 : FaceManager(TestFaceTableFixture::m_faceTable, TestFaceManagerCommon::m_face),
764 m_createFaceFired(false),
765 m_destroyFaceFired(false)
766 {
767
768 }
769
770 virtual void
771 createFace(const Name& requestName,
772 ndn::nfd::FaceManagementOptions& options)
773 {
774 m_createFaceFired = true;
775 }
776
777 virtual void
778 destroyFace(const Name& requestName,
779 ndn::nfd::FaceManagementOptions& options)
780 {
781 m_destroyFaceFired = true;
782 }
783
784 virtual
785 ~ValidatedFaceRequestFixture()
786 {
787
788 }
789
790 bool
791 didCreateFaceFire() const
792 {
793 return m_createFaceFired;
794 }
795
796 bool
797 didDestroyFaceFire() const
798 {
799 return m_destroyFaceFired;
800 }
801
802private:
803 bool m_createFaceFired;
804 bool m_destroyFaceFired;
805};
806
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700807BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestBadOptionParse,
808 AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700809{
810 Name commandName("/localhost/nfd/faces");
811 commandName.append("create");
812 commandName.append("NotReallyOptions");
813
814 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700815 generateCommand(*command);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700816
817 getFace()->onReceiveData +=
818 bind(&ValidatedFaceRequestFixture::validateControlResponse, this, _1,
819 command->getName(), 400, "Malformed command");
820
821 onValidatedFaceRequest(command);
822
823 BOOST_REQUIRE(didCallbackFire());
824}
825
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700826BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestCreateFace,
827 AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700828{
829 ndn::nfd::FaceManagementOptions options;
830 options.setUri("tcp://127.0.0.1");
831
832 Block encodedOptions(options.wireEncode());
833
834 Name commandName("/localhost/nfd/faces");
835 commandName.append("create");
836 commandName.append(encodedOptions);
837
838 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700839 generateCommand(*command);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700840
841 onValidatedFaceRequest(command);
842 BOOST_CHECK(didCreateFaceFire());
843}
844
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700845BOOST_FIXTURE_TEST_CASE(ValidatedFaceRequestDestroyFace,
846 AuthorizedCommandFixture<ValidatedFaceRequestFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700847{
848 ndn::nfd::FaceManagementOptions options;
849 options.setUri("tcp://127.0.0.1");
850
851 Block encodedOptions(options.wireEncode());
852
853 Name commandName("/localhost/nfd/faces");
854 commandName.append("destroy");
855 commandName.append(encodedOptions);
856
857 shared_ptr<Interest> command(make_shared<Interest>(commandName));
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700858 generateCommand(*command);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700859
860 onValidatedFaceRequest(command);
861 BOOST_CHECK(didDestroyFaceFire());
862}
863
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600864class FaceTableFixture
865{
866public:
867 FaceTableFixture()
868 : m_faceTable(m_forwarder)
869 {
870 }
871
872 virtual
873 ~FaceTableFixture()
874 {
875 }
876
877protected:
878 Forwarder m_forwarder;
879 FaceTable m_faceTable;
880};
881
882class FaceFixture : public FaceTableFixture,
883 public TestFaceManagerCommon,
884 public FaceManager
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700885{
886public:
887 FaceFixture()
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600888 : FaceManager(FaceTableFixture::m_faceTable,
889 TestFaceManagerCommon::m_face)
890 , m_receivedNotification(false)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700891 {
892
893 }
894
895 virtual
896 ~FaceFixture()
897 {
898
899 }
Steve DiBenedettofbb40a82014-03-11 19:40:15 -0600900
901 void
902 callbackDispatch(const Data& response,
903 const Name& expectedName,
904 uint32_t expectedCode,
905 const std::string& expectedText,
906 const Block& expectedBody,
907 const ndn::nfd::FaceEventNotification& expectedFaceEvent)
908 {
909 Block payload = response.getContent().blockFromValue();
910 if (payload.type() == ndn::tlv::nfd::ControlResponse)
911 {
912 validateControlResponse(response, expectedName, expectedCode,
913 expectedText, expectedBody);
914 }
915 else if (payload.type() == ndn::tlv::nfd::FaceEventNotification)
916 {
917 validateFaceEvent(payload, expectedFaceEvent);
918 }
919 else
920 {
921 BOOST_FAIL("Received unknown message type: #" << payload.type());
922 }
923 }
924
925 void
926 callbackDispatch(const Data& response,
927 const Name& expectedName,
928 uint32_t expectedCode,
929 const std::string& expectedText,
930 const ndn::nfd::FaceEventNotification& expectedFaceEvent)
931 {
932 Block payload = response.getContent().blockFromValue();
933 if (payload.type() == ndn::tlv::nfd::ControlResponse)
934 {
935 validateControlResponse(response, expectedName,
936 expectedCode, expectedText);
937 }
938 else if (payload.type() == ndn::tlv::nfd::FaceEventNotification)
939 {
940 validateFaceEvent(payload, expectedFaceEvent);
941 }
942 else
943 {
944 BOOST_FAIL("Received unknown message type: #" << payload.type());
945 }
946 }
947
948 void
949 validateFaceEvent(const Block& wire,
950 const ndn::nfd::FaceEventNotification& expectedFaceEvent)
951 {
952
953 m_receivedNotification = true;
954
955 ndn::nfd::FaceEventNotification notification(wire);
956
957 BOOST_CHECK_EQUAL(notification.getFaceId(), expectedFaceEvent.getFaceId());
958 BOOST_CHECK_EQUAL(notification.getUri(), expectedFaceEvent.getUri());
959 BOOST_CHECK_EQUAL(notification.getEventKind(), expectedFaceEvent.getEventKind());
960 }
961
962 bool
963 didReceiveNotication() const
964 {
965 return m_receivedNotification;
966 }
967
968protected:
969 bool m_receivedNotification;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700970};
971
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700972BOOST_FIXTURE_TEST_CASE(CreateFaceBadUri, AuthorizedCommandFixture<FaceFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700973{
974 ndn::nfd::FaceManagementOptions options;
975 options.setUri("tcp:/127.0.0.1");
976
977 Block encodedOptions(options.wireEncode());
978
979 Name commandName("/localhost/nfd/faces");
980 commandName.append("create");
981 commandName.append(encodedOptions);
982
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700983 shared_ptr<Interest> command(make_shared<Interest>(commandName));
984 generateCommand(*command);
985
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700986 getFace()->onReceiveData +=
987 bind(&FaceFixture::validateControlResponse, this, _1,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700988 command->getName(), 400, "Malformed command");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700989
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700990 createFace(command->getName(), options);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700991
992 BOOST_REQUIRE(didCallbackFire());
993}
994
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -0700995BOOST_FIXTURE_TEST_CASE(CreateFaceUnknownScheme, AuthorizedCommandFixture<FaceFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -0700996{
997 ndn::nfd::FaceManagementOptions options;
998 // this will be an unsupported protocol because no factories have been
999 // added to the face manager
1000 options.setUri("tcp://127.0.0.1");
1001
1002 Block encodedOptions(options.wireEncode());
1003
1004 Name commandName("/localhost/nfd/faces");
1005 commandName.append("create");
1006 commandName.append(encodedOptions);
1007
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001008 shared_ptr<Interest> command(make_shared<Interest>(commandName));
1009 generateCommand(*command);
1010
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001011 getFace()->onReceiveData +=
1012 bind(&FaceFixture::validateControlResponse, this, _1,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001013 command->getName(), 501, "Unsupported protocol");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001014
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001015 createFace(command->getName(), options);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001016
1017 BOOST_REQUIRE(didCallbackFire());
1018}
1019
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001020BOOST_FIXTURE_TEST_CASE(OnCreated, AuthorizedCommandFixture<FaceFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001021{
1022 ndn::nfd::FaceManagementOptions options;
1023 options.setUri("tcp://127.0.0.1");
1024
1025 Block encodedOptions(options.wireEncode());
1026
1027 Name commandName("/localhost/nfd/faces");
1028 commandName.append("create");
1029 commandName.append(encodedOptions);
1030
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001031 shared_ptr<Interest> command(make_shared<Interest>(commandName));
1032 generateCommand(*command);
1033
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001034 ndn::nfd::FaceManagementOptions resultOptions;
1035 resultOptions.setUri("tcp://127.0.0.1");
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001036 resultOptions.setFaceId(1);
1037
1038 shared_ptr<DummyFace> dummy(make_shared<DummyFace>());
1039
1040 ndn::nfd::FaceEventNotification expectedFaceEvent(ndn::nfd::FACE_EVENT_CREATED,
1041 1,
Alexander Afanasyev355c0662014-03-20 18:08:17 -07001042 dummy->getUri().toString(),
1043 0);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001044
1045 Block encodedResultOptions(resultOptions.wireEncode());
1046
1047 getFace()->onReceiveData +=
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001048 bind(&FaceFixture::callbackDispatch, this, _1,
1049 command->getName(), 200, "Success",
1050 encodedResultOptions, expectedFaceEvent);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001051
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001052 onCreated(command->getName(), options, dummy);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001053
1054 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001055 BOOST_REQUIRE(didReceiveNotication());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001056}
1057
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001058BOOST_FIXTURE_TEST_CASE(OnConnectFailed, AuthorizedCommandFixture<FaceFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001059{
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001060 ndn::nfd::FaceManagementOptions options;
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001061 options.setUri("tcp://127.0.0.1");
1062
1063 Block encodedOptions(options.wireEncode());
1064
1065 Name commandName("/localhost/nfd/faces");
1066 commandName.append("create");
1067 commandName.append(encodedOptions);
1068
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001069 shared_ptr<Interest> command(make_shared<Interest>(commandName));
1070 generateCommand(*command);
1071
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001072 getFace()->onReceiveData +=
1073 bind(&FaceFixture::validateControlResponse, this, _1,
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001074 command->getName(), 400, "Failed to create face");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001075
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001076 onConnectFailed(command->getName(), "unit-test-reason");
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001077
1078 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001079 BOOST_CHECK_EQUAL(didReceiveNotication(), false);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001080}
1081
1082
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001083BOOST_FIXTURE_TEST_CASE(DestroyFace, AuthorizedCommandFixture<FaceFixture>)
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001084{
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001085 shared_ptr<DummyFace> dummy(make_shared<DummyFace>());
1086 FaceTableFixture::m_faceTable.add(dummy);
1087
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001088 ndn::nfd::FaceManagementOptions options;
1089 options.setUri("tcp://127.0.0.1");
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001090 options.setFaceId(dummy->getId());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001091
1092 Block encodedOptions(options.wireEncode());
1093
1094 Name commandName("/localhost/nfd/faces");
1095 commandName.append("destroy");
1096 commandName.append(encodedOptions);
1097
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001098 shared_ptr<Interest> command(make_shared<Interest>(commandName));
1099 generateCommand(*command);
1100
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001101 ndn::nfd::FaceEventNotification expectedFaceEvent(ndn::nfd::FACE_EVENT_DESTROYED,
1102 dummy->getId(),
Alexander Afanasyev355c0662014-03-20 18:08:17 -07001103 dummy->getUri().toString(), 0);
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001104
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001105 getFace()->onReceiveData +=
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001106 bind(&FaceFixture::callbackDispatch, this, _1,
1107 command->getName(), 200, "Success", expectedFaceEvent);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001108
Steve DiBenedetto2c2b8892014-02-27 11:46:48 -07001109 destroyFace(command->getName(), options);
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001110
1111 BOOST_REQUIRE(didCallbackFire());
Steve DiBenedettofbb40a82014-03-11 19:40:15 -06001112 BOOST_REQUIRE(didReceiveNotication());
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001113}
1114
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001115class FaceListFixture : public FaceStatusPublisherFixture
1116{
1117public:
1118 FaceListFixture()
1119 : m_manager(m_table, m_face)
1120 {
1121
1122 }
1123
1124 virtual
1125 ~FaceListFixture()
1126 {
1127
1128 }
1129
1130protected:
1131 FaceManager m_manager;
1132};
1133
1134BOOST_FIXTURE_TEST_CASE(TestFaceList, FaceListFixture)
1135
1136{
1137 Name commandName("/localhost/nfd/faces/list");
1138 shared_ptr<Interest> command(make_shared<Interest>(commandName));
1139
1140 // MAX_SEGMENT_SIZE == 4400, FaceStatus size with filler counters is 55
1141 // 55 divides 4400 (== 80), so only use 79 FaceStatuses and then two smaller ones
1142 // to force a FaceStatus to span Data packets
1143 for (int i = 0; i < 79; i++)
1144 {
1145 shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
1146
1147 uint64_t filler = std::numeric_limits<uint64_t>::max() - 1;
1148 dummy->setCounters(filler, filler, filler, filler);
1149
1150 m_referenceFaces.push_front(dummy);
1151
1152 add(dummy);
1153 }
1154
1155 for (int i = 0; i < 2; i++)
1156 {
1157 shared_ptr<TestCountersFace> dummy(make_shared<TestCountersFace>());
1158 uint64_t filler = std::numeric_limits<uint32_t>::max() - 1;
1159 dummy->setCounters(filler, filler, filler, filler);
1160
1161 m_referenceFaces.push_front(dummy);
1162
1163 add(dummy);
1164 }
1165
1166 ndn::EncodingBuffer buffer;
1167
1168 m_face->onReceiveData +=
1169 bind(&FaceStatusPublisherFixture::decodeFaceStatusBlock, this, _1);
1170
1171 m_manager.listFaces(*command);
1172 BOOST_REQUIRE(m_finished);
1173}
1174
Steve DiBenedettoabe9e972014-02-20 15:37:04 -07001175BOOST_AUTO_TEST_SUITE_END()
1176
1177} // namespace tests
1178} // namespace nfd
1179
Steve DiBenedetto9f6c3642014-03-10 17:02:27 -06001180