blob: 2747fa8e2d64fd4f40bf21eb37a7711fd6df8131 [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"
Junxiao Shi84d62cb2017-07-12 16:15:18 +000030#include "test-netif-ip.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040031
Junxiao Shic31080d2017-01-24 15:10:12 +000032#include <boost/algorithm/string/replace.hpp>
Davide Pesaventob15276f2017-07-15 16:27:13 -040033#include <boost/range/algorithm/count_if.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 }
121 }
Junxiao Shi79a92082017-08-08 02:40:59 +0000122
123 this->copyRealNetifsToNetmon();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000124 }
125
126 std::vector<const Face*>
Teng Liangfe4fce32017-03-29 04:49:38 +0000127 listUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000128 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000129 return this->listFacesByScheme("udp4", linkType);
Junxiao Shi64d99f22017-01-21 23:06:36 +0000130 }
131
132 size_t
Teng Liangfe4fce32017-03-29 04:49:38 +0000133 countUdpMcastFaces(ndn::nfd::LinkType linkType = ndn::nfd::LINK_TYPE_MULTI_ACCESS) const
Junxiao Shi64d99f22017-01-21 23:06:36 +0000134 {
Teng Liangfe4fce32017-03-29 04:49:38 +0000135 return this->listUdpMcastFaces(linkType).size();
Junxiao Shi64d99f22017-01-21 23:06:36 +0000136 }
137
Junxiao Shic31080d2017-01-24 15:10:12 +0000138 /** \brief determine whether a UDP multicast face is created on \p netif
139 */
140 static bool
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000141 isFaceOnNetif(const Face& face, const shared_ptr<const ndn::net::NetworkInterface>& netif)
Junxiao Shic31080d2017-01-24 15:10:12 +0000142 {
143 auto ip = boost::asio::ip::address_v4::from_string(face.getLocalUri().getHost());
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000144 return std::any_of(netif->getNetworkAddresses().begin(), netif->getNetworkAddresses().end(),
145 [ip] (const ndn::net::NetworkAddress& a) { return a.getIp() == ip; });
Junxiao Shic31080d2017-01-24 15:10:12 +0000146 }
147
Junxiao Shi64d99f22017-01-21 23:06:36 +0000148protected:
149 /** \brief MulticastUdpTransport-capable network interfaces
150 */
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000151 std::vector<shared_ptr<const ndn::net::NetworkInterface>> netifs;
Junxiao Shi64d99f22017-01-21 23:06:36 +0000152};
153
154#define SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(n) \
155 do { \
156 if (this->netifs.size() < (n)) { \
157 BOOST_WARN_MESSAGE(false, "skipping assertions that require " #n \
158 " or more MulticastUdpTransport-capable network interfaces"); \
159 return; \
160 } \
161 } while (false)
162
163BOOST_FIXTURE_TEST_CASE(EnableDisableMcast, UdpMcastConfigFixture)
164{
165#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000166 // need superuser privilege for creating multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000167 SKIP_IF_NOT_SUPERUSER();
168#endif // __linux__
169
170 const std::string CONFIG_WITH_MCAST = R"CONFIG(
171 face_system
172 {
173 udp
174 {
175 mcast yes
176 }
177 }
178 )CONFIG";
179 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
180 face_system
181 {
182 udp
183 {
184 mcast no
185 }
186 }
187 )CONFIG";
188
189 parseConfig(CONFIG_WITHOUT_MCAST, false);
190 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
191
192 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
193
194 parseConfig(CONFIG_WITH_MCAST, false);
195 g_io.poll();
196 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), netifs.size());
197
198 parseConfig(CONFIG_WITHOUT_MCAST, false);
199 g_io.poll();
200 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(), 0);
201}
202
Teng Liangfe4fce32017-03-29 04:49:38 +0000203BOOST_FIXTURE_TEST_CASE(McastAdHoc, UdpMcastConfigFixture)
204{
205#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000206 // need superuser privilege for creating multicast faces on Linux
Teng Liangfe4fce32017-03-29 04:49:38 +0000207 SKIP_IF_NOT_SUPERUSER();
208#endif // __linux__
209 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
210
211 const std::string CONFIG = R"CONFIG(
212 face_system
213 {
214 udp
215 {
216 mcast_ad_hoc yes
217 }
218 }
219 )CONFIG";
220
221 parseConfig(CONFIG, false);
222 BOOST_CHECK_EQUAL(this->countUdpMcastFaces(ndn::nfd::LINK_TYPE_AD_HOC), netifs.size());
223}
224
Junxiao Shi64d99f22017-01-21 23:06:36 +0000225BOOST_FIXTURE_TEST_CASE(ChangeMcastEndpoint, UdpMcastConfigFixture)
226{
227#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000228 // need superuser privilege for creating multicast faces on Linux
Junxiao Shi64d99f22017-01-21 23:06:36 +0000229 SKIP_IF_NOT_SUPERUSER();
230#endif // __linux__
231 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
232
233 const std::string CONFIG1 = R"CONFIG(
234 face_system
235 {
236 udp
237 {
238 mcast_group 239.66.30.1
239 mcast_port 7011
240 }
241 }
242 )CONFIG";
243 const std::string CONFIG2 = R"CONFIG(
244 face_system
245 {
246 udp
247 {
248 mcast_group 239.66.30.2
249 mcast_port 7012
250 }
251 }
252 )CONFIG";
253
254 parseConfig(CONFIG1, false);
255 auto udpMcastFaces = this->listUdpMcastFaces();
256 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
257 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
258 FaceUri("udp4://239.66.30.1:7011"));
259
260 parseConfig(CONFIG2, false);
261 g_io.poll();
262 udpMcastFaces = this->listUdpMcastFaces();
263 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), netifs.size());
264 BOOST_CHECK_EQUAL(udpMcastFaces.front()->getRemoteUri(),
265 FaceUri("udp4://239.66.30.2:7012"));
266}
267
Junxiao Shic31080d2017-01-24 15:10:12 +0000268BOOST_FIXTURE_TEST_CASE(Whitelist, UdpMcastConfigFixture)
269{
270#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000271 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000272 SKIP_IF_NOT_SUPERUSER();
273#endif // __linux__
274 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
275
276 std::string CONFIG = R"CONFIG(
277 face_system
278 {
279 udp
280 {
281 whitelist
282 {
283 ifname %ifname
284 }
285 }
286 }
287 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000288 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000289
290 parseConfig(CONFIG, false);
291 auto udpMcastFaces = this->listUdpMcastFaces();
292 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
293 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
294}
295
296BOOST_FIXTURE_TEST_CASE(Blacklist, UdpMcastConfigFixture)
297{
298#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000299 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000300 SKIP_IF_NOT_SUPERUSER();
301#endif // __linux__
302 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(1);
303
304 std::string CONFIG = R"CONFIG(
305 face_system
306 {
307 udp
308 {
309 blacklist
310 {
311 ifname %ifname
312 }
313 }
314 }
315 )CONFIG";
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000316 boost::replace_first(CONFIG, "%ifname", netifs.front()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000317
318 parseConfig(CONFIG, false);
319 auto udpMcastFaces = this->listUdpMcastFaces();
320 BOOST_CHECK_EQUAL(udpMcastFaces.size(), netifs.size() - 1);
Davide Pesaventob15276f2017-07-15 16:27:13 -0400321 BOOST_CHECK_EQUAL(boost::count_if(udpMcastFaces, [this] (const Face* face) {
Junxiao Shic31080d2017-01-24 15:10:12 +0000322 return isFaceOnNetif(*face, netifs.front());
323 }), 0);
324}
325
326BOOST_FIXTURE_TEST_CASE(ChangePredicate, UdpMcastConfigFixture)
327{
328#ifdef __linux__
Junxiao Shibbace1d2017-08-06 20:03:37 +0000329 // need superuser privilege for creating multicast faces on Linux
Junxiao Shic31080d2017-01-24 15:10:12 +0000330 SKIP_IF_NOT_SUPERUSER();
331#endif // __linux__
332 SKIP_IF_UDP_MCAST_NETIF_COUNT_LT(2);
333
334 std::string CONFIG1 = R"CONFIG(
335 face_system
336 {
337 udp
338 {
339 whitelist
340 {
341 ifname %ifname
342 }
343 }
344 }
345 )CONFIG";
346 std::string CONFIG2 = CONFIG1;
Junxiao Shi84d62cb2017-07-12 16:15:18 +0000347 boost::replace_first(CONFIG1, "%ifname", netifs.front()->getName());
348 boost::replace_first(CONFIG2, "%ifname", netifs.back()->getName());
Junxiao Shic31080d2017-01-24 15:10:12 +0000349
350 parseConfig(CONFIG1, false);
351 auto udpMcastFaces = this->listUdpMcastFaces();
352 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
353 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.front()));
354
355 parseConfig(CONFIG2, false);
356 g_io.poll();
357 udpMcastFaces = this->listUdpMcastFaces();
358 BOOST_REQUIRE_EQUAL(udpMcastFaces.size(), 1);
359 BOOST_CHECK(isFaceOnNetif(*udpMcastFaces.front(), netifs.back()));
360}
361
Junxiao Shi64d99f22017-01-21 23:06:36 +0000362BOOST_AUTO_TEST_CASE(Omitted)
363{
364 const std::string CONFIG = R"CONFIG(
365 face_system
366 {
367 }
368 )CONFIG";
369
370 parseConfig(CONFIG, true);
371 parseConfig(CONFIG, false);
372
Junxiao Shi64d99f22017-01-21 23:06:36 +0000373 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
374 BOOST_CHECK_EQUAL(this->listFacesByScheme("udp4", ndn::nfd::LINK_TYPE_MULTI_ACCESS).size(), 0);
375}
376
377BOOST_AUTO_TEST_CASE(BadIdleTimeout)
378{
379 const std::string CONFIG = R"CONFIG(
380 face_system
381 {
382 udp
383 {
384 idle_timeout hello
385 }
386 }
387 )CONFIG";
388
389 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
390 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
391}
392
393BOOST_AUTO_TEST_CASE(BadMcast)
394{
395 const std::string CONFIG = R"CONFIG(
396 face_system
397 {
398 udp
399 {
400 mcast hello
401 }
402 }
403 )CONFIG";
404
405 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
406 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
407}
408
409BOOST_AUTO_TEST_CASE(BadMcastGroup)
410{
411 const std::string CONFIG = R"CONFIG(
412 face_system
413 {
414 udp
415 {
416 mcast_group hello
417 }
418 }
419 )CONFIG";
420
421 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
422 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
423}
424
425BOOST_AUTO_TEST_CASE(BadMcastGroupV4Unicast)
426{
427 const std::string CONFIG = R"CONFIG(
428 face_system
429 {
430 udp
431 {
432 mcast_group 10.0.0.1
433 }
434 }
435 )CONFIG";
436
437 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
438 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
439}
440
441BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
442{
443 const std::string CONFIG = R"CONFIG(
444 face_system
445 {
446 udp
447 {
448 mcast_group ff00::1
449 }
450 }
451 )CONFIG";
452
453 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
454 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
455}
456
457BOOST_AUTO_TEST_CASE(AllDisabled)
458{
459 const std::string CONFIG = R"CONFIG(
460 face_system
461 {
462 udp
463 {
464 enable_v4 no
465 enable_v6 no
466 mcast no
467 }
468 }
469 )CONFIG";
470
471 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
472 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
473}
474
475BOOST_AUTO_TEST_CASE(UnknownOption)
476{
477 const std::string CONFIG = R"CONFIG(
478 face_system
479 {
480 udp
481 {
482 hello
483 }
484 }
485 )CONFIG";
486
487 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
488 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
489}
490
491BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
492
Junxiao Shicde37ad2015-12-24 01:02:05 -0700493BOOST_AUTO_TEST_CASE(GetChannels)
494{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400495 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700496
Davide Pesaventob15276f2017-07-15 16:27:13 -0400497 std::set<std::string> expected;
498 expected.insert(factory.createChannel("127.0.0.1", "20070")->getUri().toString());
499 expected.insert(factory.createChannel("127.0.0.1", "20071")->getUri().toString());
500 expected.insert(factory.createChannel("::1", "20071")->getUri().toString());
501 checkChannelListEqual(factory, expected);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700502}
503
Weiwei Liu72cee942016-02-04 16:49:19 -0700504BOOST_AUTO_TEST_CASE(CreateChannel)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700505{
Weiwei Liu72cee942016-02-04 16:49:19 -0700506 auto channel1 = factory.createChannel("127.0.0.1", "20070");
507 auto channel1a = factory.createChannel("127.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700508 BOOST_CHECK_EQUAL(channel1, channel1a);
509 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "udp4://127.0.0.1:20070");
510
Weiwei Liu72cee942016-02-04 16:49:19 -0700511 auto channel2 = factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700512 BOOST_CHECK_NE(channel1, channel2);
513
Weiwei Liu72cee942016-02-04 16:49:19 -0700514 auto channel3 = factory.createChannel("::1", "20071");
515 BOOST_CHECK_NE(channel2, channel3);
516 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "udp6://[::1]:20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700517
Weiwei Liu72cee942016-02-04 16:49:19 -0700518 // createChannel with multicast address
519 BOOST_CHECK_EXCEPTION(factory.createChannel("224.0.0.1", "20070"), UdpFactory::Error,
520 [] (const UdpFactory::Error& e) {
521 return strcmp(e.what(),
522 "createChannel is only for unicast channels. The provided endpoint "
523 "is multicast. Use createMulticastFace to create a multicast face") == 0;
524 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700525
Weiwei Liu72cee942016-02-04 16:49:19 -0700526 // createChannel with a local endpoint that has already been allocated for a UDP multicast face
527 auto multicastFace = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20072");
528 BOOST_CHECK_EXCEPTION(factory.createChannel("127.0.0.1", "20072"), UdpFactory::Error,
529 [] (const UdpFactory::Error& e) {
530 return strcmp(e.what(),
531 "Cannot create the requested UDP unicast channel, local "
532 "endpoint is already allocated for a UDP multicast face") == 0;
533 });
534}
Junxiao Shicde37ad2015-12-24 01:02:05 -0700535
Weiwei Liu72cee942016-02-04 16:49:19 -0700536BOOST_AUTO_TEST_CASE(CreateMulticastFace)
537{
Weiwei Liu72cee942016-02-04 16:49:19 -0700538 auto multicastFace1 = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
539 auto multicastFace1a = factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700540 BOOST_CHECK_EQUAL(multicastFace1, multicastFace1a);
541
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200542 // createMulticastFace with a local endpoint that is already used by a channel
Weiwei Liu72cee942016-02-04 16:49:19 -0700543 auto channel = factory.createChannel("127.0.0.1", "20071");
544 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.1", "20071"), UdpFactory::Error,
545 [] (const UdpFactory::Error& e) {
546 return strcmp(e.what(),
547 "Cannot create the requested UDP multicast face, local "
548 "endpoint is already allocated for a UDP unicast channel") == 0;
549 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700550
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200551 // createMulticastFace with a local endpoint that is already
552 // used by a multicast face on a different multicast group
Weiwei Liu72cee942016-02-04 16:49:19 -0700553 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "224.0.0.42", "20070"), UdpFactory::Error,
554 [] (const UdpFactory::Error& e) {
555 return strcmp(e.what(),
556 "Cannot create the requested UDP multicast face, local "
557 "endpoint is already allocated for a UDP multicast face "
558 "on a different multicast group") == 0;
559 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700560
Weiwei Liu72cee942016-02-04 16:49:19 -0700561 // createMulticastFace with an IPv4 unicast address
562 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("127.0.0.1", "192.168.10.15", "20072"), UdpFactory::Error,
563 [] (const UdpFactory::Error& e) {
564 return strcmp(e.what(),
565 "Cannot create the requested UDP multicast face, "
566 "the multicast group given as input is not a multicast address") == 0;
567 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700568
Weiwei Liu72cee942016-02-04 16:49:19 -0700569 // createMulticastFace with an IPv6 multicast address
570 BOOST_CHECK_EXCEPTION(factory.createMulticastFace("::1", "ff01::114", "20073"), UdpFactory::Error,
571 [] (const UdpFactory::Error& e) {
572 return strcmp(e.what(),
573 "IPv6 multicast is not supported yet. Please provide an IPv4 "
574 "address") == 0;
575 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700576
Weiwei Liu72cee942016-02-04 16:49:19 -0700577 // createMulticastFace with different local and remote port numbers
Davide Pesaventoeee53aa2016-04-11 17:20:21 +0200578 udp::Endpoint localEndpoint(boost::asio::ip::address_v4::loopback(), 20074);
579 udp::Endpoint multicastEndpoint(boost::asio::ip::address::from_string("224.0.0.1"), 20075);
Weiwei Liu72cee942016-02-04 16:49:19 -0700580 BOOST_CHECK_EXCEPTION(factory.createMulticastFace(localEndpoint, multicastEndpoint), UdpFactory::Error,
581 [] (const UdpFactory::Error& e) {
582 return strcmp(e.what(),
583 "Cannot create the requested UDP multicast face, "
584 "both endpoints should have the same port number. ") == 0;
585 });
Junxiao Shicde37ad2015-12-24 01:02:05 -0700586}
587
Davide Pesaventob15276f2017-07-15 16:27:13 -0400588BOOST_AUTO_TEST_CASE(CreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700589{
Eric Newberry42602412016-08-27 09:33:18 -0700590 createFace(factory,
591 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000592 {},
Eric Newberry42602412016-08-27 09:33:18 -0700593 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700594 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400595 false,
Eric Newberry42602412016-08-27 09:33:18 -0700596 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700597
598 factory.createChannel("127.0.0.1", "20071");
599
Eric Newberry42602412016-08-27 09:33:18 -0700600 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400601 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000602 {},
Eric Newberry42602412016-08-27 09:33:18 -0700603 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700604 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400605 false,
Eric Newberry42602412016-08-27 09:33:18 -0700606 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Eric Newberry78e32b02017-04-01 14:34:44 +0000607
Eric Newberry42602412016-08-27 09:33:18 -0700608 createFace(factory,
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400609 FaceUri("udp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000610 {},
Eric Newberry42602412016-08-27 09:33:18 -0700611 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700612 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400613 false,
Eric Newberry42602412016-08-27 09:33:18 -0700614 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700615
Eric Newberry42602412016-08-27 09:33:18 -0700616 createFace(factory,
617 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000618 {},
Eric Newberry42602412016-08-27 09:33:18 -0700619 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
Eric Newberryf40551a2016-09-05 15:41:16 -0700620 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400621 false,
622 {CreateFaceExpectedResult::SUCCESS, 0, ""});
623
624
625 createFace(factory,
626 FaceUri("udp4://127.0.0.1:20073"),
627 {},
628 ndn::nfd::FACE_PERSISTENCY_PERMANENT,
629 false,
630 true,
Eric Newberry42602412016-08-27 09:33:18 -0700631 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700632}
633
Davide Pesaventob15276f2017-07-15 16:27:13 -0400634BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700635{
Eric Newberry78e32b02017-04-01 14:34:44 +0000636 factory.createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700637
Eric Newberry42602412016-08-27 09:33:18 -0700638 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400639 FaceUri("udp4://127.0.0.1:20072"),
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400640 FaceUri("udp4://127.0.0.1:20071"),
Davide Pesavento46afec42017-05-28 14:28:47 -0400641 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
642 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400643 false,
Davide Pesavento46afec42017-05-28 14:28:47 -0400644 {CreateFaceExpectedResult::FAILURE, 406,
645 "Unicast UDP faces cannot be created with a LocalUri"});
646
647 createFace(factory,
648 FaceUri("udp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000649 {},
Eric Newberry42602412016-08-27 09:33:18 -0700650 ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
Eric Newberryf40551a2016-09-05 15:41:16 -0700651 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400652 false,
Eric Newberry42602412016-08-27 09:33:18 -0700653 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400654 "Outgoing UDP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000655
656 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400657 FaceUri("udp4://233.252.0.1:23252"),
658 {},
Eric Newberry78e32b02017-04-01 14:34:44 +0000659 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
660 false,
Eric Newberry2642cd22017-07-13 21:34:53 -0400661 false,
Eric Newberry78e32b02017-04-01 14:34:44 +0000662 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400663 "Cannot create multicast UDP faces"});
664
665 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400666 FaceUri("udp4://127.0.0.1:20072"),
667 {},
668 ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
669 true,
Eric Newberry2642cd22017-07-13 21:34:53 -0400670 false,
Davide Pesavento46afec42017-05-28 14:28:47 -0400671 {CreateFaceExpectedResult::FAILURE, 406,
672 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700673}
674
Junxiao Shicde37ad2015-12-24 01:02:05 -0700675BOOST_AUTO_TEST_SUITE_END() // TestUdpFactory
676BOOST_AUTO_TEST_SUITE_END() // Face
677
678} // namespace tests
Junxiao Shi64d99f22017-01-21 23:06:36 +0000679} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700680} // namespace nfd