blob: f2cf9191fffe03c7f8270ea46fd0b90c6ad8067d [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
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080041 Name
Weiqi Shi28a90fb2014-07-09 10:28:55 -070042 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);
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080049
50 return data->getFullName();
Weiqi Shi28a90fb2014-07-09 10:28:55 -070051 }
52
53 Interest&
54 startInterest(const Name& name)
55 {
56 m_interest = make_shared<Interest>(name);
57 return *m_interest;
58 }
59
Weiqi Shif0330d52014-07-09 10:54:27 -070060 uint64_t
Weiqi Shi28a90fb2014-07-09 10:28:55 -070061 find()
62 {
63 std::pair<int,Name> found = m_index.find(*m_interest);
64 return found.first;
65 }
66
67protected:
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -070068 repo::Index m_index;
Weiqi Shi28a90fb2014-07-09 10:28:55 -070069 KeyChain m_keyChain;
70 shared_ptr<Interest> m_interest;
71};
72
73BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
74
75BOOST_AUTO_TEST_CASE(EmptyDataName)
76{
77 insert(1, "ndn:/");
78 startInterest("ndn:/");
79 BOOST_CHECK_EQUAL(find(), 1);
80}
81
82BOOST_AUTO_TEST_CASE(EmptyInterestName)
83{
84 insert(1, "ndn:/A");
85 startInterest("ndn:/");
86 BOOST_CHECK_EQUAL(find(), 1);
87}
88
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -080089BOOST_AUTO_TEST_CASE(ExactName)
90{
91 insert(1, "ndn:/");
92 insert(2, "ndn:/A");
93 insert(3, "ndn:/A/B");
94 insert(4, "ndn:/A/C");
95 insert(5, "ndn:/D");
96
97 startInterest("ndn:/A");
98 BOOST_CHECK_EQUAL(find(), 2);
99}
100
101BOOST_AUTO_TEST_CASE(FullName)
102{
103 Name n1 = insert(1, "ndn:/A");
104 Name n2 = insert(2, "ndn:/A");
105
106 startInterest(n1);
107 BOOST_CHECK_EQUAL(find(), 1);
108
109 startInterest(n2);
110 BOOST_CHECK_EQUAL(find(), 2);
111}
112
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700113BOOST_AUTO_TEST_CASE(Leftmost)
114{
115 insert(1, "ndn:/A");
116 insert(2, "ndn:/B/p/1");
117 insert(3, "ndn:/B/p/2");
118 insert(4, "ndn:/B/q/1");
119 insert(5, "ndn:/B/q/2");
120 insert(6, "ndn:/C");
121
122 startInterest("ndn:/B");
123 BOOST_CHECK_EQUAL(find(), 2);
124}
125
126BOOST_AUTO_TEST_CASE(Rightmost)
127{
128 insert(1, "ndn:/A");
129 insert(2, "ndn:/B/p/1");
130 insert(3, "ndn:/B/p/2");
131 insert(4, "ndn:/B/q/1");
132 insert(5, "ndn:/B/q/2");
133 insert(6, "ndn:/C");
134
135 startInterest("ndn:/B")
136 .setChildSelector(1);
137 BOOST_CHECK_EQUAL(find(), 4);
138}
139
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800140BOOST_AUTO_TEST_CASE(MinSuffixComponents)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700141{
142 insert(1, "ndn:/");
143 insert(2, "ndn:/A");
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800144 insert(3, "ndn:/B/1");
145 insert(4, "ndn:/C/1/2");
146 insert(5, "ndn:/D/1/2/3");
147 insert(6, "ndn:/E/1/2/3/4");
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700148
149 startInterest("ndn:/")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700150 .setMinSuffixComponents(0);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700151 BOOST_CHECK_EQUAL(find(), 1);
152
153 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800154 .setMinSuffixComponents(1);
155 BOOST_CHECK_EQUAL(find(), 1);
156
157 startInterest("ndn:/")
158 .setMinSuffixComponents(2);
159 BOOST_CHECK_EQUAL(find(), 2);
160
161 startInterest("ndn:/")
162 .setMinSuffixComponents(3);
163 BOOST_CHECK_EQUAL(find(), 3);
164
165 startInterest("ndn:/")
166 .setMinSuffixComponents(4);
167 BOOST_CHECK_EQUAL(find(), 4);
168
169 startInterest("ndn:/")
170 .setMinSuffixComponents(5);
171 BOOST_CHECK_EQUAL(find(), 5);
172
173 startInterest("ndn:/")
174 .setMinSuffixComponents(6);
175 BOOST_CHECK_EQUAL(find(), 6);
176
177 startInterest("ndn:/")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700178 .setMinSuffixComponents(7);
179 BOOST_CHECK_EQUAL(find(), 0);
180}
181
182BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
183{
184 insert(1, "ndn:/");
185 insert(2, "ndn:/A");
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800186 insert(3, "ndn:/B/2");
187 insert(4, "ndn:/C/2/3");
188 insert(5, "ndn:/D/2/3/4");
189 insert(6, "ndn:/E/2/3/4/5");
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700190
191 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800192 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700193 .setMaxSuffixComponents(0);
194 BOOST_CHECK_EQUAL(find(), 0);
195
196 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800197 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700198 .setMaxSuffixComponents(1);
199 BOOST_CHECK_EQUAL(find(), 1);
200
201 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800202 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700203 .setMaxSuffixComponents(2);
204 BOOST_CHECK_EQUAL(find(), 2);
205
206 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800207 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700208 .setMaxSuffixComponents(3);
209 BOOST_CHECK_EQUAL(find(), 3);
210
211 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800212 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700213 .setMaxSuffixComponents(4);
214 BOOST_CHECK_EQUAL(find(), 4);
215
216 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800217 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700218 .setMaxSuffixComponents(5);
219 BOOST_CHECK_EQUAL(find(), 5);
220
221 startInterest("ndn:/")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800222 .setChildSelector(1)
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700223 .setMaxSuffixComponents(6);
224 BOOST_CHECK_EQUAL(find(), 6);
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800225
226 startInterest("ndn:/")
227 .setChildSelector(1)
228 .setMaxSuffixComponents(7);
229 BOOST_CHECK_EQUAL(find(), 6);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700230}
231
232BOOST_AUTO_TEST_CASE(DigestOrder)
233{
234 insert(1, "ndn:/A");
235 insert(2, "ndn:/A");
236 // We don't know which comes first, but there must be some order
237
238 startInterest("ndn:/A")
239 .setChildSelector(0);
240 uint32_t leftmost = find();
241
242 startInterest("ndn:/A")
243 .setChildSelector(1);
244 uint32_t rightmost = find();
245
246 BOOST_CHECK_NE(leftmost, rightmost);
247}
248
249BOOST_AUTO_TEST_CASE(DigestExclude)
250{
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800251 insert(1, "ndn:/A");
252 Name n2 = insert(2, "ndn:/A");
253 insert(3, "ndn:/A/B");
254
255 uint8_t digest00[ndn::crypto::SHA256_DIGEST_SIZE];
256 std::fill_n(digest00, sizeof(digest00), 0x00);
257 uint8_t digestFF[ndn::crypto::SHA256_DIGEST_SIZE];
258 std::fill_n(digestFF, sizeof(digestFF), 0xFF);
259
260 Exclude excludeDigest;
261 excludeDigest.excludeRange(
262 name::Component::fromImplicitSha256Digest(digest00, sizeof(digest00)),
263 name::Component::fromImplicitSha256Digest(digestFF, sizeof(digestFF)));
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700264
265 startInterest("ndn:/A")
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800266 .setChildSelector(0)
267 .setExclude(excludeDigest);
268 BOOST_CHECK_EQUAL(find(), 3);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700269
270 startInterest("ndn:/A")
271 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800272 .setExclude(excludeDigest);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700273 BOOST_CHECK_EQUAL(find(), 3);
274
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800275 Exclude excludeGeneric;
276 excludeGeneric.excludeAfter(name::Component(static_cast<uint8_t*>(nullptr), 0));
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700277
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800278 startInterest("ndn:/A")
279 .setChildSelector(0)
280 .setExclude(excludeGeneric);
281 int found1 = find();
282 BOOST_CHECK(found1 == 1 || found1 == 2);
283
284 startInterest("ndn:/A")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700285 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800286 .setExclude(excludeGeneric);
287 int found2 = find();
288 BOOST_CHECK(found2 == 1 || found2 == 2);
289
290 Exclude exclude2 = excludeGeneric;
291 exclude2.excludeOne(n2.get(-1));
292
293 startInterest("ndn:/A")
294 .setChildSelector(0)
295 .setExclude(exclude2);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700296 BOOST_CHECK_EQUAL(find(), 1);
297
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800298 startInterest("ndn:/A")
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700299 .setChildSelector(1)
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800300 .setExclude(exclude2);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700301 BOOST_CHECK_EQUAL(find(), 1);
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700302}
303
304BOOST_AUTO_TEST_SUITE_END() // Find
305
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700306
307template<class Dataset>
308class Fixture : public Dataset
309{
310public:
311 Fixture()
312 : index(65535)
313 {
314 }
315
316public:
317 std::map<int64_t, shared_ptr<Data> > idToDataMap;
318 repo::Index index;
319};
320
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800321// Combine CommonDatasets with ComplexSelectorDataset
322typedef boost::mpl::push_back<CommonDatasets,
323 ComplexSelectorsDataset>::type Datasets;
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700324
Alexander Afanasyev595b2bd2014-12-14 12:55:36 -0800325BOOST_FIXTURE_TEST_CASE_TEMPLATE(Bulk, T, Datasets, Fixture<T>)
Alexander Afanasyevb7e8a812014-07-23 01:36:47 -0700326{
327 BOOST_TEST_MESSAGE(T::getName());
328
329 for (typename T::DataContainer::iterator i = this->data.begin();
330 i != this->data.end(); ++i)
331 {
332 int64_t id = std::abs(static_cast<int64_t>(ndn::random::generateWord64()));
333 this->idToDataMap.insert(std::make_pair(id, *i));
334
335 BOOST_CHECK_EQUAL(this->index.insert(**i, id), true);
336 }
337
338 BOOST_CHECK_EQUAL(this->index.size(), this->data.size());
339
340 for (typename T::InterestContainer::iterator i = this->interests.begin();
341 i != this->interests.end(); ++i)
342 {
343 std::pair<int64_t, Name> item = this->index.find(i->first);
344
345 BOOST_REQUIRE_GT(item.first, 0);
346 BOOST_REQUIRE(this->idToDataMap.count(item.first) > 0);
347
348 BOOST_TEST_MESSAGE(i->first);
349 BOOST_CHECK_EQUAL(*this->idToDataMap[item.first], *i->second);
350
351 BOOST_CHECK_EQUAL(this->index.hasData(*i->second), true);
352 }
353
354 // Need support for selector-based removal
355 // for (typename T::RemovalsContainer::iterator i = this->removals.begin();
356 // i != this->removals.end(); ++i)
357 // {
358 // size_t nRemoved = 0;
359 // BOOST_REQUIRE_NO_THROW(this->index.erase(*i));
360 // BOOST_CHECK_EQUAL(nRemoved, i->seconds);
361 // }
362}
363
Weiqi Shi28a90fb2014-07-09 10:28:55 -0700364BOOST_AUTO_TEST_SUITE_END()
365
366} // namespace tests
367} // namespace repo