blob: da597fdbcad6e9a46a90527190f78182482fc8b5 [file] [log] [blame]
Junxiao Shidf4b24e2016-07-14 21:41:43 +00001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shi71ff2312017-07-12 13:32:50 +00002/*
Davide Pesavento0f830802018-01-16 23:58:58 -05003 * Copyright (c) 2013-2018 Regents of the University of California.
Junxiao Shidf4b24e2016-07-14 21:41:43 +00004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "name-component.hpp"
Junxiao Shi71ff2312017-07-12 13:32:50 +000023#include "name.hpp"
Junxiao Shidf4b24e2016-07-14 21:41:43 +000024
25#include "boost-test.hpp"
26#include <boost/mpl/vector.hpp>
27
28namespace ndn {
29namespace tests {
30
31BOOST_AUTO_TEST_SUITE(TestNameComponent)
32
33static const uint8_t NAME_COMPONENT_WIRE[] = {
34 0x08, 0x03, // NameComponent
Davide Pesavento08378cb2018-02-01 16:10:54 -050035 0x6e, 0x64, 0x6e
36};
Junxiao Shidf4b24e2016-07-14 21:41:43 +000037static const uint8_t NAME_COMPONENT2_WIRE[] = {
38 0x08, 0x20, // ImplicitSha256DigestComponent
39 0x28, 0xba, 0xd4, 0xb5, 0x27, 0x5b, 0xd3, 0x92,
40 0xdb, 0xb6, 0x70, 0xc7, 0x5c, 0xf0, 0xb6, 0x6f,
41 0x13, 0xf7, 0x94, 0x2b, 0x21, 0xe8, 0x0f, 0x55,
Davide Pesavento08378cb2018-02-01 16:10:54 -050042 0xc0, 0xe8, 0x6b, 0x37, 0x47, 0x53, 0xa5, 0x49
43};
Junxiao Shidf4b24e2016-07-14 21:41:43 +000044static const uint8_t DIGEST_COMPONENT_WIRE[] = {
45 0x01, 0x20, // ImplicitSha256DigestComponent
46 0x28, 0xba, 0xd4, 0xb5, 0x27, 0x5b, 0xd3, 0x92,
47 0xdb, 0xb6, 0x70, 0xc7, 0x5c, 0xf0, 0xb6, 0x6f,
48 0x13, 0xf7, 0x94, 0x2b, 0x21, 0xe8, 0x0f, 0x55,
Davide Pesavento08378cb2018-02-01 16:10:54 -050049 0xc0, 0xe8, 0x6b, 0x37, 0x47, 0x53, 0xa5, 0x48
50};
Junxiao Shidf4b24e2016-07-14 21:41:43 +000051static const uint8_t DIGEST_COMPONENT2_WIRE[] = {
52 0x01, 0x20, // ImplicitSha256DigestComponent
53 0x28, 0xba, 0xd4, 0xb5, 0x27, 0x5b, 0xd3, 0x92,
54 0xdb, 0xb6, 0x70, 0xc7, 0x5c, 0xf0, 0xb6, 0x6f,
55 0x13, 0xf7, 0x94, 0x2b, 0x21, 0xe8, 0x0f, 0x55,
Davide Pesavento08378cb2018-02-01 16:10:54 -050056 0xc0, 0xe8, 0x6b, 0x37, 0x47, 0x53, 0xa5, 0x49
57};
Junxiao Shidf4b24e2016-07-14 21:41:43 +000058static const uint8_t INVALID_COMPONENT_WIRE[] = {
59 0x07, 0x03, // unknown component type
Davide Pesavento08378cb2018-02-01 16:10:54 -050060 0x6e, 0x64, 0x6e
61};
Junxiao Shidf4b24e2016-07-14 21:41:43 +000062
63BOOST_AUTO_TEST_SUITE(Decode)
64
65BOOST_AUTO_TEST_CASE(Generic)
66{
67 Block block(NAME_COMPONENT_WIRE, sizeof(NAME_COMPONENT_WIRE));
68 name::Component comp;
Davide Pesavento08378cb2018-02-01 16:10:54 -050069 BOOST_CHECK_NO_THROW(comp.wireDecode(block));
Junxiao Shidf4b24e2016-07-14 21:41:43 +000070 BOOST_CHECK_EQUAL(comp.toUri(), "ndn");
71}
72
73BOOST_AUTO_TEST_CASE(Digest)
74{
75 Block block(DIGEST_COMPONENT_WIRE, sizeof(DIGEST_COMPONENT_WIRE));
76 name::Component comp;
Davide Pesavento08378cb2018-02-01 16:10:54 -050077 BOOST_CHECK_NO_THROW(comp.wireDecode(block));
78 BOOST_CHECK_EQUAL(comp.toUri(), "sha256digest=28bad4b5275bd392dbb670c75cf0b66f"
79 "13f7942b21e80f55c0e86b374753a548");
Junxiao Shidf4b24e2016-07-14 21:41:43 +000080}
81
82BOOST_AUTO_TEST_CASE(Invalid)
83{
84 Block block(INVALID_COMPONENT_WIRE, sizeof(INVALID_COMPONENT_WIRE));
85 name::Component comp;
Davide Pesavento08378cb2018-02-01 16:10:54 -050086 BOOST_CHECK_THROW(comp.wireDecode(block), name::Component::Error);
Junxiao Shidf4b24e2016-07-14 21:41:43 +000087}
88
89BOOST_AUTO_TEST_SUITE_END() // Decode
90
91BOOST_AUTO_TEST_SUITE(Compare)
92
93BOOST_AUTO_TEST_CASE(Generic)
94{
Davide Pesaventoe245b052017-10-31 13:00:44 -040095 name::Component empty;
Junxiao Shidf4b24e2016-07-14 21:41:43 +000096 name::Component compD("D");
97 name::Component compD2("D");
98 name::Component compF("F");
99 name::Component compAA("AA");
100
Davide Pesaventoe245b052017-10-31 13:00:44 -0400101 BOOST_CHECK_EQUAL(empty == empty, true);
102 BOOST_CHECK_EQUAL(empty != empty, false);
103 BOOST_CHECK_EQUAL(empty < empty, false);
104 BOOST_CHECK_EQUAL(empty <= empty, true);
105 BOOST_CHECK_EQUAL(empty == compD, false);
106 BOOST_CHECK_EQUAL(empty < compD, true);
107
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000108 BOOST_CHECK_EQUAL(compD == compD2, true);
109 BOOST_CHECK_EQUAL(compD != compD2, false);
110 BOOST_CHECK_EQUAL(compD < compD2, false);
111 BOOST_CHECK_EQUAL(compD <= compD2, true);
112 BOOST_CHECK_EQUAL(compD > compD2, false);
113 BOOST_CHECK_EQUAL(compD >= compD2, true);
114
115 BOOST_CHECK_EQUAL(compD == compF, false);
116 BOOST_CHECK_EQUAL(compD != compF, true);
117 BOOST_CHECK_EQUAL(compD < compF, true);
118 BOOST_CHECK_EQUAL(compD <= compF, true);
119 BOOST_CHECK_EQUAL(compD > compF, false);
120 BOOST_CHECK_EQUAL(compD >= compF, false);
121
122 BOOST_CHECK_EQUAL(compF == compAA, false);
123 BOOST_CHECK_EQUAL(compF != compAA, true);
124 BOOST_CHECK_EQUAL(compF < compAA, true);
125 BOOST_CHECK_EQUAL(compF <= compAA, true);
126 BOOST_CHECK_EQUAL(compF > compAA, false);
127 BOOST_CHECK_EQUAL(compF >= compAA, false);
128}
129
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000130BOOST_AUTO_TEST_CASE(Digest)
131{
132 name::Component digest1(Block(DIGEST_COMPONENT_WIRE, sizeof(DIGEST_COMPONENT_WIRE)));
133 name::Component digest1b(Block(DIGEST_COMPONENT_WIRE, sizeof(DIGEST_COMPONENT_WIRE)));
134 name::Component digest2(Block(DIGEST_COMPONENT2_WIRE, sizeof(DIGEST_COMPONENT2_WIRE)));
135 name::Component generic0;
136 name::Component generic2(Block(NAME_COMPONENT2_WIRE, sizeof(NAME_COMPONENT2_WIRE)));
137
138 BOOST_CHECK_EQUAL(digest1 == digest1b, true);
139 BOOST_CHECK_EQUAL(digest1 != digest1b, false);
140 BOOST_CHECK_EQUAL(digest1 < digest1b, false);
141 BOOST_CHECK_EQUAL(digest1 <= digest1b, true);
142 BOOST_CHECK_EQUAL(digest1 > digest1b, false);
143 BOOST_CHECK_EQUAL(digest1 >= digest1b, true);
144
145 BOOST_CHECK_EQUAL(digest1 == digest2, false);
146 BOOST_CHECK_EQUAL(digest1 != digest2, true);
147 BOOST_CHECK_EQUAL(digest1 < digest2, true);
148 BOOST_CHECK_EQUAL(digest1 <= digest2, true);
149 BOOST_CHECK_EQUAL(digest1 > digest2, false);
150 BOOST_CHECK_EQUAL(digest1 >= digest2, false);
151
152 BOOST_CHECK_EQUAL(digest1 == generic0, false);
153 BOOST_CHECK_EQUAL(digest1 != generic0, true);
154 BOOST_CHECK_EQUAL(digest1 < generic0, true);
155 BOOST_CHECK_EQUAL(digest1 <= generic0, true);
156 BOOST_CHECK_EQUAL(digest1 > generic0, false);
157 BOOST_CHECK_EQUAL(digest1 >= generic0, false);
158
159 BOOST_CHECK_EQUAL(digest2 == generic2, false);
160 BOOST_CHECK_EQUAL(digest2 != generic2, true);
161 BOOST_CHECK_EQUAL(digest2 < generic2, true);
162 BOOST_CHECK_EQUAL(digest2 <= generic2, true);
163 BOOST_CHECK_EQUAL(digest2 > generic2, false);
164 BOOST_CHECK_EQUAL(digest2 >= generic2, false);
165}
166
Davide Pesavento08378cb2018-02-01 16:10:54 -0500167BOOST_AUTO_TEST_CASE(ZeroLength)
168{
169 name::Component comp0("");
170 BOOST_CHECK_EQUAL(comp0.value_size(), 0);
171
172 BOOST_CHECK_EQUAL(comp0, comp0);
173 BOOST_CHECK_EQUAL(comp0, name::Component(""));
174 BOOST_CHECK_LT(comp0, name::Component("A"));
175 BOOST_CHECK_LE(comp0, name::Component("A"));
176 BOOST_CHECK_NE(comp0, name::Component("A"));
177 BOOST_CHECK_GT(name::Component("A"), comp0);
178 BOOST_CHECK_GE(name::Component("A"), comp0);
179}
180
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000181BOOST_AUTO_TEST_SUITE_END() // Compare
182
Davide Pesavento08378cb2018-02-01 16:10:54 -0500183BOOST_AUTO_TEST_CASE(ToUri)
184{
185 using name::Component;
186
187 BOOST_CHECK_EQUAL(Component("").toUri(), "...");
188 BOOST_CHECK_EQUAL(Component(".").toUri(), "....");
189 BOOST_CHECK_EQUAL(Component("..").toUri(), ".....");
190 BOOST_CHECK_EQUAL(Component(".dot-with-other-chars").toUri(), ".dot-with-other-chars");
191
192 BOOST_CHECK_EQUAL(Component("foo42").toUri(), "foo42");
193 BOOST_CHECK_EQUAL(Component("foo%bar").toUri(), "foo%25bar");
194 BOOST_CHECK_EQUAL(Component("-._~").toUri(), "-._~");
195 BOOST_CHECK_EQUAL(Component(":/?#[]@").toUri(), "%3A%2F%3F%23%5B%5D%40");
196
197 // sha256digest component is tested in Decode/Digest
198}
199
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000200BOOST_AUTO_TEST_SUITE(CreateFromIterators) // Bug 2490
201
202typedef boost::mpl::vector<
203 std::vector<uint8_t>,
204 std::list<uint8_t>,
205 std::vector<int8_t>,
206 std::list<int8_t>
207> ContainerTypes;
208
209BOOST_AUTO_TEST_CASE_TEMPLATE(ZeroOctet, T, ContainerTypes)
210{
211 T bytes;
212 name::Component c(bytes.begin(), bytes.end());
213 BOOST_CHECK_EQUAL(c.value_size(), 0);
214 BOOST_CHECK_EQUAL(c.size(), 2);
215}
216
217BOOST_AUTO_TEST_CASE_TEMPLATE(OneOctet, T, ContainerTypes)
218{
219 T bytes{1};
220 name::Component c(bytes.begin(), bytes.end());
221 BOOST_CHECK_EQUAL(c.value_size(), 1);
222 BOOST_CHECK_EQUAL(c.size(), 3);
223}
224
225BOOST_AUTO_TEST_CASE_TEMPLATE(FourOctets, T, ContainerTypes)
226{
227 T bytes{1, 2, 3, 4};
228 name::Component c(bytes.begin(), bytes.end());
229 BOOST_CHECK_EQUAL(c.value_size(), 4);
230 BOOST_CHECK_EQUAL(c.size(), 6);
231}
232
233BOOST_AUTO_TEST_SUITE_END() // CreateFromIterators
234
Junxiao Shi71ff2312017-07-12 13:32:50 +0000235BOOST_AUTO_TEST_SUITE(NamingConvention)
236
237template<typename ArgType>
238struct ConventionTest
239{
240 function<name::Component(ArgType)> makeComponent;
241 function<ArgType(const name::Component&)> getValue;
242 function<Name&(Name&, ArgType)> append;
243 Name expected;
244 ArgType value;
245 function<bool(const name::Component&)> isComponent;
246};
247
248class NumberWithMarker
249{
250public:
251 ConventionTest<uint64_t>
252 operator()() const
253 {
254 return {bind(&name::Component::fromNumberWithMarker, 0xAA, _1),
255 bind(&name::Component::toNumberWithMarker, _1, 0xAA),
256 bind(&Name::appendNumberWithMarker, _1, 0xAA, _2),
257 Name("/%AA%03%E8"),
258 1000,
259 bind(&name::Component::isNumberWithMarker, _1, 0xAA)};
260 }
261};
262
263class Segment
264{
265public:
266 ConventionTest<uint64_t>
267 operator()() const
268 {
269 return {&name::Component::fromSegment,
270 bind(&name::Component::toSegment, _1),
271 bind(&Name::appendSegment, _1, _2),
272 Name("/%00%27%10"),
273 10000,
274 bind(&name::Component::isSegment, _1)};
275 }
276};
277
278class SegmentOffset
279{
280public:
281 ConventionTest<uint64_t>
282 operator()() const
283 {
284 return {&name::Component::fromSegmentOffset,
285 bind(&name::Component::toSegmentOffset, _1),
286 bind(&Name::appendSegmentOffset, _1, _2),
287 Name("/%FB%00%01%86%A0"),
288 100000,
289 bind(&name::Component::isSegmentOffset, _1)};
290 }
291};
292
293class Version
294{
295public:
296 ConventionTest<uint64_t>
297 operator()() const
298 {
299 return {&name::Component::fromVersion,
300 bind(&name::Component::toVersion, _1),
301 [] (Name& name, uint64_t version) -> Name& { return name.appendVersion(version); },
302 Name("/%FD%00%0FB%40"),
303 1000000,
304 bind(&name::Component::isVersion, _1)};
305 }
306};
307
308class Timestamp
309{
310public:
311 ConventionTest<time::system_clock::TimePoint>
312 operator()() const
313 {
314 return {&name::Component::fromTimestamp,
315 bind(&name::Component::toTimestamp, _1),
316 [] (Name& name, time::system_clock::TimePoint t) -> Name& { return name.appendTimestamp(t); },
317 Name("/%FC%00%04%7BE%E3%1B%00%00"),
Davide Pesavento0f830802018-01-16 23:58:58 -0500318 time::getUnixEpoch() + 14600_days, // 40 years
Junxiao Shi71ff2312017-07-12 13:32:50 +0000319 bind(&name::Component::isTimestamp, _1)};
320 }
321};
322
323class SequenceNumber
324{
325public:
326 ConventionTest<uint64_t>
327 operator()() const
328 {
329 return {&name::Component::fromSequenceNumber,
330 bind(&name::Component::toSequenceNumber, _1),
331 bind(&Name::appendSequenceNumber, _1, _2),
332 Name("/%FE%00%98%96%80"),
333 10000000,
334 bind(&name::Component::isSequenceNumber, _1)};
335 }
336};
337
338using ConventionTests = boost::mpl::vector<
339 NumberWithMarker,
340 Segment,
341 SegmentOffset,
342 Version,
343 Timestamp,
344 SequenceNumber
345>;
346
347BOOST_AUTO_TEST_CASE_TEMPLATE(Convention, T, ConventionTests)
348{
349 name::Component invalidComponent1;
350 name::Component invalidComponent2("1234567890");
351
352 auto test = T()();
353
354 const Name& expected = test.expected;
355 BOOST_TEST_MESSAGE("Check " << expected[0].toUri());
356
357 BOOST_CHECK_EQUAL(expected[0].isGeneric(), true);
358
359 name::Component actualComponent = test.makeComponent(test.value);
360 BOOST_CHECK_EQUAL(actualComponent, expected[0]);
361
362 Name actualName;
363 test.append(actualName, test.value);
364 BOOST_CHECK_EQUAL(actualName, expected);
365
366 BOOST_CHECK_EQUAL(test.isComponent(expected[0]), true);
367 BOOST_CHECK_EQUAL(test.getValue(expected[0]), test.value);
368
369 BOOST_CHECK_EQUAL(test.isComponent(invalidComponent1), false);
370 BOOST_CHECK_EQUAL(test.isComponent(invalidComponent2), false);
371
372 BOOST_CHECK_THROW(test.getValue(invalidComponent1), name::Component::Error);
373 BOOST_CHECK_THROW(test.getValue(invalidComponent2), name::Component::Error);
374}
375
376BOOST_AUTO_TEST_SUITE_END() // NamingConvention
377
Junxiao Shidf4b24e2016-07-14 21:41:43 +0000378BOOST_AUTO_TEST_SUITE_END() // TestNameComponent
379
380} // namespace tests
381} // namespace ndn