blob: d0f5110d739d671671440179cd6342d064cc2f36 [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
Mickey Sweattb7ee19c2016-04-21 12:18:15 -070016* General Public License along with nTorrent, e.g., in COPYING.md file. SoIf not, see
Mickey Sweatt527b0492016-03-02 11:07:48 -080017* <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
spirosmastorakis4ff8c872016-04-14 09:51:38 -070024#include "dummy-parser-fixture.hpp"
Mickey Sweatt527b0492016-03-02 11:07:48 -080025#include "torrent-manager.hpp"
26#include "torrent-file.hpp"
spirosmastorakisa46eee42016-04-05 14:24:45 -070027#include "unit-test-time-fixture.hpp"
Mickey Sweatt527b0492016-03-02 11:07:48 -080028
Mickey Sweattafda1f12016-04-04 17:15:11 -070029#include <set>
30
Mickey Sweatt527b0492016-03-02 11:07:48 -080031#include <boost/filesystem.hpp>
32
spirosmastorakisa46eee42016-04-05 14:24:45 -070033#include <ndn-cxx/util/dummy-client-face.hpp>
Mickey Sweatt527b0492016-03-02 11:07:48 -080034#include <ndn-cxx/util/io.hpp>
35
36namespace ndn {
37namespace ntorrent {
38namespace tests {
39
40using std::vector;
41using ndn::Name;
spirosmastorakisa46eee42016-04-05 14:24:45 -070042using ndn::util::DummyClientFace;
Mickey Sweatt527b0492016-03-02 11:07:48 -080043
44namespace fs = boost::filesystem;
45
46class TestTorrentManager : public TorrentManager {
spirosmastorakis4ff8c872016-04-14 09:51:38 -070047public:
Mickey Sweatte908a5c2016-04-08 14:10:45 -070048 TestTorrentManager(const ndn::Name& torrentFileName,
49 const std::string& filePath,
50 std::shared_ptr<DummyClientFace> face)
spirosmastorakisa46eee42016-04-05 14:24:45 -070051 : TorrentManager(torrentFileName, filePath, face)
spirosmastorakis4ff8c872016-04-14 09:51:38 -070052 , m_face(face)
spirosmastorakisa46eee42016-04-05 14:24:45 -070053 {
spirosmastorakis4ff8c872016-04-14 09:51:38 -070054 m_keyChain = make_shared<KeyChain>();
spirosmastorakisa46eee42016-04-05 14:24:45 -070055 }
Mickey Sweatt527b0492016-03-02 11:07:48 -080056
57 std::vector<TorrentFile> torrentSegments() const {
58 return m_torrentSegments;
59 }
60
61 std::vector<FileManifest> fileManifests() const {
62 return m_fileManifests;
63 }
64
spirosmastorakis50642f82016-04-08 12:11:18 -070065 void pushTorrentSegment(const TorrentFile& t) {
66 m_torrentSegments.push_back(t);
67 }
68
69 void pushFileManifestSegment(const FileManifest& m) {
70 m_fileManifests.push_back(m);
71 }
72
73 shared_ptr<Name> findTorrentFileSegmentToDownload() {
74 return TorrentManager::findTorrentFileSegmentToDownload();
75 }
76
77 shared_ptr<Name> findManifestSegmentToDownload(const Name& manifestName) {
78 return TorrentManager::findManifestSegmentToDownload(manifestName);
79 }
80
81 bool dataAlreadyDownloaded(const Name& name) {
82 return TorrentManager::dataAlreadyDownloaded(name);
83 }
84
Mickey Sweatt527b0492016-03-02 11:07:48 -080085 std::vector<bool> fileState(const ndn::Name& manifestName) {
Mickey Sweattafda1f12016-04-04 17:15:11 -070086 auto fout = m_fileStates[manifestName].first;
87 if (nullptr != fout) {
88 fout->flush();
89 }
Mickey Sweatt527b0492016-03-02 11:07:48 -080090 return m_fileStates[manifestName].second;
91 }
Mickey Sweattafda1f12016-04-04 17:15:11 -070092
spirosmastorakis50642f82016-04-08 12:11:18 -070093 void setFileState(const ndn::Name manifestName,
94 std::shared_ptr<fs::fstream> f,
95 const std::vector<bool>& stateVec) {
96
97 m_fileStates.insert({ manifestName, std::make_pair(f, stateVec) });
98 }
99
Mickey Sweattafda1f12016-04-04 17:15:11 -0700100 bool writeData(const Data& data) {
101 return TorrentManager::writeData(data);
102 }
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700103
104 bool writeTorrentSegment(const TorrentFile& segment, const std::string& path) {
105 return TorrentManager::writeTorrentSegment(segment, path);
106 }
spirosmastorakis50642f82016-04-08 12:11:18 -0700107
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700108 bool writeFileManifest(const FileManifest& manifest, const std::string& path) {
109 return TorrentManager::writeFileManifest(manifest, path);
110 }
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700111
112 void sendRoutablePrefixResponse() {
113 // Create a data packet containing one name as content
114 shared_ptr<Data> d = DummyParser::createDataPacket(Name("/localhop/nfd/rib/routable-prefixes"),
115 { Name("ucla") });
116 m_keyChain->sign(*d);
117 m_face->receive(*d);
118 }
119
120private:
121 shared_ptr<KeyChain> m_keyChain;
122 shared_ptr<DummyClientFace> m_face;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800123};
124
spirosmastorakisa46eee42016-04-05 14:24:45 -0700125class FaceFixture : public UnitTestTimeFixture
126{
127public:
128 explicit
129 FaceFixture(bool enableRegistrationReply = true)
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700130 : face(new DummyClientFace(io, { true, enableRegistrationReply }))
spirosmastorakisa46eee42016-04-05 14:24:45 -0700131 {
132 }
133
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700134 ~FaceFixture()
135 {
136 fs::remove_all(".appdata");
137 }
138
spirosmastorakisa46eee42016-04-05 14:24:45 -0700139public:
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700140 std::shared_ptr<DummyClientFace> face;
spirosmastorakisa46eee42016-04-05 14:24:45 -0700141};
142
143class FacesNoRegistrationReplyFixture : public FaceFixture
144{
145public:
146 FacesNoRegistrationReplyFixture()
147 : FaceFixture(false)
148 {
149 }
150};
151
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700152BOOST_FIXTURE_TEST_SUITE(TestTorrentManagerInitialize, FaceFixture)
Mickey Sweatt527b0492016-03-02 11:07:48 -0800153
154BOOST_AUTO_TEST_CASE(CheckInitializeComplete)
155{
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700156 const struct {
157 const char *d_directoryPath;
158 const char *d_initialSegmentName;
159 size_t d_namesPerSegment;
160 size_t d_subManifestSize;
161 size_t d_dataPacketSize;
162 } DATA [] = {
163 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
164 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128, 128, 128},
165 // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851", 1, 1, 128},
166 };
167 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
168 for (int i = 0; i < NUM_DATA; ++i) {
169 auto directoryPath = DATA[i].d_directoryPath;
170 Name initialSegmentName = DATA[i].d_initialSegmentName;
171 auto namesPerSegment = DATA[i].d_namesPerSegment;
172 auto dataPacketSize = DATA[i].d_dataPacketSize;
173 auto subManifestSize = DATA[i].d_subManifestSize;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800174
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700175 vector<FileManifest> manifests;
176 vector<TorrentFile> torrentSegments;
177 std::string filePath = "tests/testdata/";
178 // get torrent files and manifests
179 {
180 auto temp = TorrentFile::generate(directoryPath,
181 namesPerSegment,
182 subManifestSize,
183 dataPacketSize,
184 false);
185 torrentSegments = temp.first;
186 auto temp1 = temp.second;
187 for (const auto& ms : temp1) {
188 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
189 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800190 }
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700191 // write the torrent segments and manifests to disk
192 std::string dirPath = ".appdata/foo/";
193 boost::filesystem::create_directories(dirPath);
194 std::string torrentPath = dirPath + "torrent_files/";
195 boost::filesystem::create_directory(torrentPath);
196 auto fileNum = 0;
197 for (const auto& t : torrentSegments) {
198 fileNum++;
199 auto filename = torrentPath + to_string(fileNum);
200 io::save(t, filename);
201 }
202 auto manifestPath = dirPath + "manifests/";
203 boost::filesystem::create_directory(manifestPath);
204 for (const auto& m : manifests) {
205 fs::path filename = manifestPath + m.file_name() + "/" + to_string(m.submanifest_number());
206 boost::filesystem::create_directories(filename.parent_path());
207 io::save(m, filename.string());
208 }
209 // Initialize and verify
210 TestTorrentManager manager(initialSegmentName,
211 filePath,
212 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700213
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700214 manager.Initialize();
215
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700216 advanceClocks(time::milliseconds(1), 10);
217 manager.sendRoutablePrefixResponse();
218
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700219 // Check that the torrent segments and file manifests match (content and order)
220 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
221 BOOST_CHECK(manager.fileManifests() == manifests);
222 // next check the data packet state vectors
223 for (auto m : manager.fileManifests()) {
224 auto fileState = manager.fileState(m.getFullName());
225 BOOST_CHECK(fileState.size() == m.catalog().size());
226 for (auto s : fileState) {
227 BOOST_CHECK(s);
228 }
229 }
230 fs::remove_all(dirPath);
Mickey Sweatt527b0492016-03-02 11:07:48 -0800231 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800232}
233
234BOOST_AUTO_TEST_CASE(CheckInitializeEmpty)
235{
236 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253",
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700237 "tests/testdata/", face);
238
Mickey Sweatt527b0492016-03-02 11:07:48 -0800239 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700240
241 advanceClocks(time::milliseconds(1), 10);
242 manager.sendRoutablePrefixResponse();
243
Mickey Sweatt527b0492016-03-02 11:07:48 -0800244 BOOST_CHECK(manager.torrentSegments() == vector<TorrentFile>());
245 BOOST_CHECK(manager.fileManifests() == vector<FileManifest>());
246}
247
248BOOST_AUTO_TEST_CASE(CheckInitializeNoManifests)
249{
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700250 const struct {
251 const char *d_directoryPath;
252 const char *d_initialSegmentName;
253 size_t d_namesPerSegment;
254 size_t d_subManifestSize;
255 size_t d_dataPacketSize;
256 } DATA [] = {
257 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
258 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128, 128, 128},
259 // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851", 1, 1, 128},
260 };
261 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
262 for (int i = 0; i < NUM_DATA; ++i) {
263 auto directoryPath = DATA[i].d_directoryPath;
264 Name initialSegmentName = DATA[i].d_initialSegmentName;
265 auto namesPerSegment = DATA[i].d_namesPerSegment;
266 auto dataPacketSize = DATA[i].d_dataPacketSize;
267 auto subManifestSize = DATA[i].d_subManifestSize;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800268
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700269 vector<FileManifest> manifests;
270 vector<TorrentFile> torrentSegments;
271 std::string filePath = "tests/testdata/";
272 // get torrent files and manifests
273 {
274 auto temp = TorrentFile::generate(directoryPath,
275 namesPerSegment,
276 subManifestSize,
277 dataPacketSize,
278 false);
279 torrentSegments = temp.first;
280 }
281 // write the torrent segments and manifests to disk
282 std::string dirPath = ".appdata/foo/";
283 boost::filesystem::create_directories(dirPath);
284 std::string torrentPath = dirPath + "torrent_files/";
285 boost::filesystem::create_directory(torrentPath);
286 auto fileNum = 0;
287 for (const auto& t : torrentSegments) {
288 fileNum++;
289 auto filename = torrentPath + to_string(fileNum);
290 io::save(t, filename);
291 }
292 // Initialize and verify
293 TestTorrentManager manager(initialSegmentName,
294 filePath,
295 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700296
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700297 manager.Initialize();
Mickey Sweatt527b0492016-03-02 11:07:48 -0800298
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700299 advanceClocks(time::milliseconds(1), 10);
300 manager.sendRoutablePrefixResponse();
301
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700302 // Check that the torrent segments and file manifests match (content and order)
303 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
304 BOOST_CHECK(manager.fileManifests() == vector<FileManifest>());
305
306 fs::remove_all(".appdata");
307 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800308}
309
310BOOST_AUTO_TEST_CASE(CheckInitializeMissingManifests)
311{
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700312 const struct {
313 const char *d_directoryPath;
314 const char *d_initialSegmentName;
315 size_t d_namesPerSegment;
316 size_t d_subManifestSize;
317 size_t d_dataPacketSize;
318 } DATA [] = {
319 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
320 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128, 128, 128},
321 // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851", 1, 1, 128},
322 };
323 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
324 for (int i = 0; i < NUM_DATA; ++i) {
325 auto directoryPath = DATA[i].d_directoryPath;
326 Name initialSegmentName = DATA[i].d_initialSegmentName;
327 auto namesPerSegment = DATA[i].d_namesPerSegment;
328 auto dataPacketSize = DATA[i].d_dataPacketSize;
329 auto subManifestSize = DATA[i].d_subManifestSize;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800330
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700331 vector<FileManifest> manifests;
332 vector<TorrentFile> torrentSegments;
333 std::string filePath = "tests/testdata/";
334 // get torrent files and manifests
335 {
336 auto temp = TorrentFile::generate(directoryPath,
337 namesPerSegment,
338 subManifestSize,
339 dataPacketSize,
340 false);
341 torrentSegments = temp.first;
342 auto temp1 = temp.second;
343 temp1.pop_back(); // remove the manifests for the last file
344 for (const auto& ms : temp1) {
345 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
346 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800347 }
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700348 // write the torrent segments and manifests to disk
349 std::string dirPath = ".appdata/foo/";
350 boost::filesystem::create_directories(dirPath);
351 std::string torrentPath = dirPath + "torrent_files/";
352 boost::filesystem::create_directories(torrentPath);
353 auto fileNum = 0;
354 for (const auto& t : torrentSegments) {
355 fileNum++;
356 auto filename = torrentPath + to_string(fileNum);
357 io::save(t, filename);
358 }
359 auto manifestPath = dirPath + "manifests/";
360 boost::filesystem::create_directory(manifestPath);
361 for (const auto& m : manifests) {
362 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
363 boost::filesystem::create_directory(filename.parent_path());
364 io::save(m, filename.string());
365 }
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700366
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700367 // Initialize and verify
368 TestTorrentManager manager(initialSegmentName,
369 filePath,
370 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700371
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700372 manager.Initialize();
373
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700374 advanceClocks(time::milliseconds(1), 10);
375 manager.sendRoutablePrefixResponse();
376
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700377 // Check that the torrent segments and file manifests match (content and order)
378 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
379 BOOST_CHECK(manager.fileManifests() == manifests);
380 // next check the data packet state vectors
381 for (auto m : manager.fileManifests()) {
382 auto fileState = manager.fileState(m.getFullName());
383 BOOST_CHECK(fileState.size() == m.catalog().size());
384 for (auto s : fileState) {
385 BOOST_CHECK(s);
386 }
387 }
388 fs::remove_all(".appdata");
Mickey Sweatt527b0492016-03-02 11:07:48 -0800389 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800390}
391
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700392BOOST_AUTO_TEST_SUITE_END()
393
spirosmastorakisa46eee42016-04-05 14:24:45 -0700394BOOST_FIXTURE_TEST_SUITE(TestTorrentManagerNetworkingStuff, FaceFixture)
395
396BOOST_AUTO_TEST_CASE(TestDownloadingTorrentFile)
397{
398 vector<FileManifest> manifests;
399 vector<TorrentFile> torrentSegments;
400 std::string filePath = ".appdata/foo/";
401 // get torrent files and manifests
402 {
403 auto temp = TorrentFile::generate("tests/testdata/foo", 1, 10, 10, false);
404
405 torrentSegments = temp.first;
406 auto temp1 = temp.second;
407 temp1.pop_back(); // remove the manifests for the last file
408 for (const auto& ms : temp1) {
409 for (const auto& m : ms.first) {
410 manifests.push_back(m);
411 }
412 }
413 }
414
415 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
416 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700417
spirosmastorakisa46eee42016-04-05 14:24:45 -0700418 manager.Initialize();
419
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700420 advanceClocks(time::milliseconds(1), 10);
421 manager.sendRoutablePrefixResponse();
422
spirosmastorakisa46eee42016-04-05 14:24:45 -0700423 // Test download torrent file segments
424 uint32_t counter = 0;
spirosmastorakis50642f82016-04-08 12:11:18 -0700425 manager.downloadTorrentFile(filePath + "torrent_files", [&counter, &torrentSegments]
426 (const std::vector<ndn::Name>& vec) {
427 uint32_t manifestNum = 0;
428 for (auto i = vec.begin(); i != vec.end(); i++) {
429 Name n = torrentSegments[counter].getCatalog()[manifestNum];
430 BOOST_CHECK_EQUAL(n, *i);
431 manifestNum++;
432 }
433 counter++;
434 },
435 bind([] {
436 BOOST_FAIL("Unexpected failure");
437 }));
spirosmastorakisa46eee42016-04-05 14:24:45 -0700438
439 for (auto i = torrentSegments.begin(); i != torrentSegments.end(); i++) {
440 advanceClocks(time::milliseconds(1), 40);
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700441 face->receive(dynamic_cast<Data&>(*i));
spirosmastorakisa46eee42016-04-05 14:24:45 -0700442 }
443
444 fs::remove_all(filePath);
spirosmastorakis50642f82016-04-08 12:11:18 -0700445 fs::remove_all(".appdata");
spirosmastorakisa46eee42016-04-05 14:24:45 -0700446}
447
448BOOST_AUTO_TEST_CASE(TestDownloadingFileManifests)
449{
450 vector<FileManifest> manifests;
451 vector<TorrentFile> torrentSegments;
452 std::string filePath = ".appdata/foo/";
453 // get torrent files and manifests
454 {
455 auto temp = TorrentFile::generate("tests/testdata/foo", 1, 10, 10, false);
456
457 torrentSegments = temp.first;
458 auto temp1 = temp.second;
459 temp1.pop_back(); // remove the manifests for the last file
460 for (const auto& ms : temp1) {
461 for (const auto& m : ms.first) {
462 manifests.push_back(m);
463 }
464 }
465 }
466
467 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
468 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700469
spirosmastorakisa46eee42016-04-05 14:24:45 -0700470 manager.Initialize();
471
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700472 advanceClocks(time::milliseconds(1), 10);
473 manager.sendRoutablePrefixResponse();
474
spirosmastorakisa46eee42016-04-05 14:24:45 -0700475 // Test download manifest segments -- 2 files (the first one segment, the second multiple)
476 int counter = 0;
477 manager.download_file_manifest(manifests[0].getFullName(), filePath + "manifests",
478 [&counter, &manifests]
479 (const std::vector<ndn::Name>& vec) {
480 uint32_t packetIndex = 0;
481 for (auto j = vec.begin(); j != vec.end(); j++) {
482 BOOST_CHECK_EQUAL(manifests[counter].catalog()[packetIndex],
483 *j);
484 packetIndex++;
485 }
486 counter++;
487 },
488 [](const ndn::Name& name, const std::string& reason) {
489 BOOST_FAIL("Unexpected failure");
490 });
491
492 advanceClocks(time::milliseconds(1), 40);
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700493 face->receive(dynamic_cast<Data&>(manifests[0]));
spirosmastorakisa46eee42016-04-05 14:24:45 -0700494
495 manager.download_file_manifest(manifests[1].getFullName(), filePath + "manifests",
496 [&counter, &manifests]
497 (const std::vector<ndn::Name>& vec) {
498 uint32_t packetIndex = 0;
499 for (auto j = vec.begin(); j != vec.end(); j++) {
500 BOOST_CHECK_EQUAL(manifests[counter].catalog()[packetIndex],
501 *j);
502 // if we have read all the packet names from a
503 // segment, move to the next one
504 if (packetIndex == manifests[counter].catalog().size() - 1) {
505 packetIndex = 0;
506 counter++;
507 }
508 else {
509 packetIndex++;
510 }
511 }
512 },
513 [](const ndn::Name& name, const std::string& reason) {
514 BOOST_FAIL("Unexpected failure");
515 });
516
517 for (auto i = manifests.begin() + 1; i != manifests.end(); i++) {
518 advanceClocks(time::milliseconds(1), 40);
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700519 face->receive(dynamic_cast<Data&>(*i));
spirosmastorakisa46eee42016-04-05 14:24:45 -0700520 }
521
522 fs::remove_all(filePath);
spirosmastorakis50642f82016-04-08 12:11:18 -0700523 fs::remove_all(".appdata");
spirosmastorakisa46eee42016-04-05 14:24:45 -0700524}
525
526BOOST_AUTO_TEST_CASE(TestDownloadingDataPackets)
527{
528 std::string filePath = ".appdata/foo/";
529 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=946b92641d2b87bf4f5913930be20e3789ff5fb5d72739614f93f677d90fbd9d",
530 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700531
spirosmastorakisa46eee42016-04-05 14:24:45 -0700532 manager.Initialize();
533
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700534 advanceClocks(time::milliseconds(1), 10);
535 manager.sendRoutablePrefixResponse();
536
spirosmastorakisa46eee42016-04-05 14:24:45 -0700537 Name dataName("/test/ucla");
538
539 // Download data successfully
540 manager.download_data_packet(dataName,
541 [&dataName] (const ndn::Name& name) {
542 BOOST_CHECK_EQUAL(name, dataName);
543 },
544 [](const ndn::Name& name, const std::string& reason) {
545 BOOST_FAIL("Unexpected failure");
546 });
547
548 auto data = make_shared<Data>(dataName);
549 SignatureSha256WithRsa fakeSignature;
550 fakeSignature.setValue(encoding::makeEmptyBlock(tlv::SignatureValue));
551 data->setSignature(fakeSignature);
552 data->wireEncode();
553
554 advanceClocks(time::milliseconds(1), 40);
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700555 face->receive(*data);
spirosmastorakisa46eee42016-04-05 14:24:45 -0700556
557 // Fail to download data
558 manager.download_data_packet(dataName,
spirosmastorakis50642f82016-04-08 12:11:18 -0700559 [](const ndn::Name& name) {
spirosmastorakisa46eee42016-04-05 14:24:45 -0700560 BOOST_FAIL("Unexpected failure");
561 },
562 [&dataName](const ndn::Name& name, const std::string& reason) {
563 BOOST_CHECK_EQUAL(name, dataName);
564 });
565
566 advanceClocks(time::milliseconds(1), 2100);
567
568 fs::remove_all(filePath);
spirosmastorakis50642f82016-04-08 12:11:18 -0700569 fs::remove_all(".appdata");
570}
571
572// we already have downloaded the torrent file
573BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload1)
574{
575 std::string filePath = ".appdata/foo/";
576 TestTorrentManager manager("NTORRENT/test/torrent-file/sha256digest",
577 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700578
spirosmastorakis50642f82016-04-08 12:11:18 -0700579 manager.Initialize();
580
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700581 advanceClocks(time::milliseconds(1), 10);
582 manager.sendRoutablePrefixResponse();
583
spirosmastorakis50642f82016-04-08 12:11:18 -0700584 TorrentFile t1(Name("NTORRENT/test/torrent-file/sha256digest"),
585 Name("NTORRENT/test/torrent-file/1/sha256digest"), Name("/test"),
586 { Name("/manifest1") });
587 manager.pushTorrentSegment(t1);
588
589 TorrentFile t2(Name("NTORRENT/test/torrent-file/1/sha256digest"),
590 Name("NTORRENT/test/torrent-file/2/sha256digest"), Name("/test"),
591 { Name("/manifest2"), Name("/manifest3") });
592 manager.pushTorrentSegment(t2);
593
594 TorrentFile t3(Name("NTORRENT/test/torrent-file/3/sha256digest"),
595 Name("NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"),
596 { Name("/manifest4"), Name("/manifest5") });
597 manager.pushTorrentSegment(t3);
598
599 TorrentFile t4(Name("NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"), {});
600 manager.pushTorrentSegment(t4);
601
602 BOOST_CHECK(!(manager.findTorrentFileSegmentToDownload()));
603
604 std::vector<Name> manifests;
605 manifests = manager.downloadTorrentFile("/test");
606
607 BOOST_CHECK_EQUAL(manifests[0].toUri(), "/manifest1");
608 BOOST_CHECK_EQUAL(manifests[1].toUri(), "/manifest2");
609 BOOST_CHECK_EQUAL(manifests[2].toUri(), "/manifest3");
610 BOOST_CHECK_EQUAL(manifests[3].toUri(), "/manifest4");
611 BOOST_CHECK_EQUAL(manifests[4].toUri(), "/manifest5");
612
613 fs::remove_all(filePath);
614 fs::remove_all(".appdata");
615}
616
617// we do not have the torrent file
618BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload2)
619{
620 std::string filePath = ".appdata/foo/";
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700621 TestTorrentManager manager("NTORRENT/test/torrent-file/0/sha256digest",
spirosmastorakis50642f82016-04-08 12:11:18 -0700622 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700623
spirosmastorakis50642f82016-04-08 12:11:18 -0700624 manager.Initialize();
625
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700626 advanceClocks(time::milliseconds(1), 10);
627 manager.sendRoutablePrefixResponse();
628
629 BOOST_CHECK_EQUAL(manager.findTorrentFileSegmentToDownload()->toUri(),
630 "/NTORRENT/test/torrent-file/0/sha256digest");
spirosmastorakis50642f82016-04-08 12:11:18 -0700631
632 fs::remove_all(filePath);
633 fs::remove_all(".appdata");
634}
635
636// we have the torrent file and the manifests
637BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload3)
638{
639 vector<FileManifest> manifests;
640 vector<TorrentFile> torrentSegments;
641 // for each file, the data packets
642 std::vector<vector<Data>> fileData;
643 std::string filePath = "tests/testdata/temp";
644 // get torrent files and manifests
645 {
646 auto temp = TorrentFile::generate("tests/testdata/foo",
647 1024,
648 2048,
649 8192,
650 true);
651 torrentSegments = temp.first;
652 auto temp1 = temp.second;
653 for (const auto& ms : temp1) {
654 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
655 fileData.push_back(ms.second);
656 }
657 }
658 // write the torrent segments and manifests to disk
659 std::string dirPath = ".appdata/foo/";
660 boost::filesystem::create_directories(dirPath);
661 std::string torrentPath = dirPath + "torrent_files/";
662 boost::filesystem::create_directories(torrentPath);
663 auto fileNum = 0;
664 for (const auto& t : torrentSegments) {
665 fileNum++;
666 auto filename = torrentPath + to_string(fileNum);
667 io::save(t, filename);
668 }
669
670 auto manifestPath = dirPath + "manifests/";
671 boost::filesystem::create_directory(manifestPath);
672 for (const auto& m : manifests) {
673 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
674 boost::filesystem::create_directory(filename.parent_path());
675 io::save(m, filename.string());
676 }
677 // Initialize manager
678 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700679 filePath,
680 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700681
spirosmastorakis50642f82016-04-08 12:11:18 -0700682 manager.Initialize();
683
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700684 advanceClocks(time::milliseconds(1), 10);
685 manager.sendRoutablePrefixResponse();
686
spirosmastorakis50642f82016-04-08 12:11:18 -0700687 // Set the file state
688 std::vector<bool> v1 = {true};
689 manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
690
691 std::vector<bool> v2 = {false, true, true, false, false, false};
692 manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
693
694 std::vector<bool> v3 = {true, false, false, false, false, false};
695 manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
696
697 manager.downloadTorrentFile(filePath + "torrent_files/",
698 [&manifests](const std::vector<ndn::Name>& vec) {
699 BOOST_CHECK_EQUAL(vec[0].toUri(),
700 manifests[1].catalog()[0].toUri());
701 BOOST_CHECK_EQUAL(vec[1].toUri(),
702 manifests[1].catalog()[3].toUri());
703 BOOST_CHECK_EQUAL(vec[2].toUri(),
704 manifests[1].catalog()[4].toUri());
705 BOOST_CHECK_EQUAL(vec[3].toUri(),
706 manifests[1].catalog()[5].toUri());
707 BOOST_CHECK_EQUAL(vec[4].toUri(),
708 manifests[2].catalog()[1].toUri());
709 BOOST_CHECK_EQUAL(vec[5].toUri(),
710 manifests[2].catalog()[2].toUri());
711 BOOST_CHECK_EQUAL(vec[6].toUri(),
712 manifests[2].catalog()[3].toUri());
713 BOOST_CHECK_EQUAL(vec[7].toUri(),
714 manifests[2].catalog()[4].toUri());
715 BOOST_CHECK_EQUAL(vec[8].toUri(),
716 manifests[2].catalog()[5].toUri());
717 },
718 [](const ndn::Name& name, const std::string& reason) {
719 BOOST_FAIL("Unexpected failure");
720 });
721
722 fs::remove_all(filePath);
723 fs::remove_all(".appdata");
724}
725
spirosmastorakis50642f82016-04-08 12:11:18 -0700726BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload1)
727{
728 std::string filePath = ".appdata/foo/";
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700729 TestTorrentManager manager("NTORRENT/test/torrent-file/sha256digest",
spirosmastorakis50642f82016-04-08 12:11:18 -0700730 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700731
spirosmastorakis50642f82016-04-08 12:11:18 -0700732 manager.Initialize();
733
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700734 advanceClocks(time::milliseconds(1), 10);
735 manager.sendRoutablePrefixResponse();
736
spirosmastorakis50642f82016-04-08 12:11:18 -0700737 Name n1(Name("NTORRENT/test/file0"));
738 n1.appendSequenceNumber(0);
739
740 Name n2(Name("NTORRENT/test/file0"));
741 n2.appendSequenceNumber(1);
742
743 Name n3(Name("NTORRENT/test/file0"));
744 n3.appendSequenceNumber(2);
745
746 Name n4(Name("NTORRENT/test/file0"));
747 n4.appendSequenceNumber(3);
748
749 Name n5(Name("NTORRENT/test/file0"));
750 n5.appendSequenceNumber(4);
751
752 Name n6(Name("NTORRENT/test1/file0"));
753 n6.appendSequenceNumber(0);
754
755 Name n7(Name("NTORRENT/test1/file0"));
756 n7.appendSequenceNumber(1);
757
758 // In theory, this may not be correct, but here let's suck it up for the sake
759 // of testing the function correctness
760 Name n8(Name("NTORRENT/test1/file2"));
761 n8.appendSequenceNumber(0);
762
763 Name n9(Name("NTORRENT/test1/file2"));
764 n9.appendSequenceNumber(1);
765
766 FileManifest f1(n1, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n2));
767 manager.pushFileManifestSegment(f1);
768
769 FileManifest f2(n2, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n3));
770 manager.pushFileManifestSegment(f2);
771
772 FileManifest f3(n3, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n4));
773 manager.pushFileManifestSegment(f3);
774
775 FileManifest f4(n4, 50, Name("NTORRENT/test"), {}, make_shared<Name>(n5));
776 manager.pushFileManifestSegment(f4);
777
778 FileManifest f5(n6, 50, Name("NTORRENT/test2"), {}, make_shared<Name>(n7));
779 manager.pushFileManifestSegment(f5);
780
781 FileManifest f6(n7, 50, Name("NTORRENT/test2"), {}, {});
782 manager.pushFileManifestSegment(f6);
783
784 FileManifest f7(n8, 50, Name("NTORRENT/test3"), {}, make_shared<Name>(n9));
785 manager.pushFileManifestSegment(f7);
786
787 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n2.toUri() + "/sha256digest"))->toUri(), n5.toUri());
788 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n8.toUri() + "/sha256digest"))->toUri(), n9.toUri());
789 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n5.toUri() + "/sha256digest"))->toUri(),
790 Name(n5.toUri() + "/sha256digest").toUri());
791 BOOST_CHECK(!(manager.findManifestSegmentToDownload(Name(n7.toUri() + "/sha256digest"))));
792
793 Name n10(Name("NTORRENT/test1/file1"));
794 n10.appendSequenceNumber(1);
795 n10 = Name(n10.toUri() + "/sha256digest");
796
797 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(n10)->toUri(), n10.toUri());
spirosmastorakis50642f82016-04-08 12:11:18 -0700798}
799
800BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload2)
801{
802 vector<FileManifest> manifests;
803 vector<TorrentFile> torrentSegments;
804 // for each file, the data packets
805 std::vector<vector<Data>> fileData;
806 std::string filePath = "tests/testdata/temp";
807 // get torrent files and manifests
808 {
809 auto temp = TorrentFile::generate("tests/testdata/foo",
810 1024,
811 2048,
812 8192,
813 true);
814 torrentSegments = temp.first;
815 auto temp1 = temp.second;
816 for (const auto& ms : temp1) {
817 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
818 fileData.push_back(ms.second);
819 }
820 }
821 // write the torrent segments and manifests to disk
822 std::string dirPath = ".appdata/foo/";
823 boost::filesystem::create_directories(dirPath);
824 std::string torrentPath = dirPath + "torrent_files/";
825 boost::filesystem::create_directories(torrentPath);
826 auto fileNum = 0;
827 for (const auto& t : torrentSegments) {
828 fileNum++;
829 auto filename = torrentPath + to_string(fileNum);
830 io::save(t, filename);
831 }
832
833 auto manifestPath = dirPath + "manifests/";
834 boost::filesystem::create_directory(manifestPath);
835 for (const auto& m : manifests) {
836 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
837 boost::filesystem::create_directory(filename.parent_path());
838 io::save(m, filename.string());
839 }
840 // Initialize manager
841 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700842 filePath,
843 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700844
spirosmastorakis50642f82016-04-08 12:11:18 -0700845 manager.Initialize();
846
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700847 advanceClocks(time::milliseconds(1), 10);
848 manager.sendRoutablePrefixResponse();
849
spirosmastorakis50642f82016-04-08 12:11:18 -0700850 // Set the file state
851 std::vector<bool> v1 = {true};
852 manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
853
854 std::vector<bool> v2 = {false, true, true, false, false, false};
855 manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
856
857 std::vector<bool> v3 = {true, false, false, false, false, false};
858 manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
859
860 manager.download_file_manifest(manifests[0].getFullName(), filePath + "manifests",
861 [&manifests](const std::vector<ndn::Name>& vec) {
862 BOOST_CHECK_EQUAL(vec.size(), 0);
863 },
864 [](const ndn::Name& name, const std::string& reason) {
865 BOOST_FAIL("Unexpected failure");
866 });
867
868 manager.download_file_manifest(manifests[1].getFullName(), filePath + "manifests",
869 [&manifests](const std::vector<ndn::Name>& vec) {
870 BOOST_CHECK_EQUAL(vec[0].toUri(),
871 manifests[1].catalog()[0].toUri());
872 BOOST_CHECK_EQUAL(vec[1].toUri(),
873 manifests[1].catalog()[3].toUri());
874 BOOST_CHECK_EQUAL(vec[2].toUri(),
875 manifests[1].catalog()[4].toUri());
876 BOOST_CHECK_EQUAL(vec[3].toUri(),
877 manifests[1].catalog()[5].toUri());
878 },
879 [](const ndn::Name& name, const std::string& reason) {
880 BOOST_FAIL("Unexpected failure");
881 });
882
883 manager.download_file_manifest(manifests[2].getFullName(), filePath + "manifests",
884 [&manifests](const std::vector<ndn::Name>& vec) {
885 BOOST_CHECK_EQUAL(vec[0].toUri(),
886 manifests[2].catalog()[1].toUri());
887 BOOST_CHECK_EQUAL(vec[1].toUri(),
888 manifests[2].catalog()[2].toUri());
889 BOOST_CHECK_EQUAL(vec[2].toUri(),
890 manifests[2].catalog()[3].toUri());
891 BOOST_CHECK_EQUAL(vec[3].toUri(),
892 manifests[2].catalog()[4].toUri());
893 BOOST_CHECK_EQUAL(vec[4].toUri(),
894 manifests[2].catalog()[5].toUri());
895 },
896 [](const ndn::Name& name, const std::string& reason) {
897 BOOST_FAIL("Unexpected failure");
898 });
899 fs::remove_all(filePath);
900 fs::remove_all(".appdata");
901}
902
903BOOST_AUTO_TEST_CASE(TestDataAlreadyDownloaded)
904{
905 vector<FileManifest> manifests;
906 vector<TorrentFile> torrentSegments;
907 // for each file, the data packets
908 std::vector<vector<Data>> fileData;
909 std::string filePath = "tests/testdata/temp";
910 // get torrent files and manifests
911 {
912 auto temp = TorrentFile::generate("tests/testdata/foo",
913 1024,
914 2048,
915 8192,
916 true);
917 torrentSegments = temp.first;
918 auto temp1 = temp.second;
919 for (const auto& ms : temp1) {
920 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
921 fileData.push_back(ms.second);
922 }
923 }
924 // write the torrent segments and manifests to disk
925 std::string dirPath = ".appdata/foo/";
926 boost::filesystem::create_directories(dirPath);
927 std::string torrentPath = dirPath + "torrent_files/";
928 boost::filesystem::create_directories(torrentPath);
929 auto fileNum = 0;
930 for (const auto& t : torrentSegments) {
931 fileNum++;
932 auto filename = torrentPath + to_string(fileNum);
933 io::save(t, filename);
934 }
935
936 auto manifestPath = dirPath + "manifests/";
937 boost::filesystem::create_directory(manifestPath);
938 for (const auto& m : manifests) {
939 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
940 boost::filesystem::create_directory(filename.parent_path());
941 io::save(m, filename.string());
942 }
943 // Initialize manager
944 TestTorrentManager manager("/NTORRENT/foo/torrent-file/sha256digest=a8a2e98cd943d895b8c4b12a208343bcf9344ce85a6376dc6f5754fe8f4a573e",
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700945 filePath,
946 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700947
spirosmastorakis50642f82016-04-08 12:11:18 -0700948 manager.Initialize();
949
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700950 advanceClocks(time::milliseconds(1), 10);
951 manager.sendRoutablePrefixResponse();
952
spirosmastorakis50642f82016-04-08 12:11:18 -0700953 // Set the file state
954 std::vector<bool> v1 = {true};
955 manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
956
957 std::vector<bool> v2 = {false, true, true, false, false, false};
958 manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
959
960 std::vector<bool> v3 = {true, false, false, false, false, false};
961 manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
962
963 Name p1("NTORRENT/foo/bar1.txt");
964 p1.appendSequenceNumber(0);
965 p1.appendSequenceNumber(0);
966 p1 = Name(p1.toUri() + "/sha256digest");
967
968 BOOST_CHECK(!(manager.dataAlreadyDownloaded(p1)));
969
970 Name p2("NTORRENT/foo/bar.txt");
971 p2.appendSequenceNumber(0);
972 p2.appendSequenceNumber(0);
973 p2 = Name(p2.toUri() + "/sha256digest");
974
975 BOOST_CHECK(manager.dataAlreadyDownloaded(p2));
spirosmastorakisa46eee42016-04-05 14:24:45 -0700976}
977
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700978BOOST_AUTO_TEST_CASE(CheckSeedComplete)
979{
980 const struct {
981 const char *d_directoryPath;
982 const char *d_initialSegmentName;
983 size_t d_namesPerSegment;
984 size_t d_subManifestSize;
985 size_t d_dataPacketSize;
986 } DATA [] = {
987 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
988 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128, 128, 128},
989 // {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=76df604f23bdf257d16de588f2941df261951552a5f4435a315f59c3b018a851", 1, 1, 128},
990 };
991 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
992 for (int i = 0; i < NUM_DATA; ++i) {
993 auto directoryPath = DATA[i].d_directoryPath;
994 Name initialSegmentName = DATA[i].d_initialSegmentName;
995 auto namesPerSegment = DATA[i].d_namesPerSegment;
996 auto dataPacketSize = DATA[i].d_dataPacketSize;
997 auto subManifestSize = DATA[i].d_subManifestSize;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800998
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700999 vector<FileManifest> manifests;
1000 vector<TorrentFile> torrentSegments;
1001 std::string filePath = "tests/testdata/";
1002 std::vector<vector<Data>> fileData;
1003 // get torrent files and manifests
1004 {
1005 auto temp = TorrentFile::generate(directoryPath,
1006 namesPerSegment,
1007 subManifestSize,
1008 dataPacketSize,
1009 false);
1010 torrentSegments = temp.first;
1011 auto temp1 = temp.second;
1012 for (const auto& ms : temp1) {
1013 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
1014 fileData.push_back(ms.second);
1015 }
1016 }
1017 // write the torrent segments and manifests to disk
1018 std::string dirPath = ".appdata/foo/";
1019 boost::filesystem::create_directories(dirPath);
1020 std::string torrentPath = dirPath + "torrent_files/";
1021 boost::filesystem::create_directory(torrentPath);
1022 auto fileNum = 0;
1023 for (const auto& t : torrentSegments) {
1024 fileNum++;
1025 auto filename = torrentPath + to_string(fileNum);
1026 io::save(t, filename);
1027 }
1028 auto manifestPath = dirPath + "manifests/";
1029 boost::filesystem::create_directory(manifestPath);
1030 for (const auto& m : manifests) {
1031 fs::path filename = manifestPath + m.file_name() + "/" + to_string(m.submanifest_number());
1032 boost::filesystem::create_directories(filename.parent_path());
1033 io::save(m, filename.string());
1034 }
1035 // Initialize and verify
1036 TestTorrentManager manager(initialSegmentName,
1037 filePath,
1038 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001039
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001040 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001041
1042 advanceClocks(time::milliseconds(1), 10);
1043 manager.sendRoutablePrefixResponse();
1044
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001045 size_t nData = 0;
1046 BOOST_CHECK_EQUAL(0, face->sentData.size());
1047 // request all the torrent segments
1048 for (const auto& t : torrentSegments) {
1049 Interest interest(t.getFullName(), time::milliseconds(50));
1050 face->expressInterest(interest,
1051 [&t](const Interest& i, const Data& d) {
1052 TorrentFile t1(d.wireEncode());
1053 BOOST_CHECK(t == d);
1054 BOOST_CHECK(t1 == t);
1055 },
1056 bind([] {
1057 BOOST_FAIL("Unexpected Nack");
1058 }),
1059 bind([] {
1060 BOOST_FAIL("Unexpected timeout");
1061 }));
1062 advanceClocks(time::milliseconds(1), 40);
1063 face->receive(interest);
Mickey Sweattb7ee19c2016-04-21 12:18:15 -07001064 manager.processEvents();
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001065 // check that one piece of data is sent, and it is what was expected
1066 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
1067 face->receive(face->sentData[nData - 1]);
1068 }
1069 // request all the file manifests
1070 for (const auto& m : manifests) {
1071 Interest interest(m.getFullName(), time::milliseconds(50));
1072 face->expressInterest(interest,
1073 [&m](const Interest& i, const Data& d) {
1074 FileManifest m1(d.wireEncode());
1075 BOOST_CHECK(m == d);
1076 BOOST_CHECK(m1 == m);
1077 },
1078 bind([] {
1079 BOOST_FAIL("Unexpected Nack");
1080 }),
1081 bind([] {
1082 BOOST_FAIL("Unexpected timeout");
1083 }));
1084 advanceClocks(time::milliseconds(1), 40);
1085 face->receive(interest);
Mickey Sweattb7ee19c2016-04-21 12:18:15 -07001086 manager.processEvents();
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001087 // check that one piece of data is sent, and it is what was expected
1088 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
1089 face->receive(face->sentData[nData - 1]);
1090 }
1091 // request all the data packets
1092 for (const auto& file : fileData) {
1093 for (const auto& data : file) {
Mickey Sweattb7ee19c2016-04-21 12:18:15 -07001094 Interest interest(data.getFullName(), time::milliseconds(50));
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001095 face->expressInterest(interest,
1096 [&data](const Interest& i, const Data& d) {
1097 BOOST_CHECK(data == d);
1098 },
1099 bind([] {
1100 BOOST_FAIL("Unexpected Nack");
1101 }),
1102 bind([] {
1103 BOOST_FAIL("Unexpected timeout");
1104 }));
1105 advanceClocks(time::milliseconds(1), 40);
1106 face->receive(interest);
Mickey Sweattb7ee19c2016-04-21 12:18:15 -07001107 manager.processEvents();
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001108 // check that one piece of data is sent, and it is what was expected
1109 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
1110 face->receive(face->sentData[nData - 1]);
1111 }
1112 }
1113 // clean up tests
1114 face->sentData.clear();
1115 fs::remove_all(".appdata/");
1116 }
1117}
Mickey Sweattafda1f12016-04-04 17:15:11 -07001118
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001119BOOST_AUTO_TEST_CASE(CheckSeedRandom)
Mickey Sweattafda1f12016-04-04 17:15:11 -07001120{
1121 vector<FileManifest> manifests;
1122 vector<TorrentFile> torrentSegments;
1123 // for each file, the data packets
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001124 std::vector<Data> data;
1125 std::string filePath = "tests/testdata/";
1126 std::string dirPath = ".appdata/foo/";
1127 Name initialSegmentName = "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253";
Mickey Sweattafda1f12016-04-04 17:15:11 -07001128 // get torrent files and manifests
1129 {
1130 auto temp = TorrentFile::generate("tests/testdata/foo",
1131 1024,
1132 1024,
1133 1024,
1134 true);
1135 torrentSegments = temp.first;
1136 auto temp1 = temp.second;
1137 for (const auto& ms : temp1) {
1138 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001139 data.insert(data.end(), ms.second.begin(), ms.second.end());
Mickey Sweattafda1f12016-04-04 17:15:11 -07001140 }
1141 }
1142 // write the torrent segments and manifests to disk
Mickey Sweattafda1f12016-04-04 17:15:11 -07001143 boost::filesystem::create_directories(dirPath);
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001144 auto torrentPath = dirPath + "torrent_files/";
Mickey Sweattafda1f12016-04-04 17:15:11 -07001145 boost::filesystem::create_directories(torrentPath);
1146 auto fileNum = 0;
1147 for (const auto& t : torrentSegments) {
1148 fileNum++;
1149 auto filename = torrentPath + to_string(fileNum);
1150 io::save(t, filename);
1151 }
Mickey Sweattafda1f12016-04-04 17:15:11 -07001152 auto manifestPath = dirPath + "manifests/";
1153 boost::filesystem::create_directory(manifestPath);
1154 for (const auto& m : manifests) {
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001155 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
1156 boost::filesystem::create_directory(filename.parent_path());
1157 io::save(m, filename.string());
Mickey Sweattafda1f12016-04-04 17:15:11 -07001158 }
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001159
Mickey Sweattafda1f12016-04-04 17:15:11 -07001160 // Initialize manager
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001161 TestTorrentManager manager(initialSegmentName,
1162 filePath,
1163 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001164
Mickey Sweattafda1f12016-04-04 17:15:11 -07001165 manager.Initialize();
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001166
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001167 advanceClocks(time::milliseconds(1), 10);
1168 manager.sendRoutablePrefixResponse();
1169
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001170 // insert the other entities
1171 data.insert(data.end(), torrentSegments.begin(), torrentSegments.end());
1172 data.insert(data.end(), manifests.begin(), manifests.end());
1173
1174 std::random_shuffle(data.begin(), data.end());
1175 // request all the data packets
1176 auto nData = 0;
1177 for(const auto& d : data) {
1178 Interest interest(d.getFullName(), time::milliseconds(50));
1179 face->expressInterest(interest,
1180 [&d](const Interest& i, const Data& data) {
1181 BOOST_CHECK(data == d);
1182 },
1183 bind([] {
1184 BOOST_FAIL("Unexpected Nack");
1185 }),
1186 bind([] {
1187 BOOST_FAIL("Unexpected timeout");
1188 }));
1189 advanceClocks(time::milliseconds(1), 40);
1190 face->receive(interest);
Mickey Sweattb7ee19c2016-04-21 12:18:15 -07001191 manager.processEvents();
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001192 // check that one piece of data is sent, and it is what was expected
1193 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
1194 face->receive(face->sentData[nData - 1]);
Mickey Sweattafda1f12016-04-04 17:15:11 -07001195 }
Mickey Sweattafda1f12016-04-04 17:15:11 -07001196 fs::remove_all(".appdata");
1197}
1198
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001199BOOST_AUTO_TEST_SUITE_END()
1200
1201BOOST_FIXTURE_TEST_SUITE(CheckTorrentManagerUtilities, FaceFixture)
1202
1203BOOST_AUTO_TEST_CASE(CheckWriteDataComplete)
1204{
1205 const struct {
1206 const char *d_directoryPath;
1207 const char *d_initialSegmentName;
1208 size_t d_namesPerSegment;
1209 size_t d_subManifestSize;
1210 size_t d_dataPacketSize;
1211 } DATA [] = {
1212 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
1213 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=b88c054e87bcbb744726f7eaf79f95459b4fddce2caeb952f263a5ccbbfc9a7c", 128, 128, 128},
1214 };
1215 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
1216 for (int i = 0; i < NUM_DATA; ++i) {
1217 auto directoryPath = DATA[i].d_directoryPath;
1218 Name initialSegmentName = DATA[i].d_initialSegmentName;
1219 auto namesPerSegment = DATA[i].d_namesPerSegment;
1220 auto dataPacketSize = DATA[i].d_dataPacketSize;
1221 auto subManifestSize = DATA[i].d_subManifestSize;
1222
1223 vector<TorrentFile> torrentSegments;
1224 vector<FileManifest> manifests;
1225 // for each file, the data packets
1226 std::vector<vector<Data>> fileData;
1227 std::string filePath = "tests/testdata/temp";
1228 // get torrent files and manifests
1229 {
1230 auto temp = TorrentFile::generate(directoryPath,
1231 namesPerSegment,
1232 subManifestSize,
1233 dataPacketSize,
1234 false);
1235 torrentSegments = temp.first;
1236 auto temp1 = temp.second;
1237 for (const auto& ms : temp1) {
1238 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
1239 fileData.push_back(ms.second);
1240 }
1241 }
1242 // write the torrent segments and manifests to disk
1243 std::string dirPath = ".appdata/foo/";
1244 boost::filesystem::create_directories(dirPath);
1245 std::string torrentPath = dirPath + "torrent_files/";
1246 boost::filesystem::create_directories(torrentPath);
1247 auto fileNum = 0;
1248 for (const auto& t : torrentSegments) {
1249 fileNum++;
1250 auto filename = torrentPath + to_string(fileNum);
1251 io::save(t, filename);
1252 }
1253 auto manifestPath = dirPath + "manifests/";
1254 boost::filesystem::create_directory(manifestPath);
1255 for (const auto& m : manifests) {
1256 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
1257 boost::filesystem::create_directory(filename.parent_path());
1258 io::save(m, filename.string());
1259 }
1260 // Initialize manager
1261 TestTorrentManager manager(initialSegmentName,
1262 filePath,
1263 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001264
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001265 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001266
1267 advanceClocks(time::milliseconds(1), 10);
1268 manager.sendRoutablePrefixResponse();
1269
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001270 // check that initially there is no data on disk
1271 for (auto m : manager.fileManifests()) {
1272 auto fileState = manager.fileState(m.getFullName());
1273 BOOST_CHECK(fileState.empty());
1274 }
1275 // write all data to disk (for each file manifest)
1276 auto manifest_it = manifests.begin();
1277 for (auto& data : fileData) {
1278 for (auto& d : data) {
1279 BOOST_CHECK(manager.writeData(d));
1280 }
1281 // check that the state is updated appropriately
1282 auto fileState = manager.fileState(manifest_it->getFullName());
1283 for (auto s : fileState) {
1284 BOOST_CHECK(s);
1285 }
1286 ++manifest_it;
1287 }
1288 // get the file names (ascending)
1289 std::set<std::string> fileNames;
1290 for (auto i = fs::recursive_directory_iterator(filePath + "/foo");
1291 i != fs::recursive_directory_iterator();
1292 ++i) {
1293 fileNames.insert(i->path().string());
1294 }
1295 // verify file by file that the data packets are written correctly
1296 auto f_it = fileData.begin();
1297 for (auto f : fileNames) {
1298 // read file from disk
1299 std::vector<uint8_t> file_bytes;
1300 fs::ifstream is(f, fs::ifstream::binary | fs::ifstream::in);
1301 is >> std::noskipws;
1302 std::istream_iterator<uint8_t> start(is), end;
1303 file_bytes.insert(file_bytes.end(), start, end);
1304 std::vector<uint8_t> data_bytes;
1305 // get content from data packets
1306 for (const auto& d : *f_it) {
1307 auto content = d.getContent();
1308 data_bytes.insert(data_bytes.end(), content.value_begin(), content.value_end());
1309 }
1310 BOOST_CHECK(data_bytes == file_bytes);
1311 ++f_it;
1312 }
1313 fs::remove_all(filePath);
1314 fs::remove_all(".appdata");
1315 }
1316}
1317
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001318BOOST_AUTO_TEST_CASE(CheckWriteTorrentComplete)
1319{
1320 const struct {
1321 const char *d_directoryPath;
1322 const char *d_initialSegmentName;
1323 size_t d_namesPerSegment;
1324 size_t d_subManifestSize;
1325 size_t d_dataPacketSize;
1326 } DATA [] = {
1327 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
1328 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=96d900d6788465f9a7b00191581b004c910d74b3762d141ec0e82173731bc9f4", 1, 1, 1024},
1329 };
1330 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
1331 for (int i = 0; i < NUM_DATA; ++i) {
1332 auto directoryPath = DATA[i].d_directoryPath;
1333 Name initialSegmentName = DATA[i].d_initialSegmentName;
1334 auto namesPerSegment = DATA[i].d_namesPerSegment;
1335 auto dataPacketSize = DATA[i].d_dataPacketSize;
1336 auto subManifestSize = DATA[i].d_subManifestSize;
1337
1338 vector<TorrentFile> torrentSegments;
1339 std::string filePath = "tests/testdata/temp";
1340 // get torrent files
1341 {
1342 auto temp = TorrentFile::generate(directoryPath,
1343 namesPerSegment,
1344 subManifestSize,
1345 dataPacketSize,
1346 false);
1347 torrentSegments = temp.first;
1348 }
1349 // Initialize manager
1350 TestTorrentManager manager(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001351 filePath,
1352 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001353
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001354 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001355
1356 advanceClocks(time::milliseconds(1), 10);
1357 manager.sendRoutablePrefixResponse();
1358
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001359 std::string dirPath = ".appdata/foo/";
1360 std::string torrentPath = dirPath + "torrent_files/";
1361 BOOST_CHECK(manager.torrentSegments().empty());
1362 for (const auto& t : torrentSegments) {
1363 BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
1364 }
1365 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
1366 // check that initializing a new manager also gets all the torrent torrentSegments
1367 TestTorrentManager manager2(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001368 filePath,
1369 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001370
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001371 manager2.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001372
1373 advanceClocks(time::milliseconds(1), 10);
1374 manager2.sendRoutablePrefixResponse();
1375
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001376 BOOST_CHECK(manager2.torrentSegments() == torrentSegments);
1377
1378 // start anew
1379 fs::remove_all(torrentPath);
1380 fs::create_directories(torrentPath);
1381 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001382
1383 advanceClocks(time::milliseconds(1), 10);
1384 manager.sendRoutablePrefixResponse();
1385
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001386 BOOST_CHECK(manager.torrentSegments().empty());
1387
1388 // check that there is no dependence on the order of torrent segments
1389 // randomize the order of the torrent segments
1390 auto torrentSegmentsRandom = torrentSegments;
1391 std::random_shuffle(torrentSegmentsRandom.begin(), torrentSegmentsRandom.end());
1392 for (const auto& t : torrentSegmentsRandom) {
1393 BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
1394 }
1395 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
1396 fs::remove_all(".appdata");
1397 }
1398}
1399
1400BOOST_AUTO_TEST_CASE(CheckWriteManifestComplete)
1401{
1402 std::string dirPath = ".appdata/foo/";
1403 std::string torrentPath = dirPath + "torrent_files/";
1404 std::string manifestPath = dirPath + "manifests/";
1405
1406 const struct {
1407 const char *d_directoryPath;
1408 const char *d_initialSegmentName;
1409 size_t d_namesPerSegment;
1410 size_t d_subManifestSize;
1411 size_t d_dataPacketSize;
1412 } DATA [] = {
1413 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 1024, 1024, 1024},
1414 {"tests/testdata/foo", "/NTORRENT/foo/torrent-file/sha256digest=02c737fd4c6e7de4b4825b089f39700c2dfa8fd2bb2b91f09201e357c4463253", 128, 128, 1024},
1415 };
1416 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
1417 for (int i = 0; i < NUM_DATA; ++i) {
1418 auto directoryPath = DATA[i].d_directoryPath;
1419 Name initialSegmentName = DATA[i].d_initialSegmentName;
1420 auto namesPerSegment = DATA[i].d_namesPerSegment;
1421 auto dataPacketSize = DATA[i].d_dataPacketSize;
1422 auto subManifestSize = DATA[i].d_subManifestSize;
1423
1424 vector<FileManifest> manifests;
1425 vector<TorrentFile> torrentSegments;
1426
1427 std::string filePath = "tests/testdata/temp";
1428 // get torrent files and manifests
1429 {
1430 auto temp = TorrentFile::generate(directoryPath,
1431 namesPerSegment,
1432 subManifestSize,
1433 dataPacketSize,
1434 false);
1435 torrentSegments = temp.first;
1436 auto temp1 = temp.second;
1437 for (const auto& ms : temp1) {
1438 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
1439 }
1440 }
1441 TestTorrentManager manager(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001442 filePath,
1443 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001444
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001445 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001446
1447 advanceClocks(time::milliseconds(1), 10);
1448 manager.sendRoutablePrefixResponse();
1449
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001450 for (const auto& t : torrentSegments) {
1451 manager.writeTorrentSegment(t, torrentPath);
1452 }
1453
1454 BOOST_CHECK(manager.fileManifests().empty());
1455 for (const auto& m : manifests) {
1456 BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
1457 }
1458 BOOST_CHECK(manager.fileManifests() == manifests);
1459
1460 TestTorrentManager manager2(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001461 filePath,
1462 face);
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001463
1464 manager2.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001465
1466 advanceClocks(time::milliseconds(1), 10);
1467 manager2.sendRoutablePrefixResponse();
1468
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001469 BOOST_CHECK(manager2.fileManifests() == manifests);
1470
1471 // start anew
1472 fs::remove_all(manifestPath);
1473 fs::create_directories(manifestPath);
1474 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001475
1476 advanceClocks(time::milliseconds(1), 10);
1477 manager.sendRoutablePrefixResponse();
1478
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001479 BOOST_CHECK(manager.fileManifests().empty());
1480
1481 // check that there is no dependence on the order of torrent segments
1482 // randomize the order of the torrent segments
1483 auto fileManifestsRandom = manifests;
1484 std::random_shuffle(fileManifestsRandom.begin(), fileManifestsRandom.end());
1485 for (const auto& m : fileManifestsRandom) {
1486 BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
1487 }
1488 BOOST_CHECK(manager2.fileManifests() == manifests);
1489 fs::remove_all(".appdata");
1490 }
1491}
1492
spirosmastorakisa46eee42016-04-05 14:24:45 -07001493BOOST_AUTO_TEST_SUITE_END()
Mickey Sweattafda1f12016-04-04 17:15:11 -07001494
Mickey Sweatt527b0492016-03-02 11:07:48 -08001495} // namespace tests
1496} // namespace nTorrent
spirosmastorakisa46eee42016-04-05 14:24:45 -07001497} // namespace ndn