blob: 3fcae2e42e350040f0f3153744961bbc784cda65 [file] [log] [blame]
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 Regents of the University of California.
4 *
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"
25
26#include "boost-test.hpp"
Junxiao Shia60d9362014-11-12 09:38:21 -070027#include "util/dummy-client-face.hpp"
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040028
29namespace ndn {
30namespace tests {
31
Junxiao Shia60d9362014-11-12 09:38:21 -070032using ndn::util::DummyClientFace;
33using ndn::util::makeDummyClientFace;
34
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040035class FacesFixture
36{
37public:
Junxiao Shia60d9362014-11-12 09:38:21 -070038 FacesFixture(bool enableRegistrationReply = true)
39 : nData(0)
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040040 , nTimeouts(0)
41 , nInInterests(0)
42 , nInInterests2(0)
43 , nRegSuccesses(0)
44 , nRegFailures(0)
45 , nUnregSuccesses(0)
46 , nUnregFailures(0)
47 {
Junxiao Shia60d9362014-11-12 09:38:21 -070048 DummyClientFace::Options options { true, enableRegistrationReply };
49 this->face = makeDummyClientFace(io, options);
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -040050 }
51
52 void
53 onData()
54 {
55 ++nData;
56 }
57
58 void
59 onTimeout()
60 {
61 ++nTimeouts;
62 }
63
64 void
65 onInterest(Face& face,
66 const Name&, const Interest&)
67 {
68 ++nInInterests;
69 }
70
71 void
72 onInterest2(Face& face,
73 const Name&, const Interest&)
74 {
75 ++nInInterests2;
76 }
77
78 void
79 onInterestRegex(Face& face,
80 const InterestFilter&, const Interest&)
81 {
82 ++nInInterests;
83 }
84
85 void
86 onInterestRegexError(Face& face,
87 const Name&, const Interest&)
88 {
89 BOOST_FAIL("InterestFilter::Error should have been triggered");
90 }
91
92 void
93 onRegSucceeded()
94 {
95 ++nRegSuccesses;
96 }
97
98 void
99 onRegFailed()
100 {
101 ++nRegFailures;
102 }
103
104 void
105 onUnregSucceeded()
106 {
107 ++nUnregSuccesses;
108 }
109
110 void
111 onUnregFailed()
112 {
113 ++nUnregFailures;
114 }
115
116 shared_ptr<Data>
117 makeData(const Name& name)
118 {
119 shared_ptr<Data> data = make_shared<Data>("/Hello/World/!");
120 static KeyChain keyChain;
121 keyChain.signWithSha256(*data);
122 return data;
123 }
124
125 boost::asio::io_service io;
126 shared_ptr<DummyClientFace> face;
127
128 uint32_t nData;
129 uint32_t nTimeouts;
130
131 uint32_t nInInterests;
132 uint32_t nInInterests2;
133 uint32_t nRegSuccesses;
134 uint32_t nRegFailures;
135 uint32_t nUnregSuccesses;
136 uint32_t nUnregFailures;
137};
138
Junxiao Shia60d9362014-11-12 09:38:21 -0700139class FacesNoRegistrationReplyFixture : public FacesFixture
140{
141public:
142 FacesNoRegistrationReplyFixture()
143 : FacesFixture(false)
144 {
145 }
146};
147
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400148BOOST_FIXTURE_TEST_SUITE(TestFaces, FacesFixture)
149
150BOOST_AUTO_TEST_CASE(ExpressInterestData)
151{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400152 face->expressInterest(Interest("/Hello/World", time::milliseconds(50)),
153 bind(&FacesFixture::onData, this),
154 bind(&FacesFixture::onTimeout, this));
155
156 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
157
158 face->receive(*makeData("/Hello/World/!"));
159 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(200)));
160
161 BOOST_CHECK_EQUAL(nData, 1);
162 BOOST_CHECK_EQUAL(nTimeouts, 0);
163}
164
165BOOST_AUTO_TEST_CASE(ExpressInterestTimeout)
166{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400167 face->expressInterest(Interest("/Hello/World", time::milliseconds(50)),
168 bind(&FacesFixture::onData, this),
169 bind(&FacesFixture::onTimeout, this));
170
171 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(200)));
172
173 BOOST_CHECK_EQUAL(nData, 0);
174 BOOST_CHECK_EQUAL(nTimeouts, 1);
175}
176
177BOOST_AUTO_TEST_CASE(SetFilter)
178{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400179 face->setInterestFilter("/Hello/World",
180 bind(&FacesFixture::onInterest, this, ref(*face), _1, _2),
181 RegisterPrefixSuccessCallback(),
182 bind(&FacesFixture::onRegFailed, this));
183
184 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
185
186 face->receive(Interest("/Hello/World/!"));
187 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
188
189 BOOST_CHECK_EQUAL(nRegFailures, 0);
190 BOOST_CHECK_EQUAL(nInInterests, 1);
191}
192
Junxiao Shia60d9362014-11-12 09:38:21 -0700193BOOST_FIXTURE_TEST_CASE(SetFilterFail, FacesNoRegistrationReplyFixture)
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400194{
195 // don't enable registration reply
196
197 face->setInterestFilter("/Hello/World",
198 bind(&FacesFixture::onInterest, this, ref(*face), _1, _2),
199 RegisterPrefixSuccessCallback(),
200 bind(&FacesFixture::onRegFailed, this));
201
202 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(11000)));
203
204 BOOST_CHECK_EQUAL(nRegFailures, 1);
205}
206
207BOOST_AUTO_TEST_CASE(SetUnsetInterestFilter)
208{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400209 const RegisteredPrefixId* regPrefixId =
210 face->setInterestFilter(InterestFilter("/Hello/World"),
211 bind(&FacesFixture::onInterest, this,
212 ref(*face), _1, _2),
213 RegisterPrefixSuccessCallback(),
214 bind(&FacesFixture::onRegFailed, this));
215 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
216
217 face->receive(Interest("/Hello/World/!"));
218 BOOST_CHECK_EQUAL(nInInterests, 1);
219
220 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
221
222 face->receive(Interest("/Hello/World/!"));
223 BOOST_CHECK_EQUAL(nInInterests, 2);
224
225 face->unsetInterestFilter(regPrefixId);
226
227 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
228
229 face->receive(Interest("/Hello/World/!"));
230 BOOST_CHECK_EQUAL(nInInterests, 2);
231
232 BOOST_CHECK_NO_THROW(face->unsetInterestFilter(static_cast<const RegisteredPrefixId*>(0)));
233 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
234
235 BOOST_CHECK_NO_THROW(face->unsetInterestFilter(static_cast<const InterestFilterId*>(0)));
236 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
237}
238
239BOOST_AUTO_TEST_CASE(RegisterUnregisterPrefix)
240{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400241 const RegisteredPrefixId* regPrefixId =
242 face->registerPrefix("/Hello/World",
243 bind(&FacesFixture::onRegSucceeded, this),
244 bind(&FacesFixture::onRegFailed, this));
245
246 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
247 BOOST_CHECK_EQUAL(nRegFailures, 0);
248 BOOST_CHECK_EQUAL(nRegSuccesses, 1);
249
250 face->unregisterPrefix(regPrefixId,
251 bind(&FacesFixture::onUnregSucceeded, this),
252 bind(&FacesFixture::onUnregFailed, this));
253
254 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
255 BOOST_CHECK_EQUAL(nUnregFailures, 0);
256 BOOST_CHECK_EQUAL(nUnregSuccesses, 1);
257
258}
259
260BOOST_AUTO_TEST_CASE(SeTwoSimilarFilters)
261{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400262 face->setInterestFilter("/Hello/World",
263 bind(&FacesFixture::onInterest, this, ref(*face), _1, _2),
264 RegisterPrefixSuccessCallback(),
265 bind(&FacesFixture::onRegFailed, this));
266
267 face->setInterestFilter("/Hello",
268 bind(&FacesFixture::onInterest2, this, ref(*face), _1, _2),
269 RegisterPrefixSuccessCallback(),
270 bind(&FacesFixture::onRegFailed, this));
271
272 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
273
274 face->receive(Interest("/Hello/World/!"));
275
276 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
277
278 BOOST_CHECK_EQUAL(nRegFailures, 0);
279 BOOST_CHECK_EQUAL(nInInterests, 1);
280 BOOST_CHECK_EQUAL(nInInterests2, 1);
281}
282
283BOOST_AUTO_TEST_CASE(SetTwoDifferentFilters)
284{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400285 face->setInterestFilter("/Hello/World",
286 bind(&FacesFixture::onInterest, this, ref(*face), _1, _2),
287 RegisterPrefixSuccessCallback(),
288 bind(&FacesFixture::onRegFailed, this));
289
290 face->setInterestFilter("/Los/Angeles/Lakers",
291 bind(&FacesFixture::onInterest2, this, ref(*face), _1, _2),
292 RegisterPrefixSuccessCallback(),
293 bind(&FacesFixture::onRegFailed, this));
294
295 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
296
297 face->receive(Interest("/Hello/World/!"));
298
299 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
300
301 BOOST_CHECK_EQUAL(nRegFailures, 0);
302 BOOST_CHECK_EQUAL(nInInterests, 1);
303 BOOST_CHECK_EQUAL(nInInterests2, 0);
304}
305
306BOOST_AUTO_TEST_CASE(SetRegexFilterError)
307{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400308 face->setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
309 bind(&FacesFixture::onInterestRegexError, this,
310 ref(*face), _1, _2),
311 RegisterPrefixSuccessCallback(),
312 bind(&FacesFixture::onRegFailed, this));
313
314 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
315
316 BOOST_REQUIRE_THROW(face->receive(Interest("/Hello/World/XXX/b/c")), InterestFilter::Error);
317}
318
319BOOST_AUTO_TEST_CASE(SetRegexFilter)
320{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400321 face->setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
322 bind(&FacesFixture::onInterestRegex, this,
323 ref(*face), _1, _2),
324 RegisterPrefixSuccessCallback(),
325 bind(&FacesFixture::onRegFailed, this));
326
327 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
328
329 face->receive(Interest("/Hello/World/a")); // shouldn't match
330 BOOST_CHECK_EQUAL(nInInterests, 0);
331
332 face->receive(Interest("/Hello/World/a/b")); // should match
333 BOOST_CHECK_EQUAL(nInInterests, 1);
334
335 face->receive(Interest("/Hello/World/a/b/c")); // should match
336 BOOST_CHECK_EQUAL(nInInterests, 2);
337
338 face->receive(Interest("/Hello/World/a/b/d")); // should not match
339 BOOST_CHECK_EQUAL(nInInterests, 2);
340}
341
342
343BOOST_AUTO_TEST_CASE(SetRegexFilterAndRegister)
344{
Alexander Afanasyev5fc795f2014-10-20 23:06:56 -0400345 face->setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
346 bind(&FacesFixture::onInterestRegex, this,
347 ref(*face), _1, _2));
348
349 face->registerPrefix("/Hello/World",
350 bind(&FacesFixture::onRegSucceeded, this),
351 bind(&FacesFixture::onRegFailed, this));
352
353 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
354 BOOST_CHECK_EQUAL(nRegFailures, 0);
355 BOOST_CHECK_EQUAL(nRegSuccesses, 1);
356
357 face->receive(Interest("/Hello/World/a")); // shouldn't match
358 BOOST_CHECK_EQUAL(nInInterests, 0);
359
360 face->receive(Interest("/Hello/World/a/b")); // should match
361 BOOST_CHECK_EQUAL(nInInterests, 1);
362
363 face->receive(Interest("/Hello/World/a/b/c")); // should match
364 BOOST_CHECK_EQUAL(nInInterests, 2);
365
366 face->receive(Interest("/Hello/World/a/b/d")); // should not match
367 BOOST_CHECK_EQUAL(nInInterests, 2);
368}
369
370BOOST_AUTO_TEST_SUITE_END()
371
372} // tests
373} // namespace ndn