blob: 785321a74c3a577ab2802a6854829ce3556311cc [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -08002/**
Alexander Afanasyevc169a812014-05-20 20:37:29 -04003 * Copyright (c) 2013-2014 Regents of the University of California.
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
Alexander Afanasyevdfa52c42014-04-24 21:10:11 -07006 *
Alexander Afanasyevc169a812014-05-20 20:37:29 -04007 * 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.
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080020 */
21
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080022#include "name.hpp"
23
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070024#include "boost-test.hpp"
Alexander Afanasyev15f67312014-07-22 15:11:09 -070025#include <boost/tuple/tuple.hpp>
26#include <boost/mpl/vector.hpp>
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070027
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080028namespace ndn {
29
30BOOST_AUTO_TEST_SUITE(TestName)
31
32static const uint8_t TestName[] = {
Alexander Afanasyev4b456282014-02-13 00:34:34 -080033 0x7, 0x14, // Name
34 0x8, 0x5, // NameComponent
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080035 0x6c, 0x6f, 0x63, 0x61, 0x6c,
Alexander Afanasyev4b456282014-02-13 00:34:34 -080036 0x8, 0x3, // NameComponent
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080037 0x6e, 0x64, 0x6e,
Alexander Afanasyev4b456282014-02-13 00:34:34 -080038 0x8, 0x6, // NameComponent
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080039 0x70, 0x72, 0x65, 0x66, 0x69, 0x78
40};
41
Alexander Afanasyev4b456282014-02-13 00:34:34 -080042const uint8_t Name1[] = {0x7, 0x7, // Name
43 0x8, 0x5, // NameComponent
44 0x6c, 0x6f, 0x63, 0x61, 0x6c};
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070045
Alexander Afanasyev4b456282014-02-13 00:34:34 -080046const uint8_t Name2[] = {0x7, 0xc, // Name
47 0x8, 0x5, // NameComponent
48 0x6c, 0x6f, 0x63, 0x61, 0x6c,
49 0x8, 0x3, // NameComponent
50 0x6e, 0x64, 0x6e};
51
52
Alexander Afanasyevc2344292014-03-02 00:08:00 +000053BOOST_AUTO_TEST_CASE(Basic)
54{
55 Name name("/hello/world");
56
57 BOOST_CHECK_NO_THROW(name.at(0));
58 BOOST_CHECK_NO_THROW(name.at(1));
59 BOOST_CHECK_NO_THROW(name.at(-1));
60 BOOST_CHECK_NO_THROW(name.at(-2));
61
62 BOOST_CHECK_THROW(name.at(2), Name::Error);
63 BOOST_CHECK_THROW(name.at(-3), Name::Error);
64}
65
66BOOST_AUTO_TEST_CASE(Encode)
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080067{
68 Name name("/local/ndn/prefix");
69
70 const Block &wire = name.wireEncode();
71
72 // for (Buffer::const_iterator i = wire.begin();
73 // i != wire.end();
74 // ++i)
75 // {
76 // std::ios::fmtflags saveFlags = std::cout.flags(std::ios::hex);
77
78 // if (i != wire.begin())
79 // std::cout << ", ";
80 // std::cout << "0x" << static_cast<uint32_t>(*i);
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070081
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080082 // std::cout.flags(saveFlags);
83 // }
84 // std::cout << std::endl;
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070085
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -080086 BOOST_CHECK_EQUAL_COLLECTIONS(TestName, TestName+sizeof(TestName),
87 wire.begin(), wire.end());
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080088}
89
90
Alexander Afanasyevc2344292014-03-02 00:08:00 +000091BOOST_AUTO_TEST_CASE(Decode)
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -080092{
93 Block block(TestName, sizeof(TestName));
94
95 Name name(block);
96
97 BOOST_CHECK_EQUAL(name.toUri(), "/local/ndn/prefix");
98}
99
Alexander Afanasyevc2344292014-03-02 00:08:00 +0000100BOOST_AUTO_TEST_CASE(AppendsAndMultiEncode)
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800101{
102 Name name("/local");
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700103
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800104 BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
Alexander Afanasyev4b456282014-02-13 00:34:34 -0800105 Name1, Name1 + sizeof(Name1));
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800106
107 name.append("ndn");
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700108
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800109 BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
Alexander Afanasyev4b456282014-02-13 00:34:34 -0800110 Name2, Name2 + sizeof(Name2));
Alexander Afanasyev29e5c3d2014-02-11 00:01:10 -0800111
112 name.append("prefix");
113 BOOST_CHECK_EQUAL_COLLECTIONS(name.wireEncode().begin(), name.wireEncode().end(),
114 TestName, TestName+sizeof(TestName));
115}
116
Steve DiBenedettoc145d492014-03-11 16:35:45 -0600117BOOST_AUTO_TEST_CASE(AppendNumber)
118{
119 Name name;
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700120 for (uint32_t i = 0; i < 10; i++)
Steve DiBenedettoc145d492014-03-11 16:35:45 -0600121 {
122 name.appendNumber(i);
123 }
124
125 BOOST_CHECK_EQUAL(name.size(), 10);
126
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -0700127 for (uint32_t i = 0; i < 10; i++)
Steve DiBenedettoc145d492014-03-11 16:35:45 -0600128 {
129 BOOST_CHECK_EQUAL(name[i].toNumber(), i);
130 }
131}
132
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700133class Numeric
134{
135public:
136 typedef std::list<boost::tuple<function<name::Component(uint64_t)>,
137 function<uint64_t(const name::Component&)>,
138 function<Name&(Name&, uint64_t)>,
139 Name/*expected*/,
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700140 uint64_t/*value*/,
141 function<bool(const name::Component&)> > > Dataset;
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700142
143 Numeric()
144 {
145 dataset.push_back(boost::make_tuple(bind(&name::Component::fromNumberWithMarker,
146 0xAA, _1),
147 bind(&name::Component::toNumberWithMarker, _1, 0xAA),
148 bind(&Name::appendNumberWithMarker, _1, 0xAA, _2),
149 Name("/%AA%03%E8"),
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700150 1000,
151 bind(&name::Component::isNumberWithMarker, _1, 0xAA)));
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700152 dataset.push_back(boost::make_tuple(&name::Component::fromSegment,
153 bind(&name::Component::toSegment, _1),
154 bind(&Name::appendSegment, _1, _2),
155 Name("/%00%27%10"),
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700156 10000,
157 bind(&name::Component::isSegment, _1)));
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700158 dataset.push_back(boost::make_tuple(&name::Component::fromSegmentOffset,
159 bind(&name::Component::toSegmentOffset, _1),
160 bind(&Name::appendSegmentOffset, _1, _2),
161 Name("/%FB%00%01%86%A0"),
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700162 100000,
163 bind(&name::Component::isSegmentOffset, _1)));
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700164 dataset.push_back(boost::make_tuple(&name::Component::fromVersion,
165 bind(&name::Component::toVersion, _1),
Davide Pesaventodfe9c6b2014-08-25 21:17:10 +0200166 bind(static_cast<Name&(Name::*)(uint64_t)>(
167 &Name::appendVersion), _1, _2),
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700168 Name("/%FD%00%0FB%40"),
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700169 1000000,
170 bind(&name::Component::isVersion, _1)));
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700171 dataset.push_back(boost::make_tuple(&name::Component::fromSequenceNumber,
172 bind(&name::Component::toSequenceNumber, _1),
173 bind(&Name::appendSequenceNumber, _1, _2),
174 Name("/%FE%00%98%96%80"),
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700175 10000000,
176 bind(&name::Component::isSequenceNumber, _1)));
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700177 }
178
179 Dataset dataset;
180};
181
182class Timestamp
183{
184public:
185 typedef std::list<boost::tuple<function<name::Component(const time::system_clock::TimePoint&)>,
186 function<time::system_clock::TimePoint(const name::Component&)>,
187 function<Name&(Name&, const time::system_clock::TimePoint&)>,
188 Name/*expected*/,
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700189 time::system_clock::TimePoint/*value*/,
190 function<bool(const name::Component&)> > > Dataset;
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700191 Timestamp()
192 {
193 dataset.push_back(boost::make_tuple(&name::Component::fromTimestamp,
Alexander Afanasyev6f9ec932014-10-31 10:34:00 -0700194 ndn::bind(&name::Component::toTimestamp, _1),
195 ndn::bind(&Name::appendTimestamp, _1, _2),
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700196 Name("/%FC%00%04%7BE%E3%1B%00%00"),
Davide Pesaventodfe9c6b2014-08-25 21:17:10 +0200197 time::getUnixEpoch() + time::days(14600/*40 years*/),
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700198 bind(&name::Component::isTimestamp, _1)));
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700199 }
200
201 Dataset dataset;
202};
203
204typedef boost::mpl::vector<Numeric, Timestamp> ConventionsDatasets;
205
206BOOST_FIXTURE_TEST_CASE_TEMPLATE(NamingConventions, T, ConventionsDatasets, T)
207{
208 // // These octets are obtained by the snippet below.
209 // // This check is intended to detect unexpected encoding change in the future.
210 // for (typename T::Dataset::const_iterator it = this->dataset.begin();
211 // it != this->dataset.end(); ++it) {
212 // Name name;
213 // name.append(it->template get<0>()(it->template get<4>()));
214 // std::cout << name << std::endl;
215 // }
216
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700217 name::Component invalidComponent1;
218 name::Component invalidComponent2("1234567890");
219
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700220 for (typename T::Dataset::const_iterator it = this->dataset.begin();
221 it != this->dataset.end(); ++it) {
222 const Name& expected = it->template get<3>();
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700223 BOOST_TEST_MESSAGE("Check " << expected[0].toUri());
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700224
225 name::Component actualComponent = it->template get<0>()(it->template get<4>());
226 BOOST_CHECK_EQUAL(actualComponent, expected[0]);
227
228 Name actualName;
229 it->template get<2>()(actualName, it->template get<4>());
230 BOOST_CHECK_EQUAL(actualName, expected);
231
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700232 BOOST_CHECK_EQUAL(it->template get<5>()(expected[0]), true);
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700233 BOOST_REQUIRE_NO_THROW(it->template get<1>()(expected[0]));
234 BOOST_CHECK_EQUAL(it->template get<1>()(expected[0]), it->template get<4>());
Alexander Afanasyev0f232c52014-10-23 13:07:31 -0700235
236 BOOST_CHECK_EQUAL(it->template get<5>()(invalidComponent1), false);
237 BOOST_CHECK_EQUAL(it->template get<5>()(invalidComponent2), false);
238
239 BOOST_REQUIRE_THROW(it->template get<1>()(invalidComponent1), name::Component::Error);
240 BOOST_REQUIRE_THROW(it->template get<1>()(invalidComponent2), name::Component::Error);
Alexander Afanasyev15f67312014-07-22 15:11:09 -0700241 }
242}
243
Shuo Chen5aa8c742014-06-22 15:00:02 +0800244BOOST_AUTO_TEST_CASE(GetSuccessor)
245{
246 BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%02").getSuccessor(), Name("ndn:/%00%01/%01%03"));
247 BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%01%FF").getSuccessor(), Name("ndn:/%00%01/%02%00"));
248 BOOST_CHECK_EQUAL(Name("ndn:/%00%01/%FF%FF").getSuccessor(), Name("ndn:/%00%01/%00%00%00"));
249 BOOST_CHECK_EQUAL(Name().getSuccessor(), Name("ndn:/%00"));
250}
251
Junxiao Shi937e4612014-10-22 15:39:07 -0700252BOOST_AUTO_TEST_CASE(Markers)
253{
254 Name name;
255 uint64_t number;
256
257 BOOST_REQUIRE_NO_THROW(number = name.appendSegment(30923).at(-1).toSegment());
258 BOOST_CHECK_EQUAL(number, 30923);
259
260 BOOST_REQUIRE_NO_THROW(number = name.appendSegmentOffset(589).at(-1).toSegmentOffset());
261 BOOST_CHECK_EQUAL(number, 589);
262
263 BOOST_REQUIRE_NO_THROW(number = name.appendVersion().at(-1).toVersion());
264
265 BOOST_REQUIRE_NO_THROW(number = name.appendVersion(25912).at(-1).toVersion());
266 BOOST_CHECK_EQUAL(number, 25912);
267
268 const time::system_clock::TimePoint tp = time::system_clock::now();
269 time::system_clock::TimePoint tp2;
270 BOOST_REQUIRE_NO_THROW(tp2 = name.appendTimestamp(tp).at(-1).toTimestamp());
271 BOOST_CHECK_LE(std::abs(time::duration_cast<time::microseconds>(tp2 - tp).count()), 1);
272
273 BOOST_REQUIRE_NO_THROW(number = name.appendSequenceNumber(11676).at(-1).toSequenceNumber());
274 BOOST_CHECK_EQUAL(number, 11676);
275}
276
Alexander Afanasyev52eb20d2014-02-06 18:25:54 -0800277BOOST_AUTO_TEST_SUITE_END()
278
279} // namespace ndn