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