forked from premiere/premiere-libtorrent
parent
0a3cb77d23
commit
e72f95e0d9
|
@ -2843,11 +2843,11 @@ namespace libtorrent
|
||||||
, std::bind(&peer_connection::on_disk_write_complete
|
, std::bind(&peer_connection::on_disk_write_complete
|
||||||
, self(), _1, p, t));
|
, self(), _1, p, t));
|
||||||
|
|
||||||
std::uint64_t write_queue_size = m_counters.inc_stats_counter(
|
std::uint64_t const write_queue_size = m_counters.inc_stats_counter(
|
||||||
counters::queued_write_bytes, p.length);
|
counters::queued_write_bytes, p.length);
|
||||||
m_outstanding_writing_bytes += p.length;
|
m_outstanding_writing_bytes += p.length;
|
||||||
|
|
||||||
std::uint64_t max_queue_size = m_settings.get_int(
|
std::uint64_t const max_queue_size = m_settings.get_int(
|
||||||
settings_pack::max_queued_disk_bytes);
|
settings_pack::max_queued_disk_bytes);
|
||||||
if (write_queue_size > max_queue_size
|
if (write_queue_size > max_queue_size
|
||||||
&& write_queue_size - p.length < max_queue_size
|
&& write_queue_size - p.length < max_queue_size
|
||||||
|
@ -3033,13 +3033,6 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(p.start == j->d.io.offset);
|
TORRENT_ASSERT(p.start == j->d.io.offset);
|
||||||
TORRENT_ASSERT(picker.num_peers(block_finished) == 0);
|
TORRENT_ASSERT(picker.num_peers(block_finished) == 0);
|
||||||
|
|
||||||
if (j->ret == -1
|
|
||||||
&& j->error.ec == boost::system::errc::operation_canceled)
|
|
||||||
{
|
|
||||||
picker.mark_as_canceled(block_finished, peer_info_struct());
|
|
||||||
TORRENT_ASSERT_FAIL(); // how do we get here?
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// std::fprintf(stderr, "peer_connection mark_as_finished peer: %p piece: %d block: %d\n"
|
// std::fprintf(stderr, "peer_connection mark_as_finished peer: %p piece: %d block: %d\n"
|
||||||
// , peer_info_struct(), block_finished.piece_index, block_finished.block_index);
|
// , peer_info_struct(), block_finished.piece_index, block_finished.block_index);
|
||||||
picker.mark_as_finished(block_finished, peer_info_struct());
|
picker.mark_as_finished(block_finished, peer_info_struct());
|
||||||
|
|
|
@ -1288,6 +1288,8 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: 3 there's some duplication between this function and
|
||||||
|
// peer_connection::incoming_piece(). is there a way to merge something?
|
||||||
void torrent::add_piece(int piece, char const* data, int flags)
|
void torrent::add_piece(int piece, char const* data, int flags)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_single_thread());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
|
@ -1333,14 +1335,28 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inc_refcount("add_piece");
|
inc_refcount("add_piece");
|
||||||
|
m_stats_counters.inc_stats_counter(counters::queued_write_bytes, p.length);
|
||||||
m_ses.disk_thread().async_write(&storage(), p, std::move(buffer)
|
m_ses.disk_thread().async_write(&storage(), p, std::move(buffer)
|
||||||
, std::bind(&torrent::on_disk_write_complete
|
, std::bind(&torrent::on_disk_write_complete
|
||||||
, shared_from_this(), _1, p));
|
, shared_from_this(), _1, p));
|
||||||
|
|
||||||
piece_block block(piece, i);
|
piece_block block(piece, i);
|
||||||
|
bool const was_finished = picker().is_piece_finished(p.piece);
|
||||||
|
bool const multi = picker().num_peers(block) > 1;
|
||||||
|
|
||||||
picker().mark_as_downloading(block, nullptr);
|
picker().mark_as_downloading(block, nullptr);
|
||||||
picker().mark_as_writing(block, nullptr);
|
picker().mark_as_writing(block, nullptr);
|
||||||
|
|
||||||
|
if (multi) cancel_block(block);
|
||||||
|
|
||||||
|
// did we just finish the piece?
|
||||||
|
// this means all blocks are either written
|
||||||
|
// to disk or are in the disk write cache
|
||||||
|
if (picker().is_piece_finished(p.piece) && !was_finished)
|
||||||
|
{
|
||||||
|
verify_piece(p.piece);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
verify_piece(piece);
|
|
||||||
picker().dec_refcount(piece, nullptr);
|
picker().dec_refcount(piece, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1363,16 +1379,13 @@ namespace libtorrent
|
||||||
|
|
||||||
schedule_storage_tick();
|
schedule_storage_tick();
|
||||||
|
|
||||||
|
m_stats_counters.inc_stats_counter(counters::queued_write_bytes, -p.length);
|
||||||
|
|
||||||
// std::fprintf(stderr, "torrent::on_disk_write_complete ret:%d piece:%d block:%d\n"
|
// std::fprintf(stderr, "torrent::on_disk_write_complete ret:%d piece:%d block:%d\n"
|
||||||
// , j->ret, j->piece, j->offset/0x4000);
|
// , j->ret, j->piece, j->offset/0x4000);
|
||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
if (m_abort) return;
|
||||||
if (m_abort)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
piece_block block_finished(p.piece, p.start / block_size());
|
piece_block block_finished(p.piece, p.start / block_size());
|
||||||
|
|
||||||
if (j->ret == -1)
|
if (j->ret == -1)
|
||||||
|
@ -1390,6 +1403,13 @@ namespace libtorrent
|
||||||
|
|
||||||
picker().mark_as_finished(block_finished, nullptr);
|
picker().mark_as_finished(block_finished, nullptr);
|
||||||
maybe_done_flushing();
|
maybe_done_flushing();
|
||||||
|
|
||||||
|
if (alerts().should_post<block_finished_alert>())
|
||||||
|
{
|
||||||
|
alerts().emplace_alert<block_finished_alert>(get_handle(),
|
||||||
|
tcp::endpoint(), peer_id(), int(block_finished.block_index)
|
||||||
|
, int(block_finished.piece_index));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::on_disk_tick_done(disk_io_job const* j)
|
void torrent::on_disk_tick_done(disk_io_job const* j)
|
||||||
|
@ -10552,7 +10572,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// verify piece is used when checking resume data or when the user
|
// verify piece is used when checking resume data or when the user
|
||||||
// adds a piece
|
// adds a piece
|
||||||
void torrent::verify_piece(int piece)
|
void torrent::verify_piece(int const piece)
|
||||||
{
|
{
|
||||||
// picker().mark_as_checking(piece);
|
// picker().mark_as_checking(piece);
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ using namespace libtorrent;
|
||||||
// out, such as the log
|
// out, such as the log
|
||||||
int old_stdout = -1;
|
int old_stdout = -1;
|
||||||
int old_stderr = -1;
|
int old_stderr = -1;
|
||||||
bool redirect_output = false;
|
bool redirect_output = true;
|
||||||
bool keep_files = false;
|
bool keep_files = false;
|
||||||
|
|
||||||
extern int _g_test_idx;
|
extern int _g_test_idx;
|
||||||
|
|
|
@ -33,6 +33,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <tuple>
|
||||||
|
#include <functional>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
#include "libtorrent/hasher.hpp"
|
#include "libtorrent/hasher.hpp"
|
||||||
|
@ -50,8 +53,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/broadcast_socket.hpp" // for supports_ipv6()
|
#include "libtorrent/broadcast_socket.hpp" // for supports_ipv6()
|
||||||
#include "libtorrent/hex.hpp" // to_hex
|
#include "libtorrent/hex.hpp" // to_hex
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <functional>
|
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
|
@ -604,6 +605,64 @@ boost::shared_ptr<T> clone_ptr(boost::shared_ptr<T> const& ptr)
|
||||||
unsigned char random_byte()
|
unsigned char random_byte()
|
||||||
{ return lt::random() & 0xff; }
|
{ return lt::random() & 0xff; }
|
||||||
|
|
||||||
|
std::vector<char> generate_piece(int const idx, int const piece_size)
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
std::vector<char> ret(piece_size);
|
||||||
|
|
||||||
|
std::mt19937 rng(idx);
|
||||||
|
std::uniform_int_distribution<int> rand(-128, 127);
|
||||||
|
for (char& c : ret)
|
||||||
|
{
|
||||||
|
c = static_cast<char>(rand(rng));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
lt::file_storage make_file_storage(const int file_sizes[], int num_files
|
||||||
|
, int const piece_size, std::string base_name)
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
file_storage fs;
|
||||||
|
for (int i = 0; i != num_files; ++i)
|
||||||
|
{
|
||||||
|
char filename[200];
|
||||||
|
std::snprintf(filename, sizeof(filename), "test%d", i);
|
||||||
|
char dirname[200];
|
||||||
|
std::snprintf(dirname, sizeof(dirname), "%s%d", base_name.c_str()
|
||||||
|
, i / 5);
|
||||||
|
std::string full_path = combine_path(dirname, filename);
|
||||||
|
|
||||||
|
fs.add_file(full_path, file_sizes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.set_piece_length(piece_size);
|
||||||
|
fs.set_num_pieces(int((fs.total_size() + piece_size - 1) / piece_size));
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<lt::torrent_info> make_torrent(const int file_sizes[]
|
||||||
|
, int const num_files, int const piece_size)
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
file_storage fs = make_file_storage(file_sizes, num_files, piece_size);
|
||||||
|
|
||||||
|
libtorrent::create_torrent ct(fs, piece_size, 0x4000
|
||||||
|
, libtorrent::create_torrent::optimize_alignment);
|
||||||
|
|
||||||
|
for (int i = 0; i < fs.num_pieces(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<char> const piece = generate_piece(i, fs.piece_size(i));
|
||||||
|
ct.set_hash(i, hasher(piece.data(), int(piece.size())).final());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> buf;
|
||||||
|
bencode(std::back_inserter(buf), ct.generate());
|
||||||
|
error_code ec;
|
||||||
|
return boost::make_shared<torrent_info>(&buf[0], int(buf.size()), ec);
|
||||||
|
}
|
||||||
|
|
||||||
void create_random_files(std::string const& path, const int file_sizes[], int num_files)
|
void create_random_files(std::string const& path, const int file_sizes[], int num_files)
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
|
|
|
@ -81,7 +81,13 @@ EXPORT bool print_alerts(libtorrent::session& ses, char const* name
|
||||||
EXPORT void wait_for_listen(libtorrent::session& ses, char const* name);
|
EXPORT void wait_for_listen(libtorrent::session& ses, char const* name);
|
||||||
EXPORT void wait_for_downloading(libtorrent::session& ses, char const* name);
|
EXPORT void wait_for_downloading(libtorrent::session& ses, char const* name);
|
||||||
|
|
||||||
EXPORT void create_random_files(std::string const& path, const int file_sizes[], int num_files);
|
EXPORT std::vector<char> generate_piece(int idx, int const piece_size = 0x4000);
|
||||||
|
EXPORT libtorrent::file_storage make_file_storage(const int file_sizes[], int num_files
|
||||||
|
, int const piece_size, std::string base_name = "test_dir-");
|
||||||
|
EXPORT boost::shared_ptr<libtorrent::torrent_info> make_torrent(const int file_sizes[]
|
||||||
|
, int num_files, int piece_size);
|
||||||
|
EXPORT void create_random_files(std::string const& path, const int file_sizes[]
|
||||||
|
, int num_files);
|
||||||
|
|
||||||
EXPORT boost::shared_ptr<libtorrent::torrent_info> create_torrent(std::ostream* file = 0
|
EXPORT boost::shared_ptr<libtorrent::torrent_info> create_torrent(std::ostream* file = 0
|
||||||
, char const* name = "temporary", int piece_size = 16 * 1024, int num_pieces = 13
|
, char const* name = "temporary", int piece_size = 16 * 1024, int num_pieces = 13
|
||||||
|
|
|
@ -110,11 +110,11 @@ extern int EXPORT _g_test_failures;
|
||||||
#ifdef BOOST_NO_EXCEPTIONS
|
#ifdef BOOST_NO_EXCEPTIONS
|
||||||
#define TEST_CHECK(x) \
|
#define TEST_CHECK(x) \
|
||||||
if (!(x)) \
|
if (!(x)) \
|
||||||
TEST_REPORT_AUX("TEST_CHECK failed: \"" #x "\"", __FILE__, __LINE__);
|
TEST_REPORT_AUX("TEST_ERROR: check failed: \"" #x "\"", __FILE__, __LINE__);
|
||||||
#define TEST_EQUAL(x, y) \
|
#define TEST_EQUAL(x, y) \
|
||||||
if ((x) != (y)) { \
|
if ((x) != (y)) { \
|
||||||
std::stringstream s__; \
|
std::stringstream s__; \
|
||||||
s__ << "TEST_EQUAL_ERROR:\n" #x ": " << (x) << "\nexpected: " << (y); \
|
s__ << "TEST_ERROR: equal check failed:\n" #x ": " << (x) << "\nexpected: " << (y); \
|
||||||
TEST_REPORT_AUX(s__.str().c_str(), __FILE__, __LINE__); \
|
TEST_REPORT_AUX(s__.str().c_str(), __FILE__, __LINE__); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -122,37 +122,37 @@ extern int EXPORT _g_test_failures;
|
||||||
try \
|
try \
|
||||||
{ \
|
{ \
|
||||||
if (!(x)) \
|
if (!(x)) \
|
||||||
TEST_REPORT_AUX("TEST_CHECK failed: \"" #x "\"", __FILE__, __LINE__); \
|
TEST_REPORT_AUX("TEST_ERROR: check failed: \"" #x "\"", __FILE__, __LINE__); \
|
||||||
} \
|
} \
|
||||||
catch (std::exception& e) \
|
catch (std::exception& e) \
|
||||||
{ \
|
{ \
|
||||||
TEST_ERROR("Exception thrown: " #x " :" + std::string(e.what())); \
|
TEST_ERROR("TEST_ERROR: Exception thrown: " #x " :" + std::string(e.what())); \
|
||||||
} \
|
} \
|
||||||
catch (...) \
|
catch (...) \
|
||||||
{ \
|
{ \
|
||||||
TEST_ERROR("Exception thrown: " #x); \
|
TEST_ERROR("TEST_ERROR: Exception thrown: " #x); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_EQUAL(x, y) \
|
#define TEST_EQUAL(x, y) \
|
||||||
try { \
|
try { \
|
||||||
if ((x) != (y)) { \
|
if ((x) != (y)) { \
|
||||||
std::stringstream s__; \
|
std::stringstream s__; \
|
||||||
s__ << "TEST_EQUAL_ERROR: " #x ": " << (x) << " expected: " << (y); \
|
s__ << "TEST_ERROR: " #x ": " << (x) << " expected: " << (y); \
|
||||||
TEST_REPORT_AUX(s__.str().c_str(), __FILE__, __LINE__); \
|
TEST_REPORT_AUX(s__.str().c_str(), __FILE__, __LINE__); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
catch (std::exception& e) \
|
catch (std::exception& e) \
|
||||||
{ \
|
{ \
|
||||||
TEST_ERROR("Exception thrown: " #x " :" + std::string(e.what())); \
|
TEST_ERROR("TEST_ERROR: Exception thrown: " #x " :" + std::string(e.what())); \
|
||||||
} \
|
} \
|
||||||
catch (...) \
|
catch (...) \
|
||||||
{ \
|
{ \
|
||||||
TEST_ERROR("Exception thrown: " #x); \
|
TEST_ERROR("TEST_ERROR: Exception thrown: " #x); \
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define TEST_ERROR(x) \
|
#define TEST_ERROR(x) \
|
||||||
TEST_REPORT_AUX((std::string("ERROR: \"") + (x) + "\"").c_str(), __FILE__, __LINE__)
|
TEST_REPORT_AUX((std::string("TEST_ERROR: \"") + (x) + "\"").c_str(), __FILE__, __LINE__)
|
||||||
|
|
||||||
#define TEST_NOTHROW(x) \
|
#define TEST_NOTHROW(x) \
|
||||||
try \
|
try \
|
||||||
|
@ -161,7 +161,7 @@ extern int EXPORT _g_test_failures;
|
||||||
} \
|
} \
|
||||||
catch (...) \
|
catch (...) \
|
||||||
{ \
|
{ \
|
||||||
TEST_ERROR("Exception thrown: " #x); \
|
TEST_ERROR("TEST_ERROR: Exception thrown: " #x); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TEST_HPP
|
#endif // TEST_HPP
|
||||||
|
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "setup_transfer.hpp"
|
#include "setup_transfer.hpp"
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -46,514 +47,157 @@ using namespace libtorrent;
|
||||||
namespace lt = libtorrent;
|
namespace lt = libtorrent;
|
||||||
using std::ignore;
|
using std::ignore;
|
||||||
|
|
||||||
namespace {
|
bool all_of(std::vector<bool> const& v)
|
||||||
|
|
||||||
template <class T>
|
|
||||||
boost::shared_ptr<T> clone_ptr(boost::shared_ptr<T> const& ptr)
|
|
||||||
{
|
{
|
||||||
return boost::shared_ptr<T>(new T(*ptr));
|
return std::all_of(v.begin(), v.end(), [](bool v){ return v; });
|
||||||
}
|
}
|
||||||
|
|
||||||
int peer_disconnects = 0;
|
void test_remap_files(storage_mode_t storage_mode = storage_mode_sparse)
|
||||||
|
|
||||||
bool on_alert(alert const* a)
|
|
||||||
{
|
{
|
||||||
if (alert_cast<peer_disconnected_alert>(a))
|
using namespace libtorrent;
|
||||||
++peer_disconnects;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // anonymous namespace
|
|
||||||
|
|
||||||
void test_remap_files_gather(storage_mode_t storage_mode = storage_mode_sparse)
|
|
||||||
{
|
|
||||||
// in case the previous run was terminated
|
|
||||||
error_code ec;
|
|
||||||
|
|
||||||
int const alert_mask = alert::all_categories
|
|
||||||
& ~alert::progress_notification
|
|
||||||
& ~alert::stats_notification;
|
|
||||||
|
|
||||||
session_proxy p1;
|
|
||||||
session_proxy p2;
|
|
||||||
|
|
||||||
settings_pack sett;
|
|
||||||
sett.set_bool(settings_pack::enable_upnp, false);
|
|
||||||
sett.set_bool(settings_pack::enable_natpmp, false);
|
|
||||||
sett.set_bool(settings_pack::enable_lsd, false);
|
|
||||||
sett.set_bool(settings_pack::enable_dht, false);
|
|
||||||
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:48075");
|
|
||||||
sett.set_int(settings_pack::alert_mask, alert_mask);
|
|
||||||
|
|
||||||
lt::session ses1(sett);
|
|
||||||
|
|
||||||
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:49075");
|
|
||||||
lt::session ses2(sett);
|
|
||||||
|
|
||||||
torrent_handle tor1;
|
|
||||||
torrent_handle tor2;
|
|
||||||
|
|
||||||
create_directory("tmp1_remap", ec);
|
|
||||||
create_directory(combine_path("tmp1_remap", "test_torrent_dir"), ec);
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
std::fprintf(stderr, "error creating directory: %s\n"
|
|
||||||
, ec.message().c_str());
|
|
||||||
TEST_CHECK(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int file_sizes[] =
|
|
||||||
{ 50, 16000-50, 16000, 1700, 100, 8000, 8000, 1,1,10,10,10,1000,10,10,10,10,1000,10,10,10,1,1,1
|
|
||||||
,10,1000,1000,1000,10,1000,130,65000,340,750,20,300,400,5000,23000,900,43000,4000,43000,60, 40};
|
|
||||||
|
|
||||||
create_random_files(combine_path("tmp1_remap", "test_torrent_dir")
|
|
||||||
, file_sizes, sizeof(file_sizes)/sizeof(file_sizes[0]));
|
|
||||||
file_storage fs;
|
|
||||||
|
|
||||||
// generate a torrent with pad files to make sure they
|
|
||||||
// are not requested web seeds
|
|
||||||
add_files(fs, combine_path("tmp1_remap", "test_torrent_dir"));
|
|
||||||
libtorrent::create_torrent ct(fs, 0x8000, 0x4000);
|
|
||||||
set_piece_hashes(ct, "tmp1_remap", ec);
|
|
||||||
if (ec)
|
|
||||||
{
|
|
||||||
std::fprintf(stderr, "error creating hashes for test torrent: %s\n"
|
|
||||||
, ec.message().c_str());
|
|
||||||
TEST_CHECK(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::vector<char> buf;
|
|
||||||
bencode(std::back_inserter(buf), ct.generate());
|
|
||||||
boost::shared_ptr<torrent_info> t(new torrent_info(&buf[0], int(buf.size()), ec));
|
|
||||||
boost::shared_ptr<torrent_info> t2(new torrent_info(&buf[0], int(buf.size()), ec));
|
|
||||||
|
|
||||||
// remap the files to a single one
|
|
||||||
file_storage st;
|
|
||||||
st.add_file("single_file", t->total_size());
|
|
||||||
t2->remap_files(st);
|
|
||||||
|
|
||||||
add_torrent_params params;
|
|
||||||
params.storage_mode = storage_mode;
|
|
||||||
params.flags &= ~add_torrent_params::flag_paused;
|
|
||||||
params.flags &= ~add_torrent_params::flag_auto_managed;
|
|
||||||
|
|
||||||
wait_for_listen(ses1, "ses1");
|
|
||||||
wait_for_listen(ses2, "ses2");
|
|
||||||
|
|
||||||
peer_disconnects = 0;
|
|
||||||
|
|
||||||
// test using piece sizes smaller than 16kB
|
|
||||||
std::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, nullptr
|
|
||||||
, true, false, true, "_remap", 8 * 1024, &t, false, ¶ms
|
|
||||||
, true, false, &t2);
|
|
||||||
|
|
||||||
std::fprintf(stderr, "\ntesting remap gather\n\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < 100; ++i)
|
|
||||||
{
|
|
||||||
print_alerts(ses1, "ses1", true, true, true, &on_alert);
|
|
||||||
print_alerts(ses2, "ses2", true, true, true, &on_alert);
|
|
||||||
|
|
||||||
torrent_status st1 = tor1.status();
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
|
|
||||||
if (i % 10 == 0)
|
|
||||||
{
|
|
||||||
print_ses_rate(i / 10.f, &st1, &st2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st2.is_finished) break;
|
|
||||||
|
|
||||||
if (st2.state != torrent_status::downloading)
|
|
||||||
{
|
|
||||||
static char const* state_str[] =
|
|
||||||
{"checking (q)", "checking", "dl metadata"
|
|
||||||
, "downloading", "finished", "seeding", "allocating", "checking (r)"};
|
|
||||||
std::cerr << "st2 state: " << state_str[st2.state] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CHECK(st1.state == torrent_status::seeding
|
|
||||||
|| st1.state == torrent_status::checking_files);
|
|
||||||
TEST_CHECK(st2.state == torrent_status::downloading
|
|
||||||
|| st2.state == torrent_status::checking_resume_data);
|
|
||||||
|
|
||||||
if (peer_disconnects >= 2) break;
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(lt::milliseconds(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
TEST_CHECK(st2.is_seeding);
|
|
||||||
|
|
||||||
if (!st2.is_seeding) return;
|
|
||||||
|
|
||||||
std::fprintf(stderr, "\ntesting force recheck\n\n");
|
|
||||||
|
|
||||||
// test force rechecking a seeding torrent with remapped files
|
|
||||||
tor2.force_recheck();
|
|
||||||
|
|
||||||
for (int i = 0; i < 50; ++i)
|
|
||||||
{
|
|
||||||
print_alerts(ses2, "ses2", true, true, true, &on_alert);
|
|
||||||
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
|
|
||||||
if (i % 10 == 0)
|
|
||||||
{
|
|
||||||
print_ses_rate(i / 10.f, nullptr, &st2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st2.state != torrent_status::checking_files)
|
|
||||||
{
|
|
||||||
static char const* state_str[] =
|
|
||||||
{"checking (q)", "checking", "dl metadata"
|
|
||||||
, "downloading", "finished", "seeding", "allocating", "checking (r)"};
|
|
||||||
std::cerr << "st2 state: " << state_str[st2.state] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st2.progress == 1.0) break;
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(lt::milliseconds(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
st2 = tor2.status();
|
|
||||||
TEST_CHECK(st2.is_seeding);
|
|
||||||
|
|
||||||
p1 = ses1.abort();
|
|
||||||
p2 = ses2.abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_remap_files_scatter(storage_mode_t storage_mode = storage_mode_sparse)
|
|
||||||
{
|
|
||||||
int num_files = 10;
|
|
||||||
|
|
||||||
// in case the previous run was terminated
|
// in case the previous run was terminated
|
||||||
error_code ec;
|
error_code ec;
|
||||||
|
|
||||||
int const alert_mask = alert::all_categories
|
|
||||||
& ~alert::progress_notification
|
|
||||||
& ~alert::stats_notification;
|
|
||||||
|
|
||||||
session_proxy p1;
|
|
||||||
session_proxy p2;
|
|
||||||
|
|
||||||
settings_pack sett;
|
|
||||||
sett.set_bool(settings_pack::enable_upnp, false);
|
|
||||||
sett.set_bool(settings_pack::enable_natpmp, false);
|
|
||||||
sett.set_bool(settings_pack::enable_lsd, false);
|
|
||||||
sett.set_bool(settings_pack::enable_dht, false);
|
|
||||||
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:48075");
|
|
||||||
sett.set_int(settings_pack::alert_mask, alert_mask);
|
|
||||||
|
|
||||||
lt::session ses1(sett);
|
|
||||||
|
|
||||||
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:49075");
|
|
||||||
sett.set_int(settings_pack::alert_mask, alert_mask);
|
|
||||||
lt::session ses2(sett);
|
|
||||||
|
|
||||||
torrent_handle tor1;
|
|
||||||
torrent_handle tor2;
|
|
||||||
|
|
||||||
create_directory("tmp1_remap2", ec);
|
|
||||||
std::ofstream file("tmp1_remap2/temporary");
|
|
||||||
boost::shared_ptr<torrent_info> t = ::create_torrent(&file, "temporary", 32 * 1024, 7);
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
file_storage fs;
|
|
||||||
for (int i = 0; i < num_files-1; ++i)
|
|
||||||
{
|
|
||||||
char name[100];
|
|
||||||
std::snprintf(name, sizeof(name), "multifile/file%d.txt", i);
|
|
||||||
fs.add_file(name, t->total_size() / 10);
|
|
||||||
}
|
|
||||||
char name[100];
|
|
||||||
std::snprintf(name, sizeof(name), "multifile/file%d.txt", num_files);
|
|
||||||
// the last file has to be a special case to make the size
|
|
||||||
// add up exactly (in case the total size is not divisible by 10).
|
|
||||||
fs.add_file(name, t->total_size() - fs.total_size());
|
|
||||||
|
|
||||||
boost::shared_ptr<torrent_info> t2 = clone_ptr(t);
|
|
||||||
|
|
||||||
t2->remap_files(fs);
|
|
||||||
|
|
||||||
add_torrent_params params;
|
|
||||||
params.storage_mode = storage_mode;
|
|
||||||
params.flags &= ~add_torrent_params::flag_paused;
|
|
||||||
params.flags &= ~add_torrent_params::flag_auto_managed;
|
|
||||||
|
|
||||||
wait_for_listen(ses1, "ses1");
|
|
||||||
wait_for_listen(ses2, "ses2");
|
|
||||||
|
|
||||||
peer_disconnects = 0;
|
|
||||||
|
|
||||||
// test using piece sizes smaller than 16kB
|
|
||||||
std::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, nullptr
|
|
||||||
, true, false, true, "_remap2", 8 * 1024, &t, false, ¶ms
|
|
||||||
, true, false, &t2);
|
|
||||||
|
|
||||||
std::fprintf(stderr, "\ntesting remap scatter\n\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < 50; ++i)
|
|
||||||
{
|
|
||||||
print_alerts(ses1, "ses1", true, true, true, &on_alert);
|
|
||||||
print_alerts(ses2, "ses2", true, true, true, &on_alert);
|
|
||||||
|
|
||||||
torrent_status st1 = tor1.status();
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
|
|
||||||
if (i % 10 == 0)
|
|
||||||
{
|
|
||||||
print_ses_rate(i / 10.f, &st1, &st2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st2.is_finished) break;
|
|
||||||
|
|
||||||
if (st2.state != torrent_status::downloading)
|
|
||||||
{
|
|
||||||
static char const* state_str[] =
|
|
||||||
{"checking (q)", "checking", "dl metadata"
|
|
||||||
, "downloading", "finished", "seeding", "allocating", "checking (r)"};
|
|
||||||
std::cerr << "st2 state: " << state_str[st2.state] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CHECK(st1.state == torrent_status::seeding
|
|
||||||
|| st1.state == torrent_status::checking_files);
|
|
||||||
TEST_CHECK(st2.state == torrent_status::downloading
|
|
||||||
|| st2.state == torrent_status::checking_resume_data);
|
|
||||||
|
|
||||||
if (peer_disconnects >= 2) break;
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(lt::milliseconds(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
TEST_CHECK(st2.is_seeding);
|
|
||||||
|
|
||||||
if (!st2.is_seeding) return;
|
|
||||||
|
|
||||||
std::fprintf(stderr, "\ntesting force recheck\n\n");
|
|
||||||
|
|
||||||
// test force rechecking a seeding torrent with remapped files
|
|
||||||
tor2.force_recheck();
|
|
||||||
|
|
||||||
for (int i = 0; i < 50; ++i)
|
|
||||||
{
|
|
||||||
print_alerts(ses2, "ses2", true, true, true, &on_alert);
|
|
||||||
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
|
|
||||||
if (i % 10 == 0)
|
|
||||||
{
|
|
||||||
print_ses_rate(i / 10.f, nullptr, &st2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st2.state != torrent_status::checking_files)
|
|
||||||
{
|
|
||||||
static char const* state_str[] =
|
|
||||||
{"checking (q)", "checking", "dl metadata"
|
|
||||||
, "downloading", "finished", "seeding", "allocating", "checking (r)"};
|
|
||||||
std::cerr << "st2 state: " << state_str[st2.state] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st2.progress == 1.0) break;
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(lt::milliseconds(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
st2 = tor2.status();
|
|
||||||
TEST_CHECK(st2.is_seeding);
|
|
||||||
|
|
||||||
p1 = ses1.abort();
|
|
||||||
p2 = ses2.abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_remap_files_prio(storage_mode_t storage_mode = storage_mode_sparse)
|
|
||||||
{
|
|
||||||
// in case the previous run was terminated
|
|
||||||
error_code ec;
|
|
||||||
|
|
||||||
int const alert_mask = alert::all_categories
|
|
||||||
& ~alert::progress_notification
|
|
||||||
& ~alert::stats_notification;
|
|
||||||
|
|
||||||
session_proxy p1;
|
|
||||||
session_proxy p2;
|
|
||||||
|
|
||||||
settings_pack sett;
|
|
||||||
sett.set_bool(settings_pack::enable_upnp, false);
|
|
||||||
sett.set_bool(settings_pack::enable_natpmp, false);
|
|
||||||
sett.set_bool(settings_pack::enable_lsd, false);
|
|
||||||
sett.set_bool(settings_pack::enable_dht, false);
|
|
||||||
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:48075");
|
|
||||||
sett.set_int(settings_pack::alert_mask, alert_mask);
|
|
||||||
lt::session ses1(sett);
|
|
||||||
|
|
||||||
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:49075");
|
|
||||||
lt::session ses2(sett);
|
|
||||||
|
|
||||||
torrent_handle tor1;
|
|
||||||
torrent_handle tor2;
|
|
||||||
|
|
||||||
create_directory("tmp1_remap3", ec);
|
|
||||||
create_directory(combine_path("tmp1_remap3", "test_torrent_dir"), ec);
|
|
||||||
|
|
||||||
// create a torrent with 2 files, remap them into 3 files and make sure
|
// create a torrent with 2 files, remap them into 3 files and make sure
|
||||||
// the file priorities don't break things
|
// the file priorities don't break things
|
||||||
static const int file_sizes[] = {100000, 100000};
|
static const int file_sizes[] = {100000, 100000};
|
||||||
const int num_files = sizeof(file_sizes)/sizeof(file_sizes[0]);
|
const int num_files = 2;
|
||||||
|
const int piece_size = 0x8000;
|
||||||
|
auto t = make_torrent(file_sizes, num_files, piece_size);
|
||||||
|
|
||||||
create_random_files(combine_path("tmp1_remap3", "test_torrent_dir")
|
static const int remap_file_sizes[] = {10000, 10000, int(t->total_size() - 20000)};
|
||||||
, file_sizes, num_files);
|
int const num_new_files = 3;
|
||||||
|
|
||||||
file_storage fs1;
|
file_storage fs = make_file_storage(remap_file_sizes, num_new_files
|
||||||
const int piece_size = 0x4000;
|
, piece_size, "multifile-");
|
||||||
|
|
||||||
add_files(fs1, combine_path("tmp1_remap3", "test_torrent_dir"));
|
t->remap_files(fs);
|
||||||
libtorrent::create_torrent ct(fs1, piece_size, 0x4000
|
|
||||||
, libtorrent::create_torrent::optimize_alignment);
|
|
||||||
|
|
||||||
// calculate the hash for all pieces
|
int const alert_mask = alert::all_categories
|
||||||
set_piece_hashes(ct, "tmp1_remap3", ec);
|
& ~alert::stats_notification;
|
||||||
if (ec) std::fprintf(stderr, "ERROR: set_piece_hashes: (%d) %s\n"
|
|
||||||
, ec.value(), ec.message().c_str());
|
|
||||||
|
|
||||||
std::vector<char> buf;
|
session_proxy p1;
|
||||||
bencode(std::back_inserter(buf), ct.generate());
|
|
||||||
boost::shared_ptr<torrent_info> t(new torrent_info(&buf[0], int(buf.size()), ec));
|
|
||||||
|
|
||||||
int num_new_files = 3;
|
settings_pack sett = settings();
|
||||||
|
sett.set_int(settings_pack::alert_mask, alert_mask);
|
||||||
file_storage fs;
|
lt::session ses(sett);
|
||||||
for (int i = 0; i < num_new_files-1; ++i)
|
|
||||||
{
|
|
||||||
char name[100];
|
|
||||||
std::snprintf(name, sizeof(name), "multifile/file%d.txt", i);
|
|
||||||
fs.add_file(name, t->total_size() / 10);
|
|
||||||
}
|
|
||||||
char name[100];
|
|
||||||
std::snprintf(name, sizeof(name), "multifile/file%d.txt", num_new_files);
|
|
||||||
// the last file has to be a special case to make the size
|
|
||||||
// add up exactly (in case the total size is not divisible by 10).
|
|
||||||
fs.add_file(name, t->total_size() - fs.total_size());
|
|
||||||
|
|
||||||
boost::shared_ptr<torrent_info> t2 = clone_ptr(t);
|
|
||||||
|
|
||||||
t2->remap_files(fs);
|
|
||||||
|
|
||||||
add_torrent_params params;
|
add_torrent_params params;
|
||||||
|
params.save_path = ".";
|
||||||
params.storage_mode = storage_mode;
|
params.storage_mode = storage_mode;
|
||||||
params.flags |= add_torrent_params::flag_paused;
|
params.flags &= ~add_torrent_params::flag_paused;
|
||||||
params.flags &= ~add_torrent_params::flag_auto_managed;
|
params.flags &= ~add_torrent_params::flag_auto_managed;
|
||||||
|
params.ti = t;
|
||||||
|
|
||||||
wait_for_listen(ses1, "ses1");
|
torrent_handle tor1 = ses.add_torrent(params);
|
||||||
wait_for_listen(ses2, "ses2");
|
|
||||||
|
|
||||||
peer_disconnects = 0;
|
// write pieces
|
||||||
|
for (int i = 0; i < fs.num_pieces(); ++i)
|
||||||
|
{
|
||||||
|
std::vector<char> piece = generate_piece(i, fs.piece_size(i));
|
||||||
|
tor1.add_piece(i, piece.data());
|
||||||
|
}
|
||||||
|
|
||||||
// test using piece sizes smaller than 16kB
|
// read pieces
|
||||||
std::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, nullptr
|
for (int i = 0; i < fs.num_pieces(); ++i)
|
||||||
, true, false, true, "_remap3", 8 * 1024, &t, false, ¶ms
|
{
|
||||||
, true, false, &t2);
|
tor1.read_piece(i);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<int> file_prio(3, 1);
|
// wait for all alerts to come back and verify the data against the expected
|
||||||
file_prio[0] = 0;
|
// piece adata
|
||||||
tor2.prioritize_files(file_prio);
|
std::vector<bool> pieces(fs.num_pieces(), false);
|
||||||
|
std::vector<bool> passed(fs.num_pieces(), false);
|
||||||
|
std::vector<bool> files(fs.num_files(), false);
|
||||||
|
|
||||||
// torrent1 will attempt to connect to torrent2
|
while (!all_of(pieces) || !all_of(passed) || !all_of(files))
|
||||||
// make sure torrent2 is up and running by then
|
{
|
||||||
tor2.resume();
|
alert* a = ses.wait_for_alert(lt::seconds(5));
|
||||||
|
if (a == nullptr) break;
|
||||||
|
|
||||||
|
std::vector<alert*> alerts;
|
||||||
|
ses.pop_alerts(&alerts);
|
||||||
|
|
||||||
|
for (alert* i : alerts)
|
||||||
|
{
|
||||||
|
printf("%s\n", i->message().c_str());
|
||||||
|
|
||||||
|
read_piece_alert* rp = alert_cast<read_piece_alert>(i);
|
||||||
|
if (rp)
|
||||||
|
{
|
||||||
|
int const idx = rp->piece;
|
||||||
|
TEST_EQUAL(t->piece_size(idx), rp->size);
|
||||||
|
|
||||||
|
std::vector<char> const piece = generate_piece(idx, t->piece_size(idx));
|
||||||
|
TEST_CHECK(memcmp(rp->buffer.get(), piece.data(), rp->size) == 0);
|
||||||
|
TEST_CHECK(pieces[idx] == false);
|
||||||
|
pieces[idx] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_completed_alert* fc = alert_cast<file_completed_alert>(i);
|
||||||
|
if (fc)
|
||||||
|
{
|
||||||
|
int const idx = fc->index;
|
||||||
|
TEST_CHECK(files[idx] == false);
|
||||||
|
files[idx] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
piece_finished_alert* pf = alert_cast<piece_finished_alert>(i);
|
||||||
|
if (pf)
|
||||||
|
{
|
||||||
|
int const idx = pf->piece_index;
|
||||||
|
TEST_CHECK(passed[idx] == false);
|
||||||
|
passed[idx] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CHECK(all_of(pieces));
|
||||||
|
TEST_CHECK(all_of(files));
|
||||||
|
TEST_CHECK(all_of(passed));
|
||||||
|
|
||||||
|
// just because we can read them back throught libtorrent, doesn't mean the
|
||||||
|
// files have hit disk yet (because of the cache). Retry a few times to try
|
||||||
|
// to pick up the files
|
||||||
|
for (int i = 0; i < num_new_files; ++i)
|
||||||
|
{
|
||||||
|
std::string name = fs.file_path(i);
|
||||||
|
for (int j = 0; j < 10 && !exists(name); ++j)
|
||||||
|
{
|
||||||
std::this_thread::sleep_for(lt::milliseconds(500));
|
std::this_thread::sleep_for(lt::milliseconds(500));
|
||||||
tor1.resume();
|
print_alerts(ses, "ses");
|
||||||
|
}
|
||||||
|
|
||||||
std::fprintf(stderr, "\ntesting remap scatter prio\n\n");
|
fprintf(stderr, "%s\n", name.c_str());
|
||||||
|
TEST_CHECK(exists(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
print_alerts(ses, "ses");
|
||||||
|
|
||||||
|
torrent_status st = tor1.status();
|
||||||
|
TEST_EQUAL(st.is_seeding, true);
|
||||||
|
|
||||||
|
std::fprintf(stderr, "\ntesting force recheck\n\n");
|
||||||
|
|
||||||
|
// test force rechecking a seeding torrent with remapped files
|
||||||
|
tor1.force_recheck();
|
||||||
|
|
||||||
for (int i = 0; i < 50; ++i)
|
for (int i = 0; i < 50; ++i)
|
||||||
{
|
{
|
||||||
print_alerts(ses1, "ses1", true, true, true, &on_alert);
|
torrent_status st = tor1.status();
|
||||||
print_alerts(ses2, "ses2", true, true, true, &on_alert);
|
if (st.is_seeding) break;
|
||||||
|
|
||||||
torrent_status st1 = tor1.status();
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
|
|
||||||
if (i % 10 == 0)
|
|
||||||
{
|
|
||||||
std::cerr
|
|
||||||
<< "\033[32m" << int(st1.download_payload_rate / 1000.f) << "kB/s "
|
|
||||||
<< "\033[33m" << int(st1.upload_payload_rate / 1000.f) << "kB/s "
|
|
||||||
<< "\033[0m" << int(st1.progress * 100) << "% "
|
|
||||||
<< st1.num_peers
|
|
||||||
<< ": "
|
|
||||||
<< "\033[32m" << int(st2.download_payload_rate / 1000.f) << "kB/s "
|
|
||||||
<< "\033[31m" << int(st2.upload_payload_rate / 1000.f) << "kB/s "
|
|
||||||
<< "\033[0m" << int(st2.progress * 100) << "% "
|
|
||||||
<< st2.num_peers
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st2.is_finished) break;
|
|
||||||
|
|
||||||
if (st2.state != torrent_status::downloading)
|
|
||||||
{
|
|
||||||
static char const* state_str[] =
|
|
||||||
{"checking (q)", "checking", "dl metadata"
|
|
||||||
, "downloading", "finished", "seeding", "allocating", "checking (r)"};
|
|
||||||
std::cerr << "st2 state: " << state_str[st2.state] << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CHECK(st1.state == torrent_status::seeding);
|
|
||||||
TEST_CHECK(st2.state == torrent_status::downloading
|
|
||||||
|| st2.state == torrent_status::checking_resume_data);
|
|
||||||
|
|
||||||
if (peer_disconnects >= 2) break;
|
|
||||||
|
|
||||||
std::this_thread::sleep_for(lt::milliseconds(100));
|
std::this_thread::sleep_for(lt::milliseconds(100));
|
||||||
|
print_alerts(ses, "ses");
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent_status st2 = tor2.status();
|
print_alerts(ses, "ses");
|
||||||
TEST_CHECK(st2.is_finished);
|
st = tor1.status();
|
||||||
|
TEST_CHECK(st.is_seeding);
|
||||||
p1 = ses1.abort();
|
|
||||||
p2 = ses2.abort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace libtorrent;
|
|
||||||
|
|
||||||
TORRENT_TEST(remap_files)
|
TORRENT_TEST(remap_files)
|
||||||
{
|
{
|
||||||
test_remap_files_gather();
|
test_remap_files();
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
remove_all("tmp1_remap", ec);
|
|
||||||
remove_all("tmp2_remap", ec);
|
|
||||||
remove_all("tmp1_remap2", ec);
|
|
||||||
remove_all("tmp2_remap2", ec);
|
|
||||||
}
|
|
||||||
|
|
||||||
TORRENT_TEST(scatter)
|
|
||||||
{
|
|
||||||
test_remap_files_scatter();
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
remove_all("tmp1_remap", ec);
|
|
||||||
remove_all("tmp2_remap", ec);
|
|
||||||
remove_all("tmp1_remap2", ec);
|
|
||||||
remove_all("tmp2_remap2", ec);
|
|
||||||
remove_all("tmp1_remap3", ec);
|
|
||||||
remove_all("tmp2_remap3", ec);
|
|
||||||
}
|
|
||||||
|
|
||||||
TORRENT_TEST(prio)
|
|
||||||
{
|
|
||||||
test_remap_files_prio();
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
remove_all("tmp1_remap", ec);
|
|
||||||
remove_all("tmp2_remap", ec);
|
|
||||||
remove_all("tmp1_remap2", ec);
|
|
||||||
remove_all("tmp2_remap2", ec);
|
|
||||||
remove_all("tmp1_remap3", ec);
|
|
||||||
remove_all("tmp2_remap3", ec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue