blob: 36ccba4c84f59e17627d3db6692fc01c1f9924a8 [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
Junxiao Shi64d99f22017-01-21 23:06:36 +000028#include "face-system-fixture.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040029#include "factory-test-common.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040030
Junxiao Shic31080d2017-01-24 15:10:12 +000031#include <boost/algorithm/string/replace.hpp>
Davide Pesaventob15276f2017-07-15 16:27:13 -040032#include <boost/range/algorithm/count_if.hpp>
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040033#include <ndn-cxx/net/address-converter.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
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040039class UdpFactoryFixture : public FaceSystemFactoryFixture<UdpFactory>
40{
41protected:
42 shared_ptr<UdpChannel>
43 createChannel(const std::string& localIp, const std::string& localPort)
44 {
45 udp::Endpoint endpoint(ndn::ip::addressFromString(localIp),
46 boost::lexical_cast<uint16_t>(localPort));
47 return factory.createChannel(endpoint, time::minutes(5));
48 }
49};
Junxiao Shi0ba6d642017-07-17 00:53:22 +000050
Junxiao Shicde37ad2015-12-24 01:02:05 -070051BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +000052BOOST_FIXTURE_TEST_SUITE(TestUdpFactory, UdpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -070053
54using nfd::Face;
55
Junxiao Shi0ba6d642017-07-17 00:53:22 +000056BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi64d99f22017-01-21 23:06:36 +000057
58BOOST_AUTO_TEST_CASE(Channels)
59{
60 const std::string CONFIG = R"CONFIG(
61 face_system
62 {
63 udp
64 {
65 port 7001
66 enable_v4 yes
67 enable_v6 yes
68 idle_timeout 30
69 mcast no
70 }
71 }
72 )CONFIG";
73
74 parseConfig(CONFIG, true);
75 parseConfig(CONFIG, false);
76
Junxiao Shi64d99f22017-01-21 23:06:36 +000077 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001", "udp6://[::]:7001"});
78}
79
80BOOST_AUTO_TEST_CASE(ChannelV4)
81{
82 const std::string CONFIG = R"CONFIG(
83 face_system
84 {
85 udp
86 {
87 port 7001
88 enable_v4 yes
89 enable_v6 no
90 mcast no
91 }
92 }
93 )CONFIG";
94
95 parseConfig(CONFIG, true);
96 parseConfig(CONFIG, false);
97
Junxiao Shi64d99f22017-01-21 23:06:36 +000098 checkChannelListEqual(factory, {"udp4://0.0.0.0:7001"});
99}
100
101BOOST_AUTO_TEST_CASE(ChannelV6)
102{
103 const std::string CONFIG = R"CONFIG(
104 face_system
105 {
106 udp
107 {
108 port 7001
109 enable_v4 no
110 enable_v6 yes
111 mcast no
112 }
113 }
114 )CONFIG";
115
116 parseConfig(CONFIG, true);
117 parseConfig(CONFIG, false);
118
Junxiao Shi64d99f22017-01-21 23:06:36 +0000119 checkChannelListEqual(factory, {"udp6://[::]:7001"});
120}
121
Junxiao Shi0ba6d642017-07-17 00:53:22 +0000122class UdpMcastConfigFixture : public UdpFactoryFixture
Junxiao Shi64d99f22017-01-21 23:06:36 +0000123{
124protected:
125 UdpMcastConfigFixture()
126 {
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000127 for (const auto& netif : collectNetworkInterfaces()) {
Davide Pesavento22fba352017-10-17 15:53:51 -0400128 if (netif->isUp() && netif->canMulticast() &&
129 hasAddressFamily(*netif, ndn::net::AddressFamily::V4)) {
Junxiao Shi64d99f22017-01-21 23:06:36 +0000130 netifs.push_back(netif);
131 }
132 }
Junxiao Shi79a92082017-08-08 02:40:59 +0000133
134 this->copyRealNetifsToNetmon();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000135 }
136
137 std::vector<const Face*>
Teng Liangfe4fce32017-03-29 04:49:38 +0000138 listUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000139 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000140 return this->listFacesByScheme("udp4", linkType);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000141 }
142
143 size_t
Teng Liangfe4fce32017-03-29 04:49:38 +0000144 countUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000145 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000146 return this->listUdpMcastFaces(linkType).size();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000147 }
148
Davide Pesavento22fba352017-10-17 15:53:51 -0400149 /** \brief determine whether \p netif has at least one address of the given family
150 */
151 static bool
152 hasAddressFamily(const NetworkInterface& netif, ndn::net::AddressFamily af)
153 {
154 return std::any_of(netif.getNetworkAddresses().begin(), netif.getNetworkAddresses().end(),
155 [af] (const NetworkAddress& a) { return a.getFamily() == af; });
156 }
157
Junxiao Shic31080d2017-01-24 15:10:12 +0000158 /** \brief determine whether a UDP multicast face is created on \p netif
159 */
160 static bool
Davide Pesavento22fba352017-10-17 15:53:51 -0400161 isFaceOnNetif(const Face& face, const shared_ptr<const NetworkInterface>& netif)
Junxiao Shic31080d2017-01-24 15:10:12 +0000162 {
163 auto ip = boost::asio::ip::address_v4::from_string(face.getLocalUri().getHost());
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000164 return std::any_of(netif->getNetworkAddresses().begin(), netif->getNetworkAddresses().end(),
Davide Pesavento22fba352017-10-17 15:53:51 -0400165 [ip] (const NetworkAddress& a) { return a.getIp() == ip; });
Junxiao Shic31080d2017-01-24 15:10:12 +0000166 }
167
Junxiao Shi64d99f22017-01-21 23:06:36 +0000168protected:
169 /** \brief MulticastUdpTransport-capable network interfaces
170 */
Davide Pesavento22fba352017-10-17 15:53:51 -0400171 std::vector<shared_ptr<const NetworkInterface>> netifs;
Junxiao Shi64d99f22017-01-21 23:06:36 +0000172};
173
174#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
175 do { \
176 if (this->netifs.size() < (n)) { \
177 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
178 " or more MulticastUdpTransport-capable network interfaces"); \
179 return; \
180 } \
181 } while (false)
182
183BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpMcastConfigFixture)
184{
185#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000186 // need superuser privilege for creating multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000187 SKIP_IF_NOT_SUPERUSER();
188#endif // __linux__
189
190 const std::string CONFIG_WITH_MCAST = R"CONFIG(
191 face_system
192 {
193 udp
194 {
195 mcast yes
196 }
197 }
198 )CONFIG";
199 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
200 face_system
201 {
202 udp
203 {
204 mcast no
205 }
206 }
207 )CONFIG";
208
209 parseConfig(CONFIG_WITHOUT_MCAST, false);
210 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
211
212 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
213
214 parseConfig(CONFIG_WITH_MCAST, false);
215 g_io.poll();
216 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), netifs.size());
217
218 parseConfig(CONFIG_WITHOUT_MCAST, false);
219 g_io.poll();
220 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
221}
222
Teng Liangfe4fce32017-03-29 04:49:38 +0000223BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpMcastConfigFixture)
224{
225#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000226 // need superuser privilege for creating multicast faces on Linux
Teng Liangfe4fce32017-03-29 04:49:38 +0000227 SKIP_IF_NOT_SUPERUSER();
228#endif // __linux__
229 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
230
231 const std::string CONFIG = R"CONFIG(
232 face_system
233 {
234 udp
235 {
236 mcast_ad_hoc yes
237 }
238 }
239 )CONFIG";
240
241 parseConfig(CONFIG, false);
242 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC), netifs.size());
243}
244
Junxiao Shi64d99f22017-01-21 23:06:36 +0000245BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpoint, UdpMcastConfigFixture)
246{
247#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000248 // need superuser privilege for creating multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000249 SKIP_IF_NOT_SUPERUSER();
250#endif // __linux__
251 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
252
253 const std::string CONFIG1 = R"CONFIG(
254 face_system
255 {
256 udp
257 {
258 mcast_group 239.66.30.1
259 mcast_port 7011
260 }
261 }
262 )CONFIG";
263 const std::string CONFIG2 = R"CONFIG(
264 face_system
265 {
266 udp
267 {
268 mcast_group 239.66.30.2
269 mcast_port 7012
270 }
271 }
272 )CONFIG";
273
274 parseConfig(CONFIG1, false);
275 auto udpMcastFaces = this->listUdpMcastFaces();
276 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
277 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
278 FaceUri("udp4://239.66.30.1:7011"));
279
280 parseConfig(CONFIG2, false);
281 g_io.poll();
282 udpMcastFaces = this->listUdpMcastFaces();
283 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
284 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
285 FaceUri("udp4://239.66.30.2:7012"));
286}
287
Junxiao Shic31080d2017-01-24 15:10:12 +0000288BOOST_FIXTURE_TEST_CASE(Whitelist, UdpMcastConfigFixture)
289{
290#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000291 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000292 SKIP_IF_NOT_SUPERUSER();
293#endif // __linux__
294 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
295
296 std::string CONFIG = R"CONFIG(
297 face_system
298 {
299 udp
300 {
301 whitelist
302 {
303 ifname %ifname
304 }
305 }
306 }
307 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000308 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000309
310 parseConfig(CONFIG, false);
311 auto udpMcastFaces = this->listUdpMcastFaces();
312 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
313 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
314}
315
316BOOST_FIXTURE_TEST_CASE(Blacklist, UdpMcastConfigFixture)
317{
318#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000319 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000320 SKIP_IF_NOT_SUPERUSER();
321#endif // __linux__
322 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
323
324 std::string CONFIG = R"CONFIG(
325 face_system
326 {
327 udp
328 {
329 blacklist
330 {
331 ifname %ifname
332 }
333 }
334 }
335 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000336 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000337
338 parseConfig(CONFIG, false);
339 auto udpMcastFaces = this->listUdpMcastFaces();
340 BOOST_CHECK_EQUAL(udpMcastFaces.size(), netifs.size() - 1);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400341 BOOST_CHECK_EQUAL(boost::count_if(udpMcastFaces, [this] (const Face* face) {
Junxiao Shic31080d2017-01-24 15:10:12 +0000342 return isFaceOnNetif(*face, netifs.front());
343 }), 0);
344}
345
346BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpMcastConfigFixture)
347{
348#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000349 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000350 SKIP_IF_NOT_SUPERUSER();
351#endif // __linux__
352 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
353
354 std::string CONFIG1 = R"CONFIG(
355 face_system
356 {
357 udp
358 {
359 whitelist
360 {
361 ifname %ifname
362 }
363 }
364 }
365 )CONFIG";
366 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000367 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
368 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000369
370 parseConfig(CONFIG1, false);
371 auto udpMcastFaces = this->listUdpMcastFaces();
372 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
373 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
374
375 parseConfig(CONFIG2, false);
376 g_io.poll();
377 udpMcastFaces = this->listUdpMcastFaces();
378 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
379 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.back()));
380}
381
Junxiao Shi64d99f22017-01-21 23:06:36 +0000382BOOST_AUTO_TEST_CASE(Omitted)
383{
384 const std::string CONFIG = R"CONFIG(
385 face_system
386 {
387 }
388 )CONFIG";
389
390 parseConfig(CONFIG, true);
391 parseConfig(CONFIG, false);
392
Junxiao Shi64d99f22017-01-21 23:06:36 +0000393 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
394 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
395}
396
397BOOST_AUTO_TEST_CASE(BadIdleTimeout)
398{
399 const std::string CONFIG = R"CONFIG(
400 face_system
401 {
402 udp
403 {
404 idle_timeout hello
405 }
406 }
407 )CONFIG";
408
409 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
410 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
411}
412
413BOOST_AUTO_TEST_CASE(BadMcast)
414{
415 const std::string CONFIG = R"CONFIG(
416 face_system
417 {
418 udp
419 {
420 mcast hello
421 }
422 }
423 )CONFIG";
424
425 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
426 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
427}
428
429BOOST_AUTO_TEST_CASE(BadMcastGroup)
430{
431 const std::string CONFIG = R"CONFIG(
432 face_system
433 {
434 udp
435 {
436 mcast_group hello
437 }
438 }
439 )CONFIG";
440
441 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
442 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
443}
444
445BOOST_AUTO_TEST_CASE(BadMcastGroupV4Unicast)
446{
447 const std::string CONFIG = R"CONFIG(
448 face_system
449 {
450 udp
451 {
452 mcast_group 10.0.0.1
453 }
454 }
455 )CONFIG";
456
457 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
458 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
459}
460
461BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
462{
463 const std::string CONFIG = R"CONFIG(
464 face_system
465 {
466 udp
467 {
468 mcast_group ff00::1
469 }
470 }
471 )CONFIG";
472
473 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
474 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
475}
476
477BOOST_AUTO_TEST_CASE(AllDisabled)
478{
479 const std::string CONFIG = R"CONFIG(
480 face_system
481 {
482 udp
483 {
484 enable_v4 no
485 enable_v6 no
486 mcast no
487 }
488 }
489 )CONFIG";
490
491 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
492 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
493}
494
495BOOST_AUTO_TEST_CASE(UnknownOption)
496{
497 const std::string CONFIG = R"CONFIG(
498 face_system
499 {
500 udp
501 {
502 hello
503 }
504 }
505 )CONFIG";
506
507 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
508 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
509}
510
511BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
512
Junxiao Shicde37ad2015-12-24 01:02:05 -0700513BOOST_AUTO_TEST_CASE(GetChannels)
514{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400515 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700516
Davide Pesaventob15276f2017-07-15 16:27:13 -0400517 std::set<std::string> expected;
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400518 expected.insert(createChannel("127.0.0.1", "20070")->getUri().toString());
519 expected.insert(createChannel("127.0.0.1", "20071")->getUri().toString());
520 expected.insert(createChannel("::1", "20071")->getUri().toString());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400521 checkChannelListEqual(factory, expected);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700522}
523
Weiwei Liu72cee942016-02-04 16:49:19 -0700524BOOST_AUTO_TEST_CASE(CreateChannel)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700525{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400526 auto channel1 = createChannel("127.0.0.1", "20070");
527 auto channel1a = 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
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400531 auto channel2 = createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700532 BOOST_CHECK_NE(channel1, channel2);
533
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400534 auto channel3 = createChannel("::1", "20071");
Weiwei Liu72cee942016-02-04 16:49:19 -0700535 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
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400539 BOOST_CHECK_EXCEPTION(createChannel("224.0.0.1", "20070"), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700540 [] (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");
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400548 BOOST_CHECK_EXCEPTION(createChannel("127.0.0.1", "20072"), UdpFactory::Error,
Weiwei Liu72cee942016-02-04 16:49:19 -0700549 [] (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
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400563 auto channel = createChannel("127.0.0.1", "20071");
Weiwei Liu72cee942016-02-04 16:49:19 -0700564 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
Davide Pesaventob15276f2017-07-15 16:27:13 -0400608BOOST_AUTO_TEST_CASE(CreateFace)
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 Newberry2642cd22017-07-13 21:34:53 -0400615 false,
Eric Newberry42602412016-08-27 09:33:18 -0700616 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700617
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400618 createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700619
Eric Newberry42602412016-08-27 09:33:18 -0700620 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400621 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000622 {},
Eric Newberry42602412016-08-27 09:33:18 -0700623 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700624 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400625 false,
Eric Newberry42602412016-08-27 09:33:18 -0700626 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +0000627
Eric Newberry42602412016-08-27 09:33:18 -0700628 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400629 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000630 {},
Eric Newberry42602412016-08-27 09:33:18 -0700631 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700632 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400633 false,
Eric Newberry42602412016-08-27 09:33:18 -0700634 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700635
Eric Newberry42602412016-08-27 09:33:18 -0700636 createFace(factory,
637 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000638 {},
Eric Newberry42602412016-08-27 09:33:18 -0700639 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700640 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400641 false,
642 {CreateFaceExpectedResult::SUCCESS, 0, ""});
643
644
645 createFace(factory,
646 FaceUri("udp4://127.0.0.1:20073"),
647 {},
648 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
649 false,
650 true,
Eric Newberry42602412016-08-27 09:33:18 -0700651 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700652}
653
Davide Pesaventob15276f2017-07-15 16:27:13 -0400654BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700655{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400656 createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700657
Eric Newberry42602412016-08-27 09:33:18 -0700658 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400659 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400660 FaceUri("udp4://127.0.0.1:20071"),
Davide Pesavento46afec42017-05-28 14:28:47 -0400661 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
662 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400663 false,
Davide Pesavento46afec42017-05-28 14:28:47 -0400664 {CreateFaceExpectedResult::FAILURE, 406,
665 "Unicast UDP faces cannot be created with a LocalUri"});
666
667 createFace(factory,
668 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000669 {},
Eric Newberry42602412016-08-27 09:33:18 -0700670 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
Eric Newberryf40551a2016-09-05 15:41:16 -0700671 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400672 false,
Eric Newberry42602412016-08-27 09:33:18 -0700673 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400674 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000675
676 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400677 FaceUri("udp4://233.252.0.1:23252"),
678 {},
Eric Newberry78e32b02017-04-01 14:34:44 +0000679 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
680 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400681 false,
Eric Newberry78e32b02017-04-01 14:34:44 +0000682 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400683 "Cannot create multicast UDP faces"});
684
685 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400686 FaceUri("udp4://127.0.0.1:20072"),
687 {},
688 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
689 true,
Eric Newberry2642cd22017-07-13 21:34:53 -0400690 false,
Davide Pesavento46afec42017-05-28 14:28:47 -0400691 {CreateFaceExpectedResult::FAILURE, 406,
692 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700693}
694
Junxiao Shicde37ad2015-12-24 01:02:05 -0700695BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
696BOOST_AUTO_TEST_SUITE_END() // Face
697
698} // namespace tests
Junxiao Shi64d99f22017-01-21 23:06:36 +0000699} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700700} // namespace nfd