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:
Arvid Norberg 2008-03-14 10:17:27 +00:00
parent 155005f387
commit 2cfbfd203f
7 changed files with 85 additions and 83 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);
} }

View File

@ -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;

View File

@ -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();

View File

@ -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)
{ {

View File

@ -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"));