blob: cd900785385443f8c7d1feebf95b9b7fc23a4feb [file] [log] [blame]
Junxiao Shib8590312016-12-29 21:22:25 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi38b24c72017-01-05 02:59:31 +00003 * Copyright (c) 2014-2017, Regents of the University of California,
Junxiao Shib8590312016-12-29 21:22:25 +00004 * 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/face-system.hpp"
Junxiao Shi38b24c72017-01-05 02:59:31 +000027#include "face-system-fixture.hpp"
Junxiao Shib8590312016-12-29 21:22:25 +000028
29// ProtocolFactory includes, sorted alphabetically
Junxiao Shib8590312016-12-29 21:22:25 +000030#include "face/udp-factory.hpp"
Junxiao Shib8590312016-12-29 21:22:25 +000031
32#include "tests/test-common.hpp"
33
34namespace nfd {
35namespace face {
36namespace tests {
37
38using namespace nfd::tests;
39
Junxiao Shi38b24c72017-01-05 02:59:31 +000040BOOST_AUTO_TEST_SUITE(Face)
41BOOST_FIXTURE_TEST_SUITE(TestFaceSystem, FaceSystemFixture)
42
43BOOST_AUTO_TEST_SUITE(ProcessConfig)
44
45class DummyProtocolFactory : public ProtocolFactory
Junxiao Shib8590312016-12-29 21:22:25 +000046{
47public:
Junxiao Shi38b24c72017-01-05 02:59:31 +000048 void
49 processConfig(OptionalConfigSection configSection,
50 FaceSystem::ConfigContext& context) override
Junxiao Shib8590312016-12-29 21:22:25 +000051 {
Junxiao Shi38b24c72017-01-05 02:59:31 +000052 processConfigHistory.push_back({configSection, context.isDryRun});
53 if (!context.isDryRun) {
54 this->providedSchemes = this->newProvidedSchemes;
55 }
Junxiao Shib8590312016-12-29 21:22:25 +000056 }
57
58 void
Junxiao Shi38b24c72017-01-05 02:59:31 +000059 createFace(const FaceUri& uri,
60 ndn::nfd::FacePersistency persistency,
61 bool wantLocalFieldsEnabled,
62 const FaceCreatedCallback& onCreated,
63 const FaceCreationFailedCallback& onFailure) override
Junxiao Shib8590312016-12-29 21:22:25 +000064 {
Junxiao Shi38b24c72017-01-05 02:59:31 +000065 BOOST_FAIL("createFace should not be called");
Junxiao Shib8590312016-12-29 21:22:25 +000066 }
67
Junxiao Shi38b24c72017-01-05 02:59:31 +000068 std::vector<shared_ptr<const Channel>>
69 getChannels() const override
70 {
71 BOOST_FAIL("getChannels should not be called");
72 return {};
73 }
74
75public:
76 struct ProcessConfigArgs
77 {
78 OptionalConfigSection configSection;
79 bool isDryRun;
80 };
81 std::vector<ProcessConfigArgs> processConfigHistory;
82
83 std::set<std::string> newProvidedSchemes;
Junxiao Shib8590312016-12-29 21:22:25 +000084};
85
Junxiao Shi38b24c72017-01-05 02:59:31 +000086BOOST_AUTO_TEST_CASE(Normal)
87{
88 auto f1 = make_shared<DummyProtocolFactory>();
89 auto f2 = make_shared<DummyProtocolFactory>();
90 faceSystem.m_factories["f1"] = f1;
91 faceSystem.m_factories["f2"] = f2;
92
93 const std::string CONFIG = R"CONFIG(
94 face_system
95 {
96 f1
97 {
98 key v1
99 }
100 f2
101 {
102 key v2
103 }
104 }
105 )CONFIG";
106
107 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
108 BOOST_REQUIRE_EQUAL(f1->processConfigHistory.size(), 1);
109 BOOST_CHECK_EQUAL(f1->processConfigHistory.back().isDryRun, true);
110 BOOST_CHECK_EQUAL(f1->processConfigHistory.back().configSection->get<std::string>("key"), "v1");
111 BOOST_REQUIRE_EQUAL(f2->processConfigHistory.size(), 1);
112 BOOST_CHECK_EQUAL(f2->processConfigHistory.back().isDryRun, true);
113 BOOST_CHECK_EQUAL(f2->processConfigHistory.back().configSection->get<std::string>("key"), "v2");
114
115 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
116 BOOST_REQUIRE_EQUAL(f1->processConfigHistory.size(), 2);
117 BOOST_CHECK_EQUAL(f1->processConfigHistory.back().isDryRun, false);
118 BOOST_CHECK_EQUAL(f1->processConfigHistory.back().configSection->get<std::string>("key"), "v1");
119 BOOST_REQUIRE_EQUAL(f2->processConfigHistory.size(), 2);
120 BOOST_CHECK_EQUAL(f2->processConfigHistory.back().isDryRun, false);
121 BOOST_CHECK_EQUAL(f2->processConfigHistory.back().configSection->get<std::string>("key"), "v2");
122}
123
124BOOST_AUTO_TEST_CASE(OmittedSection)
125{
126 auto f1 = make_shared<DummyProtocolFactory>();
127 auto f2 = make_shared<DummyProtocolFactory>();
128 faceSystem.m_factories["f1"] = f1;
129 faceSystem.m_factories["f2"] = f2;
130
131 const std::string CONFIG = R"CONFIG(
132 face_system
133 {
134 f1
135 {
136 }
137 }
138 )CONFIG";
139
140 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
141 BOOST_REQUIRE_EQUAL(f1->processConfigHistory.size(), 1);
142 BOOST_CHECK_EQUAL(f1->processConfigHistory.back().isDryRun, true);
143 BOOST_REQUIRE_EQUAL(f2->processConfigHistory.size(), 1);
144 BOOST_CHECK_EQUAL(f2->processConfigHistory.back().isDryRun, true);
145 BOOST_CHECK(!f2->processConfigHistory.back().configSection);
146
147 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
148 BOOST_REQUIRE_EQUAL(f1->processConfigHistory.size(), 2);
149 BOOST_CHECK_EQUAL(f1->processConfigHistory.back().isDryRun, false);
150 BOOST_REQUIRE_EQUAL(f2->processConfigHistory.size(), 2);
151 BOOST_CHECK_EQUAL(f2->processConfigHistory.back().isDryRun, false);
152 BOOST_CHECK(!f2->processConfigHistory.back().configSection);
153}
154
155BOOST_AUTO_TEST_CASE(UnknownSection)
156{
157 const std::string CONFIG = R"CONFIG(
158 face_system
159 {
160 f0
161 {
162 }
163 }
164 )CONFIG";
165
166 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
167 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
168}
169
170BOOST_AUTO_TEST_CASE(ChangeProvidedSchemes)
171{
172 auto f1 = make_shared<DummyProtocolFactory>();
173 faceSystem.m_factories["f1"] = f1;
174
175 const std::string CONFIG = R"CONFIG(
176 face_system
177 {
178 f1
179 {
180 }
181 }
182 )CONFIG";
183
184 f1->newProvidedSchemes.insert("s1");
185 f1->newProvidedSchemes.insert("s2");
186 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
187 BOOST_CHECK(faceSystem.getFactoryByScheme("f1") == nullptr);
188 BOOST_CHECK_EQUAL(faceSystem.getFactoryByScheme("s1"), f1.get());
189 BOOST_CHECK_EQUAL(faceSystem.getFactoryByScheme("s2"), f1.get());
190
191 f1->newProvidedSchemes.erase("s2");
192 f1->newProvidedSchemes.insert("s3");
193 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
194 BOOST_CHECK(faceSystem.getFactoryByScheme("f1") == nullptr);
195 BOOST_CHECK_EQUAL(faceSystem.getFactoryByScheme("s1"), f1.get());
196 BOOST_CHECK(faceSystem.getFactoryByScheme("s2") == nullptr);
197 BOOST_CHECK_EQUAL(faceSystem.getFactoryByScheme("s3"), f1.get());
198}
199
200BOOST_AUTO_TEST_SUITE_END() // ProcessConfig
201
202///\todo #3904 move Config* to *Factory test suite
Junxiao Shib8590312016-12-29 21:22:25 +0000203
Junxiao Shib8590312016-12-29 21:22:25 +0000204BOOST_AUTO_TEST_SUITE(ConfigUdp)
205
206BOOST_AUTO_TEST_CASE(Normal)
207{
208 SKIP_IF_NOT_SUPERUSER();
209
210 const std::string CONFIG = R"CONFIG(
211 face_system
212 {
213 udp
214 {
215 port 6363
216 enable_v4 yes
217 enable_v6 yes
218 idle_timeout 30
219 keep_alive_interval 25
220 mcast yes
221 mcast_port 56363
222 mcast_group 224.0.23.170
223 }
224 }
225 )CONFIG";
226
227 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, true));
228 BOOST_CHECK_NO_THROW(parseConfig(CONFIG, false));
229
Junxiao Shi38b24c72017-01-05 02:59:31 +0000230 auto& factory = this->getFactoryByScheme<UdpFactory>("udp");
231 BOOST_CHECK_EQUAL(factory.getChannels().size(), 2);
Junxiao Shib8590312016-12-29 21:22:25 +0000232}
233
234BOOST_AUTO_TEST_CASE(BadIdleTimeout)
235{
236 const std::string CONFIG = R"CONFIG(
237 face_system
238 {
239 udp
240 {
241 idle_timeout hello
242 }
243 }
244 )CONFIG";
245
246 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
247 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
248}
249
250BOOST_AUTO_TEST_CASE(BadMcast)
251{
252 const std::string CONFIG = R"CONFIG(
253 face_system
254 {
255 udp
256 {
257 mcast hello
258 }
259 }
260 )CONFIG";
261
262 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
263 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
264}
265
266BOOST_AUTO_TEST_CASE(BadMcastGroup)
267{
268 const std::string CONFIG = R"CONFIG(
269 face_system
270 {
271 udp
272 {
273 mcast no
274 mcast_port 50
275 mcast_group hello
276 }
277 }
278 )CONFIG";
279
280 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
281 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
282}
283
284BOOST_AUTO_TEST_CASE(BadMcastGroupV6)
285{
286 const std::string CONFIG = R"CONFIG(
287 face_system
288 {
289 udp
290 {
291 mcast no
292 mcast_port 50
293 mcast_group ::1
294 }
295 }
296 )CONFIG";
297
298 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
299 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
300}
301
302BOOST_AUTO_TEST_CASE(ChannelsDisabled)
303{
304 const std::string CONFIG = R"CONFIG(
305 face_system
306 {
307 udp
308 {
309 port 6363
310 enable_v4 no
311 enable_v6 no
312 idle_timeout 30
313 keep_alive_interval 25
314 mcast yes
315 mcast_port 56363
316 mcast_group 224.0.23.170
317 }
318 }
319 )CONFIG";
320
321 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
322 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
323}
324
325BOOST_AUTO_TEST_CASE(ConflictingMcast)
326{
327 const std::string CONFIG = R"CONFIG(
328 face_system
329 {
330 udp
331 {
332 port 6363
333 enable_v4 no
334 enable_v6 yes
335 idle_timeout 30
336 keep_alive_interval 25
337 mcast yes
338 mcast_port 56363
339 mcast_group 224.0.23.170
340 }
341 }
342 )CONFIG";
343
344 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
345 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
346}
347
348BOOST_AUTO_TEST_CASE(UnknownOption)
349{
350 const std::string CONFIG = R"CONFIG(
351 face_system
352 {
353 udp
354 {
355 hello
356 }
357 }
358 )CONFIG";
359
360 BOOST_CHECK_THROW(parseConfig(CONFIG, true), ConfigFile::Error);
361 BOOST_CHECK_THROW(parseConfig(CONFIG, false), ConfigFile::Error);
362}
363
364BOOST_AUTO_TEST_CASE(MulticastReinit)
365{
366 SKIP_IF_NOT_SUPERUSER();
367
368 const std::string CONFIG_WITH_MCAST = R"CONFIG(
369 face_system
370 {
371 udp
372 {
373 mcast yes
374 }
375 }
376 )CONFIG";
377
378 BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITH_MCAST, false));
379
Junxiao Shi38b24c72017-01-05 02:59:31 +0000380 auto& factory = this->getFactoryByScheme<UdpFactory>("udp");
Junxiao Shib8590312016-12-29 21:22:25 +0000381
Junxiao Shi38b24c72017-01-05 02:59:31 +0000382 if (factory.getMulticastFaces().empty()) {
Junxiao Shib8590312016-12-29 21:22:25 +0000383 BOOST_WARN_MESSAGE(false, "skipping assertions that require at least one UDP multicast face");
384 return;
385 }
386
387 const std::string CONFIG_WITHOUT_MCAST = R"CONFIG(
388 face_system
389 {
390 udp
391 {
392 mcast no
393 }
394 }
395 )CONFIG";
396
397 BOOST_CHECK_NO_THROW(parseConfig(CONFIG_WITHOUT_MCAST, false));
398 BOOST_REQUIRE_NO_THROW(g_io.poll());
Junxiao Shi38b24c72017-01-05 02:59:31 +0000399 BOOST_CHECK_EQUAL(factory.getMulticastFaces().size(), 0);
Junxiao Shib8590312016-12-29 21:22:25 +0000400}
401BOOST_AUTO_TEST_SUITE_END() // ConfigUdp
402
Junxiao Shib8590312016-12-29 21:22:25 +0000403BOOST_AUTO_TEST_SUITE_END() // TestFaceSystem
404BOOST_AUTO_TEST_SUITE_END() // Mgmt
405
406} // namespace tests
407} // namespace face
408} // namespace nfd