blob: 18cf581bbe8d40339971804d910cf57f2faaa510 [file] [log] [blame]
Junxiao Shi8127d1a2018-08-24 15:29:21 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesavento8e047e12024-02-12 16:50:23 -05003 * Copyright (c) 2013-2024 Regents of the University of California.
Junxiao Shi8127d1a2018-08-24 15:29:21 -06004 *
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
Davide Pesavento7e780642018-11-24 15:51:34 -050022#include "ndn-cxx/prefix-announcement.hpp"
23#include "ndn-cxx/encoding/tlv-nfd.hpp"
Junxiao Shi8127d1a2018-08-24 15:29:21 -060024
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -050025#include "tests/key-chain-fixture.hpp"
26#include "tests/test-common.hpp"
Junxiao Shi8127d1a2018-08-24 15:29:21 -060027
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040028namespace ndn::tests {
Junxiao Shi8127d1a2018-08-24 15:29:21 -060029
Davide Pesaventofffdd622023-08-28 22:50:43 -040030BOOST_CONCEPT_ASSERT((boost::EqualityComparable<PrefixAnnouncement>));
31static_assert(std::is_convertible_v<PrefixAnnouncement::Error*, tlv::Error*>,
32 "PrefixAnnouncement::Error must inherit from tlv::Error");
33
Junxiao Shi8127d1a2018-08-24 15:29:21 -060034BOOST_AUTO_TEST_SUITE(TestPrefixAnnouncement)
35
36static Data
37makePrefixAnnData()
38{
39 return Data(
Eric Newberryc25e4632021-02-11 10:48:11 -080040 "0678 0718 announced-name=/net/example 08036E6574 08076578616D706C65"
Davide Pesavento47a94d12021-10-31 16:41:05 -040041 " keyword-prefix-ann=20025041 version=360101 segment=320100"
Junxiao Shi8127d1a2018-08-24 15:29:21 -060042 " 1403 content-type=prefix-ann 180105"
43 " 1530 expire in one hour 6D040036EE80"
44 " validity FD00FD26 FD00FE0F323031383130333054303030303030"
45 " FD00FF0F323031383131323454323335393539"
46 " 1603 1B0100 signature"
47 " 1720 0000000000000000000000000000000000000000000000000000000000000000"_block);
48}
49
Junxiao Shi8127d1a2018-08-24 15:29:21 -060050BOOST_AUTO_TEST_CASE(DecodeGood)
51{
52 Data data0 = makePrefixAnnData();
53 PrefixAnnouncement pa0(data0);
54 BOOST_CHECK_EQUAL(pa0.getAnnouncedName(), "/net/example");
55 BOOST_CHECK_EQUAL(pa0.getExpiration(), 1_h);
56 BOOST_CHECK(pa0.getValidityPeriod());
57 BOOST_CHECK_EQUAL(*pa0.getValidityPeriod(),
58 security::ValidityPeriod(time::fromIsoString("20181030T000000"),
59 time::fromIsoString("20181124T235959")));
60
61 // reorder ExpirationPeriod and ValidityPeriod, unrecognized non-critical element
62 Data data1 = makePrefixAnnData();
63 Block payload1 = data1.getContent();
64 payload1.parse();
65 Block expirationElement = payload1.get(tlv::nfd::ExpirationPeriod);
66 payload1.remove(tlv::nfd::ExpirationPeriod);
67 payload1.push_back(expirationElement);
68 payload1.push_back("2000"_block);
69 payload1.encode();
70 data1.setContent(payload1);
71 PrefixAnnouncement pa1(data1);
72 BOOST_CHECK_EQUAL(pa1.getAnnouncedName(), "/net/example");
73 BOOST_CHECK_EQUAL(pa1.getExpiration(), 1_h);
74 BOOST_CHECK(pa1.getValidityPeriod());
75 BOOST_CHECK_EQUAL(*pa1.getValidityPeriod(),
76 security::ValidityPeriod(time::fromIsoString("20181030T000000"),
77 time::fromIsoString("20181124T235959")));
78
79 // no ValidityPeriod
80 Data data2 = makePrefixAnnData();
81 Block payload2 = data2.getContent();
82 payload2.parse();
83 payload2.remove(tlv::ValidityPeriod);
84 payload2.encode();
85 data2.setContent(payload2);
86 PrefixAnnouncement pa2(data2);
87 BOOST_CHECK_EQUAL(pa2.getAnnouncedName(), "/net/example");
88 BOOST_CHECK_EQUAL(pa2.getExpiration(), 1_h);
89 BOOST_CHECK(!pa2.getValidityPeriod());
90}
91
92BOOST_AUTO_TEST_CASE(DecodeBad)
93{
94 // wrong ContentType
95 Data data0 = makePrefixAnnData();
96 data0.setContentType(tlv::ContentType_Blob);
Davide Pesavento81bd6962020-06-17 16:03:23 -040097 BOOST_CHECK_EXCEPTION(PrefixAnnouncement{data0}, tlv::Error, [] (const auto& e) {
98 return e.what() == "Data is not a prefix announcement: ContentType is 0"s;
99 });
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600100
101 // Name has no "32=PA" keyword
102 Data data1 = makePrefixAnnData();
Davide Pesavento8e047e12024-02-12 16:50:23 -0500103 setNameComponent(data1, -3, name::Component::fromUri("32=not-PA"));
Davide Pesavento81bd6962020-06-17 16:03:23 -0400104 BOOST_CHECK_EXCEPTION(PrefixAnnouncement{data1}, tlv::Error, [] (const auto& e) {
105 return e.what() == "Data is not a prefix announcement: wrong name structure"s;
106 });
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600107
108 // Name has no version component
109 Data data2 = makePrefixAnnData();
110 setNameComponent(data2, -2, "not-version");
Davide Pesavento81bd6962020-06-17 16:03:23 -0400111 BOOST_CHECK_EXCEPTION(PrefixAnnouncement{data2}, tlv::Error, [] (const auto& e) {
112 return e.what() == "Data is not a prefix announcement: wrong name structure"s;
113 });
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600114
115 // Name has no segment number component
116 Data data3 = makePrefixAnnData();
117 setNameComponent(data3, -2, "not-segment");
Davide Pesavento81bd6962020-06-17 16:03:23 -0400118 BOOST_CHECK_EXCEPTION(PrefixAnnouncement{data3}, tlv::Error, [] (const auto& e) {
119 return e.what() == "Data is not a prefix announcement: wrong name structure"s;
120 });
121
122 // Data without Content
123 Data data4 = makePrefixAnnData();
124 data4.unsetContent();
125 BOOST_CHECK_EXCEPTION(PrefixAnnouncement{data4}, tlv::Error, [] (const auto& e) {
126 return e.what() == "Prefix announcement is empty"s;
127 });
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600128
129 // Content has no ExpirationPeriod element
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600130 Data data5 = makePrefixAnnData();
131 Block payload5 = data5.getContent();
132 payload5.parse();
133 payload5.remove(tlv::nfd::ExpirationPeriod);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600134 data5.setContent(payload5);
Davide Pesavento81bd6962020-06-17 16:03:23 -0400135 BOOST_CHECK_EXCEPTION(PrefixAnnouncement{data5}, tlv::Error, [] (const auto& e) {
136 return e.what() == "No sub-element of type 109 found in block of type 21"s;
137 });
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600138
Davide Pesavento81bd6962020-06-17 16:03:23 -0400139 // ExpirationPeriod is malformed
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600140 Data data6 = makePrefixAnnData();
141 Block payload6 = data6.getContent();
142 payload6.parse();
Davide Pesavento81bd6962020-06-17 16:03:23 -0400143 payload6.remove(tlv::nfd::ExpirationPeriod);
144 payload6.push_back("6D03010101"_block);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600145 data6.setContent(payload6);
Davide Pesavento81bd6962020-06-17 16:03:23 -0400146 BOOST_CHECK_THROW(PrefixAnnouncement{data6}, tlv::Error);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600147
Davide Pesavento81bd6962020-06-17 16:03:23 -0400148 // ValidityPeriod is malformed
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600149 Data data7 = makePrefixAnnData();
150 Block payload7 = data7.getContent();
151 payload7.parse();
Davide Pesavento81bd6962020-06-17 16:03:23 -0400152 payload7.remove(tlv::ValidityPeriod);
153 payload7.push_back("FD00FD00"_block);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600154 data7.setContent(payload7);
Davide Pesavento81bd6962020-06-17 16:03:23 -0400155 BOOST_CHECK_THROW(PrefixAnnouncement{data7}, tlv::Error);
156
157 // Content has unrecognized critical element
158 Data data8 = makePrefixAnnData();
159 Block payload8 = data8.getContent();
160 payload8.parse();
161 payload8.push_back("0200"_block);
162 data8.setContent(payload8);
163 BOOST_CHECK_EXCEPTION(PrefixAnnouncement{data8}, tlv::Error, [] (const auto& e) {
164 return e.what() == "Unrecognized element of critical type 2"s;
165 });
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600166}
167
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500168BOOST_FIXTURE_TEST_CASE(EncodeEmpty, KeyChainFixture)
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000169{
170 PrefixAnnouncement pa;
171 BOOST_CHECK(!pa.getData());
172 BOOST_CHECK_EQUAL(pa.getAnnouncedName(), "/");
173 BOOST_CHECK_EQUAL(pa.getExpiration(), 0_ms);
174 BOOST_CHECK(!pa.getValidityPeriod());
175
176 const Data& data = pa.toData(m_keyChain, signingWithSha256(), 5);
Eric Newberryc25e4632021-02-11 10:48:11 -0800177 BOOST_CHECK_EQUAL(data.getName(), "/32=PA/v=5/seg=0");
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000178 BOOST_CHECK_EQUAL(data.getContentType(), tlv::ContentType_PrefixAnn);
179 BOOST_REQUIRE(pa.getData());
180 BOOST_CHECK_EQUAL(*pa.getData(), data);
181
182 PrefixAnnouncement decoded(data);
183 BOOST_CHECK_EQUAL(decoded.getAnnouncedName(), "/");
184 BOOST_CHECK_EQUAL(decoded.getExpiration(), 0_s);
185 BOOST_CHECK(!decoded.getValidityPeriod());
186
187 BOOST_CHECK_EQUAL(pa, decoded);
188}
189
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500190BOOST_FIXTURE_TEST_CASE(EncodeNoValidity, KeyChainFixture)
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000191{
192 PrefixAnnouncement pa;
193 pa.setAnnouncedName("/net/example");
194 BOOST_CHECK_THROW(pa.setExpiration(-1_ms), std::invalid_argument);
195 pa.setExpiration(1_h);
196
197 const Data& data = pa.toData(m_keyChain, signingWithSha256(), 1);
Eric Newberryc25e4632021-02-11 10:48:11 -0800198 BOOST_CHECK_EQUAL(data.getName(), "/net/example/32=PA/v=1/seg=0");
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000199 BOOST_CHECK_EQUAL(data.getContentType(), tlv::ContentType_PrefixAnn);
200
201 const Block& payload = data.getContent();
202 payload.parse();
203 BOOST_CHECK_EQUAL(readNonNegativeInteger(payload.get(tlv::nfd::ExpirationPeriod)), 3600000);
204 BOOST_CHECK(payload.find(tlv::ValidityPeriod) == payload.elements_end());
205
206 PrefixAnnouncement decoded(data);
207 BOOST_CHECK_EQUAL(decoded.getAnnouncedName(), "/net/example");
208 BOOST_CHECK_EQUAL(decoded.getExpiration(), 1_h);
209 BOOST_CHECK(!decoded.getValidityPeriod());
210
211 BOOST_CHECK_EQUAL(pa, decoded);
212}
213
Davide Pesavento4c1ad4c2020-11-16 21:12:02 -0500214BOOST_FIXTURE_TEST_CASE(EncodeWithValidity, KeyChainFixture)
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000215{
216 PrefixAnnouncement pa;
217 pa.setAnnouncedName("/net/example");
218 pa.setExpiration(1_h);
219 security::ValidityPeriod validity(time::fromIsoString("20181030T000000"),
220 time::fromIsoString("20181124T235959"));
221 pa.setValidityPeriod(validity);
222
223 const Data& data = pa.toData(m_keyChain);
224 const Block& payload = data.getContent();
225 payload.parse();
226 BOOST_CHECK_EQUAL(readNonNegativeInteger(payload.get(tlv::nfd::ExpirationPeriod)), 3600000);
227 BOOST_CHECK_EQUAL(payload.get(tlv::ValidityPeriod), validity.wireEncode());
228
229 PrefixAnnouncement decoded(data);
230 BOOST_CHECK_EQUAL(decoded.getAnnouncedName(), "/net/example");
231 BOOST_CHECK_EQUAL(decoded.getExpiration(), 1_h);
232 BOOST_REQUIRE(decoded.getValidityPeriod());
233 BOOST_CHECK_EQUAL(*decoded.getValidityPeriod(), validity);
234
235 BOOST_CHECK_EQUAL(pa, decoded);
236}
237
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600238BOOST_AUTO_TEST_CASE(Modify)
239{
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000240 PrefixAnnouncement pa(makePrefixAnnData());
241
242 PrefixAnnouncement pa0(pa);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600243 BOOST_REQUIRE(pa0.getData());
244 BOOST_CHECK_EQUAL(*pa0.getData(), makePrefixAnnData());
245 pa0.setAnnouncedName("/com/example");
246 BOOST_CHECK(!pa0.getData());
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000247 BOOST_CHECK_NE(pa0, pa);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600248
249 PrefixAnnouncement pa1(makePrefixAnnData());
250 pa1.setExpiration(5_min);
251 BOOST_CHECK(!pa1.getData());
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000252 BOOST_CHECK_NE(pa1, pa);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600253
254 PrefixAnnouncement pa2(makePrefixAnnData());
255 pa2.setValidityPeriod(security::ValidityPeriod(time::fromIsoString("20180118T000000"),
256 time::fromIsoString("20180212T235959")));
257 BOOST_CHECK(!pa2.getData());
Junxiao Shi1748b1e2018-09-06 04:13:42 +0000258 BOOST_CHECK_NE(pa2, pa);
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600259}
260
Davide Pesavento21ce3ad2021-11-01 22:00:45 -0400261BOOST_AUTO_TEST_CASE(KeywordComponent)
262{
263 BOOST_CHECK_EQUAL(PrefixAnnouncement::getKeywordComponent().wireEncode(),
264 "20 02 5041"_block);
265 BOOST_CHECK_EQUAL(PrefixAnnouncement::getKeywordComponent().toUri(name::UriFormat::CANONICAL),
266 "32=PA");
267}
268
Junxiao Shi8127d1a2018-08-24 15:29:21 -0600269BOOST_AUTO_TEST_SUITE_END() // TestPrefixAnnouncement
270
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400271} // namespace ndn::tests