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;
|
||||
|
||||
if (m_torrent_file->num_pieces() == 0) return;
|
||||
bool was_finished = is_finished();
|
||||
|
||||
size_type position = 0;
|
||||
int piece_length = m_torrent_file->piece_length();
|
||||
|
@ -1826,7 +1825,6 @@ namespace libtorrent
|
|||
, bind(&set_if_greater, _1, m_file_priority[i]));
|
||||
}
|
||||
prioritize_pieces(pieces);
|
||||
update_peer_interest(was_finished);
|
||||
}
|
||||
|
||||
// this is called when piece priorities have been updated
|
||||
|
@ -1836,16 +1834,18 @@ namespace libtorrent
|
|||
for (peer_iterator i = begin(); i != end(); ++i)
|
||||
(*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
|
||||
if (is_finished() && !was_finished)
|
||||
{
|
||||
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();
|
||||
m_policy.recalculate_connect_candidates();
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::filter_piece(int index, bool filter)
|
||||
|
@ -3265,6 +3265,12 @@ namespace libtorrent
|
|||
|
||||
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 (m_sequential_download)
|
||||
|
@ -3274,6 +3280,13 @@ namespace libtorrent
|
|||
// likely to be unpaused
|
||||
if (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
|
||||
|
@ -3290,12 +3303,6 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
if (is_seed())
|
||||
{
|
||||
m_complete_sent = true;
|
||||
finished();
|
||||
}
|
||||
|
||||
if (!m_connections_initialized)
|
||||
{
|
||||
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;
|
||||
|
||||
start_announcing();
|
||||
|
|
|
@ -34,6 +34,7 @@ test-suite libtorrent :
|
|||
[ run test_buffer.cpp ]
|
||||
[ run test_storage.cpp ]
|
||||
[ run test_torrent.cpp ]
|
||||
[ run test_transfer.cpp ]
|
||||
[ run test_piece_picker.cpp ]
|
||||
# [ run test_entry.cpp ]
|
||||
[ run test_fast_extension.cpp ]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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_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)
|
||||
|
||||
|
@ -61,6 +61,9 @@ test_bandwidth_limiter_LDADD = $(top_builddir)/src/libtorrent-rasterbar.la
|
|||
test_torrent_SOURCES = main.cpp test_torrent.cpp
|
||||
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
|
||||
|
||||
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>
|
||||
setup_transfer(session* ses1, session* ses2, session* ses3
|
||||
, 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;
|
||||
|
||||
|
@ -247,18 +248,24 @@ setup_transfer(session* ses1, session* ses2, session* ses3
|
|||
if (ses3)
|
||||
assert(ses3->id() != ses2->id());
|
||||
|
||||
|
||||
boost::intrusive_ptr<torrent_info> t;
|
||||
if (torrent == 0)
|
||||
{
|
||||
create_directory("./tmp1" + suffix);
|
||||
std::ofstream file(("./tmp1" + suffix + "/temporary").c_str());
|
||||
boost::intrusive_ptr<torrent_info> t = ::create_torrent(&file, piece_size);
|
||||
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;
|
||||
}
|
||||
|
||||
ses1->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>
|
||||
setup_transfer(libtorrent::session* ses1, libtorrent::session* ses2
|
||||
, 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 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