blob: e0b4d3a1dccc082ce64d9f9a0f521652d3ce0dc2 [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
37{
38public:
39 RemoteRegistratorFixture()
40 : face(ndn::util::makeDummyClientFace())
41 , controller(make_shared<ndn::nfd::Controller>(std::ref(*face), m_keyChain))
42 , remoteRegistrator(make_shared<RemoteRegistrator>(std::ref(*controller),
43 m_keyChain,
44 rib))
45 , COMMAND_PREFIX("/localhop/nfd/rib")
46 , REGISTER_VERB("register")
47 , UNREGISTER_VERB("unregister")
48 {
49 readConfig();
50
51 registerCallback();
52
53 face->processEvents(time::milliseconds(1));
54 face->sentInterests.clear();
55 }
56
57 void
58 readConfig()
59 {
60 ConfigFile config;
61 config.addSectionHandler("remote_register",
62 bind(&RemoteRegistrator::loadConfig, remoteRegistrator, _1));
63
64 const std::string CONFIG_STRING =
65 "remote_register\n"
66 "{\n"
67 " cost 15\n"
68 " timeout 10000\n"
69 " retry 2\n"
70 " refresh_interval 5\n"
71 "}";
72
73 config.parse(CONFIG_STRING, true, "test-remote-register");
74 }
75
76 void
77 registerCallback()
78 {
79 rib.afterInsertEntry += [this] (const Name& prefix) {
80 remoteRegistrator->registerPrefix(prefix);
81 };
82
83 rib.afterEraseEntry += [this] (const Name& prefix) {
84 remoteRegistrator->unregisterPrefix(prefix);
85 };
86 }
87
88 void
89 insertEntryWithIdentity(Name identity,
90 name::Component appName = DEFAULT_APP_NAME,
91 uint64_t faceId = 0)
92 {
93 BOOST_CHECK_EQUAL(addIdentity(identity), true);
94
95 FaceEntry faceEntry;
96 faceEntry.faceId = faceId;
97
98 rib.insert(identity.append(appName), faceEntry);
99
100 face->processEvents(time::milliseconds(1));
101 }
102
103 void
104 insertEntryWithoutIdentity(Name identity,
105 name::Component appName = DEFAULT_APP_NAME,
106 uint64_t faceId = 0)
107 {
108 FaceEntry faceEntry;
109 faceEntry.faceId = faceId;
110
111 rib.insert(identity.append(appName), faceEntry);
112
113 face->processEvents(time::milliseconds(1));
114 }
115
116 void
117 eraseEntryWithIdentity(Name identity,
118 name::Component appName = DEFAULT_APP_NAME,
119 uint64_t faceId = 0)
120 {
121 BOOST_CHECK_EQUAL(addIdentity(identity), true);
122
123 FaceEntry faceEntry;
124 faceEntry.faceId = faceId;
125
126 rib.erase(identity.append(appName), faceEntry);
127
128 face->processEvents(time::milliseconds(1));
129 }
130
131 void
132 eraseEntryWithoutIdentity(Name identity,
133 name::Component appName = DEFAULT_APP_NAME,
134 uint64_t faceId = 0)
135 {
136 FaceEntry faceEntry;
137 faceEntry.faceId = faceId;
138
139 rib.erase(identity.append(appName), faceEntry);
140
141 face->processEvents(time::milliseconds(1));
142 }
143
144 void
145 eraseFace(uint64_t faceId)
146 {
147 rib.erase(faceId);
148
149 face->processEvents(time::milliseconds(1));
150 }
151
152 void
153 connectToHub()
154 {
155 rib.insert(Name("/localhop/nfd"), FaceEntry());
156
157 face->processEvents(time::milliseconds(1));
158 }
159
160 void
161 disconnectToHub()
162 {
163 rib.erase(Name("/localhop/nfd"), FaceEntry());
164
165 face->processEvents(time::milliseconds(1));
166 }
167
168 void
169 extractParameters(Interest& interest, Name::Component& verb,
170 ndn::nfd::ControlParameters& extractedParameters)
171 {
172 const Name& name = interest.getName();
173 verb = name[COMMAND_PREFIX.size()];
174 const Name::Component& parameterComponent = name[COMMAND_PREFIX.size() + 1];
175
176 Block rawParameters = parameterComponent.blockFromValue();
177 extractedParameters.wireDecode(rawParameters);
178 }
179
180public:
181 Rib rib;
182 shared_ptr<ndn::util::DummyClientFace> face;
183 shared_ptr<ndn::nfd::Controller> controller;
184 shared_ptr<RemoteRegistrator> remoteRegistrator;
185
186 const Name COMMAND_PREFIX;
187 const name::Component REGISTER_VERB;
188 const name::Component UNREGISTER_VERB;
189
190 static const name::Component DEFAULT_APP_NAME;
191};
192
193const name::Component RemoteRegistratorFixture::DEFAULT_APP_NAME("app");
194
195BOOST_FIXTURE_TEST_SUITE(RemoteRegistrator, RemoteRegistratorFixture)
196
197BOOST_FIXTURE_TEST_CASE(AutoTest, RemoteRegistratorFixture)
198{
199 BOOST_REQUIRE_EQUAL(1, 1);
200}
201
202BOOST_FIXTURE_TEST_CASE(RegisterWithoutConnection, RemoteRegistratorFixture)
203{
204 insertEntryWithIdentity("/remote/register");
205
206 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
207}
208
209BOOST_FIXTURE_TEST_CASE(RegisterWithoutIdentity, RemoteRegistratorFixture)
210{
211 connectToHub();
212
213 insertEntryWithoutIdentity("/remote/register");
214
215 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
216}
217
218BOOST_FIXTURE_TEST_CASE(RegisterWithHubPrefix, RemoteRegistratorFixture)
219{
220 connectToHub();
221
222 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
223}
224
225BOOST_FIXTURE_TEST_CASE(RegisterWithLocalPrefix, RemoteRegistratorFixture)
226{
227 connectToHub();
228
229 insertEntryWithIdentity("/localhost/prefix");
230
231 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
232}
233
234BOOST_FIXTURE_TEST_CASE(RegisterBasic, RemoteRegistratorFixture)
235{
236 connectToHub();
237
238 Name identity("/remote/register");
239 insertEntryWithIdentity(identity);
240
241 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
242
243 Interest& request = face->sentInterests[0];
244
245 ndn::nfd::ControlParameters extractedParameters;
246 Name::Component verb;
247 extractParameters(request, verb, extractedParameters);
248
249 BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
250 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
251}
252
253BOOST_FIXTURE_TEST_CASE(RegisterAdvanced, RemoteRegistratorFixture)
254{
255 connectToHub();
256
257 Name identity("/remote/register");
258 Name identityAddRib("/remote/register/rib");
259 insertEntryWithIdentity(identityAddRib);
260
261 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
262
263 Interest& request = face->sentInterests[0];
264
265 ndn::nfd::ControlParameters extractedParameters;
266 Name::Component verb;
267 extractParameters(request, verb, extractedParameters);
268
269 BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
270 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
271}
272
273BOOST_FIXTURE_TEST_CASE(UnregisterWithoutInsert, RemoteRegistratorFixture)
274{
275 connectToHub();
276
277 eraseEntryWithIdentity("/remote/register");
278
279 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
280}
281
282BOOST_FIXTURE_TEST_CASE(UnregisterWithoutConnection, RemoteRegistratorFixture)
283{
284 connectToHub();
285
286 disconnectToHub();
287
288 Name indentity("/remote/register");
289 remoteRegistrator->m_regEntries.insert(
290 nfd::rib::RemoteRegistrator::RegisteredEntry(indentity, EventId()));
291
292 eraseEntryWithIdentity(indentity);
293
294 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 0);
295}
296
297BOOST_FIXTURE_TEST_CASE(UnregisterWithoutSuccessfullRegistration,
298 RemoteRegistratorFixture)
299{
300 connectToHub();
301
302 Name identity("/remote/register");
303
304 insertEntryWithIdentity(identity);
305
306 eraseEntryWithIdentity(identity);
307
308 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 1);
309
310 Interest& request = face->sentInterests[0];
311
312 ndn::nfd::ControlParameters extractedParameters;
313 Name::Component verb;
314 extractParameters(request, verb, extractedParameters);
315
316 BOOST_CHECK_EQUAL(verb, REGISTER_VERB);
317 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
318}
319
320BOOST_FIXTURE_TEST_CASE(UnregisterBasic, RemoteRegistratorFixture)
321{
322 connectToHub();
323
324 Name identity("/remote/register");
325
326 insertEntryWithIdentity(identity);
327
328 EventId event;
329
330 remoteRegistrator->m_regEntries.insert(
331 nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
332
333 eraseEntryWithIdentity(identity);
334
335 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
336
337 Interest& request = face->sentInterests[1];
338
339 ndn::nfd::ControlParameters extractedParameters;
340 Name::Component verb;
341 extractParameters(request, verb, extractedParameters);
342
343 BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
344 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
345}
346
347BOOST_FIXTURE_TEST_CASE(UnregisterAdvanced, RemoteRegistratorFixture)
348{
349 connectToHub();
350
351 Name identityShort("/remote/register");
352 Name identityLong("/remote/register/long");
353
354 EventId eventShort;
355 EventId eventLong;
356
357 insertEntryWithIdentity(identityShort, name::Component("appA"));
358
359 remoteRegistrator->m_regEntries.insert(
360 nfd::rib::RemoteRegistrator::RegisteredEntry(identityShort,
361 eventShort));
362
363 insertEntryWithIdentity(identityShort, name::Component("appB"));
364
365 insertEntryWithIdentity(identityLong);
366
367 remoteRegistrator->m_regEntries.insert(
368 nfd::rib::RemoteRegistrator::RegisteredEntry(identityLong,
369 eventLong));
370
371 // two registration commands are generated for identityShort and identityLong
372 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
373
374 eraseEntryWithIdentity(identityShort, name::Component("appA"));
375
376 // no unregistration command is generated as appB also exists
377 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
378
379 eraseEntryWithIdentity(identityShort, name::Component("appB"));
380
381 // one unregistration command is generated for identityShort
382 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 3);
383
384 Interest& request = face->sentInterests[2];
385
386 ndn::nfd::ControlParameters extractedParameters;
387 Name::Component verb;
388 extractParameters(request, verb, extractedParameters);
389
390 BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
391 BOOST_CHECK_EQUAL(extractedParameters.getName(), identityShort);
392}
393
394BOOST_FIXTURE_TEST_CASE(EraseFace, RemoteRegistratorFixture)
395{
396 connectToHub();
397
398 Name identity("/remote/register");
399 uint64_t faceId = 517;
400
401 insertEntryWithIdentity(identity, DEFAULT_APP_NAME, faceId);
402
403 EventId event;
404
405 remoteRegistrator->m_regEntries.insert(
406 nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
407
408 eraseFace(faceId);
409
410 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
411
412 Interest& request = face->sentInterests[1];
413
414 ndn::nfd::ControlParameters extractedParameters;
415 Name::Component verb;
416 extractParameters(request, verb, extractedParameters);
417
418 BOOST_CHECK_EQUAL(verb, UNREGISTER_VERB);
419 BOOST_CHECK_EQUAL(extractedParameters.getName(), identity);
420}
421
422BOOST_FIXTURE_TEST_CASE(RebuildConnection, RemoteRegistratorFixture)
423{
424 connectToHub();
425
426 Name identity("/remote/register");
427
428 insertEntryWithIdentity(identity);
429
430 EventId event;
431
432 remoteRegistrator->m_regEntries.insert(
433 nfd::rib::RemoteRegistrator::RegisteredEntry(identity, event));
434
435 disconnectToHub();
436
437 connectToHub();
438
439 BOOST_REQUIRE_EQUAL(face->sentInterests.size(), 2);
440
441 Interest& request1 = face->sentInterests[0];
442 Interest& request2 = face->sentInterests[1];
443
444 ndn::nfd::ControlParameters extractedParameters1, extractedParameters2;
445 Name::Component verb1, verb2;
446 extractParameters(request1, verb1, extractedParameters1);
447 extractParameters(request2, verb2, extractedParameters2);
448
449 BOOST_CHECK_EQUAL(verb1, REGISTER_VERB);
450 BOOST_CHECK_EQUAL(verb2, REGISTER_VERB);
451 BOOST_CHECK_EQUAL(extractedParameters1.getName(),
452 extractedParameters2.getName());
453}
454
455BOOST_AUTO_TEST_SUITE_END()
456
457} // namespace tests
458} // namespace rib
459} // namespace nfd