blob: 226ae2bc30129c3ba34ec4bf73600066e39e6a47 [file] [log] [blame]
Mickey Sweatt3b0bea62016-01-25 22:12:27 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3* Copyright (c) 2016 Regents of the University of California.
4*
5* This file is part of the nTorrent codebase.
6*
7* nTorrent 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* nTorrent 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 nTorrent, e.g., in COPYING.md file. If not, see
17* <http://www.gnu.org/licenses/>.
18*
19* See AUTHORS for complete list of nTorrent authors and contributors.
20*/
21
22#include "file-manifest.hpp"
23#include "boost-test.hpp"
24
25#include <vector>
26
27#include <ndn-cxx/data.hpp>
Mickey Sweatt3b0bea62016-01-25 22:12:27 -080028#include <ndn-cxx/security/key-chain.hpp>
Mickey Sweattebc01952016-02-19 11:38:30 -080029#include <ndn-cxx/security/signing-helpers.hpp>
30#include <ndn-cxx/signature.hpp>
Mickey Sweatt6de5dde2016-03-15 16:44:56 -070031#include <ndn-cxx/util/io.hpp>
Mickey Sweattebc01952016-02-19 11:38:30 -080032
33#include <boost/filesystem.hpp>
34#include <boost/filesystem/fstream.hpp>
35#include <boost/lexical_cast.hpp>
36
37namespace fs = boost::filesystem;
Mickey Sweatt3b0bea62016-01-25 22:12:27 -080038
39BOOST_TEST_DONT_PRINT_LOG_VALUE(std::nullptr_t)
40BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<ndn::Name>)
Mickey Sweattebc01952016-02-19 11:38:30 -080041BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<ndn::ntorrent::FileManifest>)
Mickey Sweatt6de5dde2016-03-15 16:44:56 -070042BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<ndn::ntorrent::FileManifest>::iterator)
Mickey Sweattebc01952016-02-19 11:38:30 -080043BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<uint8_t>)
44BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<ndn::Data>::iterator)
Mickey Sweatt3b0bea62016-01-25 22:12:27 -080045
46namespace ndn {
47namespace ntorrent {
48namespace tests {
49
50using std::vector;
51using ndn::Name;
52
53BOOST_AUTO_TEST_SUITE(TestFileManifest)
54
55BOOST_AUTO_TEST_CASE(CheckPrimaryAccessorsAndManipulators)
56{
57 FileManifest m1("/file0/1A2B3C4D", 256, "/foo/");
58
59 // Check the values on most simply constructed m1
60 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
61 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
62 BOOST_CHECK_EQUAL(nullptr, m1.submanifest_ptr());
63 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
64 BOOST_CHECK_EQUAL(vector<Name>({}), m1.catalog());
65
66 // Append names to catalog and recheck all salient attributes
67 m1.push_back("/foo/0/ABC123");
68 m1.push_back("/foo/1/DEADBEFF");
69 m1.push_back("/foo/2/CAFEBABE");
70
71 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
72 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
73 BOOST_CHECK_EQUAL(nullptr, m1.submanifest_ptr());
74 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
75 BOOST_CHECK_EQUAL(vector<Name>({"/foo/0/ABC123", "/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}),
76 m1.catalog());
77
78 // Remove a value from the catalog and recheck all salient attributes
79 BOOST_CHECK_EQUAL(true, m1.remove("/foo/0/ABC123"));
80
81 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
82 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
83 BOOST_CHECK_EQUAL(nullptr, m1.submanifest_ptr());
84 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
85 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}), m1.catalog());
86
87 // Try to remove a value no longer in the catalog, and recheck that all salient attributes
88 BOOST_CHECK_EQUAL(false, m1.remove("/foo/0/ABC123"));
89
90 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
91 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
92 BOOST_CHECK_EQUAL(nullptr, m1.submanifest_ptr());
93 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
94 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}), m1.catalog());
95
96 // Try to remove a value never in the catalog, and recheck that all salient attributes
97 BOOST_CHECK_EQUAL(false, m1.remove("/bar/0/ABC123"));
98 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
99 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
100 BOOST_CHECK_EQUAL(nullptr, m1.submanifest_ptr());
101 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
102 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}),
103 m1.catalog());
104
105 // Remove a value from the end of the list
106 BOOST_CHECK_EQUAL(true, m1.remove("/foo/2/CAFEBABE"));
107
108 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
109 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
110 BOOST_CHECK_EQUAL(nullptr, m1.submanifest_ptr());
111 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
112 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF"}),
113 m1.catalog());
114}
115
116BOOST_AUTO_TEST_CASE(CheckValueCtors)
117{
118 FileManifest m1("/file0/1A2B3C4D",
119 256,
120 "/foo/",
121 {"/foo/0/ABC123", "/foo/1/DEADBEFF", "/foo/2/CAFEBABE"},
122 std::make_shared<Name>("/file0/1/5E6F7G8H"));
123
124 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
125 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
126 BOOST_CHECK_EQUAL("/file0/1/5E6F7G8H", *m1.submanifest_ptr());
127 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
128 BOOST_CHECK_EQUAL(vector<Name>({"/foo/0/ABC123", "/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}),
129 m1.catalog());
130
131 // Remove a value from the catalog and recheck all salient attributes
132 BOOST_CHECK_EQUAL(true, m1.remove("/foo/0/ABC123"));
133
134 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
135 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
136 BOOST_CHECK_EQUAL("/file0/1/5E6F7G8H", *m1.submanifest_ptr());
137 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
138 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}), m1.catalog());
139
140 // Try to remove a value no longer in the catalog, and recheck that all salient attributes
141 BOOST_CHECK_EQUAL(false, m1.remove("/foo/0/ABC123"));
142
143 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
144 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
145 BOOST_CHECK_EQUAL("/file0/1/5E6F7G8H", *m1.submanifest_ptr());
146 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
147 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}), m1.catalog());
148
149 // Try to remove a value never in the catalog, and recheck that all salient attributes
150 BOOST_CHECK_EQUAL(false, m1.remove("/bar/0/ABC123"));
151 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
152 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
153 BOOST_CHECK_EQUAL("/file0/1/5E6F7G8H", *m1.submanifest_ptr());
154 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
155 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF", "/foo/2/CAFEBABE"}), m1.catalog());
156
157 // Remove a value from the end of the list
158 BOOST_CHECK_EQUAL(true, m1.remove("/foo/2/CAFEBABE"));
159
160 BOOST_CHECK_EQUAL("/file0/1A2B3C4D", m1.name());
161 BOOST_CHECK_EQUAL(256, m1.data_packet_size());
162 BOOST_CHECK_EQUAL("/file0/1/5E6F7G8H", *m1.submanifest_ptr());
163 BOOST_CHECK_EQUAL("/foo/", m1.catalog_prefix());
164 BOOST_CHECK_EQUAL(vector<Name>({"/foo/1/DEADBEFF"}), m1.catalog());
165}
166
167BOOST_AUTO_TEST_CASE(CheckAssignmentOperatorEqaulityAndCopyCtor)
168{
169 // Construct two manifests with the same attributes, and check that they related equal
170 {
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700171 FileManifest m1("/file0/1A2B3C4D",
172 256,
173 "/foo/",
174 vector<Name>({}),
175 std::make_shared<Name>("/file0/1/5E6F7G8H"));
176
177 FileManifest m2("/file0/1A2B3C4D",
178 256,
179 "/foo/",
180 vector<Name>({}),
181 std::make_shared<Name>("/file0/1/5E6F7G8H"));
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800182
183 BOOST_CHECK_EQUAL(m1, m2);
184 BOOST_CHECK(!(m1 != m2));
185
186 // Change value of one
187 m1.push_back("/foo/0/ABC123");
188 BOOST_CHECK_NE(m1, m2);
189 BOOST_CHECK(!(m1 == m2));
190
191 // Update other
192 m2.push_back("/foo/0/ABC123");
193 BOOST_CHECK_EQUAL(m1, m2);
194 BOOST_CHECK(!(m1 != m2));
195
196 // Change value again
197 m1.remove("/foo/0/ABC123");
198 BOOST_CHECK_NE(m1, m2);
199 BOOST_CHECK(!(m1 == m2));
200
201 m2.remove("/foo/0/ABC123");
202 BOOST_CHECK_EQUAL(m1, m2);
203 BOOST_CHECK(!(m1 != m2));
204 }
205
206 // Set sub-manifest pointer in one and not the other
207 {
208 FileManifest m1("/file0/1A2B3C4D",
209 256,
210 "/foo/",
211 vector<Name>({}),
212 std::make_shared<Name>("/file0/1/5E6F7G8H"));
213
214 FileManifest m2("/file0/1A2B3C4D", 256, "/foo/");
215 BOOST_CHECK_NE(m1, m2);
216 BOOST_CHECK(!(m1 == m2));
217
218 std::swap(m1, m2);
219 BOOST_CHECK_NE(m1, m2);
220 BOOST_CHECK(!(m1 == m2));
221 }
222
223 // Construct two manifests using copy ctor for one
224 {
225 FileManifest m1("/file0/1A2B3C4D", 256, "/foo/");
226 FileManifest m2(m1);
227
228 BOOST_CHECK_EQUAL(m1, m2);
229 BOOST_CHECK(!(m1 != m2));
230
231 // Change value of one
232 m1.push_back("/foo/0/ABC123");
233 BOOST_CHECK_NE(m1, m2);
234 BOOST_CHECK(!(m1 == m2));
235
236 // Update other
237 m2.push_back("/foo/0/ABC123");
238 BOOST_CHECK_EQUAL(m1, m2);
239 BOOST_CHECK(!(m1 != m2));
240
241 // Change value again
242 m1.remove("/foo/0/ABC123");
243 BOOST_CHECK_NE(m1, m2);
244 BOOST_CHECK(!(m1 == m2));
245
246 m2.remove("/foo/0/ABC123");
247 BOOST_CHECK_EQUAL(m1, m2);
248 BOOST_CHECK(!(m1 != m2));
249 }
250
251 // Use assignment operator
252 {
253 FileManifest m1("/file1/1A2B3C4D", 256, "/foo/");
254 FileManifest m2("/file1/5E6F7G8H", 256, "/foo/");
255
256 BOOST_CHECK_NE(m1, m2);
257 BOOST_CHECK(!(m1 == m2));
258
259 m2 = m1;
260 BOOST_CHECK_EQUAL(m1, m2);
261 BOOST_CHECK(!(m1 != m2));
262
263 // Change value of one
264 m1.push_back("/foo/0/ABC123");
265 BOOST_CHECK_NE(m1, m2);
266 BOOST_CHECK(!(m1 == m2));
267
268 // Update other
269 m2.push_back("/foo/0/ABC123");
270 BOOST_CHECK_EQUAL(m1, m2);
271 BOOST_CHECK(!(m1 != m2));
272
273 // Change value again
274 m1.remove("/foo/0/ABC123");
275 BOOST_CHECK_NE(m1, m2);
276 BOOST_CHECK(!(m1 == m2));
277
278 m2.remove("/foo/0/ABC123");
279 BOOST_CHECK_EQUAL(m1, m2);
280 BOOST_CHECK(!(m1 != m2));
281 }
282}
283
284BOOST_AUTO_TEST_CASE(CheckEncodeDecode)
285{
286 // Construct new FileManifest from wire encoding of another FileManifest
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700287 {
288 FileManifest m1("/file0/1A2B3C4D",
289 256,
290 "/foo/",
291 {"/foo/0/ABC123", "/foo/1/DEADBEFF", "/foo/2/CAFEBABE"},
292 std::make_shared<Name>("/file0/1/5E6F7G8H"));
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800293
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700294 KeyChain keyChain;
295 m1.finalize();
296 keyChain.sign(m1);
297 BOOST_CHECK_EQUAL(m1, FileManifest(m1.wireEncode()));
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800298
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700299 // Change value and be sure that wireEncoding still works
300 m1.remove("/foo/2/CAFEBABE");
301 m1.finalize();
302 keyChain.sign(m1);
303 BOOST_CHECK_EQUAL(m1, FileManifest(m1.wireEncode()));
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800304
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700305 // Explicitly call wireEncode and ensure the value works
306 FileManifest m2 = m1;
307 m1.remove("/foo/0/ABC123");
308 keyChain.sign(m1);
309 m1.finalize();
310 m2.wireDecode(m1.wireEncode());
311 BOOST_CHECK_EQUAL(m1, m2);
312 }
313 {
314 FileManifest m1("/file0/1A2B3C4D",
315 256,
316 "/foo/",
317 {"/foo/0/ABC123", "/foo/1/DEADBEFF", "/foo/2/CAFEBABE"});
318 KeyChain keyChain;
319 m1.finalize();
320 keyChain.sign(m1);
321 BOOST_CHECK_EQUAL(m1, FileManifest(m1.wireEncode()));
322 }
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800323}
324
Mickey Sweattebc01952016-02-19 11:38:30 -0800325BOOST_AUTO_TEST_CASE(CheckGenerateFileManifest)
326{
327 const size_t TEST_FILE_LEN = fs::file_size("tests/testdata/foo/bar.txt");
328 const struct {
329 size_t d_dataPacketSize;
330 size_t d_subManifestSize;
331 const char *d_filePath;
332 const char *d_catalogPrefix;
333 bool d_getData;
334 bool d_shouldThrow;
335 } DATA [] = {
336 // Affirmative tests
337 {1 , TEST_FILE_LEN, "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
338 {10 , 10 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
339 {10 , 1 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
340 {1 , 10 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
341 {1 , 1 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
342 {1024 , 1 , "tests/testdata/foo/bar1.txt", "/NTORRENT/foo/", true, false },
343 {1024 , 100 , "tests/testdata/foo/bar1.txt", "/NTORRENT/foo/", true, false },
344 {TEST_FILE_LEN, 1 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700345 // Negative tests
346 // non-existent file
Mickey Sweattebc01952016-02-19 11:38:30 -0800347 {128 , 128 , "tests/testdata/foo/fake.txt", "/NTORRENT/foo/", false, true },
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700348 // // prefix mismatch
Mickey Sweattebc01952016-02-19 11:38:30 -0800349 {128 , 128 , "tests/testdata/foo/bar.txt", "/NTORRENT/bar/", false, true },
350 // scaling test
351 // {10240 , 5120 , "tests/testdata/foo/huge_file", "/NTORRENT/foo/", false, false },
352 // assertion failures (tests not supported on platforms)
353 // {0 , 128 , "tests/testdata/foo/bar.txt", "/NTORRENT/bar/", true },
354 // {128 , 0 , "tests/testdata/foo/bar.txt", "/NTORRENT/bar/", true },
355 };
356 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
357 for (int i = 0; i < NUM_DATA; ++i) {
358 auto dataPacketSize = DATA[i].d_dataPacketSize;
359 auto subManifestSize = DATA[i].d_subManifestSize;
360 auto filePath = DATA[i].d_filePath;
361 auto catalogPrefix = DATA[i].d_catalogPrefix;
362 auto getData = DATA[i].d_getData;
363 auto shouldThrow = DATA[i].d_shouldThrow;
364
365 std::pair<std::vector<FileManifest>, std::vector<Data>> manifestsDataPair;
366 if (shouldThrow) {
367 BOOST_CHECK_THROW(FileManifest::generate(filePath,
368 catalogPrefix,
369 subManifestSize,
370 dataPacketSize,
371 getData),
372 FileManifest::Error);
373 }
374 else {
375 manifestsDataPair = FileManifest::generate(filePath,
376 catalogPrefix,
377 subManifestSize,
378 dataPacketSize,
379 getData);
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700380 auto fileSize = fs::file_size(filePath);
381 auto EXP_NUM_DATA_PACKETS = fileSize / dataPacketSize + !!(fileSize % dataPacketSize);
382 auto EXP_NUM_FILE_MANIFESTS = EXP_NUM_DATA_PACKETS / subManifestSize +
383 !!(EXP_NUM_DATA_PACKETS % subManifestSize);
Mickey Sweattebc01952016-02-19 11:38:30 -0800384 auto manifests = manifestsDataPair.first;
385 auto data = manifestsDataPair.second;
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700386
Mickey Sweattebc01952016-02-19 11:38:30 -0800387 // Verify the basic attributes of the manifest
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700388 BOOST_CHECK_EQUAL(manifests.size(), EXP_NUM_FILE_MANIFESTS);
Mickey Sweattebc01952016-02-19 11:38:30 -0800389 for (auto it = manifests.begin(); it != manifests.end(); ++it) {
390 // Verify that each file manifest is signed.
391 BOOST_CHECK_NO_THROW(it->getFullName());
392 BOOST_CHECK_EQUAL(it->data_packet_size(), dataPacketSize);
393 BOOST_CHECK_EQUAL(it->catalog_prefix(), catalogPrefix);
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700394 auto block = it->wireEncode();
395 BOOST_CHECK_EQUAL(*it, FileManifest(block));
Mickey Sweattebc01952016-02-19 11:38:30 -0800396 if (it != manifests.end() -1) {
397 BOOST_CHECK_EQUAL(it->catalog().size(), subManifestSize);
398 BOOST_CHECK_EQUAL(*(it->submanifest_ptr()), (it+1)->getFullName());
399 }
400 else {
401 BOOST_CHECK_LE(it->catalog().size(), subManifestSize);
402 BOOST_CHECK_EQUAL(it->submanifest_ptr(), nullptr);
Mickey Sweattebc01952016-02-19 11:38:30 -0800403 }
404 }
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700405 // test that we can write the manifest to the disk and read it out again
406 {
407 std::string dirPath = "tests/testdata/temp/";
408 boost::filesystem::create_directory(dirPath);
409 auto fileNum = 0;
410 for (auto &m : manifests) {
411 fileNum++;
412 auto filename = dirPath + to_string(fileNum);
413 io::save(m, filename);
414 }
415 // read them back out
416 fileNum = 0;
417 for (auto &m : manifests) {
418 fileNum++;
419 auto filename = dirPath + to_string(fileNum);
420 auto manifest_ptr = io::load<FileManifest>(filename);
421 BOOST_CHECK_NE(manifest_ptr, nullptr);
422 BOOST_CHECK_EQUAL(m, *manifest_ptr);
423 }
424 fs::remove_all(dirPath);
425 }
Mickey Sweattebc01952016-02-19 11:38:30 -0800426 // confirm the manifests catalogs includes exactly the data packets
427 if (getData) {
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700428 BOOST_CHECK_EQUAL(EXP_NUM_DATA_PACKETS, data.size());
Mickey Sweattebc01952016-02-19 11:38:30 -0800429 auto data_it = data.begin();
430 size_t total_manifest_length = 0;
431 for (auto& m : manifests) {
432 total_manifest_length += m.wireEncode().value_size();
433 for (auto& data_name : m.catalog()) {
434 BOOST_CHECK_EQUAL(data_name, data_it->getFullName());
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700435 ++data_it;
Mickey Sweattebc01952016-02-19 11:38:30 -0800436 }
437 }
438 BOOST_CHECK_EQUAL(data_it, data.end());
439 std::vector<uint8_t> data_bytes;
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700440 data_bytes.reserve(fileSize);
Mickey Sweattebc01952016-02-19 11:38:30 -0800441 for (const auto& d : data) {
442 auto content = d.getContent();
443 data_bytes.insert(data_bytes.end(), content.value_begin(), content.value_end());
444 }
445 data_bytes.shrink_to_fit();
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700446 // load the contents of the file from disk
Mickey Sweattebc01952016-02-19 11:38:30 -0800447 fs::ifstream is(filePath, fs::ifstream::binary | fs::ifstream::in);
448 is >> std::noskipws;
449 std::istream_iterator<uint8_t> start(is), end;
450 std::vector<uint8_t> file_bytes;
Mickey Sweatt6de5dde2016-03-15 16:44:56 -0700451 file_bytes.reserve(fileSize);
Mickey Sweattebc01952016-02-19 11:38:30 -0800452 file_bytes.insert(file_bytes.begin(), start, end);
453 file_bytes.shrink_to_fit();
454 BOOST_CHECK_EQUAL(file_bytes, data_bytes);
455 }
456 else {
457 BOOST_CHECK(data.empty());
458 BOOST_CHECK(data.capacity() == 0);
459 }
460 }
461 }
462}
463
Mickey Sweatt3b0bea62016-01-25 22:12:27 -0800464BOOST_AUTO_TEST_SUITE_END()
465
466} // namespace tests
467} // namespace nTorrent
468} // namespace ndn