blob: d675d1869b7c6766ba93146ef43572b1d26e00e7 [file] [log] [blame]
Jiewen Tan99135962014-09-20 02:18:53 -07001/* -*- 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 "util/in-memory-storage-persistent.hpp"
23#include "util/in-memory-storage-fifo.hpp"
24#include "util/in-memory-storage-lfu.hpp"
25#include "util/in-memory-storage-lru.hpp"
26#include "security/key-chain.hpp"
27
28#include "boost-test.hpp"
29#include "../test-make-interest-data.hpp"
30
31#include <boost/mpl/list.hpp>
32
33namespace ndn {
34namespace util {
35
36typedef boost::mpl::list<InMemoryStoragePersistent, InMemoryStorageFifo, InMemoryStorageLfu,
37 InMemoryStorageLru> InMemoryStorages;
38
39BOOST_AUTO_TEST_SUITE(UtilInMemoryStorageTemplate)
40
41BOOST_AUTO_TEST_CASE_TEMPLATE(Insertion, T, InMemoryStorages)
42{
43 T ims;
44
45 ims.insert(*makeData("/insertion"));
46}
47
48BOOST_AUTO_TEST_CASE_TEMPLATE(Insertion2, T, InMemoryStorages)
49{
50 T ims;
51
52 ims.insert(*makeData("/a"));
53 ims.insert(*makeData("/b"));
54 ims.insert(*makeData("/c"));
55 ims.insert(*makeData("/d"));
56
57 BOOST_CHECK_EQUAL(ims.size(), 4);
58}
59
60BOOST_AUTO_TEST_CASE_TEMPLATE(Insertion3, T, InMemoryStorages)
61{
62 T ims;
63
64 Name name("/a");
65
66 uint32_t content1 = 1;
67 shared_ptr<Data> data1 = makeData(name);
68 data1->setFreshnessPeriod(time::milliseconds(99999));
69 data1->setContent(reinterpret_cast<const uint8_t*>(&content1), sizeof(content1));
70 signData(data1);
71 ims.insert(*data1);
72
73 uint32_t content2 = 2;
74 shared_ptr<Data> data2 = makeData(name);
75 data2->setFreshnessPeriod(time::milliseconds(99999));
76 data2->setContent(reinterpret_cast<const uint8_t*>(&content2), sizeof(content2));
77 signData(data2);
78 ims.insert(*data2);
79
80 BOOST_CHECK_EQUAL(ims.size(), 2);
81}
82
83BOOST_AUTO_TEST_CASE_TEMPLATE(DuplicateInsertion, T, InMemoryStorages)
84{
85 T ims;
86
87 shared_ptr<Data> data0 = makeData("/insert/smth");
88 ims.insert(*data0);
89
90 shared_ptr<Data> data = makeData("/insert/duplicate");
91 ims.insert(*data);
92
93 ims.insert(*data);
94 BOOST_CHECK_EQUAL(ims.size(), 2);
95}
96
97BOOST_AUTO_TEST_CASE_TEMPLATE(DuplicateInsertion2, T, InMemoryStorages)
98{
99 T ims;
100
101 shared_ptr<Data> data = makeData("/insert/duplicate");
102 ims.insert(*data);
103
104 ims.insert(*data);
105 BOOST_CHECK_EQUAL(ims.size(), 1);
106
107 shared_ptr<Data> data2 = makeData("/insert/original");
108 ims.insert(*data2);
109 BOOST_CHECK_EQUAL(ims.size(), 2);
110}
111
112BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndFind, T, InMemoryStorages)
113{
114 T ims;
115
116 Name name("/insert/and/find");
117
118 shared_ptr<Data> data = makeData(name);
119 ims.insert(*data);
120
121 shared_ptr<Interest> interest = makeInterest(name);
122
123 shared_ptr<const Data> found = ims.find(*interest);
124
125 BOOST_CHECK(static_cast<bool>(found));
126 BOOST_CHECK_EQUAL(data->getName(), found->getName());
127}
128
129BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndNotFind, T, InMemoryStorages)
130{
131 T ims;
132
133 Name name("/insert/and/find");
134 shared_ptr<Data> data = makeData(name);
135 ims.insert(*data);
136
137 Name name2("/not/find");
138 shared_ptr<Interest> interest = makeInterest(name2);
139
140 shared_ptr<const Data> found = ims.find(*interest);
141
142 BOOST_CHECK_EQUAL(found.get(), static_cast<const Data*>(0));
143}
144
145BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndFindByName, T, InMemoryStorages)
146{
147 T ims;
148
149 Name name("/insert/and/find");
150
151 shared_ptr<Data> data = makeData(name);
152 ims.insert(*data);
153
154 shared_ptr<const Data> found = ims.find(name);
155
156 BOOST_CHECK(static_cast<bool>(found));
157 BOOST_CHECK_EQUAL(data->getName(), found->getName());
158}
159
160BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndFindByFullName, T, InMemoryStorages)
161{
162 T ims;
163
164 Name name("/insert/and/find");
165
166 shared_ptr<Data> data = makeData(name);
167 ims.insert(*data);
168
169 shared_ptr<const Data> found = ims.find(data->getFullName());
170
171 BOOST_CHECK(static_cast<bool>(found));
172 BOOST_CHECK_EQUAL(data->getFullName(), found->getFullName());
173}
174
175BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndNotFindByName, T, InMemoryStorages)
176{
177 T ims;
178
179 Name name("/insert/and/find");
180 shared_ptr<Data> data = makeData(name);
181 ims.insert(*data);
182
183 Name name2("/not/find");
184
185 shared_ptr<const Data> found = ims.find(name2);
186
187 BOOST_CHECK(!static_cast<bool>(found));
188}
189
190BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndNotFindByFullName, T, InMemoryStorages)
191{
192 T ims;
193
194 Name name("/a");
195 uint32_t content1 = 1;
196 shared_ptr<Data> data1 = makeData(name);
197 data1->setContent(reinterpret_cast<const uint8_t*>(&content1), sizeof(content1));
198 signData(data1);
199 ims.insert(*data1);
200
201 uint32_t content2 = 2;
202 shared_ptr<Data> data2 = makeData(name);
203 data2->setContent(reinterpret_cast<const uint8_t*>(&content2), sizeof(content2));
204 signData(data2);
205
206 shared_ptr<const Data> found = ims.find(data2->getFullName());
207
208 BOOST_CHECK(!static_cast<bool>(found));
209}
210
211BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndEraseByName, T, InMemoryStorages)
212{
213 T ims;
214
215 Name name("/insertandremovebyname");
216
217 uint32_t content1 = 1;
218 shared_ptr<Data> data1 = makeData(name);
219 data1->setFreshnessPeriod(time::milliseconds(99999));
220 data1->setContent(reinterpret_cast<const uint8_t*>(&content1), sizeof(content1));
221 signData(data1);
222 ims.insert(*data1);
223
224 uint32_t content2 = 2;
225 shared_ptr<Data> data2 = makeData(name);
226 data2->setFreshnessPeriod(time::milliseconds(99999));
227 data2->setContent(reinterpret_cast<const uint8_t*>(&content2), sizeof(content2));
228 signData(data2);
229 ims.insert(*data2);
230
231 shared_ptr<Data> data3 = makeData("/insertandremovebyname/1");
232 ims.insert(*data3);
233
234 shared_ptr<Data> data4 = makeData("/insertandremovebyname/2");
235 ims.insert(*data4);
236
237 BOOST_CHECK_EQUAL(ims.size(), 4);
238
239 ims.erase(data1->getFullName(), false);
240 BOOST_CHECK_EQUAL(ims.size(), 3);
241}
242
243BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndEraseByPrefix, T, InMemoryStorages)
244{
245 T ims;
246
247 shared_ptr<Data> data = makeData("/a");
248 ims.insert(*data);
249
250 shared_ptr<Data> data2 = makeData("/b");
251 ims.insert(*data2);
252
253 shared_ptr<Data> data3 = makeData("/c");
254 ims.insert(*data3);
255
256 shared_ptr<Data> data4 = makeData("/d");
257 ims.insert(*data4);
258
259 shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
260 ims.insert(*data5);
261
262 shared_ptr<Data> data6 = makeData("/c/c/1/2/3");
263 ims.insert(*data6);
264
265 shared_ptr<Data> data7 = makeData("/c/c/1");
266 ims.insert(*data7);
267
268 BOOST_CHECK_EQUAL(ims.size(), 7);
269
270 Name name("/c");
271 ims.erase(name);
272 BOOST_CHECK_EQUAL(ims.size(), 3);
273 BOOST_CHECK_EQUAL(ims.getCapacity(), 5);
274}
275
276BOOST_AUTO_TEST_CASE_TEMPLATE(DigestCalculation, T, InMemoryStorages)
277{
278 shared_ptr<Data> data = makeData("/digest/compute");
279
280 ndn::ConstBufferPtr digest1 = ndn::crypto::sha256(data->wireEncode().wire(),
281 data->wireEncode().size());
282 BOOST_CHECK_EQUAL(digest1->size(), 32);
283
284 InMemoryStorageEntry* entry = new InMemoryStorageEntry();
285 entry->setData(*data);
286
287 BOOST_CHECK_EQUAL_COLLECTIONS(digest1->begin(), digest1->end(),
288 entry->getFullName()[-1].value_begin(),
289 entry->getFullName()[-1].value_end());
290}
291
292BOOST_AUTO_TEST_CASE_TEMPLATE(Iterator, T, InMemoryStorages)
293{
294 T ims;
295
296 BOOST_CONCEPT_ASSERT((boost::InputIterator<InMemoryStorage::const_iterator>));
297
298 for (int i = 0; i < 10; i++) {
299 std::ostringstream convert;
300 convert << i;
301 Name name("/" + convert.str());
302 shared_ptr<Data> data = makeData(name);
303 ims.insert(*data);
304 }
305
306 InMemoryStorage::const_iterator it = ims.begin();
307 InMemoryStorage::const_iterator tmp1 = it;
308 BOOST_REQUIRE(tmp1 == it);
309 InMemoryStorage::const_iterator tmp2 = tmp1++;
310 BOOST_REQUIRE(tmp2 != tmp1);
311 tmp2 = ++tmp1;
312 BOOST_REQUIRE(tmp2 == tmp1);
313
314 int i = 0;
315 for (;it != ims.end(); it++) {
316 std::ostringstream convert;
317 convert << i;
318 Name name("/" + convert.str());
319 BOOST_CHECK_EQUAL(it->getName(), name);
320 BOOST_CHECK_EQUAL((*it).getName(), name);
321 i++;
322 }
323}
324
325BOOST_AUTO_TEST_CASE_TEMPLATE(InsertCanonical, T, InMemoryStorages)
326{
327 T ims;
328
329 shared_ptr<Data> data = makeData("/a");
330 ims.insert(*data);
331
332 shared_ptr<Data> data2 = makeData("/b");
333 ims.insert(*data2);
334
335 shared_ptr<Data> data3 = makeData("/c");
336 ims.insert(*data3);
337
338 shared_ptr<Data> data4 = makeData("/d");
339 ims.insert(*data4);
340
341 shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
342 ims.insert(*data5);
343
344 shared_ptr<Data> data6 = makeData("/c/c/1/2/3");
345 ims.insert(*data6);
346
347 shared_ptr<Data> data7 = makeData("/c/c/1");
348 ims.insert(*data7);
349}
350
351BOOST_AUTO_TEST_CASE_TEMPLATE(EraseCanonical, T, InMemoryStorages)
352{
353 T ims;
354
355 shared_ptr<Data> data = makeData("/a");
356 ims.insert(*data);
357
358 shared_ptr<Data> data2 = makeData("/b");
359 ims.insert(*data2);
360
361 shared_ptr<Data> data3 = makeData("/c");
362 ims.insert(*data3);
363
364 shared_ptr<Data> data4 = makeData("/d");
365 ims.insert(*data4);
366
367 shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
368 ims.insert(*data5);
369
370 shared_ptr<Data> data6 = makeData("/c/c/1/2/3");
371 ims.insert(*data6);
372
373 shared_ptr<Data> data7 = makeData("/c/c/1");
374 ims.insert(*data7);
375
376 ndn::ConstBufferPtr digest1 = ndn::crypto::sha256(data->wireEncode().wire(),
377 data->wireEncode().size());
378
379 Name name("/a");
380 ims.erase(name);
381 BOOST_CHECK_EQUAL(ims.size(), 6);
382}
383
384BOOST_AUTO_TEST_CASE_TEMPLATE(ImplicitDigestSelector, T, InMemoryStorages)
385{
386 T ims;
387
388 Name name("/digest/works");
389 shared_ptr<Data> data = makeData(name);
390 ims.insert(*data);
391
392 shared_ptr<Data> data2 = makeData("/a");
393 ims.insert(*data2);
394
395 shared_ptr<Data> data3 = makeData("/z/z/z");
396 ims.insert(*data3);
397
398 ndn::ConstBufferPtr digest1 = ndn::crypto::sha256(data->wireEncode().wire(),
399 data->wireEncode().size());
400 uint8_t digest2[32] = {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
401 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1};
402
403 shared_ptr<Interest> interest = makeInterest("");
404 interest->setName(Name(name).append(digest1->buf(), digest1->size()));
405 interest->setMinSuffixComponents(0);
406 interest->setMaxSuffixComponents(0);
407
408 shared_ptr<const Data> found = ims.find(*interest);
409 BOOST_CHECK(static_cast<bool>(found));
410 BOOST_CHECK_EQUAL(found->getName(), name);
411
412 shared_ptr<Interest> interest2 = makeInterest("");
413 interest2->setName(Name(name).append(digest2, 32));
414 interest2->setMinSuffixComponents(0);
415 interest2->setMaxSuffixComponents(0);
416
417 shared_ptr<const Data> notfound = ims.find(*interest2);
418 BOOST_CHECK(static_cast<bool>(found));
419}
420
421BOOST_AUTO_TEST_CASE_TEMPLATE(ChildSelector, T, InMemoryStorages)
422{
423 T ims;
424
425 shared_ptr<Data> data = makeData("/a");
426 ims.insert(*data);
427
428 shared_ptr<Data> data2 = makeData("/b");
429 ims.insert(*data2);
430
431 shared_ptr<Data> data4 = makeData("/d");
432 ims.insert(*data4);
433
434 shared_ptr<Data> data5 = makeData("/c/c");
435 ims.insert(*data5);
436
437 shared_ptr<Data> data6 = makeData("/c/f");
438 ims.insert(*data6);
439
440 shared_ptr<Data> data7 = makeData("/c/n");
441 ims.insert(*data7);
442
443 shared_ptr<Interest> interest = makeInterest("/c");
444 interest->setChildSelector(1);
445
446 shared_ptr<const Data> found = ims.find(*interest);
447 BOOST_CHECK_EQUAL(found->getName(), "/c/n");
448
449 shared_ptr<Interest> interest2 = makeInterest("/c");
450 interest2->setChildSelector(0);
451
452 shared_ptr<const Data> found2 = ims.find(*interest2);
453 BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
454}
455
456BOOST_AUTO_TEST_CASE_TEMPLATE(ChildSelector2, T, InMemoryStorages)
457{
458 T ims;
459
460 shared_ptr<Data> data = makeData("/a/b/1");
461 ims.insert(*data);
462
463 shared_ptr<Data> data2 = makeData("/a/b/2");
464 ims.insert(*data2);
465
466 shared_ptr<Data> data3 = makeData("/a/z/1");
467 ims.insert(*data3);
468
469 shared_ptr<Data> data4 = makeData("/a/z/2");
470 ims.insert(*data4);
471
472 shared_ptr<Interest> interest = makeInterest("/a");
473 interest->setChildSelector(1);
474
475 shared_ptr<const Data> found = ims.find(*interest);
476 BOOST_CHECK_EQUAL(found->getName(), "/a/z/1");
477}
478
479BOOST_AUTO_TEST_CASE_TEMPLATE(PublisherKeySelector, T, InMemoryStorages)
480{
481 T ims;
482
483 Name name("/insert/withkey");
484 shared_ptr<Data> data = makeData(name);
485 ims.insert(*data);
486
487 shared_ptr<Interest> interest = makeInterest(name);
488 Name keyName("/somewhere/key");
489
490 ndn::KeyLocator locator(keyName);
491 interest->setPublisherPublicKeyLocator(locator);
492
493 shared_ptr<const Data> found = ims.find(*interest);
494 BOOST_CHECK(!static_cast<bool>(found));
495}
496
497BOOST_AUTO_TEST_CASE_TEMPLATE(PublisherKeySelector2, T, InMemoryStorages)
498{
499 T ims;
500 Name name("/insert/withkey");
501 shared_ptr<Data> data = makeData(name);
502 ims.insert(*data);
503
504 Name name2("/insert/withkey2");
505 shared_ptr<Data> data2 = make_shared<Data>(name2);
506
507 Name keyName("/somewhere/key");
508 const ndn::KeyLocator locator(keyName);
509
510 ndn::SignatureSha256WithRsa fakeSignature;
511 fakeSignature.setValue(ndn::dataBlock(tlv::SignatureValue,
512 reinterpret_cast<const uint8_t*>(0), 0));
513
514 fakeSignature.setKeyLocator(locator);
515 data2->setSignature(fakeSignature);
516 data2->wireEncode();
517
518 ims.insert(*data2);
519
520 shared_ptr<Interest> interest = makeInterest(name2);
521 interest->setPublisherPublicKeyLocator(locator);
522
523 shared_ptr<const Data> found = ims.find(*interest);
524 BOOST_CHECK(static_cast<bool>(found));
525 BOOST_CHECK_EQUAL(found->getName(), data2->getName());
526}
527
528BOOST_AUTO_TEST_CASE_TEMPLATE(MinMaxComponentsSelector, T, InMemoryStorages)
529{
530 T ims;
531
532 shared_ptr<Data> data = makeData("/a");
533 ims.insert(*data);
534
535 shared_ptr<Data> data2 = makeData("/b");
536 ims.insert(*data2);
537
538 shared_ptr<Data> data4 = makeData("/d");
539 ims.insert(*data4);
540
541 shared_ptr<Data> data5 = makeData("/c/c/1/2/3/4/5/6");
542 ims.insert(*data5);
543
544 shared_ptr<Data> data6 = makeData("/c/c/6/7/8/9");
545 ims.insert(*data6);
546
547 shared_ptr<Data> data7 = makeData("/c/c/1/2/3");
548 ims.insert(*data7);
549
550 shared_ptr<Data> data8 = makeData("/c/c/1");
551 ims.insert(*data8);
552
553 shared_ptr<Interest> interest = makeInterest("/c/c");
554 interest->setMinSuffixComponents(3);
555 interest->setChildSelector(0);
556
557 shared_ptr<const Data> found = ims.find(*interest);
558 BOOST_CHECK_EQUAL(found->getName(), "/c/c/1/2/3/4/5/6");
559
560 shared_ptr<Interest> interest2 = makeInterest("/c/c");
561 interest2->setMinSuffixComponents(4);
562 interest2->setChildSelector(1);
563
564 shared_ptr<const Data> found2 = ims.find(*interest2);
565 BOOST_CHECK_EQUAL(found2->getName(), "/c/c/6/7/8/9");
566
567 shared_ptr<Interest> interest3 = makeInterest("/c/c");
568 interest3->setMaxSuffixComponents(2);
569 interest3->setChildSelector(1);
570
571 shared_ptr<const Data> found3 = ims.find(*interest3);
572 BOOST_CHECK_EQUAL(found3->getName(), "/c/c/1");
573}
574
575BOOST_AUTO_TEST_CASE_TEMPLATE(ExcludeSelector, T, InMemoryStorages)
576{
577 T ims;
578
579 shared_ptr<Data> data = makeData("/a");
580 ims.insert(*data);
581
582 shared_ptr<Data> data2 = makeData("/b");
583 ims.insert(*data2);
584
585 shared_ptr<Data> data3 = makeData("/c/a");
586 ims.insert(*data3);
587
588 shared_ptr<Data> data4 = makeData("/d");
589 ims.insert(*data4);
590
591 shared_ptr<Data> data5 = makeData("/c/c");
592 ims.insert(*data5);
593
594 shared_ptr<Data> data6 = makeData("/c/f");
595 ims.insert(*data6);
596
597 shared_ptr<Data> data7 = makeData("/c/n");
598 ims.insert(*data7);
599
600 shared_ptr<Interest> interest = makeInterest("/c");
601 interest->setChildSelector(1);
602 Exclude e;
603 e.excludeOne (Name::Component("n"));
604 interest->setExclude(e);
605
606 shared_ptr<const Data> found = ims.find(*interest);
607 BOOST_CHECK_EQUAL(found->getName(), "/c/f");
608
609 shared_ptr<Interest> interest2 = makeInterest("/c");
610 interest2->setChildSelector(0);
611
612 Exclude e2;
613 e2.excludeOne (Name::Component("a"));
614 interest2->setExclude(e2);
615
616 shared_ptr<const Data> found2 = ims.find(*interest2);
617 BOOST_CHECK_EQUAL(found2->getName(), "/c/c");
618
619 shared_ptr<Interest> interest3 = makeInterest("/c");
620 interest3->setChildSelector(0);
621
622 Exclude e3;
623 e3.excludeOne (Name::Component("c"));
624 interest3->setExclude(e3);
625
626 shared_ptr<const Data> found3 = ims.find(*interest3);
627 BOOST_CHECK_EQUAL(found3->getName(), "/c/a");
628}
629
630typedef boost::mpl::list<InMemoryStorageFifo, InMemoryStorageLfu, InMemoryStorageLru>
631 InMemoryStoragesLimited;
632
633BOOST_AUTO_TEST_CASE_TEMPLATE(setCapacity, T, InMemoryStoragesLimited)
634{
635 T ims;
636
637 ims.setCapacity(3);
638 ims.insert(*makeData("/1"));
639 ims.insert(*makeData("/2"));
640 ims.insert(*makeData("/3"));
641 BOOST_CHECK_EQUAL(ims.size(), 3);
642
643 ims.setCapacity(2);
644 BOOST_CHECK_EQUAL(ims.size(), 2);
645}
646
647BOOST_AUTO_TEST_CASE_TEMPLATE(GetLimit, T, InMemoryStoragesLimited)
648{
649 T ims(10000);
650
651 BOOST_CHECK_EQUAL(ims.getLimit(), 10000);
652
653 T ims2(4);
654
655 BOOST_CHECK_EQUAL(ims2.getLimit(), 4);
656}
657
658BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndDouble, T, InMemoryStoragesLimited)
659{
660 T ims(40);
661
662 for (int i = 0; i < 11; i++) {
663 std::ostringstream convert;
664 convert << i;
665 Name name("/" + convert.str());
666 shared_ptr<Data> data = makeData(name);
667 data->setFreshnessPeriod(time::milliseconds(5000));
668 signData(data);
669 ims.insert(*data);
670 }
671
672 BOOST_CHECK_EQUAL(ims.size(), 11);
673
674 BOOST_CHECK_EQUAL(ims.getCapacity(), 20);
675}
676
677BOOST_AUTO_TEST_CASE_TEMPLATE(InsertAndEvict, T, InMemoryStoragesLimited)
678{
679 T ims(2);
680
681 Name name("/insert/1");
682 shared_ptr<Data> data = makeData(name);
683 ims.insert(*data);
684
685 Name name2("/insert/2");
686 shared_ptr<Data> data2 = makeData(name2);
687 ims.insert(*data2);
688
689 Name name3("/insert/3");
690 shared_ptr<Data> data3 = makeData(name3);
691 ims.insert(*data3);
692
693 BOOST_CHECK_EQUAL(ims.size(), 2);
694
695 shared_ptr<Interest> interest = makeInterest(name);
696 shared_ptr<const Data> found = ims.find(*interest);
697 BOOST_CHECK(!static_cast<bool>(found));
698}
699
700///as Find function is implemented at the base case, therefore testing for one derived class is
701///sufficient for all
702class FindFixture
703{
704protected:
705 void
706 insert(uint32_t id, const Name& name)
707 {
708 shared_ptr<Data> data = makeData(name);
709 data->setFreshnessPeriod(time::milliseconds(99999));
710 data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
711 signData(data);
712
713 m_ims.insert(*data);
714 }
715
716 Interest&
717 startInterest(const Name& name)
718 {
719 m_interest = makeInterest(name);
720 return *m_interest;
721 }
722
723 uint32_t
724 find()
725 {
726 shared_ptr<const Data> found = m_ims.find(*m_interest);
727 if (found == 0) {
728 return 0;
729 }
730 const Block& content = found->getContent();
731 if (content.value_size() != sizeof(uint32_t)) {
732 return 0;
733 }
734 return *reinterpret_cast<const uint32_t*>(content.value());
735 }
736
737protected:
738 InMemoryStoragePersistent m_ims;
739 shared_ptr<Interest> m_interest;
740};
741
742BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
743
744BOOST_AUTO_TEST_CASE(EmptyDataName)
745{
746 insert(1, "ndn:/");
747
748 startInterest("ndn:/");
749 BOOST_CHECK_EQUAL(find(), 1);
750}
751
752BOOST_AUTO_TEST_CASE(EmptyInterestName)
753{
754 insert(1, "ndn:/A");
755
756 startInterest("ndn:/");
757 BOOST_CHECK_EQUAL(find(), 1);
758}
759
760BOOST_AUTO_TEST_CASE(Leftmost)
761{
762 insert(1, "ndn:/A");
763 insert(2, "ndn:/B/p/1");
764 insert(3, "ndn:/B/p/2");
765 insert(4, "ndn:/B/q/1");
766 insert(5, "ndn:/B/q/2");
767 insert(6, "ndn:/C");
768
769 startInterest("ndn:/B");
770 BOOST_CHECK_EQUAL(find(), 2);
771}
772
773BOOST_AUTO_TEST_CASE(Rightmost)
774{
775 insert(1, "ndn:/A");
776 insert(2, "ndn:/B/p/1");
777 insert(3, "ndn:/B/p/2");
778 insert(4, "ndn:/B/q/1");
779 insert(5, "ndn:/B/q/2");
780 insert(6, "ndn:/C");
781
782 startInterest("ndn:/B")
783 .setChildSelector(1);
784 BOOST_CHECK_EQUAL(find(), 4);
785}
786
787BOOST_AUTO_TEST_CASE(Leftmost_ExactName1)
788{
789 insert(1, "ndn:/");
790 insert(2, "ndn:/A/B");
791 insert(3, "ndn:/A/C");
792 insert(4, "ndn:/A");
793 insert(5, "ndn:/D");
794
795 // Intuitively you would think Data 4 should be between Data 1 and 2,
796 // but Data 4 has full Name ndn:/A/<32-octet hash>.
797 startInterest("ndn:/A");
798 BOOST_CHECK_EQUAL(find(), 2);
799}
800
801BOOST_AUTO_TEST_CASE(Leftmost_ExactName33)
802{
803 insert(1, "ndn:/");
804 insert(2, "ndn:/A");
805 insert(3, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 33 'B's
806 insert(4, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
807 insert(5, "ndn:/D");
808
809 // Data 2 is returned, because <32-octet hash> is less than Data 3.
810 startInterest("ndn:/A");
811 BOOST_CHECK_EQUAL(find(), 2);
812}
813
814BOOST_AUTO_TEST_CASE(MinSuffixComponents)
815{
816 insert(1, "ndn:/A/1/2/3/4");
817 insert(2, "ndn:/B/1/2/3");
818 insert(3, "ndn:/C/1/2");
819 insert(4, "ndn:/D/1");
820 insert(5, "ndn:/E");
821 insert(6, "ndn:/");
822
823 startInterest("ndn:/")
824 .setChildSelector(1)
825 .setMinSuffixComponents(0);
826 BOOST_CHECK_EQUAL(find(), 6);
827
828 startInterest("ndn:/")
829 .setChildSelector(1)
830 .setMinSuffixComponents(1);
831 BOOST_CHECK_EQUAL(find(), 6);
832
833 startInterest("ndn:/")
834 .setChildSelector(1)
835 .setMinSuffixComponents(2);
836 BOOST_CHECK_EQUAL(find(), 5);
837
838 startInterest("ndn:/")
839 .setChildSelector(1)
840 .setMinSuffixComponents(3);
841 BOOST_CHECK_EQUAL(find(), 4);
842
843 startInterest("ndn:/")
844 .setChildSelector(1)
845 .setMinSuffixComponents(4);
846 BOOST_CHECK_EQUAL(find(), 3);
847
848 startInterest("ndn:/")
849 .setChildSelector(1)
850 .setMinSuffixComponents(5);
851 BOOST_CHECK_EQUAL(find(), 2);
852
853 startInterest("ndn:/")
854 .setChildSelector(1)
855 .setMinSuffixComponents(6);
856 BOOST_CHECK_EQUAL(find(), 1);
857
858 startInterest("ndn:/")
859 .setChildSelector(1)
860 .setMinSuffixComponents(7);
861 BOOST_CHECK_EQUAL(find(), 0);
862}
863
864BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
865{
866 insert(1, "ndn:/");
867 insert(2, "ndn:/A");
868 insert(3, "ndn:/A/B");
869 insert(4, "ndn:/A/B/C");
870 insert(5, "ndn:/A/B/C/D");
871 insert(6, "ndn:/A/B/C/D/E");
872 // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
873
874 startInterest("ndn:/")
875 .setMaxSuffixComponents(0);
876 BOOST_CHECK_EQUAL(find(), 0);
877
878 startInterest("ndn:/")
879 .setMaxSuffixComponents(1);
880 BOOST_CHECK_EQUAL(find(), 1);
881
882 startInterest("ndn:/")
883 .setMaxSuffixComponents(2);
884 BOOST_CHECK_EQUAL(find(), 2);
885
886 startInterest("ndn:/")
887 .setMaxSuffixComponents(3);
888 BOOST_CHECK_EQUAL(find(), 3);
889
890 startInterest("ndn:/")
891 .setMaxSuffixComponents(4);
892 BOOST_CHECK_EQUAL(find(), 4);
893
894 startInterest("ndn:/")
895 .setMaxSuffixComponents(5);
896 BOOST_CHECK_EQUAL(find(), 5);
897
898 startInterest("ndn:/")
899 .setMaxSuffixComponents(6);
900 BOOST_CHECK_EQUAL(find(), 6);
901}
902
903BOOST_AUTO_TEST_CASE(DigestOrder)
904{
905 insert(1, "ndn:/A");
906 insert(2, "ndn:/A");
907 // We don't know which comes first, but there must be some order
908
909 startInterest("ndn:/A")
910 .setChildSelector(0);
911 uint32_t leftmost = find();
912
913 startInterest("ndn:/A")
914 .setChildSelector(1);
915 uint32_t rightmost = find();
916
917 BOOST_CHECK_NE(leftmost, rightmost);
918}
919
920BOOST_AUTO_TEST_CASE(DigestExclude)
921{
922 insert(1, "ndn:/A/B");
923 insert(2, "ndn:/A");
924 insert(3, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
925
926 startInterest("ndn:/A")
927 .setExclude(Exclude().excludeBefore(name::Component(reinterpret_cast<const uint8_t*>(
928 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
929 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"), 31))); // 31 0xFF's
930 BOOST_CHECK_EQUAL(find(), 2);
931
932 startInterest("ndn:/A")
933 .setChildSelector(1)
934 .setExclude(Exclude().excludeAfter(name::Component(reinterpret_cast<const uint8_t*>(
935 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
936 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
937 "\x00"), 33))); // 33 0x00's
938 BOOST_CHECK_EQUAL(find(), 2);
939}
940
941BOOST_AUTO_TEST_CASE(ExactName32)
942{
943 insert(1, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 32 'B's
944 insert(2, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 32 'C's
945
946 startInterest("ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
947 BOOST_CHECK_EQUAL(find(), 1);
948}
949
950BOOST_AUTO_TEST_CASE(MinSuffixComponents32)
951{
952 insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/1/2/3/4"); // 32 'x's
953 insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B/1/2/3");
954 insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/C/1/2");
955 insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/D/1");
956 insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/E");
957 insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
958
959 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
960 .setChildSelector(1)
961 .setMinSuffixComponents(0);
962 BOOST_CHECK_EQUAL(find(), 6);
963
964 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
965 .setChildSelector(1)
966 .setMinSuffixComponents(1);
967 BOOST_CHECK_EQUAL(find(), 6);
968
969 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
970 .setChildSelector(1)
971 .setMinSuffixComponents(2);
972 BOOST_CHECK_EQUAL(find(), 5);
973
974 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
975 .setChildSelector(1)
976 .setMinSuffixComponents(3);
977 BOOST_CHECK_EQUAL(find(), 4);
978
979 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
980 .setChildSelector(1)
981 .setMinSuffixComponents(4);
982 BOOST_CHECK_EQUAL(find(), 3);
983
984 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
985 .setChildSelector(1)
986 .setMinSuffixComponents(5);
987 BOOST_CHECK_EQUAL(find(), 2);
988
989 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
990 .setChildSelector(1)
991 .setMinSuffixComponents(6);
992 BOOST_CHECK_EQUAL(find(), 1);
993
994 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
995 .setChildSelector(1)
996 .setMinSuffixComponents(7);
997 BOOST_CHECK_EQUAL(find(), 0);
998}
999
1000BOOST_AUTO_TEST_CASE(MaxSuffixComponents32)
1001{
1002 insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/"); // 32 'x's
1003 insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A");
1004 insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B");
1005 insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C");
1006 insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D");
1007 insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D/E");
1008 // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
1009
1010 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
1011 .setMaxSuffixComponents(0);
1012 BOOST_CHECK_EQUAL(find(), 0);
1013
1014 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
1015 .setMaxSuffixComponents(1);
1016 BOOST_CHECK_EQUAL(find(), 1);
1017
1018 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
1019 .setMaxSuffixComponents(2);
1020 BOOST_CHECK_EQUAL(find(), 2);
1021
1022 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
1023 .setMaxSuffixComponents(3);
1024 BOOST_CHECK_EQUAL(find(), 3);
1025
1026 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
1027 .setMaxSuffixComponents(4);
1028 BOOST_CHECK_EQUAL(find(), 4);
1029
1030 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
1031 .setMaxSuffixComponents(5);
1032 BOOST_CHECK_EQUAL(find(), 5);
1033
1034 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
1035 .setMaxSuffixComponents(6);
1036 BOOST_CHECK_EQUAL(find(), 6);
1037}
1038
1039BOOST_AUTO_TEST_SUITE_END()
1040
1041BOOST_AUTO_TEST_SUITE_END()
1042
1043} // namespace util
1044} // namespace ndn