blob: b5225cd6337b1243d10d4921b1dd83a0cd527b46 [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi84d62cb2017-07-12 16:15:18 +00002/*
Junxiao Shi38b24c72017-01-05 02:59:31 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
Junxiao Shicde37ad2015-12-24 01:02:05 -07004 * 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 "face/udp-factory.hpp"
27
Eric Newberry42602412016-08-27 09:33:18 -070028#include "factory-test-common.hpp"
Junxiao Shi64d99f22017-01-21 23:06:36 +000029#include "face-system-fixture.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070030#include "tests/limited-io.hpp"
Junxiao Shi84d62cb2017-07-12 16:15:18 +000031#include "test-netif-ip.hpp"
Junxiao Shic31080d2017-01-24 15:10:12 +000032#include <boost/algorithm/string/replace.hpp>
33#include <boost/range/algorithm.hpp>
Junxiao Shicde37ad2015-12-24 01:02:05 -070034
35namespace nfd {
Junxiao Shi64d99f22017-01-21 23:06:36 +000036namespace face {
Junxiao Shicde37ad2015-12-24 01:02:05 -070037namespace tests {
38
Junxiao Shi0ba6d642017-07-17 00:53:22 +000039using UdpFactoryFixture = FaceSystemFactoryFixture<UdpFactory>;
40
Junxiao Shicde37ad2015-12-24 01:02:05 -070041BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +000042BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -070043
44using nfd::Face;
45
Junxiao Shi0ba6d642017-07-17 00:53:22 +000046BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi64d99f22017-01-21 23:06:36 +000047
48BOOST_AUTO_TEST_CASE(Channels)
49{
50 const std::string CONFIG = R"CONFIG(
51 face_system
52 {
53 udp
54 {
55 port 7001
56 enable_v4 yes
57 enable_v6 yes
58 idle_timeout 30
59 mcast no
60 }
61 }
62 )CONFIG";
63
64 parseConfig(CONFIG, true);
65 parseConfig(CONFIG, false);
66
Junxiao Shi64d99f22017-01-21 23:06:36 +000067 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
68}
69
70BOOST_AUTO_TEST_CASE(ChannelV4)
71{
72 const std::string CONFIG = R"CONFIG(
73 face_system
74 {
75 udp
76 {
77 port 7001
78 enable_v4 yes
79 enable_v6 no
80 mcast no
81 }
82 }
83 )CONFIG";
84
85 parseConfig(CONFIG, true);
86 parseConfig(CONFIG, false);
87
Junxiao Shi64d99f22017-01-21 23:06:36 +000088 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
89}
90
91BOOST_AUTO_TEST_CASE(ChannelV6)
92{
93 const std::string CONFIG = R"CONFIG(
94 face_system
95 {
96 udp
97 {
98 port 7001
99 enable_v4 no
100 enable_v6 yes
101 mcast no
102 }
103 }
104 )CONFIG";
105
106 parseConfig(CONFIG, true);
107 parseConfig(CONFIG, false);
108
Junxiao Shi64d99f22017-01-21 23:06:36 +0000109 checkChannelListEqual(factory, {"udp6://[::]:7001"});
110}
111
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000112class UdpMcastConfigFixture : public UdpFactoryFixture
Junxiao Shi64d99f22017-01-21 23:06:36 +0000113{
114protected:
115 UdpMcastConfigFixture()
116 {
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000117 for (const auto& netif : collectNetworkInterfaces()) {
118 if (netif->isUp() && netif->canMulticast() && hasAddressFamily<AddressFamily::V4>(*netif)) {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000119 netifs.push_back(netif);
120 }
Junxiao Shibbace1d2017-08-06 20:03:37 +0000121
122 auto copy = netmon->makeNetworkInterface();
123 copy->setIndex(netif->getIndex());
124 copy->setName(netif->getName());
125 copy->setType(netif->getType());
126 copy->setFlags(netif->getFlags());
127 copy->setState(netif->getState());
128 copy->setMtu(netif->getMtu());
129 copy->setEthernetAddress(netif->getEthernetAddress());
130 copy->setEthernetBroadcastAddress(netif->getEthernetBroadcastAddress());
131 for (const auto& na : netif->getNetworkAddresses()) {
132 copy->addNetworkAddress(na);
133 }
134 netmon->addInterface(copy);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000135 }
Junxiao Shibbace1d2017-08-06 20:03:37 +0000136 netmon->emitEnumerationCompleted();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000137 }
138
139 std::vector<const Face*>
Teng Liangfe4fce32017-03-29 04:49:38 +0000140 listUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000141 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000142 return this->listFacesByScheme("udp4", linkType);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000143 }
144
145 size_t
Teng Liangfe4fce32017-03-29 04:49:38 +0000146 countUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000147 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000148 return this->listUdpMcastFaces(linkType).size();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000149 }
150
Junxiao Shic31080d2017-01-24 15:10:12 +0000151 /** \brief determine whether a UDP multicast face is created on \p netif
152 */
153 static bool
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000154 isFaceOnNetif(const Face& face, const shared_ptr<const ndn::net::NetworkInterface>& netif)
Junxiao Shic31080d2017-01-24 15:10:12 +0000155 {
156 auto ip = boost::asio::ip::address_v4::from_string(face.getLocalUri().getHost());
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000157 return std::any_of(netif->getNetworkAddresses().begin(), netif->getNetworkAddresses().end(),
158 [ip] (const ndn::net::NetworkAddress& a) { return a.getIp() == ip; });
Junxiao Shic31080d2017-01-24 15:10:12 +0000159 }
160
Junxiao Shi64d99f22017-01-21 23:06:36 +0000161protected:
162 /** \brief MulticastUdpTransport-capable network interfaces
163 */
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000164 std::vector<shared_ptr<const ndn::net::NetworkInterface>> netifs;
Junxiao Shi64d99f22017-01-21 23:06:36 +0000165};
166
167#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
168 do { \
169 if (this->netifs.size() < (n)) { \
170 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
171 " or more MulticastUdpTransport-capable network interfaces"); \
172 return; \
173 } \
174 } while (false)
175
176BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpMcastConfigFixture)
177{
178#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000179 // need superuser privilege for creating multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000180 SKIP_IF_NOT_SUPERUSER();
181#endif // __linux__
182
183 const std::string CONFIG_WITH_MCAST = R"CONFIG(
184 face_system
185 {
186 udp
187 {
188 mcast yes
189 }
190 }
191 )CONFIG";
192 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
193 face_system
194 {
195 udp
196 {
197 mcast no
198 }
199 }
200 )CONFIG";
201
202 parseConfig(CONFIG_WITHOUT_MCAST, false);
203 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
204
205 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
206
207 parseConfig(CONFIG_WITH_MCAST, false);
208 g_io.poll();
209 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), netifs.size());
210
211 parseConfig(CONFIG_WITHOUT_MCAST, false);
212 g_io.poll();
213 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
214}
215
Teng Liangfe4fce32017-03-29 04:49:38 +0000216BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpMcastConfigFixture)
217{
218#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000219 // need superuser privilege for creating multicast faces on Linux
Teng Liangfe4fce32017-03-29 04:49:38 +0000220 SKIP_IF_NOT_SUPERUSER();
221#endif // __linux__
222 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
223
224 const std::string CONFIG = R"CONFIG(
225 face_system
226 {
227 udp
228 {
229 mcast_ad_hoc yes
230 }
231 }
232 )CONFIG";
233
234 parseConfig(CONFIG, false);
235 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC), netifs.size());
236}
237
Junxiao Shi64d99f22017-01-21 23:06:36 +0000238BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpoint, UdpMcastConfigFixture)
239{
240#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000241 // need superuser privilege for creating multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000242 SKIP_IF_NOT_SUPERUSER();
243#endif // __linux__
244 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
245
246 const std::string CONFIG1 = R"CONFIG(
247 face_system
248 {
249 udp
250 {
251 mcast_group 239.66.30.1
252 mcast_port 7011
253 }
254 }
255 )CONFIG";
256 const std::string CONFIG2 = R"CONFIG(
257 face_system
258 {
259 udp
260 {
261 mcast_group 239.66.30.2
262 mcast_port 7012
263 }
264 }
265 )CONFIG";
266
267 parseConfig(CONFIG1, false);
268 auto udpMcastFaces = this->listUdpMcastFaces();
269 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
270 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
271 FaceUri("udp4://239.66.30.1:7011"));
272
273 parseConfig(CONFIG2, false);
274 g_io.poll();
275 udpMcastFaces = this->listUdpMcastFaces();
276 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
277 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
278 FaceUri("udp4://239.66.30.2:7012"));
279}
280
Junxiao Shic31080d2017-01-24 15:10:12 +0000281BOOST_FIXTURE_TEST_CASE(Whitelist, UdpMcastConfigFixture)
282{
283#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000284 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000285 SKIP_IF_NOT_SUPERUSER();
286#endif // __linux__
287 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
288
289 std::string CONFIG = R"CONFIG(
290 face_system
291 {
292 udp
293 {
294 whitelist
295 {
296 ifname %ifname
297 }
298 }
299 }
300 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000301 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000302
303 parseConfig(CONFIG, false);
304 auto udpMcastFaces = this->listUdpMcastFaces();
305 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
306 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
307}
308
309BOOST_FIXTURE_TEST_CASE(Blacklist, UdpMcastConfigFixture)
310{
311#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000312 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000313 SKIP_IF_NOT_SUPERUSER();
314#endif // __linux__
315 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
316
317 std::string CONFIG = R"CONFIG(
318 face_system
319 {
320 udp
321 {
322 blacklist
323 {
324 ifname %ifname
325 }
326 }
327 }
328 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000329 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000330
331 parseConfig(CONFIG, false);
332 auto udpMcastFaces = this->listUdpMcastFaces();
333 BOOST_CHECK_EQUAL(udpMcastFaces.size(), netifs.size() - 1);
334 BOOST_CHECK_EQUAL(boost::count_if(udpMcastFaces, [=] (const Face* face) {
335 return isFaceOnNetif(*face, netifs.front());
336 }), 0);
337}
338
339BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpMcastConfigFixture)
340{
341#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000342 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000343 SKIP_IF_NOT_SUPERUSER();
344#endif // __linux__
345 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
346
347 std::string CONFIG1 = R"CONFIG(
348 face_system
349 {
350 udp
351 {
352 whitelist
353 {
354 ifname %ifname
355 }
356 }
357 }
358 )CONFIG";
359 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000360 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
361 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000362
363 parseConfig(CONFIG1, false);
364 auto udpMcastFaces = this->listUdpMcastFaces();
365 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
366 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
367
368 parseConfig(CONFIG2, false);
369 g_io.poll();
370 udpMcastFaces = this->listUdpMcastFaces();
371 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
372 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.back()));
373}
374
Junxiao Shi64d99f22017-01-21 23:06:36 +0000375BOOST_AUTO_TEST_CASE(Omitted)
376{
377 const std::string CONFIG = R"CONFIG(
378 face_system
379 {
380 }
381 )CONFIG";
382
383 parseConfig(CONFIG, true);
384 parseConfig(CONFIG, false);
385
Junxiao Shi64d99f22017-01-21 23:06:36 +0000386 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
387 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
388}
389
390BOOST_AUTO_TEST_CASE(BadIdleTimeout)
391{
392 const std::string CONFIG = R"CONFIG(
393 face_system
394 {
395 udp
396 {
397 idle_timeout hello
398 }
399 }
400 )CONFIG";
401
402 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
403 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
404}
405
406BOOST_AUTO_TEST_CASE(BadMcast)
407{
408 const std::string CONFIG = R"CONFIG(
409 face_system
410 {
411 udp
412 {
413 mcast hello
414 }
415 }
416 )CONFIG";
417
418 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
419 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
420}
421
422BOOST_AUTO_TEST_CASE(BadMcastGroup)
423{
424 const std::string CONFIG = R"CONFIG(
425 face_system
426 {
427 udp
428 {
429 mcast_group hello
430 }
431 }
432 )CONFIG";
433
434 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
435 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
436}
437
438BOOST_AUTO_TEST_CASE(BadMcastGroupV4Unicast)
439{
440 const std::string CONFIG = R"CONFIG(
441 face_system
442 {
443 udp
444 {
445 mcast_group 10.0.0.1
446 }
447 }
448 )CONFIG";
449
450 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
451 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
452}
453
454BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
455{
456 const std::string CONFIG = R"CONFIG(
457 face_system
458 {
459 udp
460 {
461 mcast_group ff00::1
462 }
463 }
464 )CONFIG";
465
466 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
467 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
468}
469
470BOOST_AUTO_TEST_CASE(AllDisabled)
471{
472 const std::string CONFIG = R"CONFIG(
473 face_system
474 {
475 udp
476 {
477 enable_v4 no
478 enable_v6 no
479 mcast no
480 }
481 }
482 )CONFIG";
483
484 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
485 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
486}
487
488BOOST_AUTO_TEST_CASE(UnknownOption)
489{
490 const std::string CONFIG = R"CONFIG(
491 face_system
492 {
493 udp
494 {
495 hello
496 }
497 }
498 )CONFIG";
499
500 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
501 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
502}
503
504BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
505
Junxiao Shicde37ad2015-12-24 01:02:05 -0700506BOOST_AUTO_TEST_CASE(GetChannels)
507{
Junxiao Shicde37ad2015-12-24 01:02:05 -0700508 BOOST_REQUIRE_EQUAL(factory.getChannels().empty(), true);
509
510 std::vector<shared_ptr<const Channel>> expectedChannels;
511 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20070"));
512 expectedChannels.push_back(factory.createChannel("127.0.0.1", "20071"));
513 expectedChannels.push_back(factory.createChannel("::1", "20071"));
514
515 for (const auto& i : factory.getChannels()) {
516 auto pos = std::find(expectedChannels.begin(), expectedChannels.end(), i);
517 BOOST_REQUIRE(pos != expectedChannels.end());
518 expectedChannels.erase(pos);
519 }
520
521 BOOST_CHECK_EQUAL(expectedChannels.size(), 0);
522}
523
Weiwei Liu72cee942016-02-04 16:49:19 -0700524BOOST_AUTO_TEST_CASE(CreateChannel)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700525{
Weiwei Liu72cee942016-02-04 16:49:19 -0700526 auto channel1 = factory.createChannel("127.0.0.1", "20070");
527 auto channel1a = factory.createChannel("127.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700528 BOOST_CHECK_EQUAL(channel1, channel1a);
529 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
530
Weiwei Liu72cee942016-02-04 16:49:19 -0700531 auto channel2 = factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700532 BOOST_CHECK_NE(channel1, channel2);
533
Weiwei Liu72cee942016-02-04 16:49:19 -0700534 auto channel3 = factory.createChannel("::1", "20071");
535 BOOST_CHECK_NE(channel2, channel3);
536 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700537
Weiwei Liu72cee942016-02-04 16:49:19 -0700538 // createChannel with multicast address
539 BOOST_CHECK_EXCEPTION(factory.createChannel("224.0.0.1", "20070"), UdpFactory::Error,
540 [] (const UdpFactory::Error& e) {
541 return strcmp(e.what(),
542 "createChannel is only for unicast channels. The provided endpoint "
543 "is multicast. Use createMulticastFace to create a multicast face") == 0;
544 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700545
Weiwei Liu72cee942016-02-04 16:49:19 -0700546 // createChannel with a local endpoint that has already been allocated for a UDP multicast face
547 auto multicastFace = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20072");
548 BOOST_CHECK_EXCEPTION(factory.createChannel("127.0.0.1", "20072"), UdpFactory::Error,
549 [] (const UdpFactory::Error& e) {
550 return strcmp(e.what(),
551 "Cannot create the requested UDP unicast channel, local "
552 "endpoint is already allocated for a UDP multicast face") == 0;
553 });
554}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700555
Weiwei Liu72cee942016-02-04 16:49:19 -0700556BOOST_AUTO_TEST_CASE(CreateMulticastFace)
557{
Weiwei Liu72cee942016-02-04 16:49:19 -0700558 auto multicastFace1 = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
559 auto multicastFace1a = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700560 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
561
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200562 // createMulticastFace with a local endpoint that is already used by a channel
Weiwei Liu72cee942016-02-04 16:49:19 -0700563 auto channel = factory.createChannel("127.0.0.1", "20071");
564 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20071"), UdpFactory::Error,
565 [] (const UdpFactory::Error& e) {
566 return strcmp(e.what(),
567 "Cannot create the requested UDP multicast face, local "
568 "endpoint is already allocated for a UDP unicast channel") == 0;
569 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700570
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200571 // createMulticastFace with a local endpoint that is already
572 // used by a multicast face on a different multicast group
Weiwei Liu72cee942016-02-04 16:49:19 -0700573 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.42", "20070"), UdpFactory::Error,
574 [] (const UdpFactory::Error& e) {
575 return strcmp(e.what(),
576 "Cannot create the requested UDP multicast face, local "
577 "endpoint is already allocated for a UDP multicast face "
578 "on a different multicast group") == 0;
579 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700580
Weiwei Liu72cee942016-02-04 16:49:19 -0700581 // createMulticastFace with an IPv4 unicast address
582 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "192.168.10.15", "20072"), UdpFactory::Error,
583 [] (const UdpFactory::Error& e) {
584 return strcmp(e.what(),
585 "Cannot create the requested UDP multicast face, "
586 "the multicast group given as input is not a multicast address") == 0;
587 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700588
Weiwei Liu72cee942016-02-04 16:49:19 -0700589 // createMulticastFace with an IPv6 multicast address
590 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("::1", "ff01::114", "20073"), UdpFactory::Error,
591 [] (const UdpFactory::Error& e) {
592 return strcmp(e.what(),
593 "IPv6 multicast is not supported yet. Please provide an IPv4 "
594 "address") == 0;
595 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700596
Weiwei Liu72cee942016-02-04 16:49:19 -0700597 // createMulticastFace with different local and remote port numbers
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200598 udp::Endpoint localEndpoint(boost::asio::ip::address_v4::loopback(), 20074);
599 udp::Endpoint multicastEndpoint(boost::asio::ip::address::from_string("224.0.0.1"), 20075);
Weiwei Liu72cee942016-02-04 16:49:19 -0700600 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(localEndpoint, multicastEndpoint), UdpFactory::Error,
601 [] (const UdpFactory::Error& e) {
602 return strcmp(e.what(),
603 "Cannot create the requested UDP multicast face, "
604 "both endpoints should have the same port number. ") == 0;
605 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700606}
607
Eric Newberry42602412016-08-27 09:33:18 -0700608BOOST_AUTO_TEST_CASE(FaceCreate)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700609{
Eric Newberry42602412016-08-27 09:33:18 -0700610 createFace(factory,
611 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000612 {},
Eric Newberry42602412016-08-27 09:33:18 -0700613 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700614 false,
Eric Newberry42602412016-08-27 09:33:18 -0700615 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700616
617 factory.createChannel("127.0.0.1", "20071");
618
Eric Newberry42602412016-08-27 09:33:18 -0700619 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400620 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000621 {},
Eric Newberry42602412016-08-27 09:33:18 -0700622 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700623 false,
Eric Newberry42602412016-08-27 09:33:18 -0700624 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +0000625
Eric Newberry42602412016-08-27 09:33:18 -0700626 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400627 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000628 {},
Eric Newberry42602412016-08-27 09:33:18 -0700629 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700630 false,
Eric Newberry42602412016-08-27 09:33:18 -0700631 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700632
Eric Newberry42602412016-08-27 09:33:18 -0700633 createFace(factory,
634 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000635 {},
Eric Newberry42602412016-08-27 09:33:18 -0700636 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700637 false,
Eric Newberry42602412016-08-27 09:33:18 -0700638 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700639}
640
641BOOST_AUTO_TEST_CASE(UnsupportedFaceCreate)
642{
Eric Newberry78e32b02017-04-01 14:34:44 +0000643 factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700644
Eric Newberry42602412016-08-27 09:33:18 -0700645 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400646 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400647 FaceUri("udp4://127.0.0.1:20071"),
Davide Pesavento46afec42017-05-28 14:28:47 -0400648 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
649 false,
650 {CreateFaceExpectedResult::FAILURE, 406,
651 "Unicast UDP faces cannot be created with a LocalUri"});
652
653 createFace(factory,
654 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000655 {},
Eric Newberry42602412016-08-27 09:33:18 -0700656 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
Eric Newberryf40551a2016-09-05 15:41:16 -0700657 false,
Eric Newberry42602412016-08-27 09:33:18 -0700658 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400659 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000660
661 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400662 FaceUri("udp4://233.252.0.1:23252"),
663 {},
Eric Newberry78e32b02017-04-01 14:34:44 +0000664 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
665 false,
666 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400667 "Cannot create multicast UDP faces"});
668
669 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400670 FaceUri("udp4://127.0.0.1:20072"),
671 {},
672 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
673 true,
674 {CreateFaceExpectedResult::FAILURE, 406,
675 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700676}
677
Junxiao Shicde37ad2015-12-24 01:02:05 -0700678BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
679BOOST_AUTO_TEST_SUITE_END() // Face
680
681} // namespace tests
Junxiao Shi64d99f22017-01-21 23:06:36 +0000682} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700683} // namespace nfd