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