blob: f5b45f1ebd0d45f1bb59b7f801bb9fe5beab84f4 [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"
27
28#include "dummy-client-face.hpp"
29
30namespace ndn {
31namespace tests {
32
33class FacesFixture
34{
35public:
36 FacesFixture()
37 : face(makeDummyClientFace(io))
38 , nData(0)
39 , nTimeouts(0)
40 , nInInterests(0)
41 , nInInterests2(0)
42 , nRegSuccesses(0)
43 , nRegFailures(0)
44 , nUnregSuccesses(0)
45 , nUnregFailures(0)
46 {
47 }
48
49 void
50 onData()
51 {
52 ++nData;
53 }
54
55 void
56 onTimeout()
57 {
58 ++nTimeouts;
59 }
60
61 void
62 onInterest(Face& face,
63 const Name&, const Interest&)
64 {
65 ++nInInterests;
66 }
67
68 void
69 onInterest2(Face& face,
70 const Name&, const Interest&)
71 {
72 ++nInInterests2;
73 }
74
75 void
76 onInterestRegex(Face& face,
77 const InterestFilter&, const Interest&)
78 {
79 ++nInInterests;
80 }
81
82 void
83 onInterestRegexError(Face& face,
84 const Name&, const Interest&)
85 {
86 BOOST_FAIL("InterestFilter::Error should have been triggered");
87 }
88
89 void
90 onRegSucceeded()
91 {
92 ++nRegSuccesses;
93 }
94
95 void
96 onRegFailed()
97 {
98 ++nRegFailures;
99 }
100
101 void
102 onUnregSucceeded()
103 {
104 ++nUnregSuccesses;
105 }
106
107 void
108 onUnregFailed()
109 {
110 ++nUnregFailures;
111 }
112
113 shared_ptr<Data>
114 makeData(const Name& name)
115 {
116 shared_ptr<Data> data = make_shared<Data>("/Hello/World/!");
117 static KeyChain keyChain;
118 keyChain.signWithSha256(*data);
119 return data;
120 }
121
122 boost::asio::io_service io;
123 shared_ptr<DummyClientFace> face;
124
125 uint32_t nData;
126 uint32_t nTimeouts;
127
128 uint32_t nInInterests;
129 uint32_t nInInterests2;
130 uint32_t nRegSuccesses;
131 uint32_t nRegFailures;
132 uint32_t nUnregSuccesses;
133 uint32_t nUnregFailures;
134};
135
136BOOST_FIXTURE_TEST_SUITE(TestFaces, FacesFixture)
137
138BOOST_AUTO_TEST_CASE(ExpressInterestData)
139{
140 face->enableRegistrationReply();
141
142 face->expressInterest(Interest("/Hello/World", time::milliseconds(50)),
143 bind(&FacesFixture::onData, this),
144 bind(&FacesFixture::onTimeout, this));
145
146 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
147
148 face->receive(*makeData("/Hello/World/!"));
149 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(200)));
150
151 BOOST_CHECK_EQUAL(nData, 1);
152 BOOST_CHECK_EQUAL(nTimeouts, 0);
153}
154
155BOOST_AUTO_TEST_CASE(ExpressInterestTimeout)
156{
157 face->enableRegistrationReply();
158
159 face->expressInterest(Interest("/Hello/World", time::milliseconds(50)),
160 bind(&FacesFixture::onData, this),
161 bind(&FacesFixture::onTimeout, this));
162
163 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(200)));
164
165 BOOST_CHECK_EQUAL(nData, 0);
166 BOOST_CHECK_EQUAL(nTimeouts, 1);
167}
168
169BOOST_AUTO_TEST_CASE(SetFilter)
170{
171 face->enableRegistrationReply();
172
173 face->setInterestFilter("/Hello/World",
174 bind(&FacesFixture::onInterest, this, ref(*face), _1, _2),
175 RegisterPrefixSuccessCallback(),
176 bind(&FacesFixture::onRegFailed, this));
177
178 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
179
180 face->receive(Interest("/Hello/World/!"));
181 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
182
183 BOOST_CHECK_EQUAL(nRegFailures, 0);
184 BOOST_CHECK_EQUAL(nInInterests, 1);
185}
186
187BOOST_AUTO_TEST_CASE(SetFilterFail)
188{
189 // don't enable registration reply
190
191 face->setInterestFilter("/Hello/World",
192 bind(&FacesFixture::onInterest, this, ref(*face), _1, _2),
193 RegisterPrefixSuccessCallback(),
194 bind(&FacesFixture::onRegFailed, this));
195
196 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(11000)));
197
198 BOOST_CHECK_EQUAL(nRegFailures, 1);
199}
200
201BOOST_AUTO_TEST_CASE(SetUnsetInterestFilter)
202{
203 face->enableRegistrationReply();
204
205 const RegisteredPrefixId* regPrefixId =
206 face->setInterestFilter(InterestFilter("/Hello/World"),
207 bind(&FacesFixture::onInterest, this,
208 ref(*face), _1, _2),
209 RegisterPrefixSuccessCallback(),
210 bind(&FacesFixture::onRegFailed, this));
211 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
212
213 face->receive(Interest("/Hello/World/!"));
214 BOOST_CHECK_EQUAL(nInInterests, 1);
215
216 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
217
218 face->receive(Interest("/Hello/World/!"));
219 BOOST_CHECK_EQUAL(nInInterests, 2);
220
221 face->unsetInterestFilter(regPrefixId);
222
223 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
224
225 face->receive(Interest("/Hello/World/!"));
226 BOOST_CHECK_EQUAL(nInInterests, 2);
227
228 BOOST_CHECK_NO_THROW(face->unsetInterestFilter(static_cast<const RegisteredPrefixId*>(0)));
229 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
230
231 BOOST_CHECK_NO_THROW(face->unsetInterestFilter(static_cast<const InterestFilterId*>(0)));
232 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
233}
234
235BOOST_AUTO_TEST_CASE(RegisterUnregisterPrefix)
236{
237 face->enableRegistrationReply();
238
239 const RegisteredPrefixId* regPrefixId =
240 face->registerPrefix("/Hello/World",
241 bind(&FacesFixture::onRegSucceeded, this),
242 bind(&FacesFixture::onRegFailed, this));
243
244 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
245 BOOST_CHECK_EQUAL(nRegFailures, 0);
246 BOOST_CHECK_EQUAL(nRegSuccesses, 1);
247
248 face->unregisterPrefix(regPrefixId,
249 bind(&FacesFixture::onUnregSucceeded, this),
250 bind(&FacesFixture::onUnregFailed, this));
251
252 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
253 BOOST_CHECK_EQUAL(nUnregFailures, 0);
254 BOOST_CHECK_EQUAL(nUnregSuccesses, 1);
255
256}
257
258BOOST_AUTO_TEST_CASE(SeTwoSimilarFilters)
259{
260 face->enableRegistrationReply();
261
262 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{
285 face->enableRegistrationReply();
286
287 face->setInterestFilter("/Hello/World",
288 bind(&FacesFixture::onInterest, this, ref(*face), _1, _2),
289 RegisterPrefixSuccessCallback(),
290 bind(&FacesFixture::onRegFailed, this));
291
292 face->setInterestFilter("/Los/Angeles/Lakers",
293 bind(&FacesFixture::onInterest2, this, ref(*face), _1, _2),
294 RegisterPrefixSuccessCallback(),
295 bind(&FacesFixture::onRegFailed, this));
296
297 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
298
299 face->receive(Interest("/Hello/World/!"));
300
301 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
302
303 BOOST_CHECK_EQUAL(nRegFailures, 0);
304 BOOST_CHECK_EQUAL(nInInterests, 1);
305 BOOST_CHECK_EQUAL(nInInterests2, 0);
306}
307
308BOOST_AUTO_TEST_CASE(SetRegexFilterError)
309{
310 face->enableRegistrationReply();
311
312 face->setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
313 bind(&FacesFixture::onInterestRegexError, this,
314 ref(*face), _1, _2),
315 RegisterPrefixSuccessCallback(),
316 bind(&FacesFixture::onRegFailed, this));
317
318 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
319
320 BOOST_REQUIRE_THROW(face->receive(Interest("/Hello/World/XXX/b/c")), InterestFilter::Error);
321}
322
323BOOST_AUTO_TEST_CASE(SetRegexFilter)
324{
325 face->enableRegistrationReply();
326
327 face->setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
328 bind(&FacesFixture::onInterestRegex, this,
329 ref(*face), _1, _2),
330 RegisterPrefixSuccessCallback(),
331 bind(&FacesFixture::onRegFailed, this));
332
333 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(-100)));
334
335 face->receive(Interest("/Hello/World/a")); // shouldn't match
336 BOOST_CHECK_EQUAL(nInInterests, 0);
337
338 face->receive(Interest("/Hello/World/a/b")); // should match
339 BOOST_CHECK_EQUAL(nInInterests, 1);
340
341 face->receive(Interest("/Hello/World/a/b/c")); // should match
342 BOOST_CHECK_EQUAL(nInInterests, 2);
343
344 face->receive(Interest("/Hello/World/a/b/d")); // should not match
345 BOOST_CHECK_EQUAL(nInInterests, 2);
346}
347
348
349BOOST_AUTO_TEST_CASE(SetRegexFilterAndRegister)
350{
351 face->enableRegistrationReply();
352
353 face->setInterestFilter(InterestFilter("/Hello/World", "<><b><c>?"),
354 bind(&FacesFixture::onInterestRegex, this,
355 ref(*face), _1, _2));
356
357 face->registerPrefix("/Hello/World",
358 bind(&FacesFixture::onRegSucceeded, this),
359 bind(&FacesFixture::onRegFailed, this));
360
361 BOOST_REQUIRE_NO_THROW(face->processEvents(time::milliseconds(100)));
362 BOOST_CHECK_EQUAL(nRegFailures, 0);
363 BOOST_CHECK_EQUAL(nRegSuccesses, 1);
364
365 face->receive(Interest("/Hello/World/a")); // shouldn't match
366 BOOST_CHECK_EQUAL(nInInterests, 0);
367
368 face->receive(Interest("/Hello/World/a/b")); // should match
369 BOOST_CHECK_EQUAL(nInInterests, 1);
370
371 face->receive(Interest("/Hello/World/a/b/c")); // should match
372 BOOST_CHECK_EQUAL(nInInterests, 2);
373
374 face->receive(Interest("/Hello/World/a/b/d")); // should not match
375 BOOST_CHECK_EQUAL(nInInterests, 2);
376}
377
378BOOST_AUTO_TEST_SUITE_END()
379
380} // tests
381} // namespace ndn