blob: 8f50a2afe7fc9febf0b45946648f03e9b698bfc1 [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)
Mickey Sweatt44e4fd92016-05-02 15:43:11 -070051 : TorrentManager(torrentFileName, filePath, false, 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
Mickey Sweatt527b0492016-03-02 11:07:48 -080081 std::vector<bool> fileState(const ndn::Name& manifestName) {
Mickey Sweattafda1f12016-04-04 17:15:11 -070082 auto fout = m_fileStates[manifestName].first;
83 if (nullptr != fout) {
84 fout->flush();
85 }
Mickey Sweatt527b0492016-03-02 11:07:48 -080086 return m_fileStates[manifestName].second;
87 }
Mickey Sweattafda1f12016-04-04 17:15:11 -070088
spirosmastorakis50642f82016-04-08 12:11:18 -070089 void setFileState(const ndn::Name manifestName,
90 std::shared_ptr<fs::fstream> f,
91 const std::vector<bool>& stateVec) {
92
93 m_fileStates.insert({ manifestName, std::make_pair(f, stateVec) });
94 }
95
Mickey Sweattafda1f12016-04-04 17:15:11 -070096 bool writeData(const Data& data) {
97 return TorrentManager::writeData(data);
98 }
Mickey Sweatt599bfef2016-04-05 19:11:20 -070099
100 bool writeTorrentSegment(const TorrentFile& segment, const std::string& path) {
101 return TorrentManager::writeTorrentSegment(segment, path);
102 }
spirosmastorakis50642f82016-04-08 12:11:18 -0700103
Mickey Sweatt599bfef2016-04-05 19:11:20 -0700104 bool writeFileManifest(const FileManifest& manifest, const std::string& path) {
105 return TorrentManager::writeFileManifest(manifest, path);
106 }
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700107
108 void sendRoutablePrefixResponse() {
109 // Create a data packet containing one name as content
110 shared_ptr<Data> d = DummyParser::createDataPacket(Name("/localhop/nfd/rib/routable-prefixes"),
111 { Name("ucla") });
112 m_keyChain->sign(*d);
113 m_face->receive(*d);
114 }
115
116private:
117 shared_ptr<KeyChain> m_keyChain;
118 shared_ptr<DummyClientFace> m_face;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800119};
120
spirosmastorakisa46eee42016-04-05 14:24:45 -0700121class FaceFixture : public UnitTestTimeFixture
122{
123public:
124 explicit
125 FaceFixture(bool enableRegistrationReply = true)
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700126 : face(new DummyClientFace(io, { true, enableRegistrationReply }))
spirosmastorakisa46eee42016-04-05 14:24:45 -0700127 {
128 }
129
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700130 ~FaceFixture()
131 {
132 fs::remove_all(".appdata");
133 }
134
spirosmastorakisa46eee42016-04-05 14:24:45 -0700135public:
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700136 std::shared_ptr<DummyClientFace> face;
spirosmastorakisa46eee42016-04-05 14:24:45 -0700137};
138
139class FacesNoRegistrationReplyFixture : public FaceFixture
140{
141public:
142 FacesNoRegistrationReplyFixture()
143 : FaceFixture(false)
144 {
145 }
146};
147
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700148BOOST_FIXTURE_TEST_SUITE(TestTorrentManagerInitialize, FaceFixture)
Mickey Sweatt527b0492016-03-02 11:07:48 -0800149
150BOOST_AUTO_TEST_CASE(CheckInitializeComplete)
151{
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700152 const struct {
153 const char *d_directoryPath;
154 const char *d_initialSegmentName;
155 size_t d_namesPerSegment;
156 size_t d_subManifestSize;
157 size_t d_dataPacketSize;
158 } DATA [] = {
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700159 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
160 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128, 128, 128},
161 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d", 1, 128, 128},
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700162 };
163 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
164 for (int i = 0; i < NUM_DATA; ++i) {
165 auto directoryPath = DATA[i].d_directoryPath;
166 Name initialSegmentName = DATA[i].d_initialSegmentName;
167 auto namesPerSegment = DATA[i].d_namesPerSegment;
168 auto dataPacketSize = DATA[i].d_dataPacketSize;
169 auto subManifestSize = DATA[i].d_subManifestSize;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800170
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700171 vector<FileManifest> manifests;
172 vector<TorrentFile> torrentSegments;
173 std::string filePath = "tests/testdata/";
174 // get torrent files and manifests
175 {
176 auto temp = TorrentFile::generate(directoryPath,
177 namesPerSegment,
178 subManifestSize,
179 dataPacketSize,
180 false);
181 torrentSegments = temp.first;
182 auto temp1 = temp.second;
183 for (const auto& ms : temp1) {
184 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
185 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800186 }
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700187 // write the torrent segments and manifests to disk
188 std::string dirPath = ".appdata/foo/";
189 boost::filesystem::create_directories(dirPath);
190 std::string torrentPath = dirPath + "torrent_files/";
191 boost::filesystem::create_directory(torrentPath);
192 auto fileNum = 0;
193 for (const auto& t : torrentSegments) {
194 fileNum++;
195 auto filename = torrentPath + to_string(fileNum);
196 io::save(t, filename);
197 }
198 auto manifestPath = dirPath + "manifests/";
199 boost::filesystem::create_directory(manifestPath);
200 for (const auto& m : manifests) {
201 fs::path filename = manifestPath + m.file_name() + "/" + to_string(m.submanifest_number());
202 boost::filesystem::create_directories(filename.parent_path());
203 io::save(m, filename.string());
204 }
205 // Initialize and verify
206 TestTorrentManager manager(initialSegmentName,
207 filePath,
208 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700209
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700210 manager.Initialize();
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700211 BOOST_CHECK(manager.hasAllTorrentSegments());
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700212
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700213 advanceClocks(time::milliseconds(1), 10);
214 manager.sendRoutablePrefixResponse();
215
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700216 // Check that the torrent segments and file manifests match (content and order)
217 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
218 BOOST_CHECK(manager.fileManifests() == manifests);
219 // next check the data packet state vectors
220 for (auto m : manager.fileManifests()) {
221 auto fileState = manager.fileState(m.getFullName());
222 BOOST_CHECK(fileState.size() == m.catalog().size());
223 for (auto s : fileState) {
224 BOOST_CHECK(s);
225 }
226 }
227 fs::remove_all(dirPath);
Mickey Sweatt527b0492016-03-02 11:07:48 -0800228 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800229}
230
231BOOST_AUTO_TEST_CASE(CheckInitializeEmpty)
232{
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700233 TestTorrentManager manager("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981",
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700234 "tests/testdata/", face);
235
Mickey Sweatt527b0492016-03-02 11:07:48 -0800236 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700237
238 advanceClocks(time::milliseconds(1), 10);
239 manager.sendRoutablePrefixResponse();
240
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700241 BOOST_CHECK(!manager.hasAllTorrentSegments());
242
Mickey Sweatt527b0492016-03-02 11:07:48 -0800243 BOOST_CHECK(manager.torrentSegments() == vector<TorrentFile>());
244 BOOST_CHECK(manager.fileManifests() == vector<FileManifest>());
245}
246
247BOOST_AUTO_TEST_CASE(CheckInitializeNoManifests)
248{
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700249 const struct {
250 const char *d_directoryPath;
251 const char *d_initialSegmentName;
252 size_t d_namesPerSegment;
253 size_t d_subManifestSize;
254 size_t d_dataPacketSize;
255 } DATA [] = {
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700256 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
257 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128, 128, 128},
258 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d", 1, 128, 128},
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700259 };
260 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
261 for (int i = 0; i < NUM_DATA; ++i) {
262 auto directoryPath = DATA[i].d_directoryPath;
263 Name initialSegmentName = DATA[i].d_initialSegmentName;
264 auto namesPerSegment = DATA[i].d_namesPerSegment;
265 auto dataPacketSize = DATA[i].d_dataPacketSize;
266 auto subManifestSize = DATA[i].d_subManifestSize;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800267
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700268 vector<FileManifest> manifests;
269 vector<TorrentFile> torrentSegments;
270 std::string filePath = "tests/testdata/";
271 // get torrent files and manifests
272 {
273 auto temp = TorrentFile::generate(directoryPath,
274 namesPerSegment,
275 subManifestSize,
276 dataPacketSize,
277 false);
278 torrentSegments = temp.first;
279 }
280 // write the torrent segments and manifests to disk
281 std::string dirPath = ".appdata/foo/";
282 boost::filesystem::create_directories(dirPath);
283 std::string torrentPath = dirPath + "torrent_files/";
284 boost::filesystem::create_directory(torrentPath);
285 auto fileNum = 0;
286 for (const auto& t : torrentSegments) {
287 fileNum++;
288 auto filename = torrentPath + to_string(fileNum);
289 io::save(t, filename);
290 }
291 // Initialize and verify
292 TestTorrentManager manager(initialSegmentName,
293 filePath,
294 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700295
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700296 manager.Initialize();
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700297 BOOST_CHECK(manager.hasAllTorrentSegments());
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 [] = {
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700319 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
320 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128, 128, 128},
321 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d", 1, 128, 128},
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700322 };
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();
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700373 BOOST_CHECK(manager.hasAllTorrentSegments());
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700374
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700375 advanceClocks(time::milliseconds(1), 10);
376 manager.sendRoutablePrefixResponse();
377
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700378 // Check that the torrent segments and file manifests match (content and order)
379 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
380 BOOST_CHECK(manager.fileManifests() == manifests);
381 // next check the data packet state vectors
382 for (auto m : manager.fileManifests()) {
383 auto fileState = manager.fileState(m.getFullName());
384 BOOST_CHECK(fileState.size() == m.catalog().size());
385 for (auto s : fileState) {
386 BOOST_CHECK(s);
387 }
388 }
389 fs::remove_all(".appdata");
Mickey Sweatt527b0492016-03-02 11:07:48 -0800390 }
Mickey Sweatt527b0492016-03-02 11:07:48 -0800391}
392
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700393BOOST_AUTO_TEST_SUITE_END()
394
spirosmastorakisa46eee42016-04-05 14:24:45 -0700395BOOST_FIXTURE_TEST_SUITE(TestTorrentManagerNetworkingStuff, FaceFixture)
396
397BOOST_AUTO_TEST_CASE(TestDownloadingTorrentFile)
398{
399 vector<FileManifest> manifests;
400 vector<TorrentFile> torrentSegments;
401 std::string filePath = ".appdata/foo/";
402 // get torrent files and manifests
403 {
404 auto temp = TorrentFile::generate("tests/testdata/foo", 1, 10, 10, false);
spirosmastorakisa46eee42016-04-05 14:24:45 -0700405 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 }
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700414 TestTorrentManager manager("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=521110d7a60e317e1f36029a414f0d98318f26553720ed50a26479fe4bf982b7",
spirosmastorakisa46eee42016-04-05 14:24:45 -0700415 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700416
spirosmastorakisa46eee42016-04-05 14:24:45 -0700417 manager.Initialize();
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700418 BOOST_CHECK(!manager.hasAllTorrentSegments());
spirosmastorakisa46eee42016-04-05 14:24:45 -0700419
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 }
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700443 BOOST_CHECK(manager.hasAllTorrentSegments());
spirosmastorakisa46eee42016-04-05 14:24:45 -0700444 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
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700467 TestTorrentManager manager("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=521110d7a60e317e1f36029a414f0d98318f26553720ed50a26479fe4bf982b7",
spirosmastorakisa46eee42016-04-05 14:24:45 -0700468 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/";
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700529 TestTorrentManager manager("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=521110d7a60e317e1f36029a414f0d98318f26553720ed50a26479fe4bf982b7",
spirosmastorakisa46eee42016-04-05 14:24:45 -0700530 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/";
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700576 TestTorrentManager manager("/ndn/multicast/NTORRENT/test/torrent-file/sha256digest",
spirosmastorakis50642f82016-04-08 12:11:18 -0700577 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
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700584 TorrentFile t1(Name("/ndn/multicast/NTORRENT/test/torrent-file/sha256digest"),
585 Name("/ndn/multicast/NTORRENT/test/torrent-file/1/sha256digest"), Name("/test"),
spirosmastorakis50642f82016-04-08 12:11:18 -0700586 { Name("/manifest1") });
587 manager.pushTorrentSegment(t1);
588
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700589 TorrentFile t2(Name("/ndn/multicast/NTORRENT/test/torrent-file/1/sha256digest"),
590 Name("/ndn/multicast/NTORRENT/test/torrent-file/2/sha256digest"), Name("/test"),
spirosmastorakis50642f82016-04-08 12:11:18 -0700591 { Name("/manifest2"), Name("/manifest3") });
592 manager.pushTorrentSegment(t2);
593
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700594 TorrentFile t3(Name("/ndn/multicast/NTORRENT/test/torrent-file/3/sha256digest"),
595 Name("/ndn/multicast/NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"),
spirosmastorakis50642f82016-04-08 12:11:18 -0700596 { Name("/manifest4"), Name("/manifest5") });
597 manager.pushTorrentSegment(t3);
598
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700599 TorrentFile t4(Name("/ndn/multicast/NTORRENT/test/torrent-file/4/sha256digest"), Name("/test"), {});
spirosmastorakis50642f82016-04-08 12:11:18 -0700600 manager.pushTorrentSegment(t4);
601
602 BOOST_CHECK(!(manager.findTorrentFileSegmentToDownload()));
603
604 std::vector<Name> manifests;
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700605 manager.downloadTorrentFile("/test");
606 manager.findFileManifestsToDownload(manifests);
spirosmastorakis50642f82016-04-08 12:11:18 -0700607
608 BOOST_CHECK_EQUAL(manifests[0].toUri(), "/manifest1");
609 BOOST_CHECK_EQUAL(manifests[1].toUri(), "/manifest2");
610 BOOST_CHECK_EQUAL(manifests[2].toUri(), "/manifest3");
611 BOOST_CHECK_EQUAL(manifests[3].toUri(), "/manifest4");
612 BOOST_CHECK_EQUAL(manifests[4].toUri(), "/manifest5");
613
614 fs::remove_all(filePath);
615 fs::remove_all(".appdata");
616}
617
618// we do not have the torrent file
619BOOST_AUTO_TEST_CASE(TestFindTorrentFileSegmentToDownload2)
620{
621 std::string filePath = ".appdata/foo/";
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700622 TestTorrentManager manager("/ndn/multicast/NTORRENT/test/torrent-file/0/sha256digest",
spirosmastorakis50642f82016-04-08 12:11:18 -0700623 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700624
spirosmastorakis50642f82016-04-08 12:11:18 -0700625 manager.Initialize();
626
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700627 advanceClocks(time::milliseconds(1), 10);
628 manager.sendRoutablePrefixResponse();
629
630 BOOST_CHECK_EQUAL(manager.findTorrentFileSegmentToDownload()->toUri(),
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700631 "/ndn/multicast/NTORRENT/test/torrent-file/0/sha256digest");
spirosmastorakis50642f82016-04-08 12:11:18 -0700632
633 fs::remove_all(filePath);
634 fs::remove_all(".appdata");
635}
636
spirosmastorakis50642f82016-04-08 12:11:18 -0700637BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload1)
638{
639 std::string filePath = ".appdata/foo/";
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700640 TestTorrentManager manager("/ndn/multicast/NTORRENT/test/torrent-file/sha256digest",
spirosmastorakis50642f82016-04-08 12:11:18 -0700641 filePath, face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700642
spirosmastorakis50642f82016-04-08 12:11:18 -0700643 manager.Initialize();
644
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700645 advanceClocks(time::milliseconds(1), 10);
646 manager.sendRoutablePrefixResponse();
647
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700648 Name n1(Name("/ndn/multicast/NTORRENT/test/file0"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700649 n1.appendSequenceNumber(0);
650
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700651 Name n2(Name("/ndn/multicast/NTORRENT/test/file0"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700652 n2.appendSequenceNumber(1);
653
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700654 Name n3(Name("/ndn/multicast/NTORRENT/test/file0"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700655 n3.appendSequenceNumber(2);
656
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700657 Name n4(Name("/ndn/multicast/NTORRENT/test/file0"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700658 n4.appendSequenceNumber(3);
659
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700660 Name n5(Name("/ndn/multicast/NTORRENT/test/file0"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700661 n5.appendSequenceNumber(4);
662
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700663 Name n6(Name("/ndn/multicast/NTORRENT/test1/file0"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700664 n6.appendSequenceNumber(0);
665
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700666 Name n7(Name("/ndn/multicast/NTORRENT/test1/file0"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700667 n7.appendSequenceNumber(1);
668
669 // In theory, this may not be correct, but here let's suck it up for the sake
670 // of testing the function correctness
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700671 Name n8(Name("/ndn/multicast/NTORRENT/test1/file2"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700672 n8.appendSequenceNumber(0);
673
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700674 Name n9(Name("/ndn/multicast/NTORRENT/test1/file2"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700675 n9.appendSequenceNumber(1);
676
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700677 FileManifest f1(n1, 50, Name("/ndn/multicast/NTORRENT/test"), {}, make_shared<Name>(n2));
spirosmastorakis50642f82016-04-08 12:11:18 -0700678 manager.pushFileManifestSegment(f1);
679
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700680 FileManifest f2(n2, 50, Name("/ndn/multicast/NTORRENT/test"), {}, make_shared<Name>(n3));
spirosmastorakis50642f82016-04-08 12:11:18 -0700681 manager.pushFileManifestSegment(f2);
682
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700683 FileManifest f3(n3, 50, Name("/ndn/multicast/NTORRENT/test"), {}, make_shared<Name>(n4));
spirosmastorakis50642f82016-04-08 12:11:18 -0700684 manager.pushFileManifestSegment(f3);
685
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700686 FileManifest f4(n4, 50, Name("/ndn/multicast/NTORRENT/test"), {}, make_shared<Name>(n5));
spirosmastorakis50642f82016-04-08 12:11:18 -0700687 manager.pushFileManifestSegment(f4);
688
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700689 FileManifest f5(n6, 50, Name("/ndn/multicast/NTORRENT/test2"), {}, make_shared<Name>(n7));
spirosmastorakis50642f82016-04-08 12:11:18 -0700690 manager.pushFileManifestSegment(f5);
691
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700692 FileManifest f6(n7, 50, Name("/ndn/multicast/NTORRENT/test2"), {}, {});
spirosmastorakis50642f82016-04-08 12:11:18 -0700693 manager.pushFileManifestSegment(f6);
694
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700695 FileManifest f7(n8, 50, Name("/ndn/multicast/NTORRENT/test3"), {}, make_shared<Name>(n9));
spirosmastorakis50642f82016-04-08 12:11:18 -0700696 manager.pushFileManifestSegment(f7);
697
698 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n2.toUri() + "/sha256digest"))->toUri(), n5.toUri());
699 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n8.toUri() + "/sha256digest"))->toUri(), n9.toUri());
700 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(Name(n5.toUri() + "/sha256digest"))->toUri(),
701 Name(n5.toUri() + "/sha256digest").toUri());
702 BOOST_CHECK(!(manager.findManifestSegmentToDownload(Name(n7.toUri() + "/sha256digest"))));
703
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700704 Name n10(Name("/ndn/multicast/NTORRENT/test1/file1"));
spirosmastorakis50642f82016-04-08 12:11:18 -0700705 n10.appendSequenceNumber(1);
706 n10 = Name(n10.toUri() + "/sha256digest");
707
708 BOOST_CHECK_EQUAL(manager.findManifestSegmentToDownload(n10)->toUri(), n10.toUri());
spirosmastorakis50642f82016-04-08 12:11:18 -0700709}
710
711BOOST_AUTO_TEST_CASE(TestFindManifestSegmentToDownload2)
712{
713 vector<FileManifest> manifests;
714 vector<TorrentFile> torrentSegments;
715 // for each file, the data packets
716 std::vector<vector<Data>> fileData;
717 std::string filePath = "tests/testdata/temp";
718 // get torrent files and manifests
719 {
720 auto temp = TorrentFile::generate("tests/testdata/foo",
721 1024,
722 2048,
723 8192,
724 true);
725 torrentSegments = temp.first;
726 auto temp1 = temp.second;
727 for (const auto& ms : temp1) {
728 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
729 fileData.push_back(ms.second);
730 }
731 }
732 // write the torrent segments and manifests to disk
733 std::string dirPath = ".appdata/foo/";
734 boost::filesystem::create_directories(dirPath);
735 std::string torrentPath = dirPath + "torrent_files/";
736 boost::filesystem::create_directories(torrentPath);
737 auto fileNum = 0;
738 for (const auto& t : torrentSegments) {
739 fileNum++;
740 auto filename = torrentPath + to_string(fileNum);
741 io::save(t, filename);
742 }
743
744 auto manifestPath = dirPath + "manifests/";
745 boost::filesystem::create_directory(manifestPath);
746 for (const auto& m : manifests) {
747 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
748 boost::filesystem::create_directory(filename.parent_path());
749 io::save(m, filename.string());
750 }
751 // Initialize manager
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700752 TestTorrentManager manager("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=6114e56874fc01bf8f9c40fa652741a895eb922372f1baf039ccea64dacd2152",
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700753 filePath,
754 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700755
spirosmastorakis50642f82016-04-08 12:11:18 -0700756 manager.Initialize();
757
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700758 advanceClocks(time::milliseconds(1), 10);
759 manager.sendRoutablePrefixResponse();
760
spirosmastorakis50642f82016-04-08 12:11:18 -0700761 // Set the file state
762 std::vector<bool> v1 = {true};
763 manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
764
765 std::vector<bool> v2 = {false, true, true, false, false, false};
766 manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
767
768 std::vector<bool> v3 = {true, false, false, false, false, false};
769 manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
770
771 manager.download_file_manifest(manifests[0].getFullName(), filePath + "manifests",
772 [&manifests](const std::vector<ndn::Name>& vec) {
773 BOOST_CHECK_EQUAL(vec.size(), 0);
774 },
775 [](const ndn::Name& name, const std::string& reason) {
776 BOOST_FAIL("Unexpected failure");
777 });
778
779 manager.download_file_manifest(manifests[1].getFullName(), filePath + "manifests",
780 [&manifests](const std::vector<ndn::Name>& vec) {
781 BOOST_CHECK_EQUAL(vec[0].toUri(),
782 manifests[1].catalog()[0].toUri());
783 BOOST_CHECK_EQUAL(vec[1].toUri(),
784 manifests[1].catalog()[3].toUri());
785 BOOST_CHECK_EQUAL(vec[2].toUri(),
786 manifests[1].catalog()[4].toUri());
787 BOOST_CHECK_EQUAL(vec[3].toUri(),
788 manifests[1].catalog()[5].toUri());
789 },
790 [](const ndn::Name& name, const std::string& reason) {
791 BOOST_FAIL("Unexpected failure");
792 });
793
794 manager.download_file_manifest(manifests[2].getFullName(), filePath + "manifests",
795 [&manifests](const std::vector<ndn::Name>& vec) {
796 BOOST_CHECK_EQUAL(vec[0].toUri(),
797 manifests[2].catalog()[1].toUri());
798 BOOST_CHECK_EQUAL(vec[1].toUri(),
799 manifests[2].catalog()[2].toUri());
800 BOOST_CHECK_EQUAL(vec[2].toUri(),
801 manifests[2].catalog()[3].toUri());
802 BOOST_CHECK_EQUAL(vec[3].toUri(),
803 manifests[2].catalog()[4].toUri());
804 BOOST_CHECK_EQUAL(vec[4].toUri(),
805 manifests[2].catalog()[5].toUri());
806 },
807 [](const ndn::Name& name, const std::string& reason) {
808 BOOST_FAIL("Unexpected failure");
809 });
810 fs::remove_all(filePath);
811 fs::remove_all(".appdata");
812}
813
814BOOST_AUTO_TEST_CASE(TestDataAlreadyDownloaded)
815{
816 vector<FileManifest> manifests;
817 vector<TorrentFile> torrentSegments;
818 // for each file, the data packets
819 std::vector<vector<Data>> fileData;
820 std::string filePath = "tests/testdata/temp";
821 // get torrent files and manifests
822 {
823 auto temp = TorrentFile::generate("tests/testdata/foo",
824 1024,
825 2048,
826 8192,
827 true);
828 torrentSegments = temp.first;
829 auto temp1 = temp.second;
830 for (const auto& ms : temp1) {
831 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
832 fileData.push_back(ms.second);
833 }
834 }
835 // write the torrent segments and manifests to disk
836 std::string dirPath = ".appdata/foo/";
837 boost::filesystem::create_directories(dirPath);
838 std::string torrentPath = dirPath + "torrent_files/";
839 boost::filesystem::create_directories(torrentPath);
840 auto fileNum = 0;
841 for (const auto& t : torrentSegments) {
842 fileNum++;
843 auto filename = torrentPath + to_string(fileNum);
844 io::save(t, filename);
845 }
846
847 auto manifestPath = dirPath + "manifests/";
848 boost::filesystem::create_directory(manifestPath);
849 for (const auto& m : manifests) {
850 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
851 boost::filesystem::create_directory(filename.parent_path());
852 io::save(m, filename.string());
853 }
854 // Initialize manager
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700855 TestTorrentManager manager("/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=6114e56874fc01bf8f9c40fa652741a895eb922372f1baf039ccea64dacd2152",
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700856 filePath,
857 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700858
spirosmastorakis50642f82016-04-08 12:11:18 -0700859 manager.Initialize();
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700860 BOOST_CHECK(manager.hasAllTorrentSegments());
spirosmastorakis50642f82016-04-08 12:11:18 -0700861
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700862 advanceClocks(time::milliseconds(1), 10);
863 manager.sendRoutablePrefixResponse();
864
spirosmastorakis50642f82016-04-08 12:11:18 -0700865 // Set the file state
866 std::vector<bool> v1 = {true};
867 manager.setFileState(manifests[0].getFullName(), make_shared<fs::fstream>(), v1);
868
869 std::vector<bool> v2 = {false, true, true, false, false, false};
870 manager.setFileState(manifests[1].getFullName(), make_shared<fs::fstream>(), v2);
871
872 std::vector<bool> v3 = {true, false, false, false, false, false};
873 manager.setFileState(manifests[2].getFullName(), make_shared<fs::fstream>(), v3);
874
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700875 Name p1("/ndn/multicast/NTORRENT/foo/bar1.txt");
spirosmastorakis50642f82016-04-08 12:11:18 -0700876 p1.appendSequenceNumber(0);
877 p1.appendSequenceNumber(0);
878 p1 = Name(p1.toUri() + "/sha256digest");
879
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700880 BOOST_CHECK(!(manager.hasDataPacket(p1)));
spirosmastorakis50642f82016-04-08 12:11:18 -0700881
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700882 Name p2("/ndn/multicast/NTORRENT/foo/bar.txt");
spirosmastorakis50642f82016-04-08 12:11:18 -0700883 p2.appendSequenceNumber(0);
884 p2.appendSequenceNumber(0);
885 p2 = Name(p2.toUri() + "/sha256digest");
886
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700887 BOOST_CHECK(manager.hasDataPacket(p2));
spirosmastorakisa46eee42016-04-05 14:24:45 -0700888}
889
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700890BOOST_AUTO_TEST_CASE(CheckSeedComplete)
891{
892 const struct {
893 const char *d_directoryPath;
894 const char *d_initialSegmentName;
895 size_t d_namesPerSegment;
896 size_t d_subManifestSize;
897 size_t d_dataPacketSize;
898 } DATA [] = {
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700899 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
900 // {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128, 128, 128},
901 // {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=24ea5e5e3af6a548cc54c0d5b3573ecb18e247f1567a0d586c1d7c131b75181d", 1, 128, 128},
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700902 };
903 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
904 for (int i = 0; i < NUM_DATA; ++i) {
905 auto directoryPath = DATA[i].d_directoryPath;
906 Name initialSegmentName = DATA[i].d_initialSegmentName;
907 auto namesPerSegment = DATA[i].d_namesPerSegment;
908 auto dataPacketSize = DATA[i].d_dataPacketSize;
909 auto subManifestSize = DATA[i].d_subManifestSize;
Mickey Sweatt527b0492016-03-02 11:07:48 -0800910
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700911 vector<FileManifest> manifests;
912 vector<TorrentFile> torrentSegments;
913 std::string filePath = "tests/testdata/";
914 std::vector<vector<Data>> fileData;
915 // get torrent files and manifests
916 {
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700917 auto temp = TorrentFile::generate(directoryPath,
918 namesPerSegment,
919 subManifestSize,
920 dataPacketSize,
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700921 true);
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700922 torrentSegments = temp.first;
923 auto temp1 = temp.second;
924 for (const auto& ms : temp1) {
925 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
926 fileData.push_back(ms.second);
927 }
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700928 }
929 // write the torrent segments and manifests to disk
930 std::string dirPath = ".appdata/foo/";
931 boost::filesystem::create_directories(dirPath);
932 std::string torrentPath = dirPath + "torrent_files/";
933 boost::filesystem::create_directory(torrentPath);
934 auto fileNum = 0;
935 for (const auto& t : torrentSegments) {
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700936 fileNum++;
937 auto filename = torrentPath + to_string(fileNum);
938 io::save(t, filename);
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700939 }
940 auto manifestPath = dirPath + "manifests/";
941 boost::filesystem::create_directory(manifestPath);
942 for (const auto& m : manifests) {
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700943 fs::path filename = manifestPath + m.file_name() + "/" + to_string(m.submanifest_number());
944 boost::filesystem::create_directories(filename.parent_path());
945 io::save(m, filename.string());
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700946 }
947 // Initialize and verify
948 TestTorrentManager manager(initialSegmentName,
949 filePath,
950 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700951
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700952 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700953
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700954 advanceClocks(time::milliseconds(1), 10);
955 manager.sendRoutablePrefixResponse();
spirosmastorakis4ff8c872016-04-14 09:51:38 -0700956
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700957 size_t nData = 0;
958 BOOST_CHECK_EQUAL(0, face->sentData.size());
959 // request all the torrent segments
960 for (const auto& t : torrentSegments) {
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700961 Interest interest(t.getFullName(), time::milliseconds(50));
962 face->expressInterest(interest,
963 [&t](const Interest& i, const Data& d) {
964 TorrentFile t1(d.wireEncode());
965 BOOST_CHECK(t == d);
966 BOOST_CHECK(t1 == t);
967 },
968 bind([] {
969 BOOST_FAIL("Unexpected Nack");
970 }),
971 bind([] {
972 BOOST_FAIL("Unexpected timeout");
973 }));
974 advanceClocks(time::milliseconds(1), 40);
975 face->receive(interest);
Mickey Sweatt15dde2d2016-04-28 23:42:45 -0700976 manager.processEvents(time::milliseconds(-1));
Mickey Sweatte908a5c2016-04-08 14:10:45 -0700977 // check that one piece of data is sent, and it is what was expected
978 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
979 face->receive(face->sentData[nData - 1]);
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -0700980 }
981 // request all the file manifests
982 for (const auto& m : manifests) {
983 Interest interest(m.getFullName(), time::milliseconds(50));
984 face->expressInterest(interest,
985 [&m](const Interest& i, const Data& d) {
986 FileManifest m1(d.wireEncode());
987 BOOST_CHECK(m == d);
988 BOOST_CHECK(m1 == m);
989 },
990 bind([] {
991 BOOST_FAIL("Unexpected Nack");
992 }),
993 bind([] {
994 BOOST_FAIL("Unexpected timeout");
995 }));
996 advanceClocks(time::milliseconds(1), 40);
997 face->receive(interest);
998 manager.processEvents(time::milliseconds(-1));
999 // check that one piece of data is sent, and it is what was expected
1000 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
1001 face->receive(face->sentData[nData - 1]);
1002 }
1003 // request all the data packets
1004 for (const auto& file : fileData) {
1005 for (const auto& data : file) {
1006 Interest interest(data.getFullName(), time::milliseconds(50));
1007 face->expressInterest(interest,
1008 [&data](const Interest& i, const Data& d) {
1009 BOOST_CHECK(data == d);
1010 },
1011 bind([] {
1012 BOOST_FAIL("Unexpected Nack");
1013 }),
1014 bind([] {
1015 BOOST_FAIL("Unexpected timeout");
1016 }));
1017 advanceClocks(time::milliseconds(1), 40);
1018 face->receive(interest);
1019 manager.processEvents(time::milliseconds(-1));
1020 // check that one piece of data is sent, and it is what was expected
1021 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
1022 face->receive(face->sentData[nData - 1]);
1023 }
1024 }
1025 // clean up tests
1026 face->sentData.clear();
1027 fs::remove_all(".appdata");
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001028 }
1029}
Mickey Sweattafda1f12016-04-04 17:15:11 -07001030
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001031BOOST_AUTO_TEST_CASE(CheckSeedRandom)
Mickey Sweattafda1f12016-04-04 17:15:11 -07001032{
1033 vector<FileManifest> manifests;
1034 vector<TorrentFile> torrentSegments;
1035 // for each file, the data packets
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001036 std::vector<Data> data;
1037 std::string filePath = "tests/testdata/";
1038 std::string dirPath = ".appdata/foo/";
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -07001039 Name initialSegmentName = "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981";
Mickey Sweattafda1f12016-04-04 17:15:11 -07001040 // get torrent files and manifests
1041 {
1042 auto temp = TorrentFile::generate("tests/testdata/foo",
1043 1024,
1044 1024,
1045 1024,
1046 true);
1047 torrentSegments = temp.first;
1048 auto temp1 = temp.second;
1049 for (const auto& ms : temp1) {
1050 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001051 data.insert(data.end(), ms.second.begin(), ms.second.end());
Mickey Sweattafda1f12016-04-04 17:15:11 -07001052 }
1053 }
1054 // write the torrent segments and manifests to disk
Mickey Sweattafda1f12016-04-04 17:15:11 -07001055 boost::filesystem::create_directories(dirPath);
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001056 auto torrentPath = dirPath + "torrent_files/";
Mickey Sweattafda1f12016-04-04 17:15:11 -07001057 boost::filesystem::create_directories(torrentPath);
1058 auto fileNum = 0;
1059 for (const auto& t : torrentSegments) {
1060 fileNum++;
1061 auto filename = torrentPath + to_string(fileNum);
1062 io::save(t, filename);
1063 }
Mickey Sweattafda1f12016-04-04 17:15:11 -07001064 auto manifestPath = dirPath + "manifests/";
1065 boost::filesystem::create_directory(manifestPath);
1066 for (const auto& m : manifests) {
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001067 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
1068 boost::filesystem::create_directory(filename.parent_path());
1069 io::save(m, filename.string());
Mickey Sweattafda1f12016-04-04 17:15:11 -07001070 }
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001071
Mickey Sweattafda1f12016-04-04 17:15:11 -07001072 // Initialize manager
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001073 TestTorrentManager manager(initialSegmentName,
1074 filePath,
1075 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001076
Mickey Sweattafda1f12016-04-04 17:15:11 -07001077 manager.Initialize();
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001078
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001079 advanceClocks(time::milliseconds(1), 10);
1080 manager.sendRoutablePrefixResponse();
1081
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001082 // insert the other entities
1083 data.insert(data.end(), torrentSegments.begin(), torrentSegments.end());
1084 data.insert(data.end(), manifests.begin(), manifests.end());
1085
1086 std::random_shuffle(data.begin(), data.end());
1087 // request all the data packets
1088 auto nData = 0;
1089 for(const auto& d : data) {
1090 Interest interest(d.getFullName(), time::milliseconds(50));
1091 face->expressInterest(interest,
1092 [&d](const Interest& i, const Data& data) {
1093 BOOST_CHECK(data == d);
1094 },
1095 bind([] {
1096 BOOST_FAIL("Unexpected Nack");
1097 }),
1098 bind([] {
1099 BOOST_FAIL("Unexpected timeout");
1100 }));
1101 advanceClocks(time::milliseconds(1), 40);
1102 face->receive(interest);
Mickey Sweatt15dde2d2016-04-28 23:42:45 -07001103 manager.processEvents(time::milliseconds(-1));
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001104 // check that one piece of data is sent, and it is what was expected
1105 BOOST_CHECK_EQUAL(++nData, face->sentData.size());
1106 face->receive(face->sentData[nData - 1]);
Mickey Sweattafda1f12016-04-04 17:15:11 -07001107 }
Mickey Sweattafda1f12016-04-04 17:15:11 -07001108 fs::remove_all(".appdata");
1109}
1110
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001111BOOST_AUTO_TEST_SUITE_END()
1112
1113BOOST_FIXTURE_TEST_SUITE(CheckTorrentManagerUtilities, FaceFixture)
1114
1115BOOST_AUTO_TEST_CASE(CheckWriteDataComplete)
1116{
1117 const struct {
1118 const char *d_directoryPath;
1119 const char *d_initialSegmentName;
1120 size_t d_namesPerSegment;
1121 size_t d_subManifestSize;
1122 size_t d_dataPacketSize;
1123 } DATA [] = {
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -07001124 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
1125 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=5351d424c7893158da35707258635d885725be0aa34321cf2e557afc2b785a76", 128, 128, 128},
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001126 };
1127 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
1128 for (int i = 0; i < NUM_DATA; ++i) {
1129 auto directoryPath = DATA[i].d_directoryPath;
1130 Name initialSegmentName = DATA[i].d_initialSegmentName;
1131 auto namesPerSegment = DATA[i].d_namesPerSegment;
1132 auto dataPacketSize = DATA[i].d_dataPacketSize;
1133 auto subManifestSize = DATA[i].d_subManifestSize;
1134
1135 vector<TorrentFile> torrentSegments;
1136 vector<FileManifest> manifests;
1137 // for each file, the data packets
1138 std::vector<vector<Data>> fileData;
1139 std::string filePath = "tests/testdata/temp";
1140 // get torrent files and manifests
1141 {
1142 auto temp = TorrentFile::generate(directoryPath,
1143 namesPerSegment,
1144 subManifestSize,
1145 dataPacketSize,
1146 false);
1147 torrentSegments = temp.first;
1148 auto temp1 = temp.second;
1149 for (const auto& ms : temp1) {
1150 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
1151 fileData.push_back(ms.second);
1152 }
1153 }
1154 // write the torrent segments and manifests to disk
1155 std::string dirPath = ".appdata/foo/";
1156 boost::filesystem::create_directories(dirPath);
1157 std::string torrentPath = dirPath + "torrent_files/";
1158 boost::filesystem::create_directories(torrentPath);
1159 auto fileNum = 0;
1160 for (const auto& t : torrentSegments) {
1161 fileNum++;
1162 auto filename = torrentPath + to_string(fileNum);
1163 io::save(t, filename);
1164 }
1165 auto manifestPath = dirPath + "manifests/";
1166 boost::filesystem::create_directory(manifestPath);
1167 for (const auto& m : manifests) {
1168 fs::path filename = manifestPath + m.file_name() + to_string(m.submanifest_number());
1169 boost::filesystem::create_directory(filename.parent_path());
1170 io::save(m, filename.string());
1171 }
1172 // Initialize manager
1173 TestTorrentManager manager(initialSegmentName,
1174 filePath,
1175 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001176
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001177 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001178
1179 advanceClocks(time::milliseconds(1), 10);
1180 manager.sendRoutablePrefixResponse();
1181
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001182 // check that initially there is no data on disk
1183 for (auto m : manager.fileManifests()) {
1184 auto fileState = manager.fileState(m.getFullName());
1185 BOOST_CHECK(fileState.empty());
1186 }
1187 // write all data to disk (for each file manifest)
1188 auto manifest_it = manifests.begin();
1189 for (auto& data : fileData) {
1190 for (auto& d : data) {
1191 BOOST_CHECK(manager.writeData(d));
1192 }
1193 // check that the state is updated appropriately
1194 auto fileState = manager.fileState(manifest_it->getFullName());
1195 for (auto s : fileState) {
1196 BOOST_CHECK(s);
1197 }
1198 ++manifest_it;
1199 }
1200 // get the file names (ascending)
1201 std::set<std::string> fileNames;
1202 for (auto i = fs::recursive_directory_iterator(filePath + "/foo");
1203 i != fs::recursive_directory_iterator();
1204 ++i) {
1205 fileNames.insert(i->path().string());
1206 }
1207 // verify file by file that the data packets are written correctly
1208 auto f_it = fileData.begin();
1209 for (auto f : fileNames) {
1210 // read file from disk
1211 std::vector<uint8_t> file_bytes;
1212 fs::ifstream is(f, fs::ifstream::binary | fs::ifstream::in);
1213 is >> std::noskipws;
1214 std::istream_iterator<uint8_t> start(is), end;
1215 file_bytes.insert(file_bytes.end(), start, end);
1216 std::vector<uint8_t> data_bytes;
1217 // get content from data packets
1218 for (const auto& d : *f_it) {
1219 auto content = d.getContent();
1220 data_bytes.insert(data_bytes.end(), content.value_begin(), content.value_end());
1221 }
1222 BOOST_CHECK(data_bytes == file_bytes);
1223 ++f_it;
1224 }
1225 fs::remove_all(filePath);
1226 fs::remove_all(".appdata");
1227 }
1228}
1229
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001230BOOST_AUTO_TEST_CASE(CheckWriteTorrentComplete)
1231{
1232 const struct {
1233 const char *d_directoryPath;
1234 const char *d_initialSegmentName;
1235 size_t d_namesPerSegment;
1236 size_t d_subManifestSize;
1237 size_t d_dataPacketSize;
1238 } DATA [] = {
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -07001239 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
1240 // {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=96d900d6788465f9a7b00191581b004c910d74b3762d141ec0e82173731bc9f4", 1, 1, 1024},
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001241 };
1242 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
1243 for (int i = 0; i < NUM_DATA; ++i) {
1244 auto directoryPath = DATA[i].d_directoryPath;
1245 Name initialSegmentName = DATA[i].d_initialSegmentName;
1246 auto namesPerSegment = DATA[i].d_namesPerSegment;
1247 auto dataPacketSize = DATA[i].d_dataPacketSize;
1248 auto subManifestSize = DATA[i].d_subManifestSize;
1249
1250 vector<TorrentFile> torrentSegments;
1251 std::string filePath = "tests/testdata/temp";
1252 // get torrent files
1253 {
1254 auto temp = TorrentFile::generate(directoryPath,
1255 namesPerSegment,
1256 subManifestSize,
1257 dataPacketSize,
1258 false);
1259 torrentSegments = temp.first;
1260 }
1261 // Initialize manager
1262 TestTorrentManager manager(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001263 filePath,
1264 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001265
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001266 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001267
1268 advanceClocks(time::milliseconds(1), 10);
1269 manager.sendRoutablePrefixResponse();
1270
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001271 std::string dirPath = ".appdata/foo/";
1272 std::string torrentPath = dirPath + "torrent_files/";
1273 BOOST_CHECK(manager.torrentSegments().empty());
1274 for (const auto& t : torrentSegments) {
1275 BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
1276 }
1277 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
1278 // check that initializing a new manager also gets all the torrent torrentSegments
1279 TestTorrentManager manager2(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001280 filePath,
1281 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001282
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001283 manager2.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001284
1285 advanceClocks(time::milliseconds(1), 10);
1286 manager2.sendRoutablePrefixResponse();
1287
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001288 BOOST_CHECK(manager2.torrentSegments() == torrentSegments);
1289
1290 // start anew
1291 fs::remove_all(torrentPath);
1292 fs::create_directories(torrentPath);
1293 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001294
1295 advanceClocks(time::milliseconds(1), 10);
1296 manager.sendRoutablePrefixResponse();
1297
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001298 BOOST_CHECK(manager.torrentSegments().empty());
1299
1300 // check that there is no dependence on the order of torrent segments
1301 // randomize the order of the torrent segments
1302 auto torrentSegmentsRandom = torrentSegments;
1303 std::random_shuffle(torrentSegmentsRandom.begin(), torrentSegmentsRandom.end());
1304 for (const auto& t : torrentSegmentsRandom) {
1305 BOOST_CHECK(manager.writeTorrentSegment(t, torrentPath));
1306 }
1307 BOOST_CHECK(manager.torrentSegments() == torrentSegments);
1308 fs::remove_all(".appdata");
1309 }
1310}
1311
1312BOOST_AUTO_TEST_CASE(CheckWriteManifestComplete)
1313{
1314 std::string dirPath = ".appdata/foo/";
1315 std::string torrentPath = dirPath + "torrent_files/";
1316 std::string manifestPath = dirPath + "manifests/";
1317
1318 const struct {
1319 const char *d_directoryPath;
1320 const char *d_initialSegmentName;
1321 size_t d_namesPerSegment;
1322 size_t d_subManifestSize;
1323 size_t d_dataPacketSize;
1324 } DATA [] = {
Mickey Sweatt0dc0a1e2016-05-04 11:25:49 -07001325 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 1024, 1024, 1024},
1326 {"tests/testdata/foo", "/ndn/multicast/NTORRENT/foo/torrent-file/sha256digest=9e0410fa477309b40a4ef9cb2bebe70ed2e9fa2defcb584979d768b3f6ced981", 128, 128, 1024},
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001327 };
1328 enum { NUM_DATA = sizeof DATA / sizeof *DATA };
1329 for (int i = 0; i < NUM_DATA; ++i) {
1330 auto directoryPath = DATA[i].d_directoryPath;
1331 Name initialSegmentName = DATA[i].d_initialSegmentName;
1332 auto namesPerSegment = DATA[i].d_namesPerSegment;
1333 auto dataPacketSize = DATA[i].d_dataPacketSize;
1334 auto subManifestSize = DATA[i].d_subManifestSize;
1335
1336 vector<FileManifest> manifests;
1337 vector<TorrentFile> torrentSegments;
1338
1339 std::string filePath = "tests/testdata/temp";
1340 // get torrent files and manifests
1341 {
1342 auto temp = TorrentFile::generate(directoryPath,
1343 namesPerSegment,
1344 subManifestSize,
1345 dataPacketSize,
1346 false);
1347 torrentSegments = temp.first;
1348 auto temp1 = temp.second;
1349 for (const auto& ms : temp1) {
1350 manifests.insert(manifests.end(), ms.first.begin(), ms.first.end());
1351 }
1352 }
1353 TestTorrentManager manager(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001354 filePath,
1355 face);
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001356
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001357 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001358
1359 advanceClocks(time::milliseconds(1), 10);
1360 manager.sendRoutablePrefixResponse();
1361
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001362 for (const auto& t : torrentSegments) {
1363 manager.writeTorrentSegment(t, torrentPath);
1364 }
1365
1366 BOOST_CHECK(manager.fileManifests().empty());
1367 for (const auto& m : manifests) {
1368 BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
1369 }
1370 BOOST_CHECK(manager.fileManifests() == manifests);
1371
1372 TestTorrentManager manager2(initialSegmentName,
Mickey Sweatte908a5c2016-04-08 14:10:45 -07001373 filePath,
1374 face);
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001375
1376 manager2.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001377
1378 advanceClocks(time::milliseconds(1), 10);
1379 manager2.sendRoutablePrefixResponse();
1380
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001381 BOOST_CHECK(manager2.fileManifests() == manifests);
1382
1383 // start anew
1384 fs::remove_all(manifestPath);
1385 fs::create_directories(manifestPath);
1386 manager.Initialize();
spirosmastorakis4ff8c872016-04-14 09:51:38 -07001387
1388 advanceClocks(time::milliseconds(1), 10);
1389 manager.sendRoutablePrefixResponse();
1390
Mickey Sweatt599bfef2016-04-05 19:11:20 -07001391 BOOST_CHECK(manager.fileManifests().empty());
1392
1393 // check that there is no dependence on the order of torrent segments
1394 // randomize the order of the torrent segments
1395 auto fileManifestsRandom = manifests;
1396 std::random_shuffle(fileManifestsRandom.begin(), fileManifestsRandom.end());
1397 for (const auto& m : fileManifestsRandom) {
1398 BOOST_CHECK(manager.writeFileManifest(m, manifestPath));
1399 }
1400 BOOST_CHECK(manager2.fileManifests() == manifests);
1401 fs::remove_all(".appdata");
1402 }
1403}
1404
spirosmastorakisa46eee42016-04-05 14:24:45 -07001405BOOST_AUTO_TEST_SUITE_END()
Mickey Sweattafda1f12016-04-04 17:15:11 -07001406
Mickey Sweatt527b0492016-03-02 11:07:48 -08001407} // namespace tests
1408} // namespace nTorrent
spirosmastorakisa46eee42016-04-05 14:24:45 -07001409} // namespace ndn