blob: c0ef54062bb88717158cebb6332bfaf130ed3cc6 [file] [log] [blame]
Yanbiao Lic17de832014-11-21 17:51:45 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California,
4 * 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 "rib/remote-registrator.hpp"
27
28#include "tests/limited-io.hpp"
29#include "tests/identity-management-fixture.hpp"
30#include <ndn-cxx/util/dummy-client-face.hpp>
31
32namespace nfd {
33namespace rib {
34namespace tests {
35
36class RemoteRegistratorFixture : public nfd::tests::IdentityManagementFixture
Yanbiao Lib9d439d2014-12-11 16:12:32 -080037 , public nfd::tests::UnitTestTimeFixture
Yanbiao Lic17de832014-11-21 17:51:45 -080038{
39public:
40 RemoteRegistratorFixture()
Yanbiao Lib9d439d2014-12-11 16:12:32 -080041 : face(ndn::util::makeDummyClientFace(getGlobalIoService()))
Yanbiao Lic17de832014-11-21 17:51:45 -080042 , controller(make_shared<ndn::nfd::Controller>(std::ref(*face), m_keyChain))
43 , remoteRegistrator(make_shared<RemoteRegistrator>(std::ref(*controller),
44 m_keyChain,
45 rib))
46 , COMMAND_PREFIX("/localhop/nfd/rib")
47 , REGISTER_VERB("register")
48 , UNREGISTER_VERB("unregister")
49 {
50 readConfig();
51
Yanbiao Lib9d439d2014-12-11 16:12:32 -080052 remoteRegistrator->enable();
Yanbiao Lic17de832014-11-21 17:51:45 -080053
Yanbiao Lib9d439d2014-12-11 16:12:32 -080054 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -080055 face->sentInterests.clear();
56 }
57
58 void
Yanbiao Lib9d439d2014-12-11 16:12:32 -080059 readConfig(bool isSetRetry = false)
Yanbiao Lic17de832014-11-21 17:51:45 -080060 {
61 ConfigFile config;
62 config.addSectionHandler("remote_register",
63 bind(&RemoteRegistrator::loadConfig, remoteRegistrator, _1));
64
Yanbiao Lic17de832014-11-21 17:51:45 -080065
Yanbiao Lib9d439d2014-12-11 16:12:32 -080066 if (isSetRetry)
67 {
68 const std::string CONFIG_STRING =
69 "remote_register\n"
70 "{\n"
71 " cost 15\n"
72 " timeout 1000\n"
73 " retry 1\n"
74 " refresh_interval 5\n"
75 "}";
76
77 config.parse(CONFIG_STRING, true, "test-remote-register");
78 }
79 else
80 {
81 const std::string CONFIG_STRING =
82 "remote_register\n"
83 "{\n"
84 " cost 15\n"
85 " timeout 100000\n"
86 " retry 0\n"
87 " refresh_interval 5\n"
88 "}";
89
90 config.parse(CONFIG_STRING, true, "test-remote-register");
91 }
Yanbiao Lic17de832014-11-21 17:51:45 -080092 }
93
94 void
Yanbiao Lib9d439d2014-12-11 16:12:32 -080095 waitForTimeout()
Yanbiao Lic17de832014-11-21 17:51:45 -080096 {
Yanbiao Lib9d439d2014-12-11 16:12:32 -080097 advanceClocks(time::milliseconds(100), time::seconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -080098 }
99
100 void
101 insertEntryWithIdentity(Name identity,
102 name::Component appName = DEFAULT_APP_NAME,
103 uint64_t faceId = 0)
104 {
105 BOOST_CHECK_EQUAL(addIdentity(identity), true);
106
107 FaceEntry faceEntry;
108 faceEntry.faceId = faceId;
109
110 rib.insert(identity.append(appName), faceEntry);
111
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800112 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -0800113 }
114
115 void
116 insertEntryWithoutIdentity(Name identity,
117 name::Component appName = DEFAULT_APP_NAME,
118 uint64_t faceId = 0)
119 {
120 FaceEntry faceEntry;
121 faceEntry.faceId = faceId;
122
123 rib.insert(identity.append(appName), faceEntry);
124
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800125 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -0800126 }
127
128 void
129 eraseEntryWithIdentity(Name identity,
130 name::Component appName = DEFAULT_APP_NAME,
131 uint64_t faceId = 0)
132 {
133 BOOST_CHECK_EQUAL(addIdentity(identity), true);
134
135 FaceEntry faceEntry;
136 faceEntry.faceId = faceId;
137
138 rib.erase(identity.append(appName), faceEntry);
139
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800140 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -0800141 }
142
143 void
144 eraseEntryWithoutIdentity(Name identity,
145 name::Component appName = DEFAULT_APP_NAME,
146 uint64_t faceId = 0)
147 {
148 FaceEntry faceEntry;
149 faceEntry.faceId = faceId;
150
151 rib.erase(identity.append(appName), faceEntry);
152
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800153 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -0800154 }
155
156 void
157 eraseFace(uint64_t faceId)
158 {
159 rib.erase(faceId);
160
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800161 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -0800162 }
163
164 void
165 connectToHub()
166 {
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800167 rib.insert(COMMAND_PREFIX, FaceEntry());
Yanbiao Lic17de832014-11-21 17:51:45 -0800168
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800169 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -0800170 }
171
172 void
173 disconnectToHub()
174 {
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800175 rib.erase(COMMAND_PREFIX, FaceEntry());
Yanbiao Lic17de832014-11-21 17:51:45 -0800176
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800177 advanceClocks(time::milliseconds(1));
Yanbiao Lic17de832014-11-21 17:51:45 -0800178 }
179
180 void
181 extractParameters(Interest& interest, Name::Component& verb,
182 ndn::nfd::ControlParameters& extractedParameters)
183 {
184 const Name& name = interest.getName();
185 verb = name[COMMAND_PREFIX.size()];
186 const Name::Component& parameterComponent = name[COMMAND_PREFIX.size() + 1];
187
188 Block rawParameters = parameterComponent.blockFromValue();
189 extractedParameters.wireDecode(rawParameters);
190 }
191
192public:
193 Rib rib;
194 shared_ptr<ndn::util::DummyClientFace> face;
195 shared_ptr<ndn::nfd::Controller> controller;
196 shared_ptr<RemoteRegistrator> remoteRegistrator;
197
198 const Name COMMAND_PREFIX;
199 const name::Component REGISTER_VERB;
200 const name::Component UNREGISTER_VERB;
201
202 static const name::Component DEFAULT_APP_NAME;
203};
204
205const name::Component RemoteRegistratorFixture::DEFAULT_APP_NAME("app");
206
207BOOST_FIXTURE_TEST_SUITE(RemoteRegistrator, RemoteRegistratorFixture)
208
209BOOST_FIXTURE_TEST_CASE(AutoTest, RemoteRegistratorFixture)
210{
211 BOOST_REQUIRE_EQUAL(1, 1);
212}
213
214BOOST_FIXTURE_TEST_CASE(RegisterWithoutConnection, RemoteRegistratorFixture)
215{
216 insertEntryWithIdentity("/remote/register");
217
218 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
219}
220
221BOOST_FIXTURE_TEST_CASE(RegisterWithoutIdentity, RemoteRegistratorFixture)
222{
223 connectToHub();
224
225 insertEntryWithoutIdentity("/remote/register");
226
227 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
228}
229
230BOOST_FIXTURE_TEST_CASE(RegisterWithHubPrefix, RemoteRegistratorFixture)
231{
232 connectToHub();
233
234 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
235}
236
237BOOST_FIXTURE_TEST_CASE(RegisterWithLocalPrefix, RemoteRegistratorFixture)
238{
239 connectToHub();
240
241 insertEntryWithIdentity("/localhost/prefix");
242
243 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
244}
245
246BOOST_FIXTURE_TEST_CASE(RegisterBasic, RemoteRegistratorFixture)
247{
248 connectToHub();
249
250 Name identity("/remote/register");
251 insertEntryWithIdentity(identity);
252
253 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
254
255 Interest& request = face->sentInterests[0];
256
257 ndn::nfd::ControlParameters extractedParameters;
258 Name::Component verb;
259 extractParameters(request, verb, extractedParameters);
260
261 BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
262 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
263}
264
265BOOST_FIXTURE_TEST_CASE(RegisterAdvanced, RemoteRegistratorFixture)
266{
267 connectToHub();
268
269 Name identity("/remote/register");
270 Name identityAddRib("/remote/register/rib");
271 insertEntryWithIdentity(identityAddRib);
272
273 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
274
275 Interest& request = face->sentInterests[0];
276
277 ndn::nfd::ControlParameters extractedParameters;
278 Name::Component verb;
279 extractParameters(request, verb, extractedParameters);
280
281 BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
282 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
283}
284
Yanbiao Lib9d439d2014-12-11 16:12:32 -0800285BOOST_FIXTURE_TEST_CASE(RegisterWithRedundantCallback, RemoteRegistratorFixture)
286{
287 remoteRegistrator->enable();
288
289 connectToHub();
290
291 Name identity("/remote/register");
292 insertEntryWithIdentity(identity);
293
294 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
295
296 Interest& request = face->sentInterests[0];
297
298 ndn::nfd::ControlParameters extractedParameters;
299 Name::Component verb;
300 extractParameters(request, verb, extractedParameters);
301
302 BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
303 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
304}
305
306BOOST_FIXTURE_TEST_CASE(RegisterRetry, RemoteRegistratorFixture)
307{
308 // setRetry
309 readConfig(true);
310
311 connectToHub();
312
313 Name identity("/remote/register");
314 insertEntryWithIdentity(identity);
315
316 waitForTimeout();
317
318 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
319
320 Interest& requestFirst = face->sentInterests[0];
321 Interest& requestSecond = face->sentInterests[1];
322
323 ndn::nfd::ControlParameters extractedParametersFirst, extractedParametersSecond;
324 Name::Component verbFirst, verbSecond;
325 extractParameters(requestFirst, verbFirst, extractedParametersFirst);
326 extractParameters(requestSecond, verbSecond, extractedParametersSecond);
327
328 BOOST_CHECK_EQUAL(verbFirst, REGISTER_VERB);
329 BOOST_CHECK_EQUAL(verbSecond, REGISTER_VERB);
330 BOOST_CHECK_EQUAL(extractedParametersFirst.getName(), identity);
331 BOOST_CHECK_EQUAL(extractedParametersSecond.getName(), identity);
332}
333
Yanbiao Lic17de832014-11-21 17:51:45 -0800334BOOST_FIXTURE_TEST_CASE(UnregisterWithoutInsert, RemoteRegistratorFixture)
335{
336 connectToHub();
337
338 eraseEntryWithIdentity("/remote/register");
339
340 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
341}
342
343BOOST_FIXTURE_TEST_CASE(UnregisterWithoutConnection, RemoteRegistratorFixture)
344{
345 connectToHub();
346
347 disconnectToHub();
348
349 Name indentity("/remote/register");
350 remoteRegistrator->m_regEntries.insert(
351 nfd::rib::RemoteRegistrator::RegisteredEntry(indentity, EventId()));
352
353 eraseEntryWithIdentity(indentity);
354
355 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
356}
357
358BOOST_FIXTURE_TEST_CASE(UnregisterWithoutSuccessfullRegistration,
359 RemoteRegistratorFixture)
360{
361 connectToHub();
362
363 Name identity("/remote/register");
364
365 insertEntryWithIdentity(identity);
366
367 eraseEntryWithIdentity(identity);
368
369 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
370
371 Interest& request = face->sentInterests[0];
372
373 ndn::nfd::ControlParameters extractedParameters;
374 Name::Component verb;
375 extractParameters(request, verb, extractedParameters);
376
377 BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
378 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
379}
380
381BOOST_FIXTURE_TEST_CASE(UnregisterBasic, RemoteRegistratorFixture)
382{
383 connectToHub();
384
385 Name identity("/remote/register");
386
387 insertEntryWithIdentity(identity);
388
389 EventId event;
390
391 remoteRegistrator->m_regEntries.insert(
392 nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
393
394 eraseEntryWithIdentity(identity);
395
396 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
397
398 Interest& request = face->sentInterests[1];
399
400 ndn::nfd::ControlParameters extractedParameters;
401 Name::Component verb;
402 extractParameters(request, verb, extractedParameters);
403
404 BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
405 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
406}
407
408BOOST_FIXTURE_TEST_CASE(UnregisterAdvanced, RemoteRegistratorFixture)
409{
410 connectToHub();
411
412 Name identityShort("/remote/register");
413 Name identityLong("/remote/register/long");
414
415 EventId eventShort;
416 EventId eventLong;
417
418 insertEntryWithIdentity(identityShort, name::Component("appA"));
419
420 remoteRegistrator->m_regEntries.insert(
421 nfd::rib::RemoteRegistrator::RegisteredEntry(identityShort,
422 eventShort));
423
424 insertEntryWithIdentity(identityShort, name::Component("appB"));
425
426 insertEntryWithIdentity(identityLong);
427
428 remoteRegistrator->m_regEntries.insert(
429 nfd::rib::RemoteRegistrator::RegisteredEntry(identityLong,
430 eventLong));
431
432 // two registration commands are generated for identityShort and identityLong
433 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
434
435 eraseEntryWithIdentity(identityShort, name::Component("appA"));
436
437 // no unregistration command is generated as appB also exists
438 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
439
440 eraseEntryWithIdentity(identityShort, name::Component("appB"));
441
442 // one unregistration command is generated for identityShort
443 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 3);
444
445 Interest& request = face->sentInterests[2];
446
447 ndn::nfd::ControlParameters extractedParameters;
448 Name::Component verb;
449 extractParameters(request, verb, extractedParameters);
450
451 BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
452 BOOST_CHECK_EQUAL(extractedParameters.getName(), identityShort);
453}
454
455BOOST_FIXTURE_TEST_CASE(EraseFace, RemoteRegistratorFixture)
456{
457 connectToHub();
458
459 Name identity("/remote/register");
460 uint64_t faceId = 517;
461
462 insertEntryWithIdentity(identity, DEFAULT_APP_NAME, faceId);
463
464 EventId event;
465
466 remoteRegistrator->m_regEntries.insert(
467 nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
468
469 eraseFace(faceId);
470
471 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
472
473 Interest& request = face->sentInterests[1];
474
475 ndn::nfd::ControlParameters extractedParameters;
476 Name::Component verb;
477 extractParameters(request, verb, extractedParameters);
478
479 BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
480 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
481}
482
483BOOST_FIXTURE_TEST_CASE(RebuildConnection, RemoteRegistratorFixture)
484{
485 connectToHub();
486
487 Name identity("/remote/register");
488
489 insertEntryWithIdentity(identity);
490
491 EventId event;
492
493 remoteRegistrator->m_regEntries.insert(
494 nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
495
496 disconnectToHub();
497
498 connectToHub();
499
500 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
501
502 Interest& request1 = face->sentInterests[0];
503 Interest& request2 = face->sentInterests[1];
504
505 ndn::nfd::ControlParameters extractedParameters1, extractedParameters2;
506 Name::Component verb1, verb2;
507 extractParameters(request1, verb1, extractedParameters1);
508 extractParameters(request2, verb2, extractedParameters2);
509
510 BOOST_CHECK_EQUAL(verb1, REGISTER_VERB);
511 BOOST_CHECK_EQUAL(verb2, REGISTER_VERB);
512 BOOST_CHECK_EQUAL(extractedParameters1.getName(),
513 extractedParameters2.getName());
514}
515
516BOOST_AUTO_TEST_SUITE_END()
517
518} // namespace tests
519} // namespace rib
520} // namespace nfd