blob: 2ffe6d4ea74494b25776469db9f349a1e706ebff [file] [log] [blame]
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev57e00362016-06-23 13:22:54 -07003 * Copyright (c) 2013-2016 Regents of the University of California.
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -04004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "face.hpp"
23#include "util/scheduler.hpp"
24#include "security/key-chain.hpp"
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080025#include "util/dummy-client-face.hpp"
Alexander Afanasyev3a6da362015-12-29 20:31:03 -080026#include "transport/tcp-transport.hpp"
Alexander Afanasyev57e00362016-06-23 13:22:54 -070027#include "transport/unix-transport.hpp"
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040028
29#include "boost-test.hpp"
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070030#include "identity-management-time-fixture.hpp"
31#include "key-chain-fixture.hpp"
Spyridon Mastorakis429634f2015-02-19 17:35:33 -080032#include "make-interest-data.hpp"
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040033
34namespace ndn {
35namespace tests {
36
Junxiao Shia60d9362014-11-12 09:38:21 -070037using ndn::util::DummyClientFace;
Junxiao Shia60d9362014-11-12 09:38:21 -070038
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070039class FaceFixture : public IdentityManagementTimeFixture
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040040{
41public:
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080042 explicit
Junxiao Shia1ea5062014-12-27 22:33:39 -070043 FaceFixture(bool enableRegistrationReply = true)
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -070044 : face(io, m_keyChain, { true, enableRegistrationReply })
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040045 {
46 }
47
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080048public:
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080049 DummyClientFace face;
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040050};
51
Junxiao Shia1ea5062014-12-27 22:33:39 -070052class FacesNoRegistrationReplyFixture : public FaceFixture
Junxiao Shia60d9362014-11-12 09:38:21 -070053{
54public:
55 FacesNoRegistrationReplyFixture()
Junxiao Shia1ea5062014-12-27 22:33:39 -070056 : FaceFixture(false)
Junxiao Shia60d9362014-11-12 09:38:21 -070057 {
58 }
59};
60
Junxiao Shia1ea5062014-12-27 22:33:39 -070061BOOST_FIXTURE_TEST_SUITE(TestFace, FaceFixture)
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040062
Junxiao Shi103d8ed2016-08-07 20:34:10 +000063BOOST_AUTO_TEST_SUITE(Consumer)
64
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040065BOOST_AUTO_TEST_CASE(ExpressInterestData)
66{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -080067 size_t nData = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080068 face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
69 [&] (const Interest& i, const Data& d) {
70 BOOST_CHECK(i.getName().isPrefixOf(d.getName()));
71 BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
72 ++nData;
73 },
Junxiao Shi103d8ed2016-08-07 20:34:10 +000074 bind([] { BOOST_FAIL("Unexpected Nack"); }),
75 bind([] { BOOST_FAIL("Unexpected timeout"); }));
Eric Newberry83872fd2015-08-06 17:01:24 -070076
77 advanceClocks(time::milliseconds(1), 40);
78
Junxiao Shi85d90832016-08-04 03:19:46 +000079 face.receive(*makeData("/Bye/World/a"));
80 face.receive(*makeData("/Hello/World/a"));
Eric Newberry83872fd2015-08-06 17:01:24 -070081
82 advanceClocks(time::milliseconds(1), 100);
83
84 BOOST_CHECK_EQUAL(nData, 1);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080085 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
86 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Eric Newberry83872fd2015-08-06 17:01:24 -070087
88 size_t nTimeouts = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -080089 face.expressInterest(Interest("/Hello/World/a/2", time::milliseconds(50)),
90 bind([]{}),
91 bind([]{}),
Junxiao Shi103d8ed2016-08-07 20:34:10 +000092 bind([&nTimeouts] { ++nTimeouts; }));
Eric Newberry83872fd2015-08-06 17:01:24 -070093 advanceClocks(time::milliseconds(10), 100);
94 BOOST_CHECK_EQUAL(nTimeouts, 1);
95}
96
97// test case for deprecated expressInterest implementation
98BOOST_AUTO_TEST_CASE(DeprecatedExpressInterestData)
99{
100 size_t nData = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800101 face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000102 [&] (const Interest& i, Data& d) {
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800103 BOOST_CHECK(i.getName().isPrefixOf(d.getName()));
104 ++nData;
105 },
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000106 bind([] { BOOST_FAIL("Unexpected timeout"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400107
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800108 advanceClocks(time::milliseconds(1), 40);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400109
Junxiao Shi85d90832016-08-04 03:19:46 +0000110 face.receive(*makeData("/Bye/World/a"));
111 face.receive(*makeData("/Hello/World/a"));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800112
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800113 advanceClocks(time::milliseconds(1), 100);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400114
115 BOOST_CHECK_EQUAL(nData, 1);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800116 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
117 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800118
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800119 face.expressInterest(Interest("/Hello/World/a", time::milliseconds(50)),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000120 [&] (const Interest& i, Data& d) {
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800121 BOOST_CHECK(i.getName().isPrefixOf(d.getName()));
122 ++nData;
123 },
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000124 bind([] { BOOST_FAIL("Unexpected timeout"); }));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800125 advanceClocks(time::milliseconds(1), 40);
Junxiao Shi85d90832016-08-04 03:19:46 +0000126 face.receive(*makeData("/Hello/World/a/1/xxxxx"));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800127
128 advanceClocks(time::milliseconds(1), 100);
129
130 BOOST_CHECK_EQUAL(nData, 2);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800131 BOOST_CHECK_EQUAL(face.sentInterests.size(), 2);
132 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800133
134 size_t nTimeouts = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800135 face.expressInterest(Interest("/Hello/World/a/2", time::milliseconds(50)),
136 bind([]{}),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000137 bind([&nTimeouts] { ++nTimeouts; }));
Alexander Afanasyev9d158f02015-02-17 21:30:19 -0800138 advanceClocks(time::milliseconds(10), 100);
139 BOOST_CHECK_EQUAL(nTimeouts, 1);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400140}
141
142BOOST_AUTO_TEST_CASE(ExpressInterestTimeout)
143{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800144 size_t nTimeouts = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800145 face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000146 bind([] { BOOST_FAIL("Unexpected Data"); }),
147 bind([] { BOOST_FAIL("Unexpected Nack"); }),
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800148 [&nTimeouts] (const Interest& i) {
149 BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
150 ++nTimeouts;
151 });
Eric Newberry83872fd2015-08-06 17:01:24 -0700152
153 advanceClocks(time::milliseconds(10), 100);
154
155 BOOST_CHECK_EQUAL(nTimeouts, 1);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800156 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
157 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
158 BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
Eric Newberry83872fd2015-08-06 17:01:24 -0700159}
160
161// test case for deprecated expressInterest implementation
162BOOST_AUTO_TEST_CASE(DeprecatedExpressInterestTimeout)
163{
164 size_t nTimeouts = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800165 face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000166 bind([] { BOOST_FAIL("Unexpected data"); }),
167 bind([&nTimeouts] { ++nTimeouts; }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400168
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800169 advanceClocks(time::milliseconds(10), 100);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400170
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400171 BOOST_CHECK_EQUAL(nTimeouts, 1);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800172 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
173 BOOST_CHECK_EQUAL(face.sentData.size(), 0);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400174}
175
Eric Newberry83872fd2015-08-06 17:01:24 -0700176BOOST_AUTO_TEST_CASE(ExpressInterestNack)
177{
178 size_t nNacks = 0;
179
180 Interest interest("/Hello/World", time::milliseconds(50));
181
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800182 face.expressInterest(interest,
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000183 bind([] { BOOST_FAIL("Unexpected Data"); }),
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800184 [&] (const Interest& i, const lp::Nack& n) {
185 BOOST_CHECK(i.getName().isPrefixOf(n.getInterest().getName()));
186 BOOST_CHECK_EQUAL(i.getName(), "/Hello/World");
187 BOOST_CHECK_EQUAL(n.getReason(), lp::NackReason::DUPLICATE);
188 ++nNacks;
189 },
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000190 bind([] { BOOST_FAIL("Unexpected timeout"); }));
Eric Newberry83872fd2015-08-06 17:01:24 -0700191
192 advanceClocks(time::milliseconds(1), 40);
193
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800194 lp::Nack nack(face.sentInterests[0]);
Eric Newberry83872fd2015-08-06 17:01:24 -0700195 nack.setReason(lp::NackReason::DUPLICATE);
196
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800197 BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
Eric Newberry83872fd2015-08-06 17:01:24 -0700198
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800199 face.receive(nack);
Eric Newberry83872fd2015-08-06 17:01:24 -0700200
201 advanceClocks(time::milliseconds(1), 100);
202
203 BOOST_CHECK_EQUAL(nNacks, 1);
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800204 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Eric Newberry83872fd2015-08-06 17:01:24 -0700205}
206
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800207BOOST_AUTO_TEST_CASE(RemovePendingInterest)
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400208{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800209 const PendingInterestId* interestId =
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800210 face.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000211 bind([] { BOOST_FAIL("Unexpected data"); }),
212 bind([] { BOOST_FAIL("Unexpected nack"); }),
213 bind([] { BOOST_FAIL("Unexpected timeout"); }));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800214 advanceClocks(time::milliseconds(10));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400215
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800216 face.removePendingInterest(interestId);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800217 advanceClocks(time::milliseconds(10));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400218
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000219 face.receive(*makeData("/Hello/World/%21"));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800220 advanceClocks(time::milliseconds(10), 100);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400221}
222
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000223BOOST_AUTO_TEST_CASE(RemoveAllPendingInterests)
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500224{
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800225 face.expressInterest(Interest("/Hello/World/0", time::milliseconds(50)),
226 bind([] { BOOST_FAIL("Unexpected data"); }),
227 bind([] { BOOST_FAIL("Unexpected nack"); }),
228 bind([] { BOOST_FAIL("Unexpected timeout"); }));
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500229
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800230 face.expressInterest(Interest("/Hello/World/1", time::milliseconds(50)),
231 bind([] { BOOST_FAIL("Unexpected data"); }),
232 bind([] { BOOST_FAIL("Unexpected nack"); }),
233 bind([] { BOOST_FAIL("Unexpected timeout"); }));
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500234
235 advanceClocks(time::milliseconds(10));
236
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800237 face.removeAllPendingInterests();
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500238 advanceClocks(time::milliseconds(10));
239
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800240 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500241
Junxiao Shi85d90832016-08-04 03:19:46 +0000242 face.receive(*makeData("/Hello/World/0"));
243 face.receive(*makeData("/Hello/World/1"));
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500244 advanceClocks(time::milliseconds(10), 100);
245}
246
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000247BOOST_AUTO_TEST_CASE(DestructionWithoutCancellingPendingInterests) // Bug #2518
248{
249 {
250 DummyClientFace face2(io, m_keyChain);
251 face2.expressInterest(Interest("/Hello/World", time::milliseconds(50)),
252 bind([]{}), bind([]{}));
253 advanceClocks(time::milliseconds(10), 10);
254 }
255
256 advanceClocks(time::milliseconds(10), 10);
257 // should not segfault
258}
259
260BOOST_AUTO_TEST_SUITE_END() // Consumer
261
262BOOST_AUTO_TEST_SUITE(Producer)
263
264BOOST_AUTO_TEST_CASE(PutNack)
265{
266 lp::Nack nack(Interest("/Hello/World", time::milliseconds(50)));
267 nack.setReason(lp::NackReason::NO_ROUTE);
268
269 BOOST_CHECK_EQUAL(face.sentNacks.size(), 0);
270
271 face.put(nack);
272
273 advanceClocks(time::milliseconds(10));
274
275 BOOST_CHECK_EQUAL(face.sentNacks.size(), 1);
276}
Ilya Moiseenko56b0bf82015-11-08 11:14:28 -0500277
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400278BOOST_AUTO_TEST_CASE(SetUnsetInterestFilter)
279{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800280 size_t nInterests = 0;
281 size_t nRegs = 0;
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400282 const RegisteredPrefixId* regPrefixId =
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800283 face.setInterestFilter("/Hello/World",
284 bind([&nInterests] { ++nInterests; }),
285 bind([&nRegs] { ++nRegs; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000286 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800287 advanceClocks(time::milliseconds(10), 10);
288 BOOST_CHECK_EQUAL(nRegs, 1);
289 BOOST_CHECK_EQUAL(nInterests, 0);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400290
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000291 face.receive(Interest("/Hello/World/%21"));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800292 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400293
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800294 BOOST_CHECK_EQUAL(nRegs, 1);
295 BOOST_CHECK_EQUAL(nInterests, 1);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400296
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000297 face.receive(Interest("/Bye/World/%21"));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800298 advanceClocks(time::milliseconds(10000), 10);
299 BOOST_CHECK_EQUAL(nInterests, 1);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400300
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000301 face.receive(Interest("/Hello/World/%21/2"));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800302 advanceClocks(time::milliseconds(10), 10);
303 BOOST_CHECK_EQUAL(nInterests, 2);
304
305 // removing filter
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800306 face.unsetInterestFilter(regPrefixId);
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800307 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400308
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000309 face.receive(Interest("/Hello/World/%21/3"));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800310 BOOST_CHECK_EQUAL(nInterests, 2);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400311
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000312 face.unsetInterestFilter(static_cast<const RegisteredPrefixId*>(nullptr));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800313 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400314
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000315 face.unsetInterestFilter(static_cast<const InterestFilterId*>(nullptr));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800316 advanceClocks(time::milliseconds(10), 10);
317}
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400318
Joao Pereira0b3cac52015-07-02 14:49:49 -0400319BOOST_AUTO_TEST_CASE(SetUnsetInterestFilterWithoutSucessCallback)
320{
321 size_t nInterests = 0;
322 const RegisteredPrefixId* regPrefixId =
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800323 face.setInterestFilter("/Hello/World",
324 bind([&nInterests] { ++nInterests; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000325 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400326 advanceClocks(time::milliseconds(10), 10);
327 BOOST_CHECK_EQUAL(nInterests, 0);
328
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000329 face.receive(Interest("/Hello/World/%21"));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400330 advanceClocks(time::milliseconds(10), 10);
331
332 BOOST_CHECK_EQUAL(nInterests, 1);
333
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000334 face.receive(Interest("/Bye/World/%21"));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400335 advanceClocks(time::milliseconds(10000), 10);
336 BOOST_CHECK_EQUAL(nInterests, 1);
337
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000338 face.receive(Interest("/Hello/World/%21/2"));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400339 advanceClocks(time::milliseconds(10), 10);
340 BOOST_CHECK_EQUAL(nInterests, 2);
341
342 // removing filter
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800343 face.unsetInterestFilter(regPrefixId);
Joao Pereira0b3cac52015-07-02 14:49:49 -0400344 advanceClocks(time::milliseconds(10), 10);
345
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000346 face.receive(Interest("/Hello/World/%21/3"));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400347 BOOST_CHECK_EQUAL(nInterests, 2);
348
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000349 face.unsetInterestFilter(static_cast<const RegisteredPrefixId*>(nullptr));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400350 advanceClocks(time::milliseconds(10), 10);
351
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000352 face.unsetInterestFilter(static_cast<const InterestFilterId*>(nullptr));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400353 advanceClocks(time::milliseconds(10), 10);
354}
355
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800356BOOST_FIXTURE_TEST_CASE(SetInterestFilterFail, FacesNoRegistrationReplyFixture)
357{
358 // don't enable registration reply
359 size_t nRegFailed = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800360 face.setInterestFilter("/Hello/World",
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000361 bind([] { BOOST_FAIL("Unexpected Interest"); }),
362 bind([] { BOOST_FAIL("Unexpected success of setInterestFilter"); }),
363 bind([&nRegFailed] { ++nRegFailed; }));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800364
365 advanceClocks(time::milliseconds(10), 10);
366 BOOST_CHECK_EQUAL(nRegFailed, 0);
367
368 advanceClocks(time::milliseconds(1000), 10);
369 BOOST_CHECK_EQUAL(nRegFailed, 1);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400370}
371
Joao Pereira0b3cac52015-07-02 14:49:49 -0400372BOOST_FIXTURE_TEST_CASE(SetInterestFilterFailWithoutSuccessCallback, FacesNoRegistrationReplyFixture)
373{
374 // don't enable registration reply
375 size_t nRegFailed = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800376 face.setInterestFilter("/Hello/World",
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000377 bind([] { BOOST_FAIL("Unexpected Interest"); }),
378 bind([&nRegFailed] { ++nRegFailed; }));
Joao Pereira0b3cac52015-07-02 14:49:49 -0400379
380 advanceClocks(time::milliseconds(10), 10);
381 BOOST_CHECK_EQUAL(nRegFailed, 0);
382
383 advanceClocks(time::milliseconds(1000), 10);
384 BOOST_CHECK_EQUAL(nRegFailed, 1);
385}
386
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400387BOOST_AUTO_TEST_CASE(RegisterUnregisterPrefix)
388{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800389 size_t nRegSuccesses = 0;
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400390 const RegisteredPrefixId* regPrefixId =
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800391 face.registerPrefix("/Hello/World",
392 bind([&nRegSuccesses] { ++nRegSuccesses; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000393 bind([] { BOOST_FAIL("Unexpected registerPrefix failure"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400394
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800395 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400396 BOOST_CHECK_EQUAL(nRegSuccesses, 1);
397
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800398 size_t nUnregSuccesses = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800399 face.unregisterPrefix(regPrefixId,
400 bind([&nUnregSuccesses] { ++nUnregSuccesses; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000401 bind([] { BOOST_FAIL("Unexpected unregisterPrefix failure"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400402
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800403 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400404 BOOST_CHECK_EQUAL(nUnregSuccesses, 1);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400405}
406
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800407BOOST_FIXTURE_TEST_CASE(RegisterUnregisterPrefixFail, FacesNoRegistrationReplyFixture)
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400408{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800409 size_t nRegFailures = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800410 face.registerPrefix("/Hello/World",
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000411 bind([] { BOOST_FAIL("Unexpected registerPrefix success"); }),
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800412 bind([&nRegFailures] { ++nRegFailures; }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400413
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800414 advanceClocks(time::milliseconds(1000), 100);
415 BOOST_CHECK_EQUAL(nRegFailures, 1);
416}
417
418BOOST_AUTO_TEST_CASE(SimilarFilters)
419{
420 size_t nInInterests1 = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800421 face.setInterestFilter("/Hello/World",
422 bind([&nInInterests1] { ++nInInterests1; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000423 nullptr,
424 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800425
426 size_t nInInterests2 = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800427 face.setInterestFilter("/Hello",
428 bind([&nInInterests2] { ++nInInterests2; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000429 nullptr,
430 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400431
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800432 size_t nInInterests3 = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800433 face.setInterestFilter("/Los/Angeles/Lakers",
434 bind([&nInInterests3] { ++nInInterests3; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000435 nullptr,
436 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400437
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800438 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400439
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000440 face.receive(Interest("/Hello/World/%21"));
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800441 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400442
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800443 BOOST_CHECK_EQUAL(nInInterests1, 1);
444 BOOST_CHECK_EQUAL(nInInterests2, 1);
445 BOOST_CHECK_EQUAL(nInInterests3, 0);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400446}
447
448BOOST_AUTO_TEST_CASE(SetRegexFilterError)
449{
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800450 face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
451 [] (const Name&, const Interest&) {
452 BOOST_FAIL("InterestFilter::Error should have been triggered");
453 },
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000454 nullptr,
455 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400456
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800457 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400458
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800459 BOOST_REQUIRE_THROW(face.receive(Interest("/Hello/World/XXX/b/c")), InterestFilter::Error);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400460}
461
462BOOST_AUTO_TEST_CASE(SetRegexFilter)
463{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800464 size_t nInInterests = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800465 face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
466 bind([&nInInterests] { ++nInInterests; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000467 nullptr,
468 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400469
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800470 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400471
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800472 face.receive(Interest("/Hello/World/a")); // shouldn't match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400473 BOOST_CHECK_EQUAL(nInInterests, 0);
474
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800475 face.receive(Interest("/Hello/World/a/b")); // should match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400476 BOOST_CHECK_EQUAL(nInInterests, 1);
477
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800478 face.receive(Interest("/Hello/World/a/b/c")); // should match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400479 BOOST_CHECK_EQUAL(nInInterests, 2);
480
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800481 face.receive(Interest("/Hello/World/a/b/d")); // should not match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400482 BOOST_CHECK_EQUAL(nInInterests, 2);
483}
484
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400485BOOST_AUTO_TEST_CASE(SetRegexFilterAndRegister)
486{
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800487 size_t nInInterests = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800488 face.setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
489 bind([&nInInterests] { ++nInInterests; }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400490
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800491 size_t nRegSuccesses = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800492 face.registerPrefix("/Hello/World",
493 bind([&nRegSuccesses] { ++nRegSuccesses; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000494 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400495
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800496 advanceClocks(time::milliseconds(10), 10);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400497 BOOST_CHECK_EQUAL(nRegSuccesses, 1);
498
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800499 face.receive(Interest("/Hello/World/a")); // shouldn't match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400500 BOOST_CHECK_EQUAL(nInInterests, 0);
501
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800502 face.receive(Interest("/Hello/World/a/b")); // should match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400503 BOOST_CHECK_EQUAL(nInInterests, 1);
504
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800505 face.receive(Interest("/Hello/World/a/b/c")); // should match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400506 BOOST_CHECK_EQUAL(nInInterests, 2);
507
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800508 face.receive(Interest("/Hello/World/a/b/d")); // should not match
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400509 BOOST_CHECK_EQUAL(nInInterests, 2);
510}
511
Junxiao Shia1ea5062014-12-27 22:33:39 -0700512BOOST_FIXTURE_TEST_CASE(SetInterestFilterNoReg, FacesNoRegistrationReplyFixture) // Bug 2318
513{
514 // This behavior is specific to DummyClientFace.
515 // Regular Face won't accept incoming packets until something is sent.
516
517 int hit = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800518 face.setInterestFilter(Name("/"), bind([&hit] { ++hit; }));
519 face.processEvents(time::milliseconds(-1));
Junxiao Shia1ea5062014-12-27 22:33:39 -0700520
521 auto interest = make_shared<Interest>("/A");
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800522 face.receive(*interest);
523 face.processEvents(time::milliseconds(-1));
Junxiao Shia1ea5062014-12-27 22:33:39 -0700524
525 BOOST_CHECK_EQUAL(hit, 1);
526}
527
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000528BOOST_AUTO_TEST_SUITE_END() // Producer
529
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500530BOOST_AUTO_TEST_CASE(ProcessEvents)
531{
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800532 face.processEvents(time::milliseconds(-1)); // io_service::reset()/poll() inside
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500533
Alexander Afanasyevd3a55b22014-11-18 19:23:28 -0800534 size_t nRegSuccesses = 0;
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800535 face.registerPrefix("/Hello/World",
536 bind([&nRegSuccesses] { ++nRegSuccesses; }),
Junxiao Shi103d8ed2016-08-07 20:34:10 +0000537 bind([] { BOOST_FAIL("Unexpected setInterestFilter failure"); }));
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500538
539 // io_service::poll() without reset
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800540 face.getIoService().poll();
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500541 BOOST_CHECK_EQUAL(nRegSuccesses, 0);
542
Alexander Afanasyev9bdbb832015-12-30 12:54:22 -0800543 face.processEvents(time::milliseconds(-1)); // io_service::reset()/poll() inside
Alexander Afanasyev8e158542014-11-18 00:47:18 -0500544 BOOST_CHECK_EQUAL(nRegSuccesses, 1);
545}
546
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -0700547struct PibDirWithDefaultTpm
548{
549 const std::string PATH = "build/keys-with-default-tpm";
550};
551
552BOOST_FIXTURE_TEST_CASE(FaceTransport, PibDirFixture<PibDirWithDefaultTpm>)
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800553{
554 KeyChain keyChain;
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -0700555 boost::asio::io_service io;
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800556
557 BOOST_CHECK(Face().getTransport() != nullptr);
558
Alexander Afanasyevbb64c172015-12-29 20:32:45 -0800559 BOOST_CHECK(Face(shared_ptr<Transport>()).getTransport() != nullptr);
560 BOOST_CHECK(Face(shared_ptr<Transport>(), io).getTransport() != nullptr);
561 BOOST_CHECK(Face(shared_ptr<Transport>(), io, keyChain).getTransport() != nullptr);
Alexander Afanasyev3a6da362015-12-29 20:31:03 -0800562
563 auto transport = make_shared<TcpTransport>("localhost", "6363"); // no real io operations will be scheduled
564 BOOST_CHECK(Face(transport).getTransport() == transport);
565 BOOST_CHECK(Face(transport, io).getTransport() == transport);
566 BOOST_CHECK(Face(transport, io, keyChain).getTransport() == transport);
567}
568
Alexander Afanasyevcf490552016-06-27 22:51:36 -0700569BOOST_AUTO_TEST_SUITE(CustomizeTransport)
570
571class WithEnv : private IdentityManagementTimeFixture
572{
573public:
574 WithEnv()
575 {
576 if (getenv("NDN_CLIENT_TRANSPORT") != nullptr) {
577 m_oldTransport = getenv("NDN_CLIENT_TRANSPORT");
578 unsetenv("NDN_CLIENT_TRANSPORT");
579 }
580 }
581
582 void
583 configure(const std::string& faceUri)
584 {
585 setenv("NDN_CLIENT_TRANSPORT", faceUri.c_str(), true);
586 }
587
588 ~WithEnv()
589 {
590 if (!m_oldTransport.empty()) {
591 setenv("NDN_CLIENT_TRANSPORT", m_oldTransport.c_str(), true);
592 }
593 else {
594 unsetenv("NDN_CLIENT_TRANSPORT");
595 }
596 }
597
598private:
599 std::string m_oldTransport;
600};
601
602class WithConfig : private TestHomeFixture<DefaultPibDir>
603{
604public:
605 void
606 configure(const std::string& faceUri)
607 {
608 createClientConf({"transport=" + faceUri});
609 }
610};
611
612class WithEnvAndConfig : public WithEnv, public WithConfig
613{
614};
615
616typedef boost::mpl::vector<WithEnv, WithConfig> ConfigOptions;
617
618BOOST_FIXTURE_TEST_CASE(NoConfig, WithEnvAndConfig) // fixture configures test HOME and PIB/TPM path
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700619{
620 shared_ptr<Face> face;
621 BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
622 BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700623}
624
Alexander Afanasyevcf490552016-06-27 22:51:36 -0700625BOOST_FIXTURE_TEST_CASE_TEMPLATE(Unix, T, ConfigOptions, T)
626{
627 this->configure("unix://some/path");
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700628
Alexander Afanasyevcf490552016-06-27 22:51:36 -0700629 shared_ptr<Face> face;
630 BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
631 BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
632}
633
634BOOST_FIXTURE_TEST_CASE_TEMPLATE(Tcp, T, ConfigOptions, T)
635{
636 this->configure("tcp://127.0.0.1:6000");
637
638 shared_ptr<Face> face;
639 BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
640 BOOST_CHECK(dynamic_pointer_cast<TcpTransport>(face->getTransport()) != nullptr);
641}
642
643BOOST_FIXTURE_TEST_CASE_TEMPLATE(WrongTransport, T, ConfigOptions, T)
644{
645 this->configure("wrong-transport:");
646
647 BOOST_CHECK_THROW(make_shared<Face>(), ConfigFile::Error);
648}
649
650BOOST_FIXTURE_TEST_CASE_TEMPLATE(WrongUri, T, ConfigOptions, T)
651{
652 this->configure("wrong-uri");
653
654 BOOST_CHECK_THROW(make_shared<Face>(), ConfigFile::Error);
655}
656
657BOOST_FIXTURE_TEST_CASE(EnvOverride, WithEnvAndConfig)
658{
659 this->WithEnv::configure("tcp://127.0.0.1:6000");
660 this->WithConfig::configure("unix://some/path");
661
662 shared_ptr<Face> face;
663 BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
664 BOOST_CHECK(dynamic_pointer_cast<TcpTransport>(face->getTransport()) != nullptr);
665}
666
667BOOST_FIXTURE_TEST_CASE(ExplicitTransport, WithEnvAndConfig)
668{
669 this->WithEnv::configure("wrong-uri");
670 this->WithConfig::configure("wrong-transport:");
671
672 auto transport = make_shared<UnixTransport>("unix://some/path");
673 shared_ptr<Face> face;
674 BOOST_REQUIRE_NO_THROW(face = make_shared<Face>(transport));
675 BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
676}
677
678BOOST_AUTO_TEST_SUITE_END() // CustomizeTransport
Alexander Afanasyev57e00362016-06-23 13:22:54 -0700679BOOST_AUTO_TEST_SUITE_END() // TestFace
680
681} // namespace tests
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400682} // namespace ndn