blob: 72e079d2ea686f9e603c23ce0fa419a2831a0161 [file] [log] [blame]
Jiewen Tan870b29b2014-11-17 19:09:49 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yumin Xia2c509c22017-02-09 14:37:36 -08002/*
Yumin Xia9d110ce2016-11-15 14:03:14 -08003 * Copyright (c) 2014-2017, Regents of the University of California.
Jiewen Tan870b29b2014-11-17 19:09:49 -08004 *
5 * This file is part of NDNS (Named Data Networking Domain Name Service).
6 * See AUTHORS.md for complete list of NDNS authors and contributors.
7 *
8 * NDNS 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 * NDNS 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 * NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
Alexander Afanasyevfde570c2016-12-19 16:02:55 -080020#include "mgmt/management-tool.hpp"
Yumin Xia2c509c22017-02-09 14:37:36 -080021#include "test-common.hpp"
Yumin Xia9d110ce2016-11-15 14:03:14 -080022#include "daemon/rrset-factory.hpp"
Yumin Xia2c509c22017-02-09 14:37:36 -080023#include "util/cert-helper.hpp"
Jiewen Tan870b29b2014-11-17 19:09:49 -080024#include "ndns-enum.hpp"
25#include "ndns-label.hpp"
26#include "ndns-tlv.hpp"
27
Jiewen Tan870b29b2014-11-17 19:09:49 -080028#include <boost/algorithm/string/replace.hpp>
29
Jiewen Tan870b29b2014-11-17 19:09:49 -080030#include <ndn-cxx/util/io.hpp>
31#include <ndn-cxx/util/regex.hpp>
Yumin Xia2c509c22017-02-09 14:37:36 -080032#include <ndn-cxx/security/transform.hpp>
Alexander Afanasyevfde570c2016-12-19 16:02:55 -080033
34using boost::test_tools::output_test_stream;
35
Jiewen Tan870b29b2014-11-17 19:09:49 -080036namespace ndn {
37namespace ndns {
38namespace tests {
39
Jiewen Tan870b29b2014-11-17 19:09:49 -080040static const boost::filesystem::path TEST_DATABASE = TEST_CONFIG_PATH "/management_tool.db";
41static const boost::filesystem::path TEST_CERTDIR = TEST_CONFIG_PATH "/management_tool_certs";
42static const Name FAKE_ROOT("/fake-root/123456789");
43
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080044/**
45 * @brief Recursive copy a directory using Boost Filesystem
46 *
47 * Based on from http://stackoverflow.com/q/8593608/2150331
48 */
49void
50copyDir(const boost::filesystem::path& source, const boost::filesystem::path& destination)
51{
52 namespace fs = boost::filesystem;
53
54 fs::create_directory(destination);
55 for (fs::directory_iterator file(source); file != fs::directory_iterator(); ++file) {
56 fs::path current(file->path());
57 if (is_directory(current)) {
58 copyDir(current, destination / current.filename());
59 }
60 else {
61 // cannot use fs::copy_file, see https://svn.boost.org/trac/boost/ticket/10038
62 // fs::copy works, as it doesn't use problematic private API
63 copy(current, destination / current.filename());
64 }
65 }
66}
67
68class TestHome : boost::noncopyable
Jiewen Tan870b29b2014-11-17 19:09:49 -080069{
70public:
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080071 TestHome()
72 {
73 if (std::getenv("HOME"))
74 m_origHome = std::getenv("HOME");
75
76 setenv("HOME", TEST_CONFIG_PATH "/tests/unit/mgmt/", 1);
77 boost::filesystem::remove_all(TEST_CONFIG_PATH "/tests/unit/mgmt/");
78 boost::filesystem::create_directories(TEST_CONFIG_PATH "/tests/unit/mgmt");
79 copyDir("tests/unit/mgmt/.ndn", TEST_CONFIG_PATH "/tests/unit/mgmt/.ndn");
80 }
81
82 ~TestHome()
83 {
84 if (!m_origHome.empty())
85 setenv("HOME", m_origHome.c_str(), 1);
86 else
87 unsetenv("HOME");
88 }
89
90protected:
91 std::string m_origHome;
92};
93
94
Alexander Afanasyevfde570c2016-12-19 16:02:55 -080095class ManagementToolFixture : public TestHome, public IdentityManagementFixture
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080096{
97public:
98 class Error : public std::runtime_error
99 {
100 public:
101 explicit
102 Error(const std::string& what)
103 : std::runtime_error(what)
104 {
105 }
106 };
107
108 class PreviousStateCleaner
109 {
110 public:
111 PreviousStateCleaner()
112 {
113 boost::filesystem::remove(TEST_DATABASE);
114 boost::filesystem::remove_all(TEST_CERTDIR);
115 }
116 };
117
Jiewen Tan870b29b2014-11-17 19:09:49 -0800118 ManagementToolFixture()
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800119 : m_tool(TEST_DATABASE.string().c_str(), m_keyChain)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800120 , m_dbMgr(TEST_DATABASE.string().c_str())
121 {
122 boost::filesystem::create_directory(TEST_CERTDIR);
Yumin Xia2c509c22017-02-09 14:37:36 -0800123 Identity root = addIdentity("NDNS");
124 Key ksk = root.getDefaultKey();
125 m_keyChain.deleteCertificate(ksk, ksk.getDefaultCertificate().getName());
126 Certificate kskCert = CertHelper::createCertificate(m_keyChain, ksk, ksk, "CERT");
127 m_keyChain.addCertificate(ksk, kskCert);
128 rootKsk = kskCert.getName();
129
130 Key dsk = m_keyChain.createKey(root);
131 // replace rootDsk's default cert with ksk-signing cert
132 m_keyChain.deleteCertificate(dsk, dsk.getDefaultCertificate().getName());
133 Certificate dskCert = CertHelper::createCertificate(m_keyChain, dsk, ksk, "CERT");
134 m_keyChain.addCertificate(dsk, dskCert);
135 rootDsk = dskCert.getName();
136
137 Identity other = addIdentity("/ndns-test/NDNS");
138 Key otherKskKey = other.getDefaultKey();
139 m_keyChain.deleteCertificate(otherKskKey, otherKskKey.getDefaultCertificate().getName());
140 Certificate otherKskCert = CertHelper::createCertificate(m_keyChain, otherKskKey, otherKskKey, "CERT");
141 m_keyChain.addCertificate(otherKskKey, otherKskCert);
142 otherKsk = otherKskCert.getName();
143
144 // replace rootDsk's default cert with ksk-signing cert
145 Key otherDskKey = m_keyChain.createKey(other);
146 m_keyChain.deleteCertificate(otherDskKey, otherDskKey.getDefaultCertificate().getName());
147 Certificate otherDskCert = CertHelper::createCertificate(m_keyChain, otherDskKey, otherKskKey, "CERT");
148 m_keyChain.addCertificate(otherDskKey, otherDskCert);
149 otherDsk = otherDskCert.getName();
150
151 Certificate rootDkeyCert = CertHelper::createCertificate(m_keyChain, otherDskKey, otherKskKey, "CERT");
152 m_keyChain.addCertificate(otherDskKey, rootDkeyCert);
153 rootDkey = rootDkeyCert.getName();
Jiewen Tan870b29b2014-11-17 19:09:49 -0800154 }
155
156 ~ManagementToolFixture()
157 {
Jiewen Tan870b29b2014-11-17 19:09:49 -0800158 }
159
Yumin Xia2c509c22017-02-09 14:37:36 -0800160 std::vector<Certificate>
161 getCerts(const Name& zoneName)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800162 {
Yumin Xia2c509c22017-02-09 14:37:36 -0800163 Zone zone(zoneName);
164 std::vector<Certificate> certs;
165 std::map<std::string, Block> zoneInfo = m_dbMgr.getZoneInfo(zone);
166 // ksk are always the first key
167 certs.push_back(Certificate(zoneInfo["ksk"]));
168 certs.push_back(Certificate(zoneInfo["dsk"]));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800169 return certs;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800170 }
171
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800172 Rrset
173 findRrSet(Zone& zone, const Name& label, const name::Component& type)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800174 {
175 Rrset rrset(&zone);
176 rrset.setLabel(label);
177 rrset.setType(type);
178
179 if (!m_dbMgr.find(rrset))
Yumin Xia2c509c22017-02-09 14:37:36 -0800180 BOOST_THROW_EXCEPTION(Error("Record not found"));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800181 else
182 return rrset;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800183 }
184
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800185 Name
186 getLabel(const Zone& zone, const Name& fullName)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800187 {
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800188 size_t zoneNameSize = zone.getName().size();
189 return fullName.getSubName(zoneNameSize + 1, fullName.size() - zoneNameSize - 3);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800190 }
191
Yumin Xia2c509c22017-02-09 14:37:36 -0800192 Certificate
193 findCertFromIdentity(const Name& identityName, const Name& certName)
194 {
195 Certificate rtn;
196 Identity identity = CertHelper::getIdentity(m_keyChain, identityName);
197 for (const auto& key : identity.getKeys()) {
198 for (const auto& cert : key.getCertificates()) {
199 if (cert.getName() == certName) {
200 rtn = cert;
201 return rtn;
202 }
203 }
204 }
205 BOOST_THROW_EXCEPTION(Error("Certificate not found in keyChain"));
206 return rtn;
207 }
208
209 Certificate
210 findCertFromDb(Zone& zone, const Name& fullName)
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800211 {
212 Rrset rrset = findRrSet(zone, getLabel(zone, fullName), label::CERT_RR_TYPE);
Yumin Xia2c509c22017-02-09 14:37:36 -0800213 Certificate cert;
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800214 cert.wireDecode(rrset.getData());
215 return cert;
216 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800217
Yumin Xia2c509c22017-02-09 14:37:36 -0800218 Certificate
219 findDkeyFromDb(const Name& zoneName)
220 {
221 Zone zone(zoneName);
222 std::map<std::string, Block> zoneInfo = m_dbMgr.getZoneInfo(zone);
223 return Certificate(zoneInfo["dkey"]);
224 }
225
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800226 Response
227 findResponse(Zone& zone, const Name& label, const name::Component& type)
228 {
229 Rrset rrset = findRrSet(zone, label, type);
230 Data data(rrset.getData());
231 Response resp;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700232 resp.fromData(zone.getName(), data);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800233 return resp;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800234 }
235
236public:
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800237 PreviousStateCleaner cleaner; // must be first variable
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800238 ndns::ManagementTool m_tool;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800239 ndns::DbMgr m_dbMgr;
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800240
241 // Names of pre-created certificates
242 // Uncomment and run InitPreconfiguredKeys test case and then update names in the
243 // constructor.
244 Name rootKsk;
245 Name rootDsk;
246 Name otherKsk;
247 Name otherDsk;
Yumin Xia2c509c22017-02-09 14:37:36 -0800248 Name rootDkey;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800249};
250
Yumin Xia9d110ce2016-11-15 14:03:14 -0800251BOOST_FIXTURE_TEST_SUITE(ManagementTool, ManagementToolFixture)
252
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800253// BOOST_FIXTURE_TEST_CASE(InitPreconfiguredKeys, ManagementToolFixture)
254// {
255// using time::seconds;
256
257// auto generateCerts = [this] (const Name& zone, const Name& parentCert = Name()) -> Name {
258// // to re-generate certificates, uncomment and then update rootKsk/rootDsk names
259// Name kskName = m_keyChain.generateRsaKeyPair(zone, true);
260// auto kskCert = m_keyChain
261// .prepareUnsignedIdentityCertificate(kskName, zone, time::fromUnixTimestamp(seconds(0)),
262// time::fromUnixTimestamp(seconds(2147483648)), {});
263// if (parentCert.empty()) {
264// m_keyChain.selfSign(*kskCert);
265// }
266// else {
267// m_keyChain.sign(*kskCert, parentCert);
268// }
269// m_keyChain.addCertificate(*kskCert);
270
271// Name dskName = m_keyChain.generateRsaKeyPair(zone, false);
272// auto dskCert = m_keyChain
273// .prepareUnsignedIdentityCertificate(dskName, zone, time::fromUnixTimestamp(seconds(0)),
274// time::fromUnixTimestamp(seconds(2147483648)), {});
275// m_keyChain.sign(*dskCert, kskCert->getName());
276// m_keyChain.addCertificate(*dskCert);
277
278// return dskCert->getName();
279// };
280
281// Name rootDsk = generateCerts(ROOT_ZONE);
282// generateCerts("/ndns-test", rootDsk);
283
284// copyDir(TEST_CONFIG_PATH "/tests/unit/mgmt/.ndn", "/tmp/.ndn");
285// std::cout << "Manually copy contents of /tmp/.ndn into tests/unit/mgmt/.ndn" << std::endl;
286// }
287
Yumin Xia9d110ce2016-11-15 14:03:14 -0800288BOOST_AUTO_TEST_CASE(CreateDeleteRootFixture)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800289{
Yumin Xia2c509c22017-02-09 14:37:36 -0800290 // creating root_zone need a rootDkey
291 BOOST_CHECK_THROW(m_tool.createZone(ROOT_ZONE, ROOT_ZONE,
292 time::seconds(4600),
293 time::seconds(4600),
294 rootKsk, rootDsk), ndns::ManagementTool::Error);
295
296 m_tool.createZone(ROOT_ZONE, ROOT_ZONE,
297 time::seconds(4600),
298 time::seconds(4600),
299 rootKsk, rootDsk, rootDkey);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800300
301 Zone zone(ROOT_ZONE);
Yumin Xia2c509c22017-02-09 14:37:36 -0800302 Name zoneIdentityName = Name(ROOT_ZONE).append("NDNS");
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800303 BOOST_REQUIRE_EQUAL(m_dbMgr.find(zone), true);
Yumin Xia2c509c22017-02-09 14:37:36 -0800304 BOOST_REQUIRE_NO_THROW(findCertFromDb(zone, rootDsk));
305 BOOST_CHECK_EQUAL(findCertFromDb(zone, rootDsk).getName(), rootDsk);
306 BOOST_CHECK_EQUAL(findCertFromDb(zone, rootKsk).getName(), rootKsk);
307 BOOST_CHECK_EQUAL(findDkeyFromDb(ROOT_ZONE).getName(), rootDkey);
308
309 BOOST_CHECK_EQUAL(findCertFromIdentity(zoneIdentityName, rootDsk).getName(), rootDsk);
310 BOOST_CHECK_EQUAL(findCertFromIdentity(zoneIdentityName, rootKsk).getName(), rootKsk);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800311
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800312 BOOST_CHECK_NO_THROW(m_tool.deleteZone(ROOT_ZONE));
313 BOOST_CHECK_EQUAL(m_dbMgr.find(zone), false);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800314}
315
Yumin Xia9d110ce2016-11-15 14:03:14 -0800316BOOST_AUTO_TEST_CASE(CreateDeleteChildFixture)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800317{
Jiewen Tan870b29b2014-11-17 19:09:49 -0800318 Name parentZoneName("/ndns-test");
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800319 Name zoneName = Name(parentZoneName).append("child-zone");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800320
Yumin Xia2c509c22017-02-09 14:37:36 -0800321 Zone zone1(zoneName);
Yumin Xia918343d2017-03-17 19:04:55 -0700322 Name zoneIdentityName = Name(zoneName).append(label::NDNS_ITERATIVE_QUERY);
Yumin Xia2c509c22017-02-09 14:37:36 -0800323 BOOST_REQUIRE_EQUAL(m_dbMgr.find(zone1), false);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800324
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800325 // will generate keys automatically
326 m_tool.createZone(zoneName, parentZoneName);
Yumin Xia2c509c22017-02-09 14:37:36 -0800327 BOOST_CHECK_EQUAL(CertHelper::doesIdentityExist(m_keyChain, zoneIdentityName), true);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800328
Yumin Xia2c509c22017-02-09 14:37:36 -0800329 std::vector<Certificate>&& certs = getCerts(zoneName);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800330 BOOST_REQUIRE_EQUAL(certs.size(), 2);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800331
Yumin Xia2c509c22017-02-09 14:37:36 -0800332 const Name& ksk = certs[0].getName();
333 const Name& dsk = certs[1].getName();
Jiewen Tan870b29b2014-11-17 19:09:49 -0800334
335 Zone zone(zoneName);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800336 BOOST_REQUIRE_EQUAL(m_dbMgr.find(zone), true);
Yumin Xia2c509c22017-02-09 14:37:36 -0800337 BOOST_REQUIRE_NO_THROW(findCertFromDb(zone, dsk));
338 BOOST_CHECK_EQUAL(findCertFromDb(zone, dsk).getName(), dsk);
339 BOOST_CHECK_EQUAL(findCertFromDb(zone, ksk).getName(), ksk);
340
341 BOOST_CHECK_EQUAL(findCertFromIdentity(zoneIdentityName, dsk), findCertFromDb(zone, dsk));
342 BOOST_CHECK_EQUAL(findCertFromIdentity(zoneIdentityName, ksk), findCertFromDb(zone, ksk));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800343
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800344 BOOST_CHECK_NO_THROW(m_tool.deleteZone(zoneName));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800345
346 BOOST_CHECK_THROW(m_tool.deleteZone(zoneName), ndns::ManagementTool::Error);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800347 BOOST_CHECK_THROW(m_tool.deleteZone("/non/existing/zone"), ndns::ManagementTool::Error);
348}
349
Yumin Xia9d110ce2016-11-15 14:03:14 -0800350BOOST_AUTO_TEST_CASE(CreateZoneWithFixture)
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800351{
352 Name parentZoneName("/ndns-test");
353 Name zoneName = Name(parentZoneName).append("child-zone");
Yumin Xia918343d2017-03-17 19:04:55 -0700354 Name zoneIdentityName = Name(zoneName).append(label::NDNS_ITERATIVE_QUERY);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800355
356 m_tool.createZone(zoneName, parentZoneName, time::seconds(4200), time::days(30));
Yumin Xia2c509c22017-02-09 14:37:36 -0800357 BOOST_CHECK_EQUAL(CertHelper::doesIdentityExist(m_keyChain, zoneIdentityName), true);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800358
Yumin Xia2c509c22017-02-09 14:37:36 -0800359 std::vector<Certificate>&& certs = getCerts(zoneName);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800360 BOOST_REQUIRE_EQUAL(certs.size(), 2);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800361
Yumin Xia2c509c22017-02-09 14:37:36 -0800362 const Name& dsk = certs[1].getName();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800363
364 // Check zone ttl
365 Zone zone(zoneName);
366 BOOST_REQUIRE_EQUAL(m_dbMgr.find(zone), true);
367 BOOST_CHECK_EQUAL(zone.getTtl(), time::seconds(4200));
368
Yumin Xia2c509c22017-02-09 14:37:36 -0800369 // check dkey name
370 Name dkeyName = Name(parentZoneName).append("NDNS").append(zoneName.getSubName(parentZoneName.size()));
371 Certificate dkey = findDkeyFromDb(zoneName);
372 BOOST_CHECK(dkeyName.isPrefixOf(dkey.getName()));
373
374 // TODO: check signing hierarchy
375
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800376 // Check dsk rrset ttl
377 Rrset rrset;
378 BOOST_REQUIRE_NO_THROW(rrset = findRrSet(zone, getLabel(zone, dsk), label::CERT_RR_TYPE));
379 BOOST_CHECK_EQUAL(rrset.getTtl(), time::seconds(4200));
380
381 // Check certificate freshnessPeriod and validity
Yumin Xia2c509c22017-02-09 14:37:36 -0800382 Certificate cert = CertHelper::getCertificate(m_keyChain, zoneIdentityName, dsk);
383 time::system_clock::TimePoint beg,end;
384 std::tie(beg, end) = cert.getValidityPeriod().getPeriod();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800385
Yumin Xia2c509c22017-02-09 14:37:36 -0800386 BOOST_REQUIRE_NO_THROW(cert = findCertFromDb(zone, dsk));
387 BOOST_CHECK_EQUAL(cert.getFreshnessPeriod(), time::seconds(4200));
388 BOOST_CHECK_EQUAL(end - beg, time::days(30));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800389 m_tool.deleteZone(zoneName);
390}
391
Yumin Xia9d110ce2016-11-15 14:03:14 -0800392BOOST_AUTO_TEST_CASE(ZoneCreatePreconditions)
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800393{
394 BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/net"));
395 BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net"), ndns::ManagementTool::Error);
396
Yumin Xia2c509c22017-02-09 14:37:36 -0800397 std::vector<Certificate>&& certs = getCerts("/net/ndnsim");
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800398 BOOST_REQUIRE_EQUAL(certs.size(), 2);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800399
Yumin Xia2c509c22017-02-09 14:37:36 -0800400 const Name& ksk = certs[0].getName();
401 const Name& dsk = certs[1].getName();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800402
403 m_tool.deleteZone("/net/ndnsim");
404 // identity will still exist after the zone is deleted
405
406 BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net/ndnsim"), ndns::ManagementTool::Error);
407
408 BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/com"), ndns::ManagementTool::Error);
409
410 BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/",
411 time::seconds(1), time::days(1), ksk, dsk));
412 BOOST_CHECK_EQUAL(getCerts("/net/ndnsim").size(), 2);
413 m_tool.deleteZone("/net/ndnsim");
414
415 BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/",
416 time::seconds(1), time::days(1), Name(), dsk));
Yumin Xia2c509c22017-02-09 14:37:36 -0800417
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800418 m_tool.deleteZone("/net/ndnsim");
419
420 BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/",
421 time::seconds(1), time::days(1), ksk, Name()));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800422 m_tool.deleteZone("/net/ndnsim");
423
424 BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
425 time::seconds(1), time::days(1), "/com/ndnsim"),
Yumin Xia2c509c22017-02-09 14:37:36 -0800426 ndns::ManagementTool::Error);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800427
Yumin Xia2c509c22017-02-09 14:37:36 -0800428 Identity id = addIdentity("/net/ndnsim/NDNS");
429 Certificate cert = id.getDefaultKey().getDefaultCertificate();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800430 BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/net",
Yumin Xia2c509c22017-02-09 14:37:36 -0800431 time::seconds(1), time::days(1), cert.getName()));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800432
Yumin Xia2c509c22017-02-09 14:37:36 -0800433 id = addIdentity("/com/ndnsim/NDNS");
434 cert = id.getDefaultKey().getDefaultCertificate();
435
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800436 BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
Yumin Xia2c509c22017-02-09 14:37:36 -0800437 time::seconds(1), time::days(1), cert.getName()),
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800438 ndns::ManagementTool::Error);
439
Yumin Xia2c509c22017-02-09 14:37:36 -0800440 id = addIdentity("/net/ndnsim/www/NDNS");
441 cert = id.getDefaultKey().getDefaultCertificate();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800442 BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
Yumin Xia2c509c22017-02-09 14:37:36 -0800443 time::seconds(1), time::days(1), cert.getName()),
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800444 ndns::ManagementTool::Error);
445
Yumin Xia2c509c22017-02-09 14:37:36 -0800446 id = addIdentity("/net/ndnsim/NDNS");
447 cert = id.getDefaultKey().getDefaultCertificate();
448 m_keyChain.deleteCertificate(id.getDefaultKey(), cert.getName());
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800449 BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
Yumin Xia2c509c22017-02-09 14:37:36 -0800450 time::seconds(1), time::days(1), cert.getName()),
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800451 ndns::ManagementTool::Error);
452
Yumin Xia2c509c22017-02-09 14:37:36 -0800453 // for root zone special case (requires a valid DKEY to be specified)
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800454 BOOST_CHECK_THROW(m_tool.createZone("/", "/"), ndns::ManagementTool::Error);
455
456 BOOST_CHECK_NO_THROW(m_tool.createZone("/", "/", time::seconds(1), time::days(1),
Yumin Xia2c509c22017-02-09 14:37:36 -0800457 DEFAULT_CERT, DEFAULT_CERT, rootDkey));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800458}
459
460class OutputTester
461{
462public:
463 OutputTester()
464 : savedBuf(std::clog.rdbuf())
465 {
466 std::cout.rdbuf(buffer.rdbuf());
467 }
468
469 ~OutputTester()
470 {
471 std::cout.rdbuf(savedBuf);
472 }
473
474public:
475 std::stringstream buffer;
476 std::streambuf* savedBuf;
477};
478
Yumin Xia2c509c22017-02-09 14:37:36 -0800479// BOOST_AUTO_TEST_CASE(ExportCertificate)
480// {
481// std::string outputFile = TEST_CERTDIR.string() + "/ss.cert";
Jiewen Tan870b29b2014-11-17 19:09:49 -0800482
Yumin Xia2c509c22017-02-09 14:37:36 -0800483// BOOST_REQUIRE_THROW(m_tool.exportCertificate("/random/name", outputFile),
484// ndns::ManagementTool::Error);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800485
Yumin Xia2c509c22017-02-09 14:37:36 -0800486// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(outputFile), false);
487// // doesn't check the zone, export from KeyChain directly
488// BOOST_CHECK_NO_THROW(m_tool.exportCertificate(otherDsk, outputFile));
489// BOOST_REQUIRE_EQUAL(boost::filesystem::exists(outputFile), true);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800490
Yumin Xia2c509c22017-02-09 14:37:36 -0800491// std::string dskValue =
492// "Bv0C3Ac3CAluZG5zLXRlc3QIA0tFWQgRZHNrLTE0MTY5NzQwMDY2NTkIB0lELUNF\n"
493// "UlQICf0AAAFJ6jt6DhQDGAECFf0BYTCCAV0wIhgPMTk3MDAxMDEwMDAwMDBaGA8y\n"
494// "MDM4MDExOTAzMTQwOFowEzARBgNVBCkTCi9uZG5zLXRlc3QwggEgMA0GCSqGSIb3\n"
495// "DQEBAQUAA4IBDQAwggEIAoIBAQDIFUL7Fz8mmxxIT8l3FtWm+CuH9+iQ0Uj/a30P\n"
496// "mKe4gWvtxzhb4vIngYbXGv2iUzHswdqYlTVeDdW6eOFKMvyY5p5eVtLqDFZ7EEK0\n"
497// "0rpTh648HjCSz+Awgp2nbiYAAVvhP6YF+NxGBH412uPI7kLY6ozypsNmYP+K4SYT\n"
498// "oY9ee4xLSjqzXfLMyP1h8OHcN/aNmccRJlyYblCmCDbZPnzu3ttHHwdrYQLeFvb0\n"
499// "B5grCAQoPHwkfxkEnzQBA/fbUdvKNdayEkuibPLlIlmj2cBtk5iVk8JCSibP3Zlz\n"
500// "36Sks1DAO+1EvCRnjoH5vYmkpMUBFue+6A40IQG4brM2CiIRAgERFjMbAQEcLgcs\n"
501// "CAluZG5zLXRlc3QIA0tFWQgRa3NrLTE0MTY5NzQwMDY1NzcIB0lELUNFUlQX/QEA\n"
502// "GP2bQqp/7rfb8tShwDbXihWrPojwEFqlfwLibK9aM1RxwpHVqbtRsPYmuWc87LaU\n"
503// "OztPOZinHGL80ypFC+wYadVGnE8MPdTkUYUik7mbHDEsYWADoyGMVhoZv+OTJ/5m\n"
504// "MUh/kR1FMiqtZcIQtLB3cdCeGlZBl9wm2SvhMKVUym3RsQO46RpnmsEQcCfWMBZg\n"
505// "u5U6mhYIpiQPZ/sYyZ9zXstwsIfaF1p0V+1dW5y99PZJXIegVKhkGGU0ibjYoJy7\n"
506// "6uUjqBBDX8KMdt6n/Zy1/pGG1eOchMyV0JZ8+MJxWuiTEh5PJeYMFHTV/BVp8aPy\n"
507// "8UNqhMpjAZwW6pdvOZADVg==\n";
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800508
Yumin Xia2c509c22017-02-09 14:37:36 -0800509// {
510// std::ifstream ifs(outputFile.c_str());
511// std::string actualValue((std::istreambuf_iterator<char>(ifs)),
512// std::istreambuf_iterator<char>());
513// BOOST_CHECK_EQUAL(actualValue, dskValue);
514// }
515// boost::filesystem::remove(outputFile);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800516
Yumin Xia2c509c22017-02-09 14:37:36 -0800517// // doesn't check the zone, export from KeyChain directly
518// BOOST_CHECK_NO_THROW(m_tool.exportCertificate(otherKsk, outputFile));
519// boost::filesystem::remove(outputFile);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800520
Yumin Xia2c509c22017-02-09 14:37:36 -0800521// Name zoneName("/ndns-test");
522// m_tool.createZone(zoneName, ROOT_ZONE, time::seconds(4200), time::days(30),
523// otherKsk, otherDsk);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800524
Yumin Xia2c509c22017-02-09 14:37:36 -0800525// m_keyChain.deleteCertificate(otherKsk);
526// m_keyChain.deleteCertificate(otherDsk);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800527
Yumin Xia2c509c22017-02-09 14:37:36 -0800528// // retrieve cert from the zone
529// BOOST_CHECK_NO_THROW(m_tool.exportCertificate(otherDsk, outputFile));
530// {
531// std::ifstream ifs(outputFile.c_str());
532// std::string actualValue((std::istreambuf_iterator<char>(ifs)),
533// std::istreambuf_iterator<char>());
534// BOOST_CHECK_EQUAL(actualValue, dskValue);
535// }
536// boost::filesystem::remove(outputFile);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800537
Yumin Xia2c509c22017-02-09 14:37:36 -0800538// BOOST_REQUIRE_THROW(m_tool.exportCertificate(otherKsk, outputFile),
539// ndns::ManagementTool::Error);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800540
Yumin Xia2c509c22017-02-09 14:37:36 -0800541// // output to std::cout
542// std::string acutalOutput;
543// {
544// OutputTester tester;
545// m_tool.exportCertificate(otherDsk, "-");
546// acutalOutput = tester.buffer.str();
547// }
548// BOOST_CHECK_EQUAL(acutalOutput, dskValue);
549// }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800550
Yumin Xia9d110ce2016-11-15 14:03:14 -0800551BOOST_AUTO_TEST_CASE(AddRrset)
552{
553 Name zoneName("/ndns-test");
554 Zone zone(zoneName);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800555
Yumin Xia9d110ce2016-11-15 14:03:14 -0800556 time::seconds ttl1(4200);
557 time::seconds ttl2(4500);
558 m_tool.createZone(zoneName, ROOT_ZONE, ttl1);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800559
Yumin Xia9d110ce2016-11-15 14:03:14 -0800560 RrsetFactory rf(TEST_DATABASE, zoneName, m_keyChain, DEFAULT_CERT);
561 rf.checkZoneKey();
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700562 Rrset rrset1 = rf.generateNsRrset("/l1", 7654, ttl2, DelegationList());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800563
Yumin Xia9d110ce2016-11-15 14:03:14 -0800564 BOOST_CHECK_NO_THROW(m_tool.addRrset(rrset1));
565 Rrset rrset2 = findRrSet(zone, "/l1", label::NS_RR_TYPE);
566 BOOST_CHECK_EQUAL(rrset1, rrset2);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800567
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700568 Rrset rrset3 = rf.generateNsRrset("/l1/l2/l3", 7654, ttl2, DelegationList());
Yumin Xia9d110ce2016-11-15 14:03:14 -0800569 BOOST_CHECK_THROW(m_tool.addRrset(rrset3), ndns::ManagementTool::Error);
570}
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800571
Yumin Xia9d110ce2016-11-15 14:03:14 -0800572BOOST_AUTO_TEST_CASE(AddMultiLevelLabelRrset)
573{
Yumin Xia9d110ce2016-11-15 14:03:14 -0800574 Name zoneName("/ndns-test");
575 Zone zone(zoneName);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800576
Yumin Xia9d110ce2016-11-15 14:03:14 -0800577 time::seconds ttl(4200);
578 m_tool.createZone(zoneName, ROOT_ZONE, ttl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800579
Yumin Xia9d110ce2016-11-15 14:03:14 -0800580 RrsetFactory rf(TEST_DATABASE, zoneName, m_keyChain, DEFAULT_CERT);
581 rf.checkZoneKey();
Jiewen Tan870b29b2014-11-17 19:09:49 -0800582
Yumin Xia9d110ce2016-11-15 14:03:14 -0800583 auto checkRrset = [&zone, &zoneName, this](Name label,
584 name::Component type,
585 NdnsContentType contentType) -> void {
586 Rrset rr1 = findRrSet(zone, label, type);
587 BOOST_CHECK_EQUAL(Data(rr1.getData()).getContentType(), contentType);
588 Response response1;
589 response1.fromData(zoneName, Data(rr1.getData()));
590 BOOST_CHECK_EQUAL(response1.getRrLabel(), label);
591 };
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800592
Yumin Xia9d110ce2016-11-15 14:03:14 -0800593 Name labelName("/l1/l2/l3");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800594
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700595 Rrset rrset1 = rf.generateNsRrset(labelName, 7654, ttl, DelegationList());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800596
Yumin Xia9d110ce2016-11-15 14:03:14 -0800597 //add NS NDNS_AUTH and check user-defined ttl
598 BOOST_CHECK_NO_THROW(m_tool.addMultiLevelLabelRrset(rrset1, rf, ttl));
599 Rrset rrset2 = findRrSet(zone, labelName, label::NS_RR_TYPE);
600 BOOST_CHECK_EQUAL(rrset1, rrset2);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800601
Yumin Xia9d110ce2016-11-15 14:03:14 -0800602 checkRrset("/l1", label::NS_RR_TYPE, ndns::NDNS_AUTH);
603 checkRrset("/l1/l2", label::NS_RR_TYPE, ndns::NDNS_AUTH);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800604
Yumin Xia9d110ce2016-11-15 14:03:14 -0800605 // insert a same-name rrset with TXT type
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700606 Rrset txtRr = rf.generateTxtRrset("/l1/l2/l3", 7654, ttl, std::vector<std::string>());
Yumin Xia9d110ce2016-11-15 14:03:14 -0800607 BOOST_CHECK_NO_THROW(m_tool.addMultiLevelLabelRrset(txtRr, rf, ttl));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800608
Yumin Xia9d110ce2016-11-15 14:03:14 -0800609 checkRrset("/l1", label::NS_RR_TYPE, ndns::NDNS_AUTH);
610 checkRrset("/l1/l2", label::NS_RR_TYPE, ndns::NDNS_AUTH);
611 checkRrset("/l1/l2/l3", label::TXT_RR_TYPE, ndns::NDNS_RESP);
612 // check that there is no confliction
613 checkRrset("/l1/l2/l3", label::NS_RR_TYPE, ndns::NDNS_LINK);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800614
Yumin Xia9d110ce2016-11-15 14:03:14 -0800615 // insert a shorter NS, when there are longer NS or TXT
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700616 Rrset shorterNs = rf.generateNsRrset("/l1/l2", 7654, ttl, DelegationList());
Yumin Xia9d110ce2016-11-15 14:03:14 -0800617 BOOST_CHECK_THROW(m_tool.addMultiLevelLabelRrset(shorterNs, rf, ttl),
618 ndns::ManagementTool::Error);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800619
Yumin Xia9d110ce2016-11-15 14:03:14 -0800620 // insert a longer NS, when there is already a shorter NS
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700621 Rrset longerNs = rf.generateNsRrset("/l1/l2/l3/l4", 7654, ttl, DelegationList());
Yumin Xia9d110ce2016-11-15 14:03:14 -0800622 BOOST_CHECK_THROW(m_tool.addMultiLevelLabelRrset(longerNs, rf, ttl),
623 ndns::ManagementTool::Error);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800624
Yumin Xia9d110ce2016-11-15 14:03:14 -0800625 // insert a smaller TXT, when there are longer NS and TXT
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700626 Rrset shorterTxt = rf.generateTxtRrset("/l1/l2", 7654, ttl, std::vector<std::string>());
Yumin Xia9d110ce2016-11-15 14:03:14 -0800627 BOOST_CHECK_NO_THROW(m_tool.addMultiLevelLabelRrset(shorterTxt, rf, ttl));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800628
Yumin Xia9d110ce2016-11-15 14:03:14 -0800629 // insert a smaller NS, when there is long TXT
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700630 Rrset longTxt = rf.generateTxtRrset("/k1/k2/k3", 7654, ttl, std::vector<std::string>());
631 Rrset smallerNs = rf.generateNsRrset("/k1/k2", 7654, ttl, DelegationList());
Yumin Xia9d110ce2016-11-15 14:03:14 -0800632 BOOST_CHECK_NO_THROW(m_tool.addMultiLevelLabelRrset(longTxt, rf, ttl));
633 BOOST_CHECK_THROW(m_tool.addMultiLevelLabelRrset(smallerNs, rf, ttl),
634 ndns::ManagementTool::Error);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800635
Yumin Xia9d110ce2016-11-15 14:03:14 -0800636 // inserting a longer TXT, when there is shoter TXT
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700637 Rrset longerTxt = rf.generateTxtRrset("/k1/k2/k3/k4", 7654, ttl, std::vector<std::string>());
Yumin Xia9d110ce2016-11-15 14:03:14 -0800638 BOOST_CHECK_NO_THROW(m_tool.addMultiLevelLabelRrset(longerTxt, rf, ttl));
639}
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800640
Yumin Xia9d110ce2016-11-15 14:03:14 -0800641BOOST_AUTO_TEST_CASE(AddRrSetDskCertPreConditon)
642{
643 // check pre-condition
644 Name zoneName("/ndns-test");
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800645
Yumin Xia9d110ce2016-11-15 14:03:14 -0800646 // Check: throw if zone not exist
647 std::string certPath = TEST_CERTDIR.string();
Yumin Xiac5ed63f2017-01-26 13:44:38 -0800648 BOOST_CHECK_THROW(m_tool.addRrsetFromFile(zoneName, certPath), ndns::ManagementTool::Error);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800649
Yumin Xia9d110ce2016-11-15 14:03:14 -0800650 m_tool.createZone(zoneName, ROOT_ZONE);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800651
Yumin Xia9d110ce2016-11-15 14:03:14 -0800652 // Check: throw if certificate does not match
Yumin Xiac5ed63f2017-01-26 13:44:38 -0800653 BOOST_CHECK_THROW(m_tool.addRrsetFromFile(zoneName, certPath), ndns::ManagementTool::Error);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800654
Yumin Xia9d110ce2016-11-15 14:03:14 -0800655 std::string rightCertPath = TEST_CERTDIR.string() + "/ss.cert";
Yumin Xia2c509c22017-02-09 14:37:36 -0800656 std::vector<Certificate>&& certs = getCerts(zoneName);
657 const Name& ksk = certs[0].getName();
658 m_tool.exportCertificate(ksk, rightCertPath);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800659
Yumin Xia2c509c22017-02-09 14:37:36 -0800660 // Check: throw if it's a duplicated certificate
661 BOOST_CHECK_THROW(m_tool.addRrsetFromFile(zoneName, rightCertPath), ndns::ManagementTool::Error);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800662}
Jiewen Tan870b29b2014-11-17 19:09:49 -0800663
Yumin Xia9d110ce2016-11-15 14:03:14 -0800664BOOST_AUTO_TEST_CASE(AddRrSetDskCert)
665{
666 Name parentZoneName("/ndns-test");
667 Name zoneName("/ndns-test/child-zone");
Yumin Xia918343d2017-03-17 19:04:55 -0700668 Name zoneIdentityName = Name(zoneName).append(label::NDNS_ITERATIVE_QUERY);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800669
Yumin Xia9d110ce2016-11-15 14:03:14 -0800670 m_tool.createZone(parentZoneName, ROOT_ZONE, time::seconds(1), time::days(1), otherKsk, otherDsk);
671 m_tool.createZone(zoneName, parentZoneName);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800672
Yumin Xia2c509c22017-02-09 14:37:36 -0800673 Zone zone(zoneName);
674 Zone parentZone(parentZoneName);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800675
Yumin Xia2c509c22017-02-09 14:37:36 -0800676 Certificate dkey(findDkeyFromDb(zone.getName()));
Yumin Xia9d110ce2016-11-15 14:03:14 -0800677 std::string output = TEST_CERTDIR.string() + "/ss.cert";
Yumin Xia2c509c22017-02-09 14:37:36 -0800678 ndn::io::save(dkey, output);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800679
Yumin Xiac5ed63f2017-01-26 13:44:38 -0800680 BOOST_CHECK_NO_THROW(m_tool.addRrsetFromFile(parentZoneName, output));
Yumin Xia2c509c22017-02-09 14:37:36 -0800681 // Check if child zone's d-key could be inserted correctly
682 BOOST_CHECK_NO_THROW(findRrSet(parentZone, getLabel(parentZone, dkey.getName()), label::CERT_RR_TYPE));
Yumin Xia9d110ce2016-11-15 14:03:14 -0800683}
Jiewen Tand2d21822015-03-19 15:37:03 -0700684
Yumin Xia9d110ce2016-11-15 14:03:14 -0800685BOOST_AUTO_TEST_CASE(AddRrSetDskCertUserProvidedCert)
686{
687 //check using user provided certificate
688 Name parentZoneName("/ndns-test");
Yumin Xia918343d2017-03-17 19:04:55 -0700689 Name parentZoneIdentityName = Name(parentZoneName).append(label::NDNS_ITERATIVE_QUERY);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800690 Name zoneName("/ndns-test/child-zone");
Yumin Xia918343d2017-03-17 19:04:55 -0700691 Name zoneIdentityName = Name(zoneName).append(label::NDNS_ITERATIVE_QUERY);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800692
Yumin Xia2c509c22017-02-09 14:37:36 -0800693 // Name dskName = m_keyChain.generateRsaKeyPair(parentZoneName, false);
694 Identity id = CertHelper::getIdentity(m_keyChain, parentZoneIdentityName);
695 Key dsk = m_keyChain.createKey(id);
696 Certificate dskCert = dsk.getDefaultCertificate();
Yumin Xia9d110ce2016-11-15 14:03:14 -0800697
Yumin Xiac5ed63f2017-01-26 13:44:38 -0800698 // check addRrsetFromFile1
Yumin Xia9d110ce2016-11-15 14:03:14 -0800699 m_tool.createZone(parentZoneName, ROOT_ZONE, time::seconds(1), time::days(1), otherKsk, otherDsk);
700 m_tool.createZone(zoneName, parentZoneName);
701
Yumin Xia2c509c22017-02-09 14:37:36 -0800702 Certificate dkey(findDkeyFromDb(zoneName));
Yumin Xia9d110ce2016-11-15 14:03:14 -0800703 std::string output = TEST_CERTDIR.string() + "/ss.cert";
Yumin Xia2c509c22017-02-09 14:37:36 -0800704 ndn::io::save(dkey, output);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800705
Yumin Xiac5ed63f2017-01-26 13:44:38 -0800706 BOOST_CHECK_NO_THROW(m_tool.addRrsetFromFile(parentZoneName, output, time::seconds(4600),
Yumin Xia2c509c22017-02-09 14:37:36 -0800707 dskCert.getName()));
Yumin Xia9d110ce2016-11-15 14:03:14 -0800708}
709
710BOOST_AUTO_TEST_CASE(AddRrSetDskCertInvalidOutput)
711{
712 //check invalid output
713 Name parentZoneName("/ndns-test");
714 Name zoneName = Name(parentZoneName).append("child-zone");
715 m_tool.createZone(zoneName, parentZoneName);
716
717 Name content = "invalid data packet";
718 std::string output = TEST_CERTDIR.string() + "/ss.cert";
719 ndn::io::save(content, output);
720
Yumin Xiac5ed63f2017-01-26 13:44:38 -0800721 BOOST_CHECK_THROW(m_tool.addRrsetFromFile(zoneName, output), ndns::ManagementTool::Error);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800722}
723
724BOOST_AUTO_TEST_CASE(AddRrSetVersionControl)
725{
726 //check version control
727 time::seconds ttl(4200);
728 Name parentZoneName("/ndns-test");
729 Name zoneName = Name(parentZoneName).append("child-zone");
730 m_tool.createZone(zoneName, parentZoneName);
731
732 Name label("/label");
733 uint64_t version = 110;
734
735 RrsetFactory rf(TEST_DATABASE, zoneName, m_keyChain, DEFAULT_CERT);
736 rf.checkZoneKey();
737
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700738 Rrset rrset1 = rf.generateTxtRrset(label, version, ttl, {});
Yumin Xia9d110ce2016-11-15 14:03:14 -0800739
740 m_tool.addRrset(rrset1);
741 // throw error when adding duplicated rrset with the same version
742 BOOST_CHECK_THROW(m_tool.addRrset(rrset1),
743 ndns::ManagementTool::Error);
744 version--;
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700745 Rrset rrset2 = rf.generateTxtRrset(label, version, ttl, {});
Yumin Xia9d110ce2016-11-15 14:03:14 -0800746 // throw error when adding duplicated rrset with older version
747 BOOST_CHECK_THROW(m_tool.addRrset(rrset2),
748 ndns::ManagementTool::Error);
749
750 version++;
751 version++;
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700752 Rrset rrset3 = rf.generateTxtRrset(label, version, ttl, {});
Yumin Xia9d110ce2016-11-15 14:03:14 -0800753 BOOST_CHECK_NO_THROW(m_tool.addRrset(rrset3));
754
755 Zone zone(zoneName);
756 m_dbMgr.find(zone);
757 Rrset rrset;
758 rrset.setZone(&zone);
759 rrset.setLabel(label);
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700760 rrset.setType(label::TXT_RR_TYPE);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800761 m_dbMgr.find(rrset);
762
763 BOOST_CHECK_EQUAL(rrset.getVersion(), name::Component::fromVersion(version));
764}
765
766BOOST_AUTO_TEST_CASE(AddRrSetDskCertFormat)
767{
768 //check input with different formats
769 Name parentZoneName("/ndns-test");
770 Name zoneName = Name(parentZoneName).append("child-zone");
Yumin Xia2c509c22017-02-09 14:37:36 -0800771 Zone parentZone(parentZoneName);
772
773 m_tool.createZone(parentZoneName, ROOT_ZONE, time::seconds(1), time::days(1), otherKsk, otherDsk);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800774 m_tool.createZone(zoneName, parentZoneName);
Jiewen Tand2d21822015-03-19 15:37:03 -0700775
Yumin Xia2c509c22017-02-09 14:37:36 -0800776 Certificate cert(findDkeyFromDb(zoneName));
Yumin Xia9d110ce2016-11-15 14:03:14 -0800777 std::string output = TEST_CERTDIR.string() + "/a.cert";
Jiewen Tand2d21822015-03-19 15:37:03 -0700778
Yumin Xia918343d2017-03-17 19:04:55 -0700779 Name parentZoneIdentityName = Name(parentZoneName).append(label::NDNS_ITERATIVE_QUERY);
780
Yumin Xia9d110ce2016-11-15 14:03:14 -0800781 // base64
Yumin Xia2c509c22017-02-09 14:37:36 -0800782 ndn::io::save(cert, output, ndn::io::BASE64);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800783 BOOST_CHECK_NO_THROW(
Yumin Xia2c509c22017-02-09 14:37:36 -0800784 m_tool.addRrsetFromFile(parentZoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::BASE64));
785 m_tool.removeRrSet(parentZoneName, getLabel(parentZone, cert.getName()), label::CERT_RR_TYPE);
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700786
Yumin Xia9d110ce2016-11-15 14:03:14 -0800787 // raw
Yumin Xia2c509c22017-02-09 14:37:36 -0800788 ndn::io::save(cert, output, ndn::io::NO_ENCODING);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800789 BOOST_CHECK_NO_THROW(
Yumin Xia2c509c22017-02-09 14:37:36 -0800790 m_tool.addRrsetFromFile(parentZoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::NO_ENCODING));
791 m_tool.removeRrSet(parentZoneName, getLabel(parentZone, cert.getName()), label::CERT_RR_TYPE);
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700792
Yumin Xia9d110ce2016-11-15 14:03:14 -0800793 // hex
Yumin Xia2c509c22017-02-09 14:37:36 -0800794 ndn::io::save(cert, output, ndn::io::HEX);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800795 BOOST_CHECK_NO_THROW(
Yumin Xia2c509c22017-02-09 14:37:36 -0800796 m_tool.addRrsetFromFile(parentZoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::HEX));
797 m_tool.removeRrSet(parentZoneName, getLabel(parentZone, cert.getName()), label::CERT_RR_TYPE);
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700798
Yumin Xia9d110ce2016-11-15 14:03:14 -0800799 // incorrect encoding input
Yumin Xia2c509c22017-02-09 14:37:36 -0800800 ndn::io::save(cert, output, ndn::io::HEX);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800801 BOOST_CHECK_THROW(
Yumin Xia2c509c22017-02-09 14:37:36 -0800802 m_tool.addRrsetFromFile(parentZoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT,
803 static_cast<ndn::io::IoEncoding>(127)),
Yumin Xia9d110ce2016-11-15 14:03:14 -0800804 ndns::ManagementTool::Error);
805}
Jiewen Tan74d745c2015-03-20 01:40:41 -0700806
Yumin Xia9d110ce2016-11-15 14:03:14 -0800807BOOST_AUTO_TEST_CASE(ListAllZones)
808{
Yumin Xia2c509c22017-02-09 14:37:36 -0800809 m_tool.createZone(ROOT_ZONE, ROOT_ZONE, time::seconds(1), time::days(1), rootKsk, rootDsk, rootDkey);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800810 m_tool.createZone("/ndns-test", ROOT_ZONE, time::seconds(10), time::days(1), otherKsk, otherDsk);
Jiewen Tan74d745c2015-03-20 01:40:41 -0700811
Yumin Xia2c509c22017-02-09 14:37:36 -0800812 Name rootDskName = CertHelper::getCertificate(m_keyChain, "/NDNS/", rootDsk).getKeyName();
813 Name otherDskName = CertHelper::getCertificate(m_keyChain, "/ndns-test/NDNS/", otherDsk).getKeyName();
814
Yumin Xia9d110ce2016-11-15 14:03:14 -0800815 std::string expectedValue =
Yumin Xia2c509c22017-02-09 14:37:36 -0800816 "/ ; default-ttl=1 default-key=" + rootDskName.toUri() + " "
817 "default-certificate=" + rootDsk.toUri() + "\n"
818 "/ndns-test ; default-ttl=10 default-key=" + otherDskName.toUri() + " "
819 "default-certificate=" + otherDsk.toUri() + "\n";
Jiewen Tan74d745c2015-03-20 01:40:41 -0700820
Yumin Xia9d110ce2016-11-15 14:03:14 -0800821 output_test_stream testOutput;
822 m_tool.listAllZones(testOutput);
823 BOOST_CHECK(testOutput.is_equal(expectedValue));
824}
Jiewen Tan74d745c2015-03-20 01:40:41 -0700825
Yumin Xia2c509c22017-02-09 14:37:36 -0800826// will be fixed after updating to new naming convention
827BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(ListZone, 1)
828
Yumin Xia9d110ce2016-11-15 14:03:14 -0800829BOOST_AUTO_TEST_CASE(ListZone)
830{
831 m_tool.createZone("/ndns-test", ROOT_ZONE, time::seconds(10), time::days(1), otherKsk, otherDsk);
Jiewen Tan74d745c2015-03-20 01:40:41 -0700832
Yumin Xia9d110ce2016-11-15 14:03:14 -0800833 RrsetFactory rf(TEST_DATABASE, "/ndns-test", m_keyChain, DEFAULT_CERT);
834 rf.checkZoneKey();
Jiewen Tan74d745c2015-03-20 01:40:41 -0700835
Yumin Xia9d110ce2016-11-15 14:03:14 -0800836 // Add NS with NDNS_RESP
Yumin Xia2c509c22017-02-09 14:37:36 -0800837 Delegation del;
838 del.preference = 10;
839 del.name = Name("/get/link");
840 DelegationList ds = {del};
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700841 Rrset rrset1 = rf.generateNsRrset("/label1", 100, DEFAULT_RR_TTL, ds);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800842 m_tool.addRrset(rrset1);
Jiewen Tan74d745c2015-03-20 01:40:41 -0700843
Yumin Xia9d110ce2016-11-15 14:03:14 -0800844 // Add NS with NDNS_AUTH
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700845 Rrset rrset2 = rf.generateAuthRrset("/label2", 100000, DEFAULT_RR_TTL);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800846 m_tool.addRrset(rrset2);
Jiewen Tan74d745c2015-03-20 01:40:41 -0700847
Yumin Xia9d110ce2016-11-15 14:03:14 -0800848 // Add TXT from file
849 std::string output = TEST_CERTDIR.string() + "/a.rrset";
850 Response re1;
851 re1.setZone("/ndns-test");
852 re1.setQueryType(label::NDNS_ITERATIVE_QUERY);
853 re1.setRrLabel("/label2");
854 re1.setRrType(label::TXT_RR_TYPE);
855 re1.setContentType(NDNS_RESP);
856 re1.setVersion(name::Component::fromVersion(654321));
857 re1.addRr("First RR");
858 re1.addRr("Second RR");
859 re1.addRr("Last RR");
860 shared_ptr<Data> data1 = re1.toData();
Yumin Xia2c509c22017-02-09 14:37:36 -0800861 m_keyChain.sign(*data1, security::signingByCertificate(otherDsk));
Yumin Xia9d110ce2016-11-15 14:03:14 -0800862 ndn::io::save(*data1, output);
Yumin Xiac5ed63f2017-01-26 13:44:38 -0800863 m_tool.addRrsetFromFile("/ndns-test", output);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800864
Yumin Xia9d110ce2016-11-15 14:03:14 -0800865 // Add TXT in normal way
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700866 Rrset rrset3 = rf.generateTxtRrset("/label3", 3333, DEFAULT_RR_TTL, {"Hello", "World"});
Yumin Xia9d110ce2016-11-15 14:03:14 -0800867 m_tool.addRrset(rrset3);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800868
Yumin Xia2c509c22017-02-09 14:37:36 -0800869 m_tool.listZone("/ndns-test", std::cout, true);
870
Yumin Xia9d110ce2016-11-15 14:03:14 -0800871 output_test_stream testOutput;
872 m_tool.listZone("/ndns-test", testOutput, true);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800873
Yumin Xia2c509c22017-02-09 14:37:36 -0800874
Yumin Xia9d110ce2016-11-15 14:03:14 -0800875 std::string expectedValue =
876 R"VALUE(; Zone /ndns-test
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800877
Yumin Xia2c509c22017-02-09 14:37:36 -0800878; rrset=/label1 type=NS version=%FDd signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
Yumin Xia9d110ce2016-11-15 14:03:14 -0800879/label1 10 NS 10,/get/link;
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800880
Yumin Xia2c509c22017-02-09 14:37:36 -0800881; rrset=/label2 type=NS version=%FD%00%01%86%A0 signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
Yumin Xia9d110ce2016-11-15 14:03:14 -0800882/label2 10 NS NDNS-Auth
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800883
Yumin Xia2c509c22017-02-09 14:37:36 -0800884; rrset=/label2 type=TXT version=%FD%00%09%FB%F1 signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
Yumin Xia9d110ce2016-11-15 14:03:14 -0800885/label2 10 TXT First RR
886/label2 10 TXT Second RR
887/label2 10 TXT Last RR
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800888
Yumin Xia2c509c22017-02-09 14:37:36 -0800889; rrset=/label3 type=TXT version=%FD%0D%05 signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
Yumin Xia9d110ce2016-11-15 14:03:14 -0800890/label3 10 TXT Hello
891/label3 10 TXT World
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800892
Yumin Xia2c509c22017-02-09 14:37:36 -0800893/dsk-1416974006659 10 CERT ; content-type=KEY version=%FD%00%00%01I%EA%3Bz%0E signed-by=/ndns-test/KEY/ksk-1416974006577/CERT
Yumin Xia9d110ce2016-11-15 14:03:14 -0800894; Certificate name:
Yumin Xia2c509c22017-02-09 14:37:36 -0800895; /ndns-test/KEY/dsk-1416974006659/CERT/%FD%00%00%01I%EA%3Bz%0E
Yumin Xia9d110ce2016-11-15 14:03:14 -0800896; Validity:
897; NotBefore: 19700101T000000
898; NotAfter: 20380119T031408
899; Subject Description:
900; 2.5.4.41: /ndns-test
901; Public key bits: (RSA)
902; MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAyBVC+xc/JpscSE/JdxbV
903; pvgrh/fokNFI/2t9D5inuIFr7cc4W+LyJ4GG1xr9olMx7MHamJU1Xg3VunjhSjL8
904; mOaeXlbS6gxWexBCtNK6U4euPB4wks/gMIKdp24mAAFb4T+mBfjcRgR+NdrjyO5C
905; 2OqM8qbDZmD/iuEmE6GPXnuMS0o6s13yzMj9YfDh3Df2jZnHESZcmG5Qpgg22T58
906; 7t7bRx8Ha2EC3hb29AeYKwgEKDx8JH8ZBJ80AQP321HbyjXWshJLomzy5SJZo9nA
907; bZOYlZPCQkomz92Zc9+kpLNQwDvtRLwkZ46B+b2JpKTFARbnvugONCEBuG6zNgoi
908; EQIB
909; Signature Information:
910; Signature Type: Unknown Signature Type
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800911
Yumin Xia9d110ce2016-11-15 14:03:14 -0800912)VALUE";
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800913
Yumin Xia9d110ce2016-11-15 14:03:14 -0800914 BOOST_CHECK(testOutput.is_equal(expectedValue));
915}
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800916
Yumin Xia9d110ce2016-11-15 14:03:14 -0800917BOOST_FIXTURE_TEST_CASE(GetRrSet, ManagementToolFixture)
918{
919 Name zoneName("/ndns-test");
920 m_tool.createZone(zoneName, ROOT_ZONE, time::seconds(1), time::days(1), otherKsk, otherDsk);
921 RrsetFactory rf(TEST_DATABASE, zoneName, m_keyChain, DEFAULT_CERT);
922 rf.checkZoneKey();
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700923 Rrset rrset1 = rf.generateTxtRrset("/label", 100, DEFAULT_RR_TTL, {"Value1", "Value2"});
Jiewen Tan870b29b2014-11-17 19:09:49 -0800924
Yumin Xia9d110ce2016-11-15 14:03:14 -0800925 m_tool.addRrset(rrset1);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800926
Yumin Xia2c509c22017-02-09 14:37:36 -0800927 std::stringstream os;
928
929 using security::transform::base64Encode;
930 using security::transform::streamSink;
931 using security::transform::bufferSource;
932
933 bufferSource(rrset1.getData().wire(), rrset1.getData().size()) >> base64Encode() >> streamSink(os);
934
935 std::string expectedValue = os.str();
Jiewen Tan870b29b2014-11-17 19:09:49 -0800936
Yumin Xia9d110ce2016-11-15 14:03:14 -0800937 output_test_stream testOutput;
938 m_tool.getRrSet(zoneName, "/label",label::TXT_RR_TYPE, testOutput);
Yumin Xia9d110ce2016-11-15 14:03:14 -0800939 BOOST_CHECK(testOutput.is_equal(expectedValue));
940}
Jiewen Tan870b29b2014-11-17 19:09:49 -0800941
Yumin Xia9d110ce2016-11-15 14:03:14 -0800942BOOST_FIXTURE_TEST_CASE(RemoveRrSet, ManagementToolFixture)
943{
944 Name zoneName("/ndns-test");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800945
Yumin Xia9d110ce2016-11-15 14:03:14 -0800946 m_tool.createZone(zoneName, ROOT_ZONE);
947 RrsetFactory rf(TEST_DATABASE, zoneName, m_keyChain, DEFAULT_CERT);
948 rf.checkZoneKey();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800949
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700950 Rrset rrset1 = rf.generateTxtRrset("/label", 100, DEFAULT_RR_TTL, {});
Jiewen Tan870b29b2014-11-17 19:09:49 -0800951
Yumin Xia9d110ce2016-11-15 14:03:14 -0800952 BOOST_CHECK_NO_THROW(m_tool.addRrset(rrset1));
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800953
Yumin Xia9d110ce2016-11-15 14:03:14 -0800954 Zone zone(zoneName);
Yumin Xiad4e8ce52017-03-17 19:56:52 -0700955 BOOST_CHECK_NO_THROW(findRrSet(zone, "/label", label::TXT_RR_TYPE));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800956
Yumin Xia9d110ce2016-11-15 14:03:14 -0800957 BOOST_CHECK_NO_THROW(m_tool.removeRrSet(zoneName, "/label", label::NS_RR_TYPE));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800958
Yumin Xia9d110ce2016-11-15 14:03:14 -0800959 BOOST_CHECK_THROW(findRrSet(zone, "/label", label::NS_RR_TYPE), Error);
960}
Jiewen Tan870b29b2014-11-17 19:09:49 -0800961
962BOOST_AUTO_TEST_SUITE_END()
963
964} // namespace tests
965} // namespace ndns
966} // namespace ndn