blob: 77b806603079b1839142d0cade132b3e241465b6 [file] [log] [blame]
Junxiao Shicde37ad2015-12-24 01:02:05 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi0ba6d642017-07-17 00:53:22 +00002/*
Davide Pesavento15b55052018-01-27 19:09:28 -05003 * Copyright (c) 2014-2018, 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/tcp-factory.hpp"
27
Junxiao Shi38b24c72017-01-05 02:59:31 +000028#include "face-system-fixture.hpp"
Davide Pesaventob15276f2017-07-15 16:27:13 -040029#include "factory-test-common.hpp"
Junxiao Shicde37ad2015-12-24 01:02:05 -070030#include "tests/limited-io.hpp"
31
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040032#include <ndn-cxx/net/address-converter.hpp>
33
Junxiao Shicde37ad2015-12-24 01:02:05 -070034namespace nfd {
Junxiao Shi38b24c72017-01-05 02:59:31 +000035namespace face {
Junxiao Shicde37ad2015-12-24 01:02:05 -070036namespace tests {
37
Davide Pesavento4b89a6e2017-10-07 15:29:50 -040038class TcpFactoryFixture : public FaceSystemFactoryFixture<TcpFactory>
39{
40protected:
41 shared_ptr<TcpChannel>
42 createChannel(const std::string& localIp, const std::string& localPort)
43 {
44 tcp::Endpoint endpoint(ndn::ip::addressFromString(localIp),
45 boost::lexical_cast<uint16_t>(localPort));
46 return factory.createChannel(endpoint);
47 }
48};
Junxiao Shi0ba6d642017-07-17 00:53:22 +000049
Junxiao Shicde37ad2015-12-24 01:02:05 -070050BOOST_AUTO_TEST_SUITE(Face)
Junxiao Shi0ba6d642017-07-17 00:53:22 +000051BOOST_FIXTURE_TEST_SUITE(TestTcpFactory, TcpFactoryFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -070052
Junxiao Shi0ba6d642017-07-17 00:53:22 +000053BOOST_AUTO_TEST_SUITE(ProcessConfig)
Junxiao Shi38b24c72017-01-05 02:59:31 +000054
Davide Pesavento494a9552018-02-04 22:16:05 -050055BOOST_AUTO_TEST_CASE(Defaults)
56{
57 const std::string CONFIG = R"CONFIG(
58 face_system
59 {
60 tcp
61 }
62 )CONFIG";
63
64 parseConfig(CONFIG, true);
65 parseConfig(CONFIG, false);
66
67 checkChannelListEqual(factory, {"tcp4://0.0.0.0:6363", "tcp6://[::]:6363"});
68 auto channels = factory.getChannels();
69 BOOST_CHECK(std::all_of(channels.begin(), channels.end(),
70 [] (const shared_ptr<const Channel>& ch) { return ch->isListening(); }));
71}
72
73BOOST_AUTO_TEST_CASE(DisableListen)
Junxiao Shi38b24c72017-01-05 02:59:31 +000074{
75 const std::string CONFIG = R"CONFIG(
76 face_system
77 {
78 tcp
79 {
Davide Pesavento494a9552018-02-04 22:16:05 -050080 listen no
81 port 7001
82 }
83 }
84 )CONFIG";
85
86 parseConfig(CONFIG, true);
87 parseConfig(CONFIG, false);
88
89 checkChannelListEqual(factory, {"tcp4://0.0.0.0:7001", "tcp6://[::]:7001"});
90 auto channels = factory.getChannels();
91 BOOST_CHECK(std::none_of(channels.begin(), channels.end(),
92 [] (const shared_ptr<const Channel>& ch) { return ch->isListening(); }));
93}
94
95BOOST_AUTO_TEST_CASE(DisableV4)
96{
97 const std::string CONFIG = R"CONFIG(
98 face_system
99 {
100 tcp
101 {
102 port 7001
103 enable_v4 no
Junxiao Shi38b24c72017-01-05 02:59:31 +0000104 enable_v6 yes
105 }
106 }
107 )CONFIG";
108
Junxiao Shi1b65ca12017-01-21 23:04:41 +0000109 parseConfig(CONFIG, true);
110 parseConfig(CONFIG, false);
Junxiao Shi38b24c72017-01-05 02:59:31 +0000111
Davide Pesavento494a9552018-02-04 22:16:05 -0500112 checkChannelListEqual(factory, {"tcp6://[::]:7001"});
113}
114
115BOOST_AUTO_TEST_CASE(DisableV6)
116{
117 const std::string CONFIG = R"CONFIG(
118 face_system
119 {
120 tcp
121 {
122 port 7001
123 enable_v4 yes
124 enable_v6 no
125 }
126 }
127 )CONFIG";
128
129 parseConfig(CONFIG, true);
130 parseConfig(CONFIG, false);
131
132 checkChannelListEqual(factory, {"tcp4://0.0.0.0:7001"});
Junxiao Shi38b24c72017-01-05 02:59:31 +0000133}
134
135BOOST_AUTO_TEST_CASE(Omitted)
136{
137 const std::string CONFIG = R"CONFIG(
138 face_system
139 {
140 }
141 )CONFIG";
142
Junxiao Shi1b65ca12017-01-21 23:04:41 +0000143 parseConfig(CONFIG, true);
144 parseConfig(CONFIG, false);
Junxiao Shi38b24c72017-01-05 02:59:31 +0000145
Junxiao Shi38b24c72017-01-05 02:59:31 +0000146 BOOST_CHECK_EQUAL(factory.getChannels().size(), 0);
147}
148
Davide Pesavento494a9552018-02-04 22:16:05 -0500149BOOST_AUTO_TEST_CASE(AllDisabled)
150{
151 const std::string CONFIG = R"CONFIG(
152 face_system
153 {
154 tcp
155 {
156 enable_v4 no
157 enable_v6 no
158 }
159 }
160 )CONFIG";
161
162 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
163 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
164}
165
Junxiao Shi38b24c72017-01-05 02:59:31 +0000166BOOST_AUTO_TEST_CASE(BadListen)
167{
168 const std::string CONFIG = R"CONFIG(
169 face_system
170 {
171 tcp
172 {
173 listen hello
174 }
175 }
176 )CONFIG";
177
178 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
179 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
180}
181
Davide Pesavento494a9552018-02-04 22:16:05 -0500182BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(BadPort, 2) // Bug #4489
183BOOST_AUTO_TEST_CASE(BadPort)
Junxiao Shi38b24c72017-01-05 02:59:31 +0000184{
Davide Pesavento494a9552018-02-04 22:16:05 -0500185 // not a number
186 const std::string CONFIG1 = R"CONFIG(
Junxiao Shi38b24c72017-01-05 02:59:31 +0000187 face_system
188 {
189 tcp
190 {
Davide Pesavento494a9552018-02-04 22:16:05 -0500191 port hello
Junxiao Shi38b24c72017-01-05 02:59:31 +0000192 }
193 }
194 )CONFIG";
195
Davide Pesavento494a9552018-02-04 22:16:05 -0500196 BOOST_CHECK_THROW(parseConfig(CONFIG1, true), ConfigFile::Error);
197 BOOST_CHECK_THROW(parseConfig(CONFIG1, false), ConfigFile::Error);
198
199 // negative number
200 const std::string CONFIG2 = R"CONFIG(
201 face_system
202 {
203 tcp
204 {
205 port -1
206 }
207 }
208 )CONFIG";
209
210 BOOST_CHECK_THROW(parseConfig(CONFIG2, true), ConfigFile::Error);
211 BOOST_CHECK_THROW(parseConfig(CONFIG2, false), ConfigFile::Error);
212
213 // out of range
214 const std::string CONFIG3 = R"CONFIG(
215 face_system
216 {
217 tcp
218 {
219 port 65536
220 }
221 }
222 )CONFIG";
223
224 BOOST_CHECK_THROW(parseConfig(CONFIG3, true), ConfigFile::Error);
225 BOOST_CHECK_THROW(parseConfig(CONFIG3, false), ConfigFile::Error);
Junxiao Shi38b24c72017-01-05 02:59:31 +0000226}
227
228BOOST_AUTO_TEST_CASE(UnknownOption)
229{
230 const std::string CONFIG = R"CONFIG(
231 face_system
232 {
233 tcp
234 {
235 hello
236 }
237 }
238 )CONFIG";
239
240 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
241 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
242}
243
244BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
245
Davide Pesaventob15276f2017-07-15 16:27:13 -0400246BOOST_AUTO_TEST_CASE(GetChannels)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700247{
Davide Pesaventob15276f2017-07-15 16:27:13 -0400248 BOOST_CHECK_EQUAL(factory.getChannels().empty(), true);
249
250 std::set<std::string> expected;
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400251 expected.insert(createChannel("127.0.0.1", "20070")->getUri().toString());
252 expected.insert(createChannel("127.0.0.1", "20071")->getUri().toString());
253 expected.insert(createChannel("::1", "20071")->getUri().toString());
Davide Pesaventob15276f2017-07-15 16:27:13 -0400254 checkChannelListEqual(factory, expected);
255}
256
257BOOST_AUTO_TEST_CASE(CreateChannel)
258{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400259 auto channel1 = createChannel("127.0.0.1", "20070");
260 auto channel1a = createChannel("127.0.0.1", "20070");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700261 BOOST_CHECK_EQUAL(channel1, channel1a);
262 BOOST_CHECK_EQUAL(channel1->getUri().toString(), "tcp4://127.0.0.1:20070");
263
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400264 auto channel2 = createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700265 BOOST_CHECK_NE(channel1, channel2);
266
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400267 auto channel3 = createChannel("::1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700268 BOOST_CHECK_NE(channel2, channel3);
269 BOOST_CHECK_EQUAL(channel3->getUri().toString(), "tcp6://[::1]:20071");
270}
271
Davide Pesaventob15276f2017-07-15 16:27:13 -0400272BOOST_AUTO_TEST_CASE(CreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700273{
Eric Newberry42602412016-08-27 09:33:18 -0700274 createFace(factory,
275 FaceUri("tcp4://127.0.0.1:6363"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000276 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700277 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700278 {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700279
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400280 createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700281
Eric Newberry42602412016-08-27 09:33:18 -0700282 createFace(factory,
Eric Newberry78e32b02017-04-01 14:34:44 +0000283 FaceUri("tcp4://127.0.0.1:6363"),
284 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700285 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700286 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400287
288 createFace(factory,
289 FaceUri("tcp4://127.0.0.1:6363"),
290 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700291 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, false, false, false},
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400292 {CreateFaceExpectedResult::SUCCESS, 0, ""});
293
294 createFace(factory,
295 FaceUri("tcp4://127.0.0.1:20072"),
296 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700297 {ndn::nfd::FACE_PERSISTENCY_PERMANENT, {}, {}, false, false, false},
Eric Newberry2642cd22017-07-13 21:34:53 -0400298 {CreateFaceExpectedResult::SUCCESS, 0, ""});
299
300 createFace(factory,
301 FaceUri("tcp4://127.0.0.1:20073"),
302 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700303 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, true, false},
304 {CreateFaceExpectedResult::SUCCESS, 0, ""});
305
306 createFace(factory,
307 FaceUri("tcp4://127.0.0.1:20073"),
308 {},
309 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, true},
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400310 {CreateFaceExpectedResult::SUCCESS, 0, ""});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700311}
312
Davide Pesaventob15276f2017-07-15 16:27:13 -0400313BOOST_AUTO_TEST_CASE(UnsupportedCreateFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700314{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400315 createChannel("127.0.0.1", "20071");
Junxiao Shicde37ad2015-12-24 01:02:05 -0700316
Eric Newberry42602412016-08-27 09:33:18 -0700317 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400318 FaceUri("tcp4://127.0.0.1:20072"),
Eric Newberry42602412016-08-27 09:33:18 -0700319 FaceUri("tcp4://127.0.0.1:20071"),
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700320 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, false, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400321 {CreateFaceExpectedResult::FAILURE, 406,
322 "Unicast TCP faces cannot be created with a LocalUri"});
323
324 createFace(factory,
325 FaceUri("tcp4://127.0.0.1:20072"),
Eric Newberry78e32b02017-04-01 14:34:44 +0000326 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700327 {ndn::nfd::FACE_PERSISTENCY_ON_DEMAND, {}, {}, false, false, false},
Eric Newberry42602412016-08-27 09:33:18 -0700328 {CreateFaceExpectedResult::FAILURE, 406,
Davide Pesavento46afec42017-05-28 14:28:47 -0400329 "Outgoing TCP faces do not support on-demand persistency"});
Eric Newberry78e32b02017-04-01 14:34:44 +0000330
331 createFace(factory,
Davide Pesavento46afec42017-05-28 14:28:47 -0400332 FaceUri("tcp4://198.51.100.100:6363"),
333 {},
Eric Newberry0c3e57b2018-01-25 20:54:46 -0700334 {ndn::nfd::FACE_PERSISTENCY_PERSISTENT, {}, {}, true, false, false},
Davide Pesavento46afec42017-05-28 14:28:47 -0400335 {CreateFaceExpectedResult::FAILURE, 406,
336 "Local fields can only be enabled on faces with local scope"});
Junxiao Shicde37ad2015-12-24 01:02:05 -0700337}
338
Davide Pesaventob15276f2017-07-15 16:27:13 -0400339class CreateFaceTimeoutFixture : public TcpFactoryFixture
Junxiao Shicde37ad2015-12-24 01:02:05 -0700340{
341public:
342 void
Davide Pesavento494a9552018-02-04 22:16:05 -0500343 onFaceCreated(const shared_ptr<nfd::Face>& newFace)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700344 {
345 BOOST_CHECK_MESSAGE(false, "Timeout expected");
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400346 face = newFace;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700347
348 limitedIo.afterOp();
349 }
350
351 void
352 onConnectFailed(const std::string& reason)
353 {
354 BOOST_CHECK_MESSAGE(true, reason);
355
356 limitedIo.afterOp();
357 }
358
359public:
360 LimitedIo limitedIo;
Davide Pesavento494a9552018-02-04 22:16:05 -0500361 shared_ptr<nfd::Face> face;
Junxiao Shicde37ad2015-12-24 01:02:05 -0700362};
363
Davide Pesaventob15276f2017-07-15 16:27:13 -0400364BOOST_FIXTURE_TEST_CASE(CreateFaceTimeout, CreateFaceTimeoutFixture)
Junxiao Shicde37ad2015-12-24 01:02:05 -0700365{
Davide Pesavento4b89a6e2017-10-07 15:29:50 -0400366 createChannel("0.0.0.0", "20070");
Davide Pesavento15b55052018-01-27 19:09:28 -0500367 factory.createFace({FaceUri("tcp4://192.0.2.1:20070"), {}, {}},
Davide Pesaventob15276f2017-07-15 16:27:13 -0400368 bind(&CreateFaceTimeoutFixture::onFaceCreated, this, _1),
369 bind(&CreateFaceTimeoutFixture::onConnectFailed, this, _2));
Junxiao Shicde37ad2015-12-24 01:02:05 -0700370
Davide Pesavento15b55052018-01-27 19:09:28 -0500371 BOOST_REQUIRE_EQUAL(limitedIo.run(1, 10_s), LimitedIo::EXCEED_OPS);
Davide Pesaventoa3c9ddb2017-04-10 22:15:24 -0400372 BOOST_CHECK(face == nullptr);
Junxiao Shicde37ad2015-12-24 01:02:05 -0700373}
374
Junxiao Shicde37ad2015-12-24 01:02:05 -0700375BOOST_AUTO_TEST_SUITE_END() // TestTcpFactory
376BOOST_AUTO_TEST_SUITE_END() // Face
377
378} // namespace tests
Junxiao Shi38b24c72017-01-05 02:59:31 +0000379} // namespace face
Junxiao Shicde37ad2015-12-24 01:02:05 -0700380} // namespace nfd