blob: 6f255a23420f1e4753061b758e839454c280239a [file] [log] [blame]
Weiqi Shi28a90fb2014-07-09 10:28:55 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyevc0e26582017-08-13 21:16:49 -04002/*
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"
21
22#include "../sqlite-fixture.hpp"
23#include "../dataset-fixtures.hpp"
24
Alexander Afanasyevc0e26582017-08-13 21:16:49 -040025#include <iostream>
26
27#include <ndn-cxx/security/signing-helpers.hpp>
28#include <ndn-cxx/util/sha256.hpp>
29#include <ndn-cxx/util/random.hpp>
30
Junxiao Shi047a6fb2017-06-08 16:16:05 +000031#include <boost/mpl/push_back.hpp>
Weiqi Shi28a90fb2014-07-09 10:28:55 -070032#include <boost/test/unit_test.hpp>
Weiqi Shi28a90fb2014-07-09 10:28:55 -070033
34namespace repo {
35namespace tests {
36
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070037BOOST_AUTO_TEST_SUITE(Index)
Weiqi Shif0330d52014-07-09 10:54:27 -070038
Weiqi Shi28a90fb2014-07-09 10:28:55 -070039class FindFixture
40{
41protected:
42 FindFixture()
43 : m_index(std::numeric_limits<size_t>::max())
44 {
45 }
46
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080047 Name
Weiqi Shi28a90fb2014-07-09 10:28:55 -070048 insert(int id, const Name& name)
49 {
50 shared_ptr<Data> data = make_shared<Data>(name);
51 data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
Junxiao Shi047a6fb2017-06-08 16:16:05 +000052 m_keyChain.sign(*data, ndn::signingWithSha256());
Weiqi Shi28a90fb2014-07-09 10:28:55 -070053 data->wireEncode();
54 m_index.insert(*data, id);
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080055
56 return data->getFullName();
Weiqi Shi28a90fb2014-07-09 10:28:55 -070057 }
58
59 Interest&
60 startInterest(const Name& name)
61 {
62 m_interest = make_shared<Interest>(name);
63 return *m_interest;
64 }
65
Alexander Afanasyevd352cce2015-11-20 14:15:11 -050066 int
Weiqi Shi28a90fb2014-07-09 10:28:55 -070067 find()
68 {
Alexander Afanasyevd352cce2015-11-20 14:15:11 -050069 std::pair<int, Name> found = m_index.find(*m_interest);
Weiqi Shi28a90fb2014-07-09 10:28:55 -070070 return found.first;
71 }
72
73protected:
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070074 repo::Index m_index;
Weiqi Shi28a90fb2014-07-09 10:28:55 -070075 KeyChain m_keyChain;
76 shared_ptr<Interest> m_interest;
77};
78
79BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
80
81BOOST_AUTO_TEST_CASE(EmptyDataName)
82{
83 insert(1, "ndn:/");
84 startInterest("ndn:/");
85 BOOST_CHECK_EQUAL(find(), 1);
86}
87
88BOOST_AUTO_TEST_CASE(EmptyInterestName)
89{
90 insert(1, "ndn:/A");
91 startInterest("ndn:/");
92 BOOST_CHECK_EQUAL(find(), 1);
93}
94
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080095BOOST_AUTO_TEST_CASE(ExactName)
96{
97 insert(1, "ndn:/");
98 insert(2, "ndn:/A");
99 insert(3, "ndn:/A/B");
100 insert(4, "ndn:/A/C");
101 insert(5, "ndn:/D");
102
103 startInterest("ndn:/A");
104 BOOST_CHECK_EQUAL(find(), 2);
105}
106
107BOOST_AUTO_TEST_CASE(FullName)
108{
109 Name n1 = insert(1, "ndn:/A");
110 Name n2 = insert(2, "ndn:/A");
111
112 startInterest(n1);
113 BOOST_CHECK_EQUAL(find(), 1);
114
115 startInterest(n2);
116 BOOST_CHECK_EQUAL(find(), 2);
117}
118
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700119BOOST_AUTO_TEST_CASE(Leftmost)
120{
121 insert(1, "ndn:/A");
122 insert(2, "ndn:/B/p/1");
123 insert(3, "ndn:/B/p/2");
124 insert(4, "ndn:/B/q/1");
125 insert(5, "ndn:/B/q/2");
126 insert(6, "ndn:/C");
127
128 startInterest("ndn:/B");
129 BOOST_CHECK_EQUAL(find(), 2);
130}
131
132BOOST_AUTO_TEST_CASE(Rightmost)
133{
134 insert(1, "ndn:/A");
135 insert(2, "ndn:/B/p/1");
136 insert(3, "ndn:/B/p/2");
137 insert(4, "ndn:/B/q/1");
138 insert(5, "ndn:/B/q/2");
139 insert(6, "ndn:/C");
140
141 startInterest("ndn:/B")
142 .setChildSelector(1);
143 BOOST_CHECK_EQUAL(find(), 4);
144}
145
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800146BOOST_AUTO_TEST_CASE(MinSuffixComponents)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700147{
148 insert(1, "ndn:/");
149 insert(2, "ndn:/A");
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800150 insert(3, "ndn:/B/1");
151 insert(4, "ndn:/C/1/2");
152 insert(5, "ndn:/D/1/2/3");
153 insert(6, "ndn:/E/1/2/3/4");
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700154
155 startInterest("ndn:/")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700156 .setMinSuffixComponents(0);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700157 BOOST_CHECK_EQUAL(find(), 1);
158
159 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800160 .setMinSuffixComponents(1);
161 BOOST_CHECK_EQUAL(find(), 1);
162
163 startInterest("ndn:/")
164 .setMinSuffixComponents(2);
165 BOOST_CHECK_EQUAL(find(), 2);
166
167 startInterest("ndn:/")
168 .setMinSuffixComponents(3);
169 BOOST_CHECK_EQUAL(find(), 3);
170
171 startInterest("ndn:/")
172 .setMinSuffixComponents(4);
173 BOOST_CHECK_EQUAL(find(), 4);
174
175 startInterest("ndn:/")
176 .setMinSuffixComponents(5);
177 BOOST_CHECK_EQUAL(find(), 5);
178
179 startInterest("ndn:/")
180 .setMinSuffixComponents(6);
181 BOOST_CHECK_EQUAL(find(), 6);
182
183 startInterest("ndn:/")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700184 .setMinSuffixComponents(7);
185 BOOST_CHECK_EQUAL(find(), 0);
186}
187
188BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
189{
190 insert(1, "ndn:/");
191 insert(2, "ndn:/A");
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800192 insert(3, "ndn:/B/2");
193 insert(4, "ndn:/C/2/3");
194 insert(5, "ndn:/D/2/3/4");
195 insert(6, "ndn:/E/2/3/4/5");
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700196
197 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800198 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700199 .setMaxSuffixComponents(0);
200 BOOST_CHECK_EQUAL(find(), 0);
201
202 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800203 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700204 .setMaxSuffixComponents(1);
205 BOOST_CHECK_EQUAL(find(), 1);
206
207 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800208 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700209 .setMaxSuffixComponents(2);
210 BOOST_CHECK_EQUAL(find(), 2);
211
212 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800213 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700214 .setMaxSuffixComponents(3);
215 BOOST_CHECK_EQUAL(find(), 3);
216
217 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800218 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700219 .setMaxSuffixComponents(4);
220 BOOST_CHECK_EQUAL(find(), 4);
221
222 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800223 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700224 .setMaxSuffixComponents(5);
225 BOOST_CHECK_EQUAL(find(), 5);
226
227 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800228 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700229 .setMaxSuffixComponents(6);
230 BOOST_CHECK_EQUAL(find(), 6);
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800231
232 startInterest("ndn:/")
233 .setChildSelector(1)
234 .setMaxSuffixComponents(7);
235 BOOST_CHECK_EQUAL(find(), 6);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700236}
237
238BOOST_AUTO_TEST_CASE(DigestOrder)
239{
240 insert(1, "ndn:/A");
241 insert(2, "ndn:/A");
242 // We don't know which comes first, but there must be some order
243
244 startInterest("ndn:/A")
245 .setChildSelector(0);
246 uint32_t leftmost = find();
247
248 startInterest("ndn:/A")
249 .setChildSelector(1);
250 uint32_t rightmost = find();
251
252 BOOST_CHECK_NE(leftmost, rightmost);
253}
254
255BOOST_AUTO_TEST_CASE(DigestExclude)
256{
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800257 insert(1, "ndn:/A");
258 Name n2 = insert(2, "ndn:/A");
259 insert(3, "ndn:/A/B");
260
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400261 uint8_t digest00[ndn::util::Sha256::DIGEST_SIZE];
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800262 std::fill_n(digest00, sizeof(digest00), 0x00);
Alexander Afanasyevc0e26582017-08-13 21:16:49 -0400263 uint8_t digestFF[ndn::util::Sha256::DIGEST_SIZE];
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800264 std::fill_n(digestFF, sizeof(digestFF), 0xFF);
265
266 Exclude excludeDigest;
267 excludeDigest.excludeRange(
268 name::Component::fromImplicitSha256Digest(digest00, sizeof(digest00)),
269 name::Component::fromImplicitSha256Digest(digestFF, sizeof(digestFF)));
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700270
271 startInterest("ndn:/A")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800272 .setChildSelector(0)
273 .setExclude(excludeDigest);
274 BOOST_CHECK_EQUAL(find(), 3);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700275
276 startInterest("ndn:/A")
277 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800278 .setExclude(excludeDigest);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700279 BOOST_CHECK_EQUAL(find(), 3);
280
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800281 Exclude excludeGeneric;
282 excludeGeneric.excludeAfter(name::Component(static_cast<uint8_t*>(nullptr), 0));
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700283
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800284 startInterest("ndn:/A")
285 .setChildSelector(0)
286 .setExclude(excludeGeneric);
287 int found1 = find();
288 BOOST_CHECK(found1 == 1 || found1 == 2);
289
290 startInterest("ndn:/A")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700291 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800292 .setExclude(excludeGeneric);
293 int found2 = find();
294 BOOST_CHECK(found2 == 1 || found2 == 2);
295
296 Exclude exclude2 = excludeGeneric;
297 exclude2.excludeOne(n2.get(-1));
298
299 startInterest("ndn:/A")
300 .setChildSelector(0)
301 .setExclude(exclude2);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700302 BOOST_CHECK_EQUAL(find(), 1);
303
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800304 startInterest("ndn:/A")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700305 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800306 .setExclude(exclude2);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700307 BOOST_CHECK_EQUAL(find(), 1);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700308}
309
310BOOST_AUTO_TEST_SUITE_END() // Find
311
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700312
313template<class Dataset>
314class Fixture : public Dataset
315{
316public:
317 Fixture()
318 : index(65535)
319 {
320 }
321
322public:
323 std::map<int64_t, shared_ptr<Data> > idToDataMap;
324 repo::Index index;
325};
326
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800327// Combine CommonDatasets with ComplexSelectorDataset
328typedef boost::mpl::push_back<CommonDatasets,
329 ComplexSelectorsDataset>::type Datasets;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700330
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800331BOOST_FIXTURE_TEST_CASE_TEMPLATE(Bulk, T, Datasets, Fixture<T>)
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700332{
333 BOOST_TEST_MESSAGE(T::getName());
334
335 for (typename T::DataContainer::iterator i = this->data.begin();
336 i != this->data.end(); ++i)
337 {
338 int64_t id = std::abs(static_cast<int64_t>(ndn::random::generateWord64()));
339 this->idToDataMap.insert(std::make_pair(id, *i));
340
341 BOOST_CHECK_EQUAL(this->index.insert(**i, id), true);
342 }
343
344 BOOST_CHECK_EQUAL(this->index.size(), this->data.size());
345
346 for (typename T::InterestContainer::iterator i = this->interests.begin();
347 i != this->interests.end(); ++i)
348 {
349 std::pair<int64_t, Name> item = this->index.find(i->first);
350
351 BOOST_REQUIRE_GT(item.first, 0);
352 BOOST_REQUIRE(this->idToDataMap.count(item.first) > 0);
353
354 BOOST_TEST_MESSAGE(i->first);
355 BOOST_CHECK_EQUAL(*this->idToDataMap[item.first], *i->second);
356
357 BOOST_CHECK_EQUAL(this->index.hasData(*i->second), true);
358 }
359
360 // Need support for selector-based removal
361 // for (typename T::RemovalsContainer::iterator i = this->removals.begin();
362 // i != this->removals.end(); ++i)
363 // {
364 // size_t nRemoved = 0;
365 // BOOST_REQUIRE_NO_THROW(this->index.erase(*i));
366 // BOOST_CHECK_EQUAL(nRemoved, i->seconds);
367 // }
368}
369
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700370BOOST_AUTO_TEST_SUITE_END()
371
372} // namespace tests
373} // namespace repo