blob: 13674039374c45ac62f3e8188d6dfb0650312a9e [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
31BOOST_AUTO_TEST_SUITE(TestIndex)
32
33template<class Dataset>
34class Fixture : public Dataset
35{
36};
37
38BOOST_FIXTURE_TEST_CASE_TEMPLATE(IndexGeneralTest, T, DatasetFixtures_Storage, Fixture<T>)
39{
40 Index index(65535);
41 for (typename T::IdContainer::iterator i = this->insert.begin();
42 i != this->insert.end(); ++i)
43 {
44 BOOST_CHECK_EQUAL(index.insert(*i->second, i->first), true);
45 }
46 BOOST_CHECK_EQUAL(index.size(), 7);
47
48 typename T::IdContainer::iterator id = this->ids.begin();
49 for (typename T::InterestContainer::iterator i = this->interests.begin();
50 i != this->interests.end(); ++i)
51 {
52 vector<std::pair<int, ndn::Name> > id_names;
53 BOOST_CHECK_EQUAL(index.find(i->first.getName()).first, id->first);
54 BOOST_CHECK_EQUAL(index.hasData(*i->second), true);
55 ++id;
56 }
57
58 for (typename T::InterestIdContainer::iterator i = this->interestsSelectors.begin();
59 i != this->interestsSelectors.end(); ++i)
60 {
61 BOOST_CHECK_EQUAL(index.find(i->first).first, i->second);
62 ndn::Name name = index.find(i->first).second;
63 BOOST_CHECK_EQUAL(index.erase(name), true);
64 }
65 BOOST_CHECK_EQUAL(index.size(), 2);
66}
67
68
69BOOST_FIXTURE_TEST_CASE_TEMPLATE(IndexTestSelector, T, DatasetFixtures_Selector, Fixture<T>)
70{
71 Index index(65535);
72 for (typename T::IdContainer::iterator i = this->insert.begin();
73 i != this->insert.end(); ++i)
74 BOOST_CHECK_EQUAL(index.insert(*i->second, i->first), true);
75 for (typename T::InterestIdContainer::iterator i = this->interestsSelectors.begin();
76 i != this->interestsSelectors.end(); ++i)
77 {
78 BOOST_CHECK_EQUAL(index.find(i->first).first, i->second);
79 }
80}
81
82class FindFixture
83{
84protected:
85 FindFixture()
86 : m_index(std::numeric_limits<size_t>::max())
87 {
88 }
89
90 void
91 insert(int id, const Name& name)
92 {
93 shared_ptr<Data> data = make_shared<Data>(name);
94 data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
95 m_keyChain.signWithSha256(*data);
96 data->wireEncode();
97 m_index.insert(*data, id);
98 }
99
100 Interest&
101 startInterest(const Name& name)
102 {
103 m_interest = make_shared<Interest>(name);
104 return *m_interest;
105 }
106
107 int
108 find()
109 {
110 std::pair<int,Name> found = m_index.find(*m_interest);
111 return found.first;
112 }
113
114protected:
115 Index m_index;
116 KeyChain m_keyChain;
117 shared_ptr<Interest> m_interest;
118};
119
120BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
121
122BOOST_AUTO_TEST_CASE(EmptyDataName)
123{
124 insert(1, "ndn:/");
125 startInterest("ndn:/");
126 BOOST_CHECK_EQUAL(find(), 1);
127}
128
129BOOST_AUTO_TEST_CASE(EmptyInterestName)
130{
131 insert(1, "ndn:/A");
132 startInterest("ndn:/");
133 BOOST_CHECK_EQUAL(find(), 1);
134}
135
136BOOST_AUTO_TEST_CASE(Leftmost)
137{
138 insert(1, "ndn:/A");
139 insert(2, "ndn:/B/p/1");
140 insert(3, "ndn:/B/p/2");
141 insert(4, "ndn:/B/q/1");
142 insert(5, "ndn:/B/q/2");
143 insert(6, "ndn:/C");
144
145 startInterest("ndn:/B");
146 BOOST_CHECK_EQUAL(find(), 2);
147}
148
149BOOST_AUTO_TEST_CASE(Rightmost)
150{
151 insert(1, "ndn:/A");
152 insert(2, "ndn:/B/p/1");
153 insert(3, "ndn:/B/p/2");
154 insert(4, "ndn:/B/q/1");
155 insert(5, "ndn:/B/q/2");
156 insert(6, "ndn:/C");
157
158 startInterest("ndn:/B")
159 .setChildSelector(1);
160 BOOST_CHECK_EQUAL(find(), 4);
161}
162
163BOOST_AUTO_TEST_CASE(Leftmost_ExactName1)
164{
165 insert(1, "ndn:/");
166 insert(2, "ndn:/A/B");
167 insert(3, "ndn:/A/C");
168 insert(4, "ndn:/A");
169 insert(5, "ndn:/D");
170
171 // Intuitively you would think Data 4 should be between Data 1 and 2,
172 // but Data 4 has full Name ndn:/A/<32-octet hash>.
173 startInterest("ndn:/A");
174 BOOST_CHECK_EQUAL(find(), 2);
175}
176
177BOOST_AUTO_TEST_CASE(Leftmost_ExactName33)
178{
179 insert(1, "ndn:/");
180 insert(2, "ndn:/A");
181 insert(3, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 33 'B's
182 insert(4, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
183 insert(5, "ndn:/D");
184
185 // Data 2 is returned, because <32-octet hash> is less than Data 3.
186 startInterest("ndn:/A");
187 BOOST_CHECK_EQUAL(find(), 2);
188}
189
190BOOST_AUTO_TEST_CASE(MinSuffixComponents)
191{
192 insert(1, "ndn:/A/1/2/3/4");
193 insert(2, "ndn:/B/1/2/3");
194 insert(3, "ndn:/C/1/2");
195 insert(4, "ndn:/D/1");
196 insert(5, "ndn:/E");
197 insert(6, "ndn:/");
198
199 startInterest("ndn:/")
200 .setChildSelector(1)
201 .setMinSuffixComponents(0);
202 BOOST_CHECK_EQUAL(find(), 6);
203
204 startInterest("ndn:/")
205 .setChildSelector(1)
206 .setMinSuffixComponents(1);
207 BOOST_CHECK_EQUAL(find(), 6);
208
209 startInterest("ndn:/")
210 .setChildSelector(1)
211 .setMinSuffixComponents(2);
212 BOOST_CHECK_EQUAL(find(), 5);
213
214 startInterest("ndn:/")
215 .setChildSelector(1)
216 .setMinSuffixComponents(3);
217 BOOST_CHECK_EQUAL(find(), 4);
218
219 startInterest("ndn:/")
220 .setChildSelector(1)
221 .setMinSuffixComponents(4);
222 BOOST_CHECK_EQUAL(find(), 3);
223
224 startInterest("ndn:/")
225 .setChildSelector(1)
226 .setMinSuffixComponents(5);
227 BOOST_CHECK_EQUAL(find(), 2);
228
229 startInterest("ndn:/")
230 .setChildSelector(1)
231 .setMinSuffixComponents(6);
232 BOOST_CHECK_EQUAL(find(), 1);
233
234 startInterest("ndn:/")
235 .setChildSelector(1)
236 .setMinSuffixComponents(7);
237 BOOST_CHECK_EQUAL(find(), 0);
238}
239
240BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
241{
242 insert(1, "ndn:/");
243 insert(2, "ndn:/A");
244 insert(3, "ndn:/A/B");
245 insert(4, "ndn:/A/B/C");
246 insert(5, "ndn:/A/B/C/D");
247 insert(6, "ndn:/A/B/C/D/E");
248 // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
249
250 startInterest("ndn:/")
251 .setMaxSuffixComponents(0);
252 BOOST_CHECK_EQUAL(find(), 0);
253
254 startInterest("ndn:/")
255 .setMaxSuffixComponents(1);
256 BOOST_CHECK_EQUAL(find(), 1);
257
258 startInterest("ndn:/")
259 .setMaxSuffixComponents(2);
260 BOOST_CHECK_EQUAL(find(), 2);
261
262 startInterest("ndn:/")
263 .setMaxSuffixComponents(3);
264 BOOST_CHECK_EQUAL(find(), 3);
265
266 startInterest("ndn:/")
267 .setMaxSuffixComponents(4);
268 BOOST_CHECK_EQUAL(find(), 4);
269
270 startInterest("ndn:/")
271 .setMaxSuffixComponents(5);
272 BOOST_CHECK_EQUAL(find(), 5);
273
274 startInterest("ndn:/")
275 .setMaxSuffixComponents(6);
276 BOOST_CHECK_EQUAL(find(), 6);
277}
278
279BOOST_AUTO_TEST_CASE(DigestOrder)
280{
281 insert(1, "ndn:/A");
282 insert(2, "ndn:/A");
283 // We don't know which comes first, but there must be some order
284
285 startInterest("ndn:/A")
286 .setChildSelector(0);
287 uint32_t leftmost = find();
288
289 startInterest("ndn:/A")
290 .setChildSelector(1);
291 uint32_t rightmost = find();
292
293 BOOST_CHECK_NE(leftmost, rightmost);
294}
295
296BOOST_AUTO_TEST_CASE(DigestExclude)
297{
298 insert(1, "ndn:/A/B");
299 insert(2, "ndn:/A");
300 insert(3, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 33 'C's
301
302 startInterest("ndn:/A")
303 .setExclude(Exclude().excludeBefore(Name::Component(reinterpret_cast<const uint8_t*>(
304 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
305 "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"), 31))); // 31 0xFF's
306 BOOST_CHECK_EQUAL(find(), 2);
307
308 startInterest("ndn:/A")
309 .setChildSelector(1)
310 .setExclude(Exclude().excludeAfter(Name::Component(reinterpret_cast<const uint8_t*>(
311 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
312 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
313 "\x00"), 33))); // 33 0x00's
314 BOOST_CHECK_EQUAL(find(), 2);
315}
316
317BOOST_AUTO_TEST_CASE(ExactName32)
318{
319 insert(1, "ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"); // 32 'B's
320 insert(2, "ndn:/A/CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"); // 32 'C's
321
322 startInterest("ndn:/A/BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB");
323 BOOST_CHECK_EQUAL(find(), 1);
324}
325
326BOOST_AUTO_TEST_CASE(MinSuffixComponents32)
327{
328 insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/1/2/3/4"); // 32 'x's
329 insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/B/1/2/3");
330 insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/C/1/2");
331 insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/D/1");
332 insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/E");
333 insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
334
335 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
336 .setChildSelector(1)
337 .setMinSuffixComponents(0);
338 BOOST_CHECK_EQUAL(find(), 6);
339
340 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
341 .setChildSelector(1)
342 .setMinSuffixComponents(1);
343 BOOST_CHECK_EQUAL(find(), 6);
344
345 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
346 .setChildSelector(1)
347 .setMinSuffixComponents(2);
348 BOOST_CHECK_EQUAL(find(), 5);
349
350 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
351 .setChildSelector(1)
352 .setMinSuffixComponents(3);
353 BOOST_CHECK_EQUAL(find(), 4);
354
355 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
356 .setChildSelector(1)
357 .setMinSuffixComponents(4);
358 BOOST_CHECK_EQUAL(find(), 3);
359
360 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
361 .setChildSelector(1)
362 .setMinSuffixComponents(5);
363 BOOST_CHECK_EQUAL(find(), 2);
364
365 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
366 .setChildSelector(1)
367 .setMinSuffixComponents(6);
368 BOOST_CHECK_EQUAL(find(), 1);
369
370 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
371 .setChildSelector(1)
372 .setMinSuffixComponents(7);
373 BOOST_CHECK_EQUAL(find(), 0);
374}
375
376BOOST_AUTO_TEST_CASE(MaxSuffixComponents32)
377{
378 insert(1, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/"); // 32 'x's
379 insert(2, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A");
380 insert(3, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B");
381 insert(4, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C");
382 insert(5, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D");
383 insert(6, "ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/A/B/C/D/E");
384 // Order is 6,5,4,3,2,1, because <32-octet hash> is greater than a 1-octet component.
385
386 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
387 .setMaxSuffixComponents(0);
388 BOOST_CHECK_EQUAL(find(), 0);
389
390 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
391 .setMaxSuffixComponents(1);
392 BOOST_CHECK_EQUAL(find(), 1);
393
394 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
395 .setMaxSuffixComponents(2);
396 BOOST_CHECK_EQUAL(find(), 2);
397
398 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
399 .setMaxSuffixComponents(3);
400 BOOST_CHECK_EQUAL(find(), 3);
401
402 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
403 .setMaxSuffixComponents(4);
404 BOOST_CHECK_EQUAL(find(), 4);
405
406 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
407 .setMaxSuffixComponents(5);
408 BOOST_CHECK_EQUAL(find(), 5);
409
410 startInterest("ndn:/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
411 .setMaxSuffixComponents(6);
412 BOOST_CHECK_EQUAL(find(), 6);
413}
414
415BOOST_AUTO_TEST_SUITE_END() // Find
416
417BOOST_AUTO_TEST_SUITE_END()
418
419} // namespace tests
420} // namespace repo