blob: 7a04c36f0ec7e7e69444fd20b45e2ede5c7eb865 [file] [log] [blame]
Weiqi Shi28a90fb2014-07-09 10:28:55 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi047a6fb2017-06-08 16:16:05 +00003 * Copyright (c) 2014-2017, Regents of the University of California.
Weiqi Shi28a90fb2014-07-09 10:28:55 -07004 *
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"
Junxiao Shi047a6fb2017-06-08 16:16:05 +000021#include <ndn-cxx/security/signing-helpers.hpp>
22#include <ndn-cxx/util/crypto.hpp>
23#include <ndn-cxx/util/random.hpp>
Weiqi Shi28a90fb2014-07-09 10:28:55 -070024
25#include "../sqlite-fixture.hpp"
26#include "../dataset-fixtures.hpp"
27
Junxiao Shi047a6fb2017-06-08 16:16:05 +000028#include <boost/mpl/push_back.hpp>
Weiqi Shi28a90fb2014-07-09 10:28:55 -070029#include <boost/test/unit_test.hpp>
30#include <iostream>
31
32namespace repo {
33namespace tests {
34
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070035BOOST_AUTO_TEST_SUITE(Index)
Weiqi Shif0330d52014-07-09 10:54:27 -070036
Weiqi Shi28a90fb2014-07-09 10:28:55 -070037class FindFixture
38{
39protected:
40 FindFixture()
41 : m_index(std::numeric_limits<size_t>::max())
42 {
43 }
44
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080045 Name
Weiqi Shi28a90fb2014-07-09 10:28:55 -070046 insert(int id, const Name& name)
47 {
48 shared_ptr<Data> data = make_shared<Data>(name);
49 data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
Junxiao Shi047a6fb2017-06-08 16:16:05 +000050 m_keyChain.sign(*data, ndn::signingWithSha256());
Weiqi Shi28a90fb2014-07-09 10:28:55 -070051 data->wireEncode();
52 m_index.insert(*data, id);
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080053
54 return data->getFullName();
Weiqi Shi28a90fb2014-07-09 10:28:55 -070055 }
56
57 Interest&
58 startInterest(const Name& name)
59 {
60 m_interest = make_shared<Interest>(name);
61 return *m_interest;
62 }
63
Alexander Afanasyevd352cce2015-11-20 14:15:11 -050064 int
Weiqi Shi28a90fb2014-07-09 10:28:55 -070065 find()
66 {
Alexander Afanasyevd352cce2015-11-20 14:15:11 -050067 std::pair<int, Name> found = m_index.find(*m_interest);
Weiqi Shi28a90fb2014-07-09 10:28:55 -070068 return found.first;
69 }
70
71protected:
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070072 repo::Index m_index;
Weiqi Shi28a90fb2014-07-09 10:28:55 -070073 KeyChain m_keyChain;
74 shared_ptr<Interest> m_interest;
75};
76
77BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
78
79BOOST_AUTO_TEST_CASE(EmptyDataName)
80{
81 insert(1, "ndn:/");
82 startInterest("ndn:/");
83 BOOST_CHECK_EQUAL(find(), 1);
84}
85
86BOOST_AUTO_TEST_CASE(EmptyInterestName)
87{
88 insert(1, "ndn:/A");
89 startInterest("ndn:/");
90 BOOST_CHECK_EQUAL(find(), 1);
91}
92
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080093BOOST_AUTO_TEST_CASE(ExactName)
94{
95 insert(1, "ndn:/");
96 insert(2, "ndn:/A");
97 insert(3, "ndn:/A/B");
98 insert(4, "ndn:/A/C");
99 insert(5, "ndn:/D");
100
101 startInterest("ndn:/A");
102 BOOST_CHECK_EQUAL(find(), 2);
103}
104
105BOOST_AUTO_TEST_CASE(FullName)
106{
107 Name n1 = insert(1, "ndn:/A");
108 Name n2 = insert(2, "ndn:/A");
109
110 startInterest(n1);
111 BOOST_CHECK_EQUAL(find(), 1);
112
113 startInterest(n2);
114 BOOST_CHECK_EQUAL(find(), 2);
115}
116
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700117BOOST_AUTO_TEST_CASE(Leftmost)
118{
119 insert(1, "ndn:/A");
120 insert(2, "ndn:/B/p/1");
121 insert(3, "ndn:/B/p/2");
122 insert(4, "ndn:/B/q/1");
123 insert(5, "ndn:/B/q/2");
124 insert(6, "ndn:/C");
125
126 startInterest("ndn:/B");
127 BOOST_CHECK_EQUAL(find(), 2);
128}
129
130BOOST_AUTO_TEST_CASE(Rightmost)
131{
132 insert(1, "ndn:/A");
133 insert(2, "ndn:/B/p/1");
134 insert(3, "ndn:/B/p/2");
135 insert(4, "ndn:/B/q/1");
136 insert(5, "ndn:/B/q/2");
137 insert(6, "ndn:/C");
138
139 startInterest("ndn:/B")
140 .setChildSelector(1);
141 BOOST_CHECK_EQUAL(find(), 4);
142}
143
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800144BOOST_AUTO_TEST_CASE(MinSuffixComponents)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700145{
146 insert(1, "ndn:/");
147 insert(2, "ndn:/A");
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800148 insert(3, "ndn:/B/1");
149 insert(4, "ndn:/C/1/2");
150 insert(5, "ndn:/D/1/2/3");
151 insert(6, "ndn:/E/1/2/3/4");
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700152
153 startInterest("ndn:/")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700154 .setMinSuffixComponents(0);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700155 BOOST_CHECK_EQUAL(find(), 1);
156
157 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800158 .setMinSuffixComponents(1);
159 BOOST_CHECK_EQUAL(find(), 1);
160
161 startInterest("ndn:/")
162 .setMinSuffixComponents(2);
163 BOOST_CHECK_EQUAL(find(), 2);
164
165 startInterest("ndn:/")
166 .setMinSuffixComponents(3);
167 BOOST_CHECK_EQUAL(find(), 3);
168
169 startInterest("ndn:/")
170 .setMinSuffixComponents(4);
171 BOOST_CHECK_EQUAL(find(), 4);
172
173 startInterest("ndn:/")
174 .setMinSuffixComponents(5);
175 BOOST_CHECK_EQUAL(find(), 5);
176
177 startInterest("ndn:/")
178 .setMinSuffixComponents(6);
179 BOOST_CHECK_EQUAL(find(), 6);
180
181 startInterest("ndn:/")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700182 .setMinSuffixComponents(7);
183 BOOST_CHECK_EQUAL(find(), 0);
184}
185
186BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
187{
188 insert(1, "ndn:/");
189 insert(2, "ndn:/A");
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800190 insert(3, "ndn:/B/2");
191 insert(4, "ndn:/C/2/3");
192 insert(5, "ndn:/D/2/3/4");
193 insert(6, "ndn:/E/2/3/4/5");
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700194
195 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800196 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700197 .setMaxSuffixComponents(0);
198 BOOST_CHECK_EQUAL(find(), 0);
199
200 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800201 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700202 .setMaxSuffixComponents(1);
203 BOOST_CHECK_EQUAL(find(), 1);
204
205 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800206 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700207 .setMaxSuffixComponents(2);
208 BOOST_CHECK_EQUAL(find(), 2);
209
210 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800211 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700212 .setMaxSuffixComponents(3);
213 BOOST_CHECK_EQUAL(find(), 3);
214
215 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800216 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700217 .setMaxSuffixComponents(4);
218 BOOST_CHECK_EQUAL(find(), 4);
219
220 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800221 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700222 .setMaxSuffixComponents(5);
223 BOOST_CHECK_EQUAL(find(), 5);
224
225 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800226 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700227 .setMaxSuffixComponents(6);
228 BOOST_CHECK_EQUAL(find(), 6);
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800229
230 startInterest("ndn:/")
231 .setChildSelector(1)
232 .setMaxSuffixComponents(7);
233 BOOST_CHECK_EQUAL(find(), 6);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700234}
235
236BOOST_AUTO_TEST_CASE(DigestOrder)
237{
238 insert(1, "ndn:/A");
239 insert(2, "ndn:/A");
240 // We don't know which comes first, but there must be some order
241
242 startInterest("ndn:/A")
243 .setChildSelector(0);
244 uint32_t leftmost = find();
245
246 startInterest("ndn:/A")
247 .setChildSelector(1);
248 uint32_t rightmost = find();
249
250 BOOST_CHECK_NE(leftmost, rightmost);
251}
252
253BOOST_AUTO_TEST_CASE(DigestExclude)
254{
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800255 insert(1, "ndn:/A");
256 Name n2 = insert(2, "ndn:/A");
257 insert(3, "ndn:/A/B");
258
259 uint8_t digest00[ndn::crypto::SHA256_DIGEST_SIZE];
260 std::fill_n(digest00, sizeof(digest00), 0x00);
261 uint8_t digestFF[ndn::crypto::SHA256_DIGEST_SIZE];
262 std::fill_n(digestFF, sizeof(digestFF), 0xFF);
263
264 Exclude excludeDigest;
265 excludeDigest.excludeRange(
266 name::Component::fromImplicitSha256Digest(digest00, sizeof(digest00)),
267 name::Component::fromImplicitSha256Digest(digestFF, sizeof(digestFF)));
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700268
269 startInterest("ndn:/A")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800270 .setChildSelector(0)
271 .setExclude(excludeDigest);
272 BOOST_CHECK_EQUAL(find(), 3);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700273
274 startInterest("ndn:/A")
275 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800276 .setExclude(excludeDigest);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700277 BOOST_CHECK_EQUAL(find(), 3);
278
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800279 Exclude excludeGeneric;
280 excludeGeneric.excludeAfter(name::Component(static_cast<uint8_t*>(nullptr), 0));
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700281
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800282 startInterest("ndn:/A")
283 .setChildSelector(0)
284 .setExclude(excludeGeneric);
285 int found1 = find();
286 BOOST_CHECK(found1 == 1 || found1 == 2);
287
288 startInterest("ndn:/A")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700289 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800290 .setExclude(excludeGeneric);
291 int found2 = find();
292 BOOST_CHECK(found2 == 1 || found2 == 2);
293
294 Exclude exclude2 = excludeGeneric;
295 exclude2.excludeOne(n2.get(-1));
296
297 startInterest("ndn:/A")
298 .setChildSelector(0)
299 .setExclude(exclude2);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700300 BOOST_CHECK_EQUAL(find(), 1);
301
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800302 startInterest("ndn:/A")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700303 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800304 .setExclude(exclude2);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700305 BOOST_CHECK_EQUAL(find(), 1);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700306}
307
308BOOST_AUTO_TEST_SUITE_END() // Find
309
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700310
311template<class Dataset>
312class Fixture : public Dataset
313{
314public:
315 Fixture()
316 : index(65535)
317 {
318 }
319
320public:
321 std::map<int64_t, shared_ptr<Data> > idToDataMap;
322 repo::Index index;
323};
324
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800325// Combine CommonDatasets with ComplexSelectorDataset
326typedef boost::mpl::push_back<CommonDatasets,
327 ComplexSelectorsDataset>::type Datasets;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700328
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800329BOOST_FIXTURE_TEST_CASE_TEMPLATE(Bulk, T, Datasets, Fixture<T>)
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700330{
331 BOOST_TEST_MESSAGE(T::getName());
332
333 for (typename T::DataContainer::iterator i = this->data.begin();
334 i != this->data.end(); ++i)
335 {
336 int64_t id = std::abs(static_cast<int64_t>(ndn::random::generateWord64()));
337 this->idToDataMap.insert(std::make_pair(id, *i));
338
339 BOOST_CHECK_EQUAL(this->index.insert(**i, id), true);
340 }
341
342 BOOST_CHECK_EQUAL(this->index.size(), this->data.size());
343
344 for (typename T::InterestContainer::iterator i = this->interests.begin();
345 i != this->interests.end(); ++i)
346 {
347 std::pair<int64_t, Name> item = this->index.find(i->first);
348
349 BOOST_REQUIRE_GT(item.first, 0);
350 BOOST_REQUIRE(this->idToDataMap.count(item.first) > 0);
351
352 BOOST_TEST_MESSAGE(i->first);
353 BOOST_CHECK_EQUAL(*this->idToDataMap[item.first], *i->second);
354
355 BOOST_CHECK_EQUAL(this->index.hasData(*i->second), true);
356 }
357
358 // Need support for selector-based removal
359 // for (typename T::RemovalsContainer::iterator i = this->removals.begin();
360 // i != this->removals.end(); ++i)
361 // {
362 // size_t nRemoved = 0;
363 // BOOST_REQUIRE_NO_THROW(this->index.erase(*i));
364 // BOOST_CHECK_EQUAL(nRemoved, i->seconds);
365 // }
366}
367
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700368BOOST_AUTO_TEST_SUITE_END()
369
370} // namespace tests
371} // namespace repo