blob: 936158c1e4d7735c58d6af823c69a5dc11b7554e [file] [log] [blame]
Weiqi Shi28a90fb2014-07-09 10:28:55 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California.
4 *
5 * This file is part of NDN repo-ng (Next generation of NDN repository).
6 * See AUTHORS.md for complete list of repo-ng authors and contributors.
7 *
8 * repo-ng is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * repo-ng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * repo-ng, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "storage/index.hpp"
21
22#include "../sqlite-fixture.hpp"
23#include "../dataset-fixtures.hpp"
24
25#include <boost/test/unit_test.hpp>
26#include <iostream>
27
28namespace repo {
29namespace tests {
30
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070031BOOST_AUTO_TEST_SUITE(Index)
Weiqi Shif0330d52014-07-09 10:54:27 -070032
Weiqi Shi28a90fb2014-07-09 10:28:55 -070033class FindFixture
34{
35protected:
36 FindFixture()
37 : m_index(std::numeric_limits<size_t>::max())
38 {
39 }
40
41 void
42 insert(int id, const Name& name)
43 {
44 shared_ptr<Data> data = make_shared<Data>(name);
45 data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
46 m_keyChain.signWithSha256(*data);
47 data->wireEncode();
48 m_index.insert(*data, id);
49 }
50
51 Interest&
52 startInterest(const Name& name)
53 {
54 m_interest = make_shared<Interest>(name);
55 return *m_interest;
56 }
57
Weiqi Shif0330d52014-07-09 10:54:27 -070058 uint64_t
Weiqi Shi28a90fb2014-07-09 10:28:55 -070059 find()
60 {
61 std::pair<int,Name> found = m_index.find(*m_interest);
62 return found.first;
63 }
64
65protected:
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070066 repo::Index m_index;
Weiqi Shi28a90fb2014-07-09 10:28:55 -070067 KeyChain m_keyChain;
68 shared_ptr<Interest> m_interest;
69};
70
71BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
72
73BOOST_AUTO_TEST_CASE(EmptyDataName)
74{
75 insert(1, "ndn:/");
76 startInterest("ndn:/");
77 BOOST_CHECK_EQUAL(find(), 1);
78}
79
80BOOST_AUTO_TEST_CASE(EmptyInterestName)
81{
82 insert(1, "ndn:/A");
83 startInterest("ndn:/");
84 BOOST_CHECK_EQUAL(find(), 1);
85}
86
87BOOST_AUTO_TEST_CASE(Leftmost)
88{
89 insert(1, "ndn:/A");
90 insert(2, "ndn:/B/p/1");
91 insert(3, "ndn:/B/p/2");
92 insert(4, "ndn:/B/q/1");
93 insert(5, "ndn:/B/q/2");
94 insert(6, "ndn:/C");
95
96 startInterest("ndn:/B");
97 BOOST_CHECK_EQUAL(find(), 2);
98}
99
100BOOST_AUTO_TEST_CASE(Rightmost)
101{
102 insert(1, "ndn:/A");
103 insert(2, "ndn:/B/p/1");
104 insert(3, "ndn:/B/p/2");
105 insert(4, "ndn:/B/q/1");
106 insert(5, "ndn:/B/q/2");
107 insert(6, "ndn:/C");
108
109 startInterest("ndn:/B")
110 .setChildSelector(1);
111 BOOST_CHECK_EQUAL(find(), 4);
112}
113
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800114BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(Leftmost_ExactName1, 1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700115BOOST_AUTO_TEST_CASE(Leftmost_ExactName1)
116{
117 insert(1, "ndn:/");
118 insert(2, "ndn:/A/B");
119 insert(3, "ndn:/A/C");
120 insert(4, "ndn:/A");
121 insert(5, "ndn:/D");
122
123 // Intuitively you would think Data 4 should be between Data 1 and 2,
124 // but Data 4 has full Name ndn:/A/<32-octet hash>.
125 startInterest("ndn:/A");
126 BOOST_CHECK_EQUAL(find(), 2);
127}
128
129BOOST_AUTO_TEST_CASE(Leftmost_ExactName33)
130{
131 insert(1, "ndn:/");
132 insert(2, "ndn:/A");
133 insert(3, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 33 'B's
134 insert(4, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
135 insert(5, "ndn:/D");
136
137 // Data 2 is returned, because <32-octet hash> is less than Data 3.
138 startInterest("ndn:/A");
139 BOOST_CHECK_EQUAL(find(), 2);
140}
141
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800142BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(MinSuffixComponents, 2)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700143BOOST_AUTO_TEST_CASE(MinSuffixComponents)
144{
145 insert(1, "ndn:/A/1/2/3/4");
146 insert(2, "ndn:/B/1/2/3");
147 insert(3, "ndn:/C/1/2");
148 insert(4, "ndn:/D/1");
149 insert(5, "ndn:/E");
150 insert(6, "ndn:/");
151
152 startInterest("ndn:/")
153 .setChildSelector(1)
154 .setMinSuffixComponents(0);
155 BOOST_CHECK_EQUAL(find(), 6);
156
157 startInterest("ndn:/")
158 .setChildSelector(1)
159 .setMinSuffixComponents(1);
160 BOOST_CHECK_EQUAL(find(), 6);
161
162 startInterest("ndn:/")
163 .setChildSelector(1)
164 .setMinSuffixComponents(2);
165 BOOST_CHECK_EQUAL(find(), 5);
166
167 startInterest("ndn:/")
168 .setChildSelector(1)
169 .setMinSuffixComponents(3);
170 BOOST_CHECK_EQUAL(find(), 4);
171
172 startInterest("ndn:/")
173 .setChildSelector(1)
174 .setMinSuffixComponents(4);
175 BOOST_CHECK_EQUAL(find(), 3);
176
177 startInterest("ndn:/")
178 .setChildSelector(1)
179 .setMinSuffixComponents(5);
180 BOOST_CHECK_EQUAL(find(), 2);
181
182 startInterest("ndn:/")
183 .setChildSelector(1)
184 .setMinSuffixComponents(6);
185 BOOST_CHECK_EQUAL(find(), 1);
186
187 startInterest("ndn:/")
188 .setChildSelector(1)
189 .setMinSuffixComponents(7);
190 BOOST_CHECK_EQUAL(find(), 0);
191}
192
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800193BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(MaxSuffixComponents, 5)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700194BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
195{
196 insert(1, "ndn:/");
197 insert(2, "ndn:/A");
198 insert(3, "ndn:/A/B");
199 insert(4, "ndn:/A/B/C");
200 insert(5, "ndn:/A/B/C/D");
201 insert(6, "ndn:/A/B/C/D/E");
202 // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
203
204 startInterest("ndn:/")
205 .setMaxSuffixComponents(0);
206 BOOST_CHECK_EQUAL(find(), 0);
207
208 startInterest("ndn:/")
209 .setMaxSuffixComponents(1);
210 BOOST_CHECK_EQUAL(find(), 1);
211
212 startInterest("ndn:/")
213 .setMaxSuffixComponents(2);
214 BOOST_CHECK_EQUAL(find(), 2);
215
216 startInterest("ndn:/")
217 .setMaxSuffixComponents(3);
218 BOOST_CHECK_EQUAL(find(), 3);
219
220 startInterest("ndn:/")
221 .setMaxSuffixComponents(4);
222 BOOST_CHECK_EQUAL(find(), 4);
223
224 startInterest("ndn:/")
225 .setMaxSuffixComponents(5);
226 BOOST_CHECK_EQUAL(find(), 5);
227
228 startInterest("ndn:/")
229 .setMaxSuffixComponents(6);
230 BOOST_CHECK_EQUAL(find(), 6);
231}
232
233BOOST_AUTO_TEST_CASE(DigestOrder)
234{
235 insert(1, "ndn:/A");
236 insert(2, "ndn:/A");
237 // We don't know which comes first, but there must be some order
238
239 startInterest("ndn:/A")
240 .setChildSelector(0);
241 uint32_t leftmost = find();
242
243 startInterest("ndn:/A")
244 .setChildSelector(1);
245 uint32_t rightmost = find();
246
247 BOOST_CHECK_NE(leftmost, rightmost);
248}
249
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800250BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(DigestExclude, 1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700251BOOST_AUTO_TEST_CASE(DigestExclude)
252{
253 insert(1, "ndn:/A/B");
254 insert(2, "ndn:/A");
255 insert(3, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
256
257 startInterest("ndn:/A")
258 .setExclude(Exclude().excludeBefore(Name::Component(reinterpret_cast<const uint8_t*>(
259 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
260 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"), 31))); // 31 0xFF's
261 BOOST_CHECK_EQUAL(find(), 2);
262
263 startInterest("ndn:/A")
264 .setChildSelector(1)
265 .setExclude(Exclude().excludeAfter(Name::Component(reinterpret_cast<const uint8_t*>(
266 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
267 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
268 "\x00"), 33))); // 33 0x00's
269 BOOST_CHECK_EQUAL(find(), 2);
270}
271
272BOOST_AUTO_TEST_CASE(ExactName32)
273{
274 insert(1, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 32 'B's
275 insert(2, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 32 'C's
276
277 startInterest("ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
278 BOOST_CHECK_EQUAL(find(), 1);
279}
280
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800281BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(MinSuffixComponents32, 2)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700282BOOST_AUTO_TEST_CASE(MinSuffixComponents32)
283{
284 insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/1/2/3/4"); // 32 'x's
285 insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B/1/2/3");
286 insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/C/1/2");
287 insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/D/1");
288 insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/E");
289 insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
290
291 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
292 .setChildSelector(1)
293 .setMinSuffixComponents(0);
294 BOOST_CHECK_EQUAL(find(), 6);
295
296 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
297 .setChildSelector(1)
298 .setMinSuffixComponents(1);
299 BOOST_CHECK_EQUAL(find(), 6);
300
301 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
302 .setChildSelector(1)
303 .setMinSuffixComponents(2);
304 BOOST_CHECK_EQUAL(find(), 5);
305
306 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
307 .setChildSelector(1)
308 .setMinSuffixComponents(3);
309 BOOST_CHECK_EQUAL(find(), 4);
310
311 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
312 .setChildSelector(1)
313 .setMinSuffixComponents(4);
314 BOOST_CHECK_EQUAL(find(), 3);
315
316 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
317 .setChildSelector(1)
318 .setMinSuffixComponents(5);
319 BOOST_CHECK_EQUAL(find(), 2);
320
321 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
322 .setChildSelector(1)
323 .setMinSuffixComponents(6);
324 BOOST_CHECK_EQUAL(find(), 1);
325
326 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
327 .setChildSelector(1)
328 .setMinSuffixComponents(7);
329 BOOST_CHECK_EQUAL(find(), 0);
330}
331
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800332BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(MaxSuffixComponents32, 5)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700333BOOST_AUTO_TEST_CASE(MaxSuffixComponents32)
334{
335 insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/"); // 32 'x's
336 insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A");
337 insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B");
338 insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C");
339 insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D");
340 insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D/E");
341 // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
342
343 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
344 .setMaxSuffixComponents(0);
345 BOOST_CHECK_EQUAL(find(), 0);
346
347 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
348 .setMaxSuffixComponents(1);
349 BOOST_CHECK_EQUAL(find(), 1);
350
351 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
352 .setMaxSuffixComponents(2);
353 BOOST_CHECK_EQUAL(find(), 2);
354
355 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
356 .setMaxSuffixComponents(3);
357 BOOST_CHECK_EQUAL(find(), 3);
358
359 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
360 .setMaxSuffixComponents(4);
361 BOOST_CHECK_EQUAL(find(), 4);
362
363 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
364 .setMaxSuffixComponents(5);
365 BOOST_CHECK_EQUAL(find(), 5);
366
367 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
368 .setMaxSuffixComponents(6);
369 BOOST_CHECK_EQUAL(find(), 6);
370}
371
372BOOST_AUTO_TEST_SUITE_END() // Find
373
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700374
375template<class Dataset>
376class Fixture : public Dataset
377{
378public:
379 Fixture()
380 : index(65535)
381 {
382 }
383
384public:
385 std::map<int64_t, shared_ptr<Data> > idToDataMap;
386 repo::Index index;
387};
388
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800389// // Combine CommonDatasets with ComplexSelectorDataset
390// typedef boost::mpl::push_back<CommonDatasets,
391// ComplexSelectorsDataset>::type Datasets;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700392
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800393// BOOST_FIXTURE_TEST_CASE_TEMPLATE(Bulk, T, Datasets, Fixture<T>)
394BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(Bulk, 7)
395BOOST_FIXTURE_TEST_CASE(Bulk, Fixture<ComplexSelectorsDataset>)
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700396{
Alexander Afanasyevd3e9da12014-11-12 11:31:31 -0800397 typedef ComplexSelectorsDataset T;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700398 BOOST_TEST_MESSAGE(T::getName());
399
400 for (typename T::DataContainer::iterator i = this->data.begin();
401 i != this->data.end(); ++i)
402 {
403 int64_t id = std::abs(static_cast<int64_t>(ndn::random::generateWord64()));
404 this->idToDataMap.insert(std::make_pair(id, *i));
405
406 BOOST_CHECK_EQUAL(this->index.insert(**i, id), true);
407 }
408
409 BOOST_CHECK_EQUAL(this->index.size(), this->data.size());
410
411 for (typename T::InterestContainer::iterator i = this->interests.begin();
412 i != this->interests.end(); ++i)
413 {
414 std::pair<int64_t, Name> item = this->index.find(i->first);
415
416 BOOST_REQUIRE_GT(item.first, 0);
417 BOOST_REQUIRE(this->idToDataMap.count(item.first) > 0);
418
419 BOOST_TEST_MESSAGE(i->first);
420 BOOST_CHECK_EQUAL(*this->idToDataMap[item.first], *i->second);
421
422 BOOST_CHECK_EQUAL(this->index.hasData(*i->second), true);
423 }
424
425 // Need support for selector-based removal
426 // for (typename T::RemovalsContainer::iterator i = this->removals.begin();
427 // i != this->removals.end(); ++i)
428 // {
429 // size_t nRemoved = 0;
430 // BOOST_REQUIRE_NO_THROW(this->index.erase(*i));
431 // BOOST_CHECK_EQUAL(nRemoved, i->seconds);
432 // }
433}
434
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700435BOOST_AUTO_TEST_SUITE_END()
436
437} // namespace tests
438} // namespace repo