made tests build and pass in trunk. fixed issues in trunk revealed by the tests. fixed failing torrent invariant check in trunk and rc0.13
This commit is contained in:
parent
155005f387
commit
2cfbfd203f
|
@ -59,6 +59,8 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
|
||||||
int port;
|
int port;
|
||||||
boost::tie(protocol, auth, hostname, port, path) = parse_url_components(url);
|
boost::tie(protocol, auth, hostname, port, path) = parse_url_components(url);
|
||||||
|
|
||||||
|
TORRENT_ASSERT(prio >= 0 && prio < 2);
|
||||||
|
|
||||||
bool ssl = false;
|
bool ssl = false;
|
||||||
if (protocol == "https") ssl = true;
|
if (protocol == "https") ssl = true;
|
||||||
#ifndef TORRENT_USE_OPENSSL
|
#ifndef TORRENT_USE_OPENSSL
|
||||||
|
@ -110,6 +112,8 @@ void http_connection::start(std::string const& hostname, std::string const& port
|
||||||
, time_duration timeout, int prio, proxy_settings const* ps, bool ssl, int handle_redirects
|
, time_duration timeout, int prio, proxy_settings const* ps, bool ssl, int handle_redirects
|
||||||
, address const& bind_addr)
|
, address const& bind_addr)
|
||||||
{
|
{
|
||||||
|
TORRENT_ASSERT(prio >= 0 && prio < 2);
|
||||||
|
|
||||||
m_redirects = handle_redirects;
|
m_redirects = handle_redirects;
|
||||||
if (ps) m_proxy = *ps;
|
if (ps) m_proxy = *ps;
|
||||||
|
|
||||||
|
|
|
@ -1413,38 +1413,7 @@ namespace libtorrent
|
||||||
, m_download_queue.end()
|
, m_download_queue.end()
|
||||||
, block_finished);
|
, block_finished);
|
||||||
|
|
||||||
if (b != m_download_queue.end())
|
if (b == m_download_queue.end())
|
||||||
{
|
|
||||||
if (m_assume_fifo)
|
|
||||||
{
|
|
||||||
for (std::deque<piece_block>::iterator i = m_download_queue.begin();
|
|
||||||
i != b; ++i)
|
|
||||||
{
|
|
||||||
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
|
||||||
(*m_logger) << time_now_string()
|
|
||||||
<< " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | "
|
|
||||||
"b: " << i->block_index << " ] ***\n";
|
|
||||||
#endif
|
|
||||||
// since this piece was skipped, clear it and allow it to
|
|
||||||
// be requested from other peers
|
|
||||||
// TODO: send cancel?
|
|
||||||
picker.abort_download(*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove the request that just finished
|
|
||||||
// from the download queue plus the
|
|
||||||
// skipped blocks.
|
|
||||||
m_download_queue.erase(m_download_queue.begin()
|
|
||||||
, boost::next(b));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_download_queue.erase(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
t->cancel_block(block_finished);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (t->alerts().should_post(alert::debug))
|
if (t->alerts().should_post(alert::debug))
|
||||||
{
|
{
|
||||||
|
@ -1464,11 +1433,36 @@ namespace libtorrent
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_assume_fifo)
|
||||||
|
{
|
||||||
|
for (std::deque<piece_block>::iterator i = m_download_queue.begin();
|
||||||
|
i != b; ++i)
|
||||||
|
{
|
||||||
|
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
|
||||||
|
(*m_logger) << time_now_string()
|
||||||
|
<< " *** SKIPPED_PIECE [ piece: " << i->piece_index << " | "
|
||||||
|
"b: " << i->block_index << " ] ***\n";
|
||||||
|
#endif
|
||||||
|
// since this piece was skipped, clear it and allow it to
|
||||||
|
// be requested from other peers
|
||||||
|
// TODO: send cancel?
|
||||||
|
picker.abort_download(*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove the request that just finished
|
||||||
|
// from the download queue plus the
|
||||||
|
// skipped blocks.
|
||||||
|
m_download_queue.erase(m_download_queue.begin(), b);
|
||||||
|
b = m_download_queue.begin();
|
||||||
|
TORRENT_ASSERT(*b == block_finished);
|
||||||
|
}
|
||||||
|
|
||||||
// if the block we got is already finished, then ignore it
|
// if the block we got is already finished, then ignore it
|
||||||
if (picker.is_downloaded(block_finished))
|
if (picker.is_downloaded(block_finished))
|
||||||
{
|
{
|
||||||
t->received_redundant_data(p.length);
|
t->received_redundant_data(p.length);
|
||||||
|
|
||||||
|
m_download_queue.erase(b);
|
||||||
request_a_block(*t, *this);
|
request_a_block(*t, *this);
|
||||||
send_block_requests();
|
send_block_requests();
|
||||||
return;
|
return;
|
||||||
|
@ -1478,7 +1472,9 @@ namespace libtorrent
|
||||||
, self(), _1, _2, p, t));
|
, self(), _1, _2, p, t));
|
||||||
m_outstanding_writing_bytes += p.length;
|
m_outstanding_writing_bytes += p.length;
|
||||||
TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle);
|
TORRENT_ASSERT(m_channel_state[download_channel] == peer_info::bw_idle);
|
||||||
|
m_download_queue.erase(b);
|
||||||
picker.mark_as_writing(block_finished, peer_info_struct());
|
picker.mark_as_writing(block_finished, peer_info_struct());
|
||||||
|
t->cancel_block(block_finished);
|
||||||
#if !defined NDEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
|
#if !defined NDEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
|
||||||
t->check_invariant();
|
t->check_invariant();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1536,6 +1536,11 @@ namespace libtorrent
|
||||||
m_piece_to_slot.resize(m_info->num_pieces(), has_no_slot);
|
m_piece_to_slot.resize(m_info->num_pieces(), has_no_slot);
|
||||||
m_slot_to_piece.clear();
|
m_slot_to_piece.clear();
|
||||||
m_slot_to_piece.resize(m_info->num_pieces(), unallocated);
|
m_slot_to_piece.resize(m_info->num_pieces(), unallocated);
|
||||||
|
if (m_storage_mode == storage_mode_compact)
|
||||||
|
{
|
||||||
|
m_unallocated_slots.clear();
|
||||||
|
m_free_slots.clear();
|
||||||
|
}
|
||||||
return need_full_check;
|
return need_full_check;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1547,7 +1552,9 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(m_unallocated_slots.empty());
|
TORRENT_ASSERT(m_unallocated_slots.empty());
|
||||||
for (int i = 0, end(m_info->num_pieces()); i < end; ++i)
|
for (int i = 0, end(m_info->num_pieces()); i < end; ++i)
|
||||||
m_unallocated_slots.push_back(i);
|
m_unallocated_slots.push_back(i);
|
||||||
|
m_piece_to_slot.clear();
|
||||||
m_piece_to_slot.resize(m_info->num_pieces(), has_no_slot);
|
m_piece_to_slot.resize(m_info->num_pieces(), has_no_slot);
|
||||||
|
m_slot_to_piece.clear();
|
||||||
m_slot_to_piece.resize(m_info->num_pieces(), unallocated);
|
m_slot_to_piece.resize(m_info->num_pieces(), unallocated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1795,6 +1795,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void torrent::cancel_block(piece_block block)
|
void torrent::cancel_block(piece_block block)
|
||||||
{
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
for (peer_iterator i = m_connections.begin()
|
for (peer_iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end; ++i)
|
, end(m_connections.end()); i != end; ++i)
|
||||||
{
|
{
|
||||||
|
@ -2400,8 +2402,9 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(p != 0);
|
TORRENT_ASSERT(p != 0);
|
||||||
TORRENT_ASSERT(!p->is_local());
|
TORRENT_ASSERT(!p->is_local());
|
||||||
|
|
||||||
if (m_state == torrent_status::queued_for_checking
|
if ((m_state == torrent_status::queued_for_checking
|
||||||
|| m_state == torrent_status::checking_files)
|
|| m_state == torrent_status::checking_files)
|
||||||
|
&& valid_metadata())
|
||||||
{
|
{
|
||||||
p->disconnect("torrent is not ready to accept peers");
|
p->disconnect("torrent is not ready to accept peers");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -75,7 +75,7 @@ void run_test(std::string const& url, int size, int status, int connected
|
||||||
|
|
||||||
boost::shared_ptr<http_connection> h(new http_connection(ios, cq
|
boost::shared_ptr<http_connection> h(new http_connection(ios, cq
|
||||||
, &::http_handler, true, &::http_connect_handler));
|
, &::http_handler, true, &::http_connect_handler));
|
||||||
h->get(url, seconds(30), &ps);
|
h->get(url, seconds(30), 0, &ps);
|
||||||
ios.reset();
|
ios.reset();
|
||||||
ios.run();
|
ios.run();
|
||||||
|
|
||||||
|
|
|
@ -39,17 +39,11 @@ boost::shared_ptr<piece_picker> setup_picker(
|
||||||
|
|
||||||
std::vector<bool> have = string2vec(have_str);
|
std::vector<bool> have = string2vec(have_str);
|
||||||
|
|
||||||
std::vector<piece_picker::downloading_piece> unfinished;
|
|
||||||
piece_picker::downloading_piece pp;
|
|
||||||
std::vector<piece_picker::block_info> blocks(blocks_per_piece * num_pieces);
|
|
||||||
|
|
||||||
for (int i = 0; i < num_pieces; ++i)
|
for (int i = 0; i < num_pieces; ++i)
|
||||||
{
|
{
|
||||||
if (partial[i] == 0) break;
|
if (partial[i] == 0) break;
|
||||||
|
|
||||||
if (partial[i] == ' ') continue;
|
if (partial[i] == ' ') continue;
|
||||||
pp.index = i;
|
|
||||||
pp.info = &blocks[i * blocks_per_piece];
|
|
||||||
|
|
||||||
int blocks = 0;
|
int blocks = 0;
|
||||||
if (partial[i] >= '0' && partial[i] <= '9')
|
if (partial[i] >= '0' && partial[i] <= '9')
|
||||||
|
@ -57,15 +51,35 @@ boost::shared_ptr<piece_picker> setup_picker(
|
||||||
else
|
else
|
||||||
blocks = partial[i] - 'a' + 10;
|
blocks = partial[i] - 'a' + 10;
|
||||||
|
|
||||||
|
int counter = 0;
|
||||||
if (blocks & 1)
|
if (blocks & 1)
|
||||||
pp.info[0].state = piece_picker::block_info::state_finished;
|
{
|
||||||
|
++counter;
|
||||||
|
p->mark_as_finished(piece_block(i, 0), 0);
|
||||||
|
}
|
||||||
if (blocks & 2)
|
if (blocks & 2)
|
||||||
pp.info[1].state = piece_picker::block_info::state_finished;
|
{
|
||||||
|
++counter;
|
||||||
|
p->mark_as_finished(piece_block(i, 1), 0);
|
||||||
|
}
|
||||||
if (blocks & 4)
|
if (blocks & 4)
|
||||||
pp.info[2].state = piece_picker::block_info::state_finished;
|
{
|
||||||
|
++counter;
|
||||||
|
p->mark_as_finished(piece_block(i, 2), 0);
|
||||||
|
}
|
||||||
if (blocks & 8)
|
if (blocks & 8)
|
||||||
pp.info[3].state = piece_picker::block_info::state_finished;
|
{
|
||||||
unfinished.push_back(pp);
|
++counter;
|
||||||
|
p->mark_as_finished(piece_block(i, 3), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
piece_picker::downloading_piece st;
|
||||||
|
p->piece_info(i, st);
|
||||||
|
TEST_CHECK(st.writing == 0);
|
||||||
|
TEST_CHECK(st.requested == 0);
|
||||||
|
TEST_CHECK(st.index == i);
|
||||||
|
|
||||||
|
TEST_CHECK(st.finished == counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num_pieces; ++i)
|
for (int i = 0; i < num_pieces; ++i)
|
||||||
|
@ -78,26 +92,7 @@ boost::shared_ptr<piece_picker> setup_picker(
|
||||||
TEST_CHECK(p->piece_priority(i) == prio);
|
TEST_CHECK(p->piece_priority(i) == prio);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> verify_pieces;
|
p->init(have);
|
||||||
p->files_checked(have, unfinished, verify_pieces);
|
|
||||||
|
|
||||||
for (std::vector<piece_picker::downloading_piece>::iterator i = unfinished.begin()
|
|
||||||
, end(unfinished.end()); i != end; ++i)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < blocks_per_piece; ++j)
|
|
||||||
TEST_CHECK(p->is_finished(piece_block(i->index, j)) == (i->info[j].state == piece_picker::block_info::state_finished));
|
|
||||||
|
|
||||||
piece_picker::downloading_piece st;
|
|
||||||
p->piece_info(i->index, st);
|
|
||||||
TEST_CHECK(st.writing == 0);
|
|
||||||
TEST_CHECK(st.requested == 0);
|
|
||||||
TEST_CHECK(st.index == i->index);
|
|
||||||
int counter = 0;
|
|
||||||
for (int j = 0; j < blocks_per_piece; ++j)
|
|
||||||
if (i->info[j].state == piece_picker::block_info::state_finished) ++counter;
|
|
||||||
|
|
||||||
TEST_CHECK(st.finished == counter);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < num_pieces; ++i)
|
for (int i = 0; i < num_pieces; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,6 +25,16 @@ void on_read_piece(int ret, disk_io_job const& j, char const* data, int size)
|
||||||
TEST_CHECK(std::equal(j.buffer, j.buffer + ret, data));
|
TEST_CHECK(std::equal(j.buffer, j.buffer + ret, data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void on_check_resume_data(int ret, disk_io_job const& j)
|
||||||
|
{
|
||||||
|
std::cerr << "on_check_resume_data ret: " << ret << " " << j.piece << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_check_files(int ret, disk_io_job const& j)
|
||||||
|
{
|
||||||
|
std::cerr << "on_check_files ret: " << ret << " " << j.piece << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void run_storage_tests(boost::intrusive_ptr<torrent_info> info
|
void run_storage_tests(boost::intrusive_ptr<torrent_info> info
|
||||||
, path const& test_path
|
, path const& test_path
|
||||||
, libtorrent::storage_mode_t storage_mode)
|
, libtorrent::storage_mode_t storage_mode)
|
||||||
|
@ -90,28 +100,15 @@ void run_storage_tests(boost::intrusive_ptr<torrent_info> info
|
||||||
disk_io_thread io(ios);
|
disk_io_thread io(ios);
|
||||||
boost::shared_ptr<int> dummy(new int);
|
boost::shared_ptr<int> dummy(new int);
|
||||||
boost::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
|
boost::intrusive_ptr<piece_manager> pm = new piece_manager(dummy, info
|
||||||
, test_path, fp, io, default_storage_constructor);
|
, test_path, fp, io, default_storage_constructor, storage_mode);
|
||||||
boost::mutex lock;
|
boost::mutex lock;
|
||||||
libtorrent::aux::piece_checker_data d;
|
|
||||||
|
|
||||||
std::vector<bool> pieces;
|
|
||||||
num_pieces = 0;
|
|
||||||
std::string error_msg;
|
|
||||||
entry frd;
|
entry frd;
|
||||||
pm->verify_resume_data(frd, error_msg);
|
pm->async_check_fastresume(&frd, &on_check_resume_data);
|
||||||
TEST_CHECK(pm->check_fastresume(d, pieces, num_pieces
|
test_sleep(2000);
|
||||||
, storage_mode, error_msg) == false);
|
|
||||||
bool finished = false;
|
|
||||||
float progress;
|
|
||||||
num_pieces = 0;
|
|
||||||
boost::recursive_mutex mutex;
|
|
||||||
bool error;
|
|
||||||
while (!finished)
|
|
||||||
boost::tie(finished, progress) = pm->check_files(pieces, num_pieces, mutex, error);
|
|
||||||
|
|
||||||
TEST_CHECK(num_pieces == std::count(pieces.begin(), pieces.end()
|
|
||||||
, true));
|
|
||||||
|
|
||||||
|
pm->async_check_files(&on_check_files);
|
||||||
|
test_sleep(2000);
|
||||||
|
|
||||||
boost::function<void(int, disk_io_job const&)> none;
|
boost::function<void(int, disk_io_job const&)> none;
|
||||||
TEST_CHECK(exists(test_path / "temp_storage"));
|
TEST_CHECK(exists(test_path / "temp_storage"));
|
||||||
|
|
Loading…
Reference in New Issue