blob: bb1634477267d71f7441cb8e6b379189738f018f [file] [log] [blame]
Mickey Sweatt527b0492016-03-02 11:07:48 -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 "boost-test.hpp"
23
24#include "torrent-manager.hpp"
25#include "torrent-file.hpp"
spirosmastorakisa46eee42016-04-05 14:24:45 -070026#include "unit-test-time-fixture.hpp"
Mickey Sweatt527b0492016-03-02 11:07:48 -080027
Mickey Sweattafda1f12016-04-04 17:15:11 -070028#include <set>
29
Mickey Sweatt527b0492016-03-02 11:07:48 -080030#include <boost/filesystem.hpp>
31
spirosmastorakisa46eee42016-04-05 14:24:45 -070032#include <ndn-cxx/util/dummy-client-face.hpp>
Mickey Sweatt527b0492016-03-02 11:07:48 -080033#include <ndn-cxx/util/io.hpp>
34
35namespace ndn {
36namespace ntorrent {
37namespace tests {
38
39using std::vector;
40using ndn::Name;
spirosmastorakisa46eee42016-04-05 14:24:45 -070041using ndn::util::DummyClientFace;
Mickey Sweatt527b0492016-03-02 11:07:48 -080042
43namespace fs = boost::filesystem;
44
45class TestTorrentManager : public TorrentManager {
46 public:
47 TestTorrentManager(const ndn::Name& torrentFileName,
48 const std::string& filePath)
49 : TorrentManager(torrentFileName, filePath)
spirosmastorakisa46eee42016-04-05 14:24:45 -070050 {
51 }
52
53 TestTorrentManager(const ndn::Name& torrentFileName,
54 const std::string& filePath,
55 DummyClientFace& face)
56 : TorrentManager(torrentFileName, filePath, face)
57 {
58 }
Mickey Sweatt527b0492016-03-02 11:07:48 -080059
60 std::vector<TorrentFile> torrentSegments() const {
61 return m_torrentSegments;
62 }
63
64 std::vector<FileManifest> fileManifests() const {
65 return m_fileManifests;
66 }
67
68 std::vector<bool> fileState(const ndn::Name& manifestName) {
Mickey Sweattafda1f12016-04-04 17:15:11 -070069 auto fout = m_fileStates[manifestName].first;
70 if (nullptr != fout) {
71 fout->flush();
72 }
Mickey Sweatt527b0492016-03-02 11:07:48 -080073 return m_fileStates[manifestName].second;
74 }
Mickey Sweattafda1f12016-04-04 17:15:11 -070075
76 bool writeData(const Data& data) {
77 return TorrentManager::writeData(data);
78 }
Mickey Sweatt599bfef2016-04-05 19:11:20 -070079
80 bool writeTorrentSegment(const TorrentFile& segment, const std::string& path) {
81 return TorrentManager::writeTorrentSegment(segment, path);
82 }
83 bool writeFileManifest(const FileManifest& manifest, const std::string& path) {
84 return TorrentManager::writeFileManifest(manifest, path);
85 }
Mickey Sweatt527b0492016-03-02 11:07:48 -080086};
87
spirosmastorakisa46eee42016-04-05 14:24:45 -070088class FaceFixture : public UnitTestTimeFixture
89{
90public:
91 explicit
92 FaceFixture(bool enableRegistrationReply = true)
93 : face(io, { true, enableRegistrationReply })
94 {
95 }
96
97public:
98 DummyClientFace face;
99};
100
101class FacesNoRegistrationReplyFixture : public FaceFixture
102{
103public:
104 FacesNoRegistrationReplyFixture()
105 : FaceFixture(false)
106 {
107 }
108};
109
Mickey Sweatt527b0492016-03-02 11:07:48 -0800110BOOST_AUTO_TEST_SUITE(TestTorrentManagerInitialize)
111
112BOOST_AUTO_TEST_CASE(CheckInitializeComplete)
113{
114 vector<FileManifest> manifests;
115 vector<TorrentFile> torrentSegments;
116 std::string filePath = "tests/testdata/";
117 // get torrent files and manifests
118 {
119 auto temp = TorrentFile::generate("tests/testdata/foo",
120 1024,
121 1024,
122 1024,
123 false);
124 torrentSegments = temp.first;
125 auto temp1 = temp.second;
126 for (const auto& ms : temp1) {
Mickey Sweattafda1f12016-04-04 17:15:11 -0700127 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
Mickey Sweatt527b0492016-03-02 11:07:48 -0800128 }
129 }
130 // write the torrent segments and manifests to disk
131 std::string dirPath = ".appdata/foo/";
132 boost::filesystem::create_directories(dirPath);
133 std::string torrentPath = dirPath + "torrent_files/";
134 boost::filesystem::create_directory(torrentPath);
135 auto fileNum = 0;
136 for (const auto& t : torrentSegments) {
137 fileNum++;
138 auto filename = torrentPath + to_string(fileNum);
139 io::save(t, filename);
140 }
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700141 //fileNum = 0;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800142 auto manifestPath = dirPath + "manifests/";
143 boost::filesystem::create_directory(manifestPath);
144 for (const auto& m : manifests) {
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700145 fs::path filename = manifestPath + m.file_name() + "/" + to_string(m.submanifest_number());
146 boost::filesystem::create_directories(filename.parent_path());
147 io::save(m, filename.string());
Mickey Sweatt527b0492016-03-02 11:07:48 -0800148 }
149 // Initialize and verify
150 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",
151 filePath);
152 manager.Initialize();
153
154 // Check that the torrent segments and file manifests match (content and order)
155 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
156 BOOST_CHECK(manager.fileManifests() == manifests);
157 // next check the data packet state vectors
158 for (auto m : manager.fileManifests()) {
159 auto fileState = manager.fileState(m.getFullName());
160 BOOST_CHECK(fileState.size() == m.catalog().size());
161 for (auto s : fileState) {
162 BOOST_CHECK(s);
163 }
164 }
165 fs::remove_all(dirPath);
166}
167
168BOOST_AUTO_TEST_CASE(CheckInitializeEmpty)
169{
170 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",
171 "tests/testdata/");
172 manager.Initialize();
173 BOOST_CHECK(manager.torrentSegments() == vector<TorrentFile>());
174 BOOST_CHECK(manager.fileManifests() == vector<FileManifest>());
175}
176
177BOOST_AUTO_TEST_CASE(CheckInitializeNoManifests)
178{
179 vector<TorrentFile> torrentSegments;
180 std::string filePath = "tests/testdata/";
181 // get torrent files and manifests
182 {
183 auto temp = TorrentFile::generate("tests/testdata/foo",
184 1024,
185 1024,
186 1024,
187 false);
188 torrentSegments = temp.first;
189 }
190 // write the torrent segments but no manifests to disk
191 std::string dirPath = ".appdata/foo/";
192 boost::filesystem::create_directories(dirPath);
193 std::string torrentPath = dirPath + "torrent_files/";
194 boost::filesystem::create_directory(torrentPath);
195 auto fileNum = 0;
196 for (const auto& t : torrentSegments) {
197 fileNum++;
198 auto filename = torrentPath + to_string(fileNum);
199 io::save(t, filename);
200 }
201 // Initialize and verify
202 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",
203 filePath);
204 manager.Initialize();
205
206 // Check that the torrent segments and file manifests match (content and order)
207 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
208 BOOST_CHECK(manager.fileManifests() == vector<FileManifest>());
209
210 fs::remove_all(dirPath);
211}
212
213BOOST_AUTO_TEST_CASE(CheckInitializeMissingManifests)
214{
215 vector<FileManifest> manifests;
216 vector<TorrentFile> torrentSegments;
217 std::string filePath = "tests/testdata/";
218 // get torrent files and manifests
219 {
220 auto temp = TorrentFile::generate("tests/testdata/foo",
221 1024,
222 1024,
223 1024,
224 false);
225 torrentSegments = temp.first;
226 auto temp1 = temp.second;
227 temp1.pop_back(); // remove the manifests for the last file
Mickey Sweattafda1f12016-04-04 17:15:11 -0700228 for (const auto& ms : temp1) {
229 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
Mickey Sweatt527b0492016-03-02 11:07:48 -0800230 }
231 }
232 // write the torrent segments and manifests to disk
233 std::string dirPath = ".appdata/foo/";
234 boost::filesystem::create_directories(dirPath);
235 std::string torrentPath = dirPath + "torrent_files/";
236 boost::filesystem::create_directories(torrentPath);
237 auto fileNum = 0;
238 for (const auto& t : torrentSegments) {
239 fileNum++;
240 auto filename = torrentPath + to_string(fileNum);
241 io::save(t, filename);
Mickey Sweatt527b0492016-03-02 11:07:48 -0800242 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800243 auto manifestPath = dirPath + "manifests/";
244 boost::filesystem::create_directory(manifestPath);
245 for (const auto& m : manifests) {
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700246 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
247 boost::filesystem::create_directory(filename.parent_path());
248 io::save(m, filename.string());
Mickey Sweatt527b0492016-03-02 11:07:48 -0800249 }
250 // Initialize and verify
251 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",
252 filePath);
253 manager.Initialize();
254
255 // Check that the torrent segments and file manifests match (content and order)
256 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
257 BOOST_CHECK(manager.fileManifests() == manifests);
258 // next check the data packet state vectors
259 for (auto m : manager.fileManifests()) {
260 auto fileState = manager.fileState(m.getFullName());
261 BOOST_CHECK(fileState.size() == m.catalog().size());
262 for (auto s : fileState) {
263 BOOST_CHECK(s);
264 }
265 }
266 fs::remove_all(dirPath);
267}
268
spirosmastorakisa46eee42016-04-05 14:24:45 -0700269BOOST_FIXTURE_TEST_SUITE(TestTorrentManagerNetworkingStuff, FaceFixture)
270
271BOOST_AUTO_TEST_CASE(TestDownloadingTorrentFile)
272{
273 vector<FileManifest> manifests;
274 vector<TorrentFile> torrentSegments;
275 std::string filePath = ".appdata/foo/";
276 // get torrent files and manifests
277 {
278 auto temp = TorrentFile::generate("tests/testdata/foo", 1, 10, 10, false);
279
280 torrentSegments = temp.first;
281 auto temp1 = temp.second;
282 temp1.pop_back(); // remove the manifests for the last file
283 for (const auto& ms : temp1) {
284 for (const auto& m : ms.first) {
285 manifests.push_back(m);
286 }
287 }
288 }
289
290 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
291 filePath, face);
292 manager.Initialize();
293
294 // Test download torrent file segments
295 uint32_t counter = 0;
296 manager.downloadTorrentFile(filePath + "torrent_files", [&counter, &torrentSegments] (const ndn::Name& name) {
297 BOOST_CHECK_EQUAL(torrentSegments[counter].getName(), name);
298 counter++;
299 },
300 bind([] {
301 BOOST_FAIL("Unexpected failure");
302 }));
303
304 for (auto i = torrentSegments.begin(); i != torrentSegments.end(); i++) {
305 advanceClocks(time::milliseconds(1), 40);
306 face.receive(dynamic_cast<Data&>(*i));
307 }
308
309 fs::remove_all(filePath);
310}
311
312BOOST_AUTO_TEST_CASE(TestDownloadingFileManifests)
313{
314 vector<FileManifest> manifests;
315 vector<TorrentFile> torrentSegments;
316 std::string filePath = ".appdata/foo/";
317 // get torrent files and manifests
318 {
319 auto temp = TorrentFile::generate("tests/testdata/foo", 1, 10, 10, false);
320
321 torrentSegments = temp.first;
322 auto temp1 = temp.second;
323 temp1.pop_back(); // remove the manifests for the last file
324 for (const auto& ms : temp1) {
325 for (const auto& m : ms.first) {
326 manifests.push_back(m);
327 }
328 }
329 }
330
331 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
332 filePath, face);
333 manager.Initialize();
334
335 // Test download manifest segments -- 2 files (the first one segment, the second multiple)
336 int counter = 0;
337 manager.download_file_manifest(manifests[0].getFullName(), filePath + "manifests",
338 [&counter, &manifests]
339 (const std::vector<ndn::Name>& vec) {
340 uint32_t packetIndex = 0;
341 for (auto j = vec.begin(); j != vec.end(); j++) {
342 BOOST_CHECK_EQUAL(manifests[counter].catalog()[packetIndex],
343 *j);
344 packetIndex++;
345 }
346 counter++;
347 },
348 [](const ndn::Name& name, const std::string& reason) {
349 BOOST_FAIL("Unexpected failure");
350 });
351
352 advanceClocks(time::milliseconds(1), 40);
353 face.receive(dynamic_cast<Data&>(manifests[0]));
354
355 manager.download_file_manifest(manifests[1].getFullName(), filePath + "manifests",
356 [&counter, &manifests]
357 (const std::vector<ndn::Name>& vec) {
358 uint32_t packetIndex = 0;
359 for (auto j = vec.begin(); j != vec.end(); j++) {
360 BOOST_CHECK_EQUAL(manifests[counter].catalog()[packetIndex],
361 *j);
362 // if we have read all the packet names from a
363 // segment, move to the next one
364 if (packetIndex == manifests[counter].catalog().size() - 1) {
365 packetIndex = 0;
366 counter++;
367 }
368 else {
369 packetIndex++;
370 }
371 }
372 },
373 [](const ndn::Name& name, const std::string& reason) {
374 BOOST_FAIL("Unexpected failure");
375 });
376
377 for (auto i = manifests.begin() + 1; i != manifests.end(); i++) {
378 advanceClocks(time::milliseconds(1), 40);
379 face.receive(dynamic_cast<Data&>(*i));
380 }
381
382 fs::remove_all(filePath);
383}
384
385BOOST_AUTO_TEST_CASE(TestDownloadingDataPackets)
386{
387 std::string filePath = ".appdata/foo/";
388 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
389 filePath, face);
390 manager.Initialize();
391
392 Name dataName("/test/ucla");
393
394 // Download data successfully
395 manager.download_data_packet(dataName,
396 [&dataName] (const ndn::Name& name) {
397 BOOST_CHECK_EQUAL(name, dataName);
398 },
399 [](const ndn::Name& name, const std::string& reason) {
400 BOOST_FAIL("Unexpected failure");
401 });
402
403 auto data = make_shared<Data>(dataName);
404 SignatureSha256WithRsa fakeSignature;
405 fakeSignature.setValue(encoding::makeEmptyBlock(tlv::SignatureValue));
406 data->setSignature(fakeSignature);
407 data->wireEncode();
408
409 advanceClocks(time::milliseconds(1), 40);
410 face.receive(*data);
411
412 // Fail to download data
413 manager.download_data_packet(dataName,
414 [] (const ndn::Name& name) {
415 BOOST_FAIL("Unexpected failure");
416 },
417 [&dataName](const ndn::Name& name, const std::string& reason) {
418 BOOST_CHECK_EQUAL(name, dataName);
419 });
420
421 advanceClocks(time::milliseconds(1), 2100);
422
423 fs::remove_all(filePath);
424}
425
Mickey Sweatt527b0492016-03-02 11:07:48 -0800426BOOST_AUTO_TEST_SUITE_END()
427
Mickey Sweattafda1f12016-04-04 17:15:11 -0700428BOOST_AUTO_TEST_SUITE(CheckTorrentManagerUtilities)
429
430BOOST_AUTO_TEST_CASE(CheckWriteDataComplete)
431{
432 vector<FileManifest> manifests;
433 vector<TorrentFile> torrentSegments;
434 // for each file, the data packets
435 std::vector<vector<Data>> fileData;
436 std::string filePath = "tests/testdata/temp";
437 // get torrent files and manifests
438 {
439 auto temp = TorrentFile::generate("tests/testdata/foo",
440 1024,
441 1024,
442 1024,
443 true);
444 torrentSegments = temp.first;
445 auto temp1 = temp.second;
446 for (const auto& ms : temp1) {
447 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
448 fileData.push_back(ms.second);
449 }
450 }
451 // write the torrent segments and manifests to disk
452 std::string dirPath = ".appdata/foo/";
453 boost::filesystem::create_directories(dirPath);
454 std::string torrentPath = dirPath + "torrent_files/";
455 boost::filesystem::create_directories(torrentPath);
456 auto fileNum = 0;
457 for (const auto& t : torrentSegments) {
458 fileNum++;
459 auto filename = torrentPath + to_string(fileNum);
460 io::save(t, filename);
461 }
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700462 //fileNum = 0;
Mickey Sweattafda1f12016-04-04 17:15:11 -0700463 auto manifestPath = dirPath + "manifests/";
464 boost::filesystem::create_directory(manifestPath);
465 for (const auto& m : manifests) {
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700466 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
467 boost::filesystem::create_directory(filename.parent_path());
468 io::save(m, filename.string());
Mickey Sweattafda1f12016-04-04 17:15:11 -0700469 }
470 // Initialize manager
471 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",
472 filePath);
473 manager.Initialize();
474 // check that initially there is no data on disk
475 for (auto m : manager.fileManifests()) {
476 auto fileState = manager.fileState(m.getFullName());
477 BOOST_CHECK(fileState.empty());
478 }
479 // write all data to disk (for each file manifest)
480 auto manifest_it = manifests.begin();
481 for (auto& data : fileData) {
482 for (auto& d : data) {
483 BOOST_CHECK(manager.writeData(d));
484 }
485 // check that the state is updated appropriately
486 auto fileState = manager.fileState(manifest_it->getFullName());
487 for (auto s : fileState) {
488 BOOST_CHECK(s);
489 }
490 ++manifest_it;
491 }
492 // get the file names (ascending)
493 std::set<std::string> fileNames;
494 for (auto i = fs::recursive_directory_iterator(filePath + "/foo");
495 i != fs::recursive_directory_iterator();
496 ++i) {
497 fileNames.insert(i->path().string());
498 }
499 // verify file by file that the data packets are written correctly
500 auto f_it = fileData.begin();
501 for (auto f : fileNames) {
502 // read file from disk
503 std::vector<uint8_t> file_bytes;
504 fs::ifstream is(f, fs::ifstream::binary | fs::ifstream::in);
505 is >> std::noskipws;
506 std::istream_iterator<uint8_t> start(is), end;
507 file_bytes.insert(file_bytes.end(), start, end);
508 std::vector<uint8_t> data_bytes;
509 // get content from data packets
510 for (const auto& d : *f_it) {
511 auto content = d.getContent();
512 data_bytes.insert(data_bytes.end(), content.value_begin(), content.value_end());
513 }
514 BOOST_CHECK(data_bytes == file_bytes);
515 ++f_it;
516 }
517 fs::remove_all(filePath);
518 fs::remove_all(".appdata");
519}
520
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700521BOOST_AUTO_TEST_CASE(CheckWriteTorrentComplete)
522{
523 const struct {
524 const char *d_directoryPath;
525 const char *d_initialSegmentName;
526 size_t d_namesPerSegment;
527 size_t d_subManifestSize;
528 size_t d_dataPacketSize;
529 } DATA [] = {
530 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
531 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=96d900d6788465f9a7b00191581b004c910d74b3762d141ec0e82173731bc9f4", 1, 1, 1024},
532 };
533 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
534 for (int i = 0; i < NUM_DATA; ++i) {
535 auto directoryPath = DATA[i].d_directoryPath;
536 Name initialSegmentName = DATA[i].d_initialSegmentName;
537 auto namesPerSegment = DATA[i].d_namesPerSegment;
538 auto dataPacketSize = DATA[i].d_dataPacketSize;
539 auto subManifestSize = DATA[i].d_subManifestSize;
540
541 vector<TorrentFile> torrentSegments;
542 std::string filePath = "tests/testdata/temp";
543 // get torrent files
544 {
545 auto temp = TorrentFile::generate(directoryPath,
546 namesPerSegment,
547 subManifestSize,
548 dataPacketSize,
549 false);
550 torrentSegments = temp.first;
551 }
552 // Initialize manager
553 TestTorrentManager manager(initialSegmentName,
554 filePath);
555 manager.Initialize();
556 std::string dirPath = ".appdata/foo/";
557 std::string torrentPath = dirPath + "torrent_files/";
558 BOOST_CHECK(manager.torrentSegments().empty());
559 for (const auto& t : torrentSegments) {
560 BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
561 }
562 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
563 // check that initializing a new manager also gets all the torrent torrentSegments
564 TestTorrentManager manager2(initialSegmentName,
565 filePath);
566 manager2.Initialize();
567 BOOST_CHECK(manager2.torrentSegments() == torrentSegments);
568
569 // start anew
570 fs::remove_all(torrentPath);
571 fs::create_directories(torrentPath);
572 manager.Initialize();
573 BOOST_CHECK(manager.torrentSegments().empty());
574
575 // check that there is no dependence on the order of torrent segments
576 // randomize the order of the torrent segments
577 auto torrentSegmentsRandom = torrentSegments;
578 std::random_shuffle(torrentSegmentsRandom.begin(), torrentSegmentsRandom.end());
579 for (const auto& t : torrentSegmentsRandom) {
580 BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
581 }
582 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
583 fs::remove_all(".appdata");
584 }
585}
586
587BOOST_AUTO_TEST_CASE(CheckWriteManifestComplete)
588{
589 std::string dirPath = ".appdata/foo/";
590 std::string torrentPath = dirPath + "torrent_files/";
591 std::string manifestPath = dirPath + "manifests/";
592
593 const struct {
594 const char *d_directoryPath;
595 const char *d_initialSegmentName;
596 size_t d_namesPerSegment;
597 size_t d_subManifestSize;
598 size_t d_dataPacketSize;
599 } DATA [] = {
600 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
601 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 128, 128, 1024},
602 };
603 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
604 for (int i = 0; i < NUM_DATA; ++i) {
605 auto directoryPath = DATA[i].d_directoryPath;
606 Name initialSegmentName = DATA[i].d_initialSegmentName;
607 auto namesPerSegment = DATA[i].d_namesPerSegment;
608 auto dataPacketSize = DATA[i].d_dataPacketSize;
609 auto subManifestSize = DATA[i].d_subManifestSize;
610
611 vector<FileManifest> manifests;
612 vector<TorrentFile> torrentSegments;
613
614 std::string filePath = "tests/testdata/temp";
615 // get torrent files and manifests
616 {
617 auto temp = TorrentFile::generate(directoryPath,
618 namesPerSegment,
619 subManifestSize,
620 dataPacketSize,
621 false);
622 torrentSegments = temp.first;
623 auto temp1 = temp.second;
624 for (const auto& ms : temp1) {
625 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
626 }
627 }
628 TestTorrentManager manager(initialSegmentName,
629 filePath);
630 manager.Initialize();
631 for (const auto& t : torrentSegments) {
632 manager.writeTorrentSegment(t, torrentPath);
633 }
634
635 BOOST_CHECK(manager.fileManifests().empty());
636 for (const auto& m : manifests) {
637 BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
638 }
639 BOOST_CHECK(manager.fileManifests() == manifests);
640
641 TestTorrentManager manager2(initialSegmentName,
642 filePath);
643
644 manager2.Initialize();
645 BOOST_CHECK(manager2.fileManifests() == manifests);
646
647 // start anew
648 fs::remove_all(manifestPath);
649 fs::create_directories(manifestPath);
650 manager.Initialize();
651 BOOST_CHECK(manager.fileManifests().empty());
652
653 // check that there is no dependence on the order of torrent segments
654 // randomize the order of the torrent segments
655 auto fileManifestsRandom = manifests;
656 std::random_shuffle(fileManifestsRandom.begin(), fileManifestsRandom.end());
657 for (const auto& m : fileManifestsRandom) {
658 BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
659 }
660 BOOST_CHECK(manager2.fileManifests() == manifests);
661 fs::remove_all(".appdata");
662 }
663}
664
spirosmastorakisa46eee42016-04-05 14:24:45 -0700665BOOST_AUTO_TEST_SUITE_END()
Mickey Sweattafda1f12016-04-04 17:15:11 -0700666
667BOOST_AUTO_TEST_SUITE_END()
668
Mickey Sweatt527b0492016-03-02 11:07:48 -0800669} // namespace tests
670} // namespace nTorrent
spirosmastorakisa46eee42016-04-05 14:24:45 -0700671} // namespace ndn