forked from premiere/premiere-libtorrent
fixed bug where a torrent would not get into the 'finished' state right after file checking. It would either go to downloading or seeding. Also added test_transfer
This commit is contained in:
parent
29bf61d364
commit
9266afe5f5
|
@ -1800,7 +1800,6 @@ namespace libtorrent
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (m_torrent_file->num_pieces() == 0) return;
|
if (m_torrent_file->num_pieces() == 0) return;
|
||||||
bool was_finished = is_finished();
|
|
||||||
|
|
||||||
size_type position = 0;
|
size_type position = 0;
|
||||||
int piece_length = m_torrent_file->piece_length();
|
int piece_length = m_torrent_file->piece_length();
|
||||||
|
@ -1826,7 +1825,6 @@ namespace libtorrent
|
||||||
, bind(&set_if_greater, _1, m_file_priority[i]));
|
, bind(&set_if_greater, _1, m_file_priority[i]));
|
||||||
}
|
}
|
||||||
prioritize_pieces(pieces);
|
prioritize_pieces(pieces);
|
||||||
update_peer_interest(was_finished);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is called when piece priorities have been updated
|
// this is called when piece priorities have been updated
|
||||||
|
@ -1836,16 +1834,18 @@ namespace libtorrent
|
||||||
for (peer_iterator i = begin(); i != end(); ++i)
|
for (peer_iterator i = begin(); i != end(); ++i)
|
||||||
(*i)->update_interest();
|
(*i)->update_interest();
|
||||||
|
|
||||||
// if we used to be finished, but we aren't anymore
|
|
||||||
// we may need to connect to peers again
|
|
||||||
if (!is_finished() && was_finished)
|
|
||||||
m_policy.recalculate_connect_candidates();
|
|
||||||
|
|
||||||
// the torrent just became finished
|
// the torrent just became finished
|
||||||
if (is_finished() && !was_finished)
|
if (is_finished() && !was_finished)
|
||||||
|
{
|
||||||
finished();
|
finished();
|
||||||
|
}
|
||||||
else if (!is_finished() && was_finished)
|
else if (!is_finished() && was_finished)
|
||||||
|
{
|
||||||
|
// if we used to be finished, but we aren't anymore
|
||||||
|
// we may need to connect to peers again
|
||||||
resume_download();
|
resume_download();
|
||||||
|
m_policy.recalculate_connect_candidates();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::filter_piece(int index, bool filter)
|
void torrent::filter_piece(int index, bool filter)
|
||||||
|
@ -3147,9 +3147,9 @@ namespace libtorrent
|
||||||
// to make sure we're cleared the piece picker
|
// to make sure we're cleared the piece picker
|
||||||
if (is_seed()) completed();
|
if (is_seed()) completed();
|
||||||
|
|
||||||
// disconnect all seeds
|
// disconnect all seeds
|
||||||
// TODO: should disconnect all peers that have the pieces we have
|
// TODO: should disconnect all peers that have the pieces we have
|
||||||
// not just seeds
|
// not just seeds
|
||||||
std::vector<peer_connection*> seeds;
|
std::vector<peer_connection*> seeds;
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end(); ++i)
|
i != m_connections.end(); ++i)
|
||||||
|
@ -3265,6 +3265,12 @@ namespace libtorrent
|
||||||
|
|
||||||
set_state(torrent_status::downloading);
|
set_state(torrent_status::downloading);
|
||||||
|
|
||||||
|
if (m_ses.m_alerts.should_post<torrent_checked_alert>())
|
||||||
|
{
|
||||||
|
m_ses.m_alerts.post_alert(torrent_checked_alert(
|
||||||
|
get_handle()));
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_seed())
|
if (!is_seed())
|
||||||
{
|
{
|
||||||
if (m_sequential_download)
|
if (m_sequential_download)
|
||||||
|
@ -3274,6 +3280,13 @@ namespace libtorrent
|
||||||
// likely to be unpaused
|
// likely to be unpaused
|
||||||
if (m_ses.m_auto_manage_time_scaler > 1)
|
if (m_ses.m_auto_manage_time_scaler > 1)
|
||||||
m_ses.m_auto_manage_time_scaler = 1;
|
m_ses.m_auto_manage_time_scaler = 1;
|
||||||
|
|
||||||
|
if (is_finished()) finished();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_complete_sent = true;
|
||||||
|
finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
|
@ -3290,12 +3303,6 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (is_seed())
|
|
||||||
{
|
|
||||||
m_complete_sent = true;
|
|
||||||
finished();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_connections_initialized)
|
if (!m_connections_initialized)
|
||||||
{
|
{
|
||||||
m_connections_initialized = true;
|
m_connections_initialized = true;
|
||||||
|
@ -3311,12 +3318,6 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_ses.m_alerts.should_post<torrent_checked_alert>())
|
|
||||||
{
|
|
||||||
m_ses.m_alerts.post_alert(torrent_checked_alert(
|
|
||||||
get_handle()));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_files_checked = true;
|
m_files_checked = true;
|
||||||
|
|
||||||
start_announcing();
|
start_announcing();
|
||||||
|
|
|
@ -34,6 +34,7 @@ test-suite libtorrent :
|
||||||
[ run test_buffer.cpp ]
|
[ run test_buffer.cpp ]
|
||||||
[ run test_storage.cpp ]
|
[ run test_storage.cpp ]
|
||||||
[ run test_torrent.cpp ]
|
[ run test_torrent.cpp ]
|
||||||
|
[ run test_transfer.cpp ]
|
||||||
[ run test_piece_picker.cpp ]
|
[ run test_piece_picker.cpp ]
|
||||||
# [ run test_entry.cpp ]
|
# [ run test_entry.cpp ]
|
||||||
[ run test_fast_extension.cpp ]
|
[ run test_fast_extension.cpp ]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
check_PROGRAMS = test_hasher test_bencoding test_ip_filter test_piece_picker \
|
check_PROGRAMS = test_hasher test_bencoding test_ip_filter test_piece_picker \
|
||||||
test_storage test_metadata_extension test_buffer test_swarm test_pe_crypto test_primitives \
|
test_storage test_metadata_extension test_buffer test_swarm test_pe_crypto test_primitives \
|
||||||
test_bandwidth_limiter test_upnp test_fast_extension test_pex test_web_seed \
|
test_bandwidth_limiter test_upnp test_fast_extension test_pex test_web_seed \
|
||||||
test_http_connection test_lsd
|
test_http_connection test_torrent test_transfer test_lsd
|
||||||
|
|
||||||
TESTS = $(check_PROGRAMS)
|
TESTS = $(check_PROGRAMS)
|
||||||
|
|
||||||
|
@ -61,6 +61,9 @@ test_bandwidth_limiter_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||||
test_torrent_SOURCES = main.cpp test_torrent.cpp
|
test_torrent_SOURCES = main.cpp test_torrent.cpp
|
||||||
test_torrent_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
test_torrent_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||||
|
|
||||||
|
test_transfer_SOURCES = main.cpp test_transfer.cpp
|
||||||
|
test_transfer_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
||||||
|
|
||||||
noinst_HEADERS = test.hpp setup_transfer.hpp
|
noinst_HEADERS = test.hpp setup_transfer.hpp
|
||||||
|
|
||||||
AM_CXXFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include -I$(top_srcdir)/include/libtorrent @DEBUGFLAGS@ @PTHREAD_CFLAGS@ -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION
|
AM_CXXFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include -I$(top_srcdir)/include/libtorrent @DEBUGFLAGS@ @PTHREAD_CFLAGS@ -DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION
|
||||||
|
|
|
@ -236,7 +236,8 @@ boost::intrusive_ptr<torrent_info> create_torrent(std::ostream* file, int piece_
|
||||||
boost::tuple<torrent_handle, torrent_handle, torrent_handle>
|
boost::tuple<torrent_handle, torrent_handle, torrent_handle>
|
||||||
setup_transfer(session* ses1, session* ses2, session* ses3
|
setup_transfer(session* ses1, session* ses2, session* ses3
|
||||||
, bool clear_files, bool use_metadata_transfer, bool connect_peers
|
, bool clear_files, bool use_metadata_transfer, bool connect_peers
|
||||||
, std::string suffix, int piece_size)
|
, std::string suffix, int piece_size
|
||||||
|
, boost::intrusive_ptr<torrent_info>* torrent)
|
||||||
{
|
{
|
||||||
using namespace boost::filesystem;
|
using namespace boost::filesystem;
|
||||||
|
|
||||||
|
@ -247,18 +248,24 @@ setup_transfer(session* ses1, session* ses2, session* ses3
|
||||||
if (ses3)
|
if (ses3)
|
||||||
assert(ses3->id() != ses2->id());
|
assert(ses3->id() != ses2->id());
|
||||||
|
|
||||||
|
boost::intrusive_ptr<torrent_info> t;
|
||||||
create_directory("./tmp1" + suffix);
|
if (torrent == 0)
|
||||||
std::ofstream file(("./tmp1" + suffix + "/temporary").c_str());
|
|
||||||
boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, piece_size);
|
|
||||||
file.close();
|
|
||||||
if (clear_files)
|
|
||||||
{
|
{
|
||||||
remove_all("./tmp2" + suffix + "/temporary");
|
create_directory("./tmp1" + suffix);
|
||||||
remove_all("./tmp3" + suffix + "/temporary");
|
std::ofstream file(("./tmp1" + suffix + "/temporary").c_str());
|
||||||
|
t = ::create_torrent(&file, piece_size);
|
||||||
|
file.close();
|
||||||
|
if (clear_files)
|
||||||
|
{
|
||||||
|
remove_all("./tmp2" + suffix + "/temporary");
|
||||||
|
remove_all("./tmp3" + suffix + "/temporary");
|
||||||
|
}
|
||||||
|
std::cerr << "generated torrent: " << t->info_hash() << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = *torrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "generated torrent: " << t->info_hash() << std::endl;
|
|
||||||
|
|
||||||
ses1->set_severity_level(alert::debug);
|
ses1->set_severity_level(alert::debug);
|
||||||
ses2->set_severity_level(alert::debug);
|
ses2->set_severity_level(alert::debug);
|
||||||
|
|
|
@ -48,7 +48,8 @@ boost::tuple<libtorrent::torrent_handle, libtorrent::torrent_handle
|
||||||
, libtorrent::torrent_handle>
|
, libtorrent::torrent_handle>
|
||||||
setup_transfer(libtorrent::session* ses1, libtorrent::session* ses2
|
setup_transfer(libtorrent::session* ses1, libtorrent::session* ses2
|
||||||
, libtorrent::session* ses3, bool clear_files, bool use_metadata_transfer = true
|
, libtorrent::session* ses3, bool clear_files, bool use_metadata_transfer = true
|
||||||
, bool connect = true, std::string suffix = "", int piece_size = 16 * 1024);
|
, bool connect = true, std::string suffix = "", int piece_size = 16 * 1024
|
||||||
|
, boost::intrusive_ptr<libtorrent::torrent_info>* torrent = 0);
|
||||||
|
|
||||||
void start_web_server(int port, bool ssl = false);
|
void start_web_server(int port, bool ssl = false);
|
||||||
void stop_web_server(int port);
|
void stop_web_server(int port);
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2008, Arvid Norberg
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the author nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libtorrent/session.hpp"
|
||||||
|
#include "libtorrent/session_settings.hpp"
|
||||||
|
#include "libtorrent/hasher.hpp"
|
||||||
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
#include "libtorrent/bencode.hpp"
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
#include <boost/filesystem/operations.hpp>
|
||||||
|
|
||||||
|
#include "test.hpp"
|
||||||
|
#include "setup_transfer.hpp"
|
||||||
|
|
||||||
|
using boost::filesystem::remove_all;
|
||||||
|
using boost::filesystem::exists;
|
||||||
|
using boost::filesystem::create_directory;
|
||||||
|
|
||||||
|
void test_transfer()
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
using boost::tuples::ignore;
|
||||||
|
|
||||||
|
session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48075, 49000));
|
||||||
|
session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49075, 50000));
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
pe_settings pes;
|
||||||
|
pes.out_enc_policy = pe_settings::forced;
|
||||||
|
pes.in_enc_policy = pe_settings::forced;
|
||||||
|
ses1.set_pe_settings(pes);
|
||||||
|
ses2.set_pe_settings(pes);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
torrent_handle tor1;
|
||||||
|
torrent_handle tor2;
|
||||||
|
|
||||||
|
create_directory("./tmp1_transfer");
|
||||||
|
std::ofstream file("./tmp1_transfer/temporary");
|
||||||
|
boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, 16 * 1024);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// test using piece sizes smaller than 16kB
|
||||||
|
boost::tie(tor1, tor2, ignore) = setup_transfer(&ses1, &ses2, 0
|
||||||
|
, true, false, true, "_transfer", 8 * 1024, &t);
|
||||||
|
|
||||||
|
// set half of the pieces to priority 0
|
||||||
|
int num_pieces = tor2.get_torrent_info().num_pieces();
|
||||||
|
std::vector<int> priorities(num_pieces, 1);
|
||||||
|
std::fill(priorities.begin(), priorities.begin() + num_pieces / 2, 0);
|
||||||
|
tor2.prioritize_pieces(priorities);
|
||||||
|
|
||||||
|
ses1.set_alert_mask(alert::all_categories & ~alert::progress_notification);
|
||||||
|
ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification);
|
||||||
|
|
||||||
|
tor1.resume();
|
||||||
|
tor2.resume();
|
||||||
|
|
||||||
|
for (int i = 0; i < 30; ++i)
|
||||||
|
{
|
||||||
|
print_alerts(ses1, "ses1");
|
||||||
|
print_alerts(ses2, "ses2");
|
||||||
|
|
||||||
|
torrent_status st1 = tor1.status();
|
||||||
|
torrent_status st2 = tor2.status();
|
||||||
|
|
||||||
|
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 (tor2.is_finished()) break;
|
||||||
|
|
||||||
|
TEST_CHECK(st1.state == torrent_status::seeding);
|
||||||
|
TEST_CHECK(st2.state == torrent_status::downloading);
|
||||||
|
|
||||||
|
test_sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CHECK(!tor2.is_seed());
|
||||||
|
std::cerr << "torrent is finished (50% complete)" << std::endl;
|
||||||
|
|
||||||
|
tor2.pause();
|
||||||
|
alert const* a = ses2.wait_for_alert(seconds(10));
|
||||||
|
while (a)
|
||||||
|
{
|
||||||
|
std::auto_ptr<alert> holder = ses2.pop_alert();
|
||||||
|
std::cerr << "ses2: " << a->message() << std::endl;
|
||||||
|
if (dynamic_cast<torrent_paused_alert const*>(a)) break;
|
||||||
|
a = ses2.wait_for_alert(seconds(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
tor2.save_resume_data();
|
||||||
|
|
||||||
|
std::vector<char> resume_data;
|
||||||
|
a = ses2.wait_for_alert(seconds(10));
|
||||||
|
while (a)
|
||||||
|
{
|
||||||
|
std::auto_ptr<alert> holder = ses2.pop_alert();
|
||||||
|
std::cerr << "ses2: " << a->message() << std::endl;
|
||||||
|
if (dynamic_cast<save_resume_data_alert const*>(a))
|
||||||
|
{
|
||||||
|
bencode(std::back_inserter(resume_data)
|
||||||
|
, *dynamic_cast<save_resume_data_alert const*>(a)->resume_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
a = ses2.wait_for_alert(seconds(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << "saved resume data" << std::endl;
|
||||||
|
|
||||||
|
ses2.remove_torrent(tor2);
|
||||||
|
|
||||||
|
std::cerr << "removed" << std::endl;
|
||||||
|
|
||||||
|
test_sleep(1000);
|
||||||
|
|
||||||
|
std::cout << "re-adding" << std::endl;
|
||||||
|
add_torrent_params p;
|
||||||
|
p.ti = t;
|
||||||
|
p.save_path = "./tmp2_transfer";
|
||||||
|
p.resume_data = &resume_data;
|
||||||
|
tor2 = ses2.add_torrent(p);
|
||||||
|
tor2.prioritize_pieces(priorities);
|
||||||
|
std::cout << "resetting priorities" << std::endl;
|
||||||
|
tor2.resume();
|
||||||
|
|
||||||
|
test_sleep(1000);
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i)
|
||||||
|
{
|
||||||
|
print_alerts(ses1, "ses1");
|
||||||
|
print_alerts(ses2, "ses2");
|
||||||
|
|
||||||
|
torrent_status st1 = tor1.status();
|
||||||
|
torrent_status st2 = tor2.status();
|
||||||
|
|
||||||
|
TEST_CHECK(st1.state == torrent_status::seeding);
|
||||||
|
TEST_CHECK(st2.state == torrent_status::finished);
|
||||||
|
|
||||||
|
test_sleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CHECK(!tor2.is_seed());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_main()
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
using namespace boost::filesystem;
|
||||||
|
|
||||||
|
// in case the previous run was terminated
|
||||||
|
try { remove_all("./tmp1_transfer"); } catch (std::exception&) {}
|
||||||
|
try { remove_all("./tmp2_transfer"); } catch (std::exception&) {}
|
||||||
|
|
||||||
|
test_transfer();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue