blob: b789020f6344579289501ee37dc6df8dbc15cbd9 [file] [log] [blame]
Alexander Afanasyevc169a812014-05-20 20:37:29 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Yingdi Yuf50098d2014-02-26 14:26:29 -08002/**
Alexander Afanasyeve4f8c3b2016-06-23 16:03:48 -07003 * Copyright (c) 2013-2016 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.
Yingdi Yuf50098d2014-02-26 14:26:29 -080020 */
21
Yingdi Yuf50098d2014-02-26 14:26:29 -080022#include "util/io.hpp"
23#include "security/key-chain.hpp"
24
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070025#include "boost-test.hpp"
Junxiao Shic1779882016-08-17 01:59:23 +000026#include "identity-management-fixture.hpp"
27#include <boost/filesystem.hpp>
28#include <fstream>
Alexander Afanasyevb1db7c62014-04-03 14:57:25 -070029
Yingdi Yuf50098d2014-02-26 14:26:29 -080030namespace ndn {
Spyridon Mastorakis429634f2015-02-19 17:35:33 -080031namespace tests {
Yingdi Yuf50098d2014-02-26 14:26:29 -080032
Junxiao Shic1779882016-08-17 01:59:23 +000033class IoFixture
Yingdi Yuf50098d2014-02-26 14:26:29 -080034{
Junxiao Shic1779882016-08-17 01:59:23 +000035protected:
36 IoFixture()
37 : filepath(boost::filesystem::path(UNIT_TEST_CONFIG_PATH) /= "TestIo")
38 , filename(filepath.string())
39 {
40 boost::filesystem::create_directories(filepath.parent_path());
41 }
42
43 ~IoFixture()
44 {
45 boost::system::error_code ec;
46 boost::filesystem::remove(filepath, ec); // ignore error
47 }
48
49 /** \brief create a directory at filename, so that it's neither readable nor writable as a file
50 */
51 void
52 mkdir() const
53 {
54 boost::filesystem::create_directory(filepath);
55 }
56
57 template<typename Container, typename CharT = typename Container::value_type>
58 Container
59 readFile() const
60 {
61 Container container;
62 std::ifstream fs(filename, std::ios_base::binary);
63 char ch;
64 while (fs.get(ch)) {
65 container.push_back(static_cast<CharT>(ch));
66 }
67 return container;
68 }
69
70 template<typename Container, typename CharT = typename Container::value_type>
71 void
72 writeFile(const Container& content) const
73 {
74 std::ofstream fs(filename, std::ios_base::binary);
75 for (CharT ch : content) {
76 fs.put(static_cast<char>(ch));
77 }
78 fs.close();
79 BOOST_REQUIRE_MESSAGE(fs, "error writing file");
80 }
81
82protected:
83 const boost::filesystem::path filepath;
84 const std::string filename;
85};
86
87BOOST_AUTO_TEST_SUITE(Util)
88BOOST_FIXTURE_TEST_SUITE(TestIo, IoFixture)
89
90class EncodableType
91{
92public:
93 class Error : public tlv::Error
94 {
95 public:
96 Error()
97 : tlv::Error("encode error")
98 {
99 }
100 };
101
102 Block
103 wireEncode() const
104 {
105 if (shouldThrow) {
106 BOOST_THROW_EXCEPTION(Error());
107 }
108
109 // block will be 0xAA, 0x01, 0xDD
110 return makeNonNegativeIntegerBlock(0xAA, 0xDD);
111 }
112
113public:
114 bool shouldThrow = false;
115};
116
117class DecodableType
118{
119public:
120 class Error : public tlv::Error
121 {
122 public:
123 Error()
124 : tlv::Error("decode error")
125 {
126 }
127 };
128
129 void
130 wireDecode(const Block& block) const
131 {
132 if (shouldThrow) {
133 BOOST_THROW_EXCEPTION(Error());
134 }
135
136 // block must be 0xBB, 0x01, 0xEE
137 BOOST_CHECK_EQUAL(block.type(), 0xBB);
138 BOOST_REQUIRE_EQUAL(block.value_size(), 1);
139 BOOST_CHECK_EQUAL(block.value()[0], 0xEE);
140 }
141
142public:
143 bool shouldThrow = false;
144};
145
146class DecodableTypeThrow : public DecodableType
147{
148public:
149 DecodableTypeThrow()
150 {
151 this->shouldThrow = true;
152 }
153};
154
155BOOST_AUTO_TEST_CASE(LoadNoEncoding)
156{
157 this->writeFile<std::vector<uint8_t>>({0xBB, 0x01, 0xEE});
158 shared_ptr<DecodableType> decoded = io::load<DecodableType>(filename, io::NO_ENCODING);
159 BOOST_CHECK(decoded != nullptr);
160}
161
162BOOST_AUTO_TEST_CASE(LoadBase64)
163{
164 this->writeFile<std::string>("uwHu\n"); // printf '\xBB\x01\xEE' | base64
165 shared_ptr<DecodableType> decoded = io::load<DecodableType>(filename, io::BASE_64);
166 BOOST_CHECK(decoded != nullptr);
167}
168
169BOOST_AUTO_TEST_CASE(LoadHex)
170{
171 this->writeFile<std::string>("BB01EE");
172 shared_ptr<DecodableType> decoded = io::load<DecodableType>(filename, io::HEX);
173 BOOST_CHECK(decoded != nullptr);
174}
175
176BOOST_AUTO_TEST_CASE(LoadException)
177{
178 this->writeFile<std::vector<uint8_t>>({0xBB, 0x01, 0xEE});
179 shared_ptr<DecodableTypeThrow> decoded;
180 BOOST_CHECK_NO_THROW(decoded = io::load<DecodableTypeThrow>(filename, io::NO_ENCODING));
181 BOOST_CHECK(decoded == nullptr);
182}
183
184BOOST_AUTO_TEST_CASE(LoadNotHex)
185{
186 this->writeFile<std::string>("not-hex");
187 shared_ptr<DecodableType> decoded;
188 BOOST_CHECK_NO_THROW(decoded = io::load<DecodableType>(filename, io::HEX));
189 BOOST_CHECK(decoded == nullptr);
190}
191
192BOOST_AUTO_TEST_CASE(LoadFileNotReadable)
193{
Junxiao Shic1779882016-08-17 01:59:23 +0000194 shared_ptr<DecodableType> decoded;
195 BOOST_CHECK_NO_THROW(decoded = io::load<DecodableType>(filename, io::NO_ENCODING));
196 BOOST_CHECK(decoded == nullptr);
197}
198
199BOOST_AUTO_TEST_CASE(SaveNoEncoding)
200{
201 EncodableType encoded;
202 BOOST_CHECK_NO_THROW(io::save(encoded, filename, io::NO_ENCODING));
203 auto content = this->readFile<std::vector<uint8_t>>();
204 uint8_t expected[] = {0xAA, 0x01, 0xDD};
205 BOOST_CHECK_EQUAL_COLLECTIONS(content.begin(), content.end(),
206 expected, expected + sizeof(expected));
207}
208
209BOOST_AUTO_TEST_CASE(SaveBase64)
210{
211 EncodableType encoded;
212 BOOST_CHECK_NO_THROW(io::save(encoded, filename, io::BASE_64));
213 auto content = this->readFile<std::string>();
214 BOOST_CHECK_EQUAL(content, "qgHd\n"); // printf '\xAA\x01\xDD' | base64
215}
216
217BOOST_AUTO_TEST_CASE(SaveHex)
218{
219 EncodableType encoded;
220 BOOST_CHECK_NO_THROW(io::save(encoded, filename, io::HEX));
221 auto content = this->readFile<std::string>();
222 BOOST_CHECK_EQUAL(content, "AA01DD");
223}
224
225BOOST_AUTO_TEST_CASE(SaveException)
226{
227 EncodableType encoded;
228 encoded.shouldThrow = true;
229 BOOST_CHECK_THROW(io::save(encoded, filename, io::NO_ENCODING), io::Error);
230}
231
232BOOST_AUTO_TEST_CASE(SaveFileNotWritable)
233{
234 this->mkdir();
235 EncodableType encoded;
236 encoded.shouldThrow = true;
237 BOOST_CHECK_THROW(io::save(encoded, filename, io::NO_ENCODING), io::Error);
238}
239
240class IdCertFixture : public IoFixture
241 , public IdentityManagementFixture
242{
243};
244
245BOOST_FIXTURE_TEST_CASE(IdCert, IdCertFixture)
246{
247 Name identity("/TestIo/IdCert");
Alexander Afanasyevaa0e7da2014-03-17 14:37:33 -0700248 identity.appendVersion();
Yingdi Yu3ed09d02014-10-13 16:24:08 -0700249 BOOST_REQUIRE(addIdentity(identity, RsaKeyParams()));
250 Name certName = m_keyChain.getDefaultCertificateNameForIdentity(identity);
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700251 shared_ptr<security::v1::IdentityCertificate> idCert;
Yingdi Yu3ed09d02014-10-13 16:24:08 -0700252 BOOST_REQUIRE_NO_THROW(idCert = m_keyChain.getCertificate(certName));
Yingdi Yuf50098d2014-02-26 14:26:29 -0800253
Junxiao Shic1779882016-08-17 01:59:23 +0000254 io::save(*idCert, filename);
Alexander Afanasyev2fa59392016-07-29 17:24:23 -0700255 shared_ptr<security::v1::IdentityCertificate> readCert = io::load<security::v1::IdentityCertificate>(filename);
Yingdi Yuf50098d2014-02-26 14:26:29 -0800256
Junxiao Shic1779882016-08-17 01:59:23 +0000257 BOOST_CHECK(readCert != nullptr);
258 BOOST_CHECK_EQUAL(idCert->getName(), readCert->getName());
Yingdi Yuf50098d2014-02-26 14:26:29 -0800259}
260
Junxiao Shic1779882016-08-17 01:59:23 +0000261BOOST_AUTO_TEST_SUITE_END() // TestIo
262BOOST_AUTO_TEST_SUITE_END() // Util
Yingdi Yuf50098d2014-02-26 14:26:29 -0800263
Spyridon Mastorakis429634f2015-02-19 17:35:33 -0800264} // namespace tests
Yingdi Yuf50098d2014-02-26 14:26:29 -0800265} // namespace ndn