move test_metadata_extension to a simulation instead of a live test
This commit is contained in:
parent
a3dbbd6a37
commit
a75699eff1
|
@ -27,5 +27,6 @@ alias libtorrent-sims :
|
||||||
[ run test_utp.cpp ]
|
[ run test_utp.cpp ]
|
||||||
[ run test_dht.cpp ]
|
[ run test_dht.cpp ]
|
||||||
[ run test_pe_crypto.cpp ]
|
[ run test_pe_crypto.cpp ]
|
||||||
|
[ run test_metadata_extension.cpp ]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct swarm
|
||||||
boost::make_shared<lt::session>(pack
|
boost::make_shared<lt::session>(pack
|
||||||
, boost::ref(*m_io_service.back()));
|
, boost::ref(*m_io_service.back()));
|
||||||
m_nodes.push_back(ses);
|
m_nodes.push_back(ses);
|
||||||
|
m_config.on_session_added(i, *ses);
|
||||||
|
|
||||||
// reserve a slot in here for when the torrent gets added (notified by
|
// reserve a slot in here for when the torrent gets added (notified by
|
||||||
// an alert)
|
// an alert)
|
||||||
|
@ -144,6 +145,9 @@ struct swarm
|
||||||
lt::torrent_handle h = at->handle;
|
lt::torrent_handle h = at->handle;
|
||||||
m_torrents[session_index] = h;
|
m_torrents[session_index] = h;
|
||||||
|
|
||||||
|
// let the config object have a chance to set up the torrent
|
||||||
|
m_config.on_torrent_added(session_index, h);
|
||||||
|
|
||||||
// now, connect this torrent to all the others in the swarm
|
// now, connect this torrent to all the others in the swarm
|
||||||
for (int k = 0; k < session_index; ++k)
|
for (int k = 0; k < session_index; ++k)
|
||||||
{
|
{
|
||||||
|
@ -154,7 +158,8 @@ struct swarm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_config.on_alert(a, session_index, m_torrents))
|
if (m_config.on_alert(a, session_index, m_torrents
|
||||||
|
, *m_nodes[session_index]))
|
||||||
term = true;
|
term = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,13 +45,22 @@ struct swarm_setup_provider
|
||||||
// called for every alert. if the simulation is done, return true
|
// called for every alert. if the simulation is done, return true
|
||||||
virtual bool on_alert(libtorrent::alert const* alert
|
virtual bool on_alert(libtorrent::alert const* alert
|
||||||
, int session_idx
|
, int session_idx
|
||||||
, std::vector<libtorrent::torrent_handle> const& handles) { return false; }
|
, std::vector<libtorrent::torrent_handle> const& handles
|
||||||
|
, libtorrent::session& ses) { return false; }
|
||||||
|
|
||||||
// called for every torrent that's added (and every session that's started).
|
// called for every torrent that's added (and every session that's started).
|
||||||
// this is useful to give every session a unique save path and to make some
|
// this is useful to give every session a unique save path and to make some
|
||||||
// sessions seeds and others downloaders
|
// sessions seeds and others downloaders
|
||||||
virtual libtorrent::add_torrent_params add_torrent(int idx) = 0;
|
virtual libtorrent::add_torrent_params add_torrent(int idx) = 0;
|
||||||
|
|
||||||
|
// called for every torrent that's added once the torrent_handle comes back.
|
||||||
|
// can be used to set options on the torrent
|
||||||
|
virtual void on_torrent_added(int idx, libtorrent::torrent_handle h) {}
|
||||||
|
|
||||||
|
// called for every session that's created. Leaves an opportunity for the
|
||||||
|
// configuration object to add extensions etc.
|
||||||
|
virtual void on_session_added(int idx, libtorrent::session& ses) {}
|
||||||
|
|
||||||
// called for every session that's added
|
// called for every session that's added
|
||||||
virtual libtorrent::settings_pack add_session(int idx) = 0;
|
virtual libtorrent::settings_pack add_session(int idx) = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct swarm_config : swarm_setup_provider
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void on_exit(std::vector<torrent_handle> const& torrents)
|
virtual void on_exit(std::vector<torrent_handle> const& torrents) override
|
||||||
{
|
{
|
||||||
TEST_CHECK(torrents.size() > 0);
|
TEST_CHECK(torrents.size() > 0);
|
||||||
for (int i = 0; i < int(torrents.size()); ++i)
|
for (int i = 0; i < int(torrents.size()); ++i)
|
||||||
|
@ -75,7 +75,8 @@ struct swarm_config : swarm_setup_provider
|
||||||
// called for every alert. if the simulation is done, return true
|
// called for every alert. if the simulation is done, return true
|
||||||
virtual bool on_alert(libtorrent::alert const* alert
|
virtual bool on_alert(libtorrent::alert const* alert
|
||||||
, int session_idx
|
, int session_idx
|
||||||
, std::vector<libtorrent::torrent_handle> const& torrents)
|
, std::vector<libtorrent::torrent_handle> const& torrents
|
||||||
|
, libtorrent::session& ses) override
|
||||||
{
|
{
|
||||||
if (torrents.empty()) return false;
|
if (torrents.empty()) return false;
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ struct swarm_config : swarm_setup_provider
|
||||||
// called for every torrent that's added (and every session that's started).
|
// called for every torrent that's added (and every session that's started).
|
||||||
// this is useful to give every session a unique save path and to make some
|
// this is useful to give every session a unique save path and to make some
|
||||||
// sessions seeds and others downloaders
|
// sessions seeds and others downloaders
|
||||||
virtual libtorrent::add_torrent_params add_torrent(int idx)
|
virtual libtorrent::add_torrent_params add_torrent(int idx) override
|
||||||
{
|
{
|
||||||
add_torrent_params p;
|
add_torrent_params p;
|
||||||
p.flags &= ~add_torrent_params::flag_paused;
|
p.flags &= ~add_torrent_params::flag_paused;
|
||||||
|
@ -108,7 +109,7 @@ struct swarm_config : swarm_setup_provider
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string save_path(int idx) const
|
virtual std::string save_path(int idx) const
|
||||||
{
|
{
|
||||||
char path[200];
|
char path[200];
|
||||||
snprintf(path, sizeof(path), "swarm-%04d-peer-%02d"
|
snprintf(path, sizeof(path), "swarm-%04d-peer-%02d"
|
||||||
|
@ -117,7 +118,7 @@ struct swarm_config : swarm_setup_provider
|
||||||
}
|
}
|
||||||
|
|
||||||
// called for every session that's added
|
// called for every session that's added
|
||||||
virtual libtorrent::settings_pack add_session(int idx)
|
virtual libtorrent::settings_pack add_session(int idx) override
|
||||||
{
|
{
|
||||||
settings_pack pack = settings();
|
settings_pack pack = settings();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
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 "test.hpp"
|
||||||
|
#include "setup_transfer.hpp"
|
||||||
|
#include "test_utils.hpp"
|
||||||
|
#include "test_utils.hpp"
|
||||||
|
#include "swarm_config.hpp"
|
||||||
|
|
||||||
|
#include "libtorrent/session.hpp"
|
||||||
|
#include "libtorrent/hasher.hpp"
|
||||||
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
#include "libtorrent/thread.hpp"
|
||||||
|
#include "libtorrent/extensions/metadata_transfer.hpp"
|
||||||
|
#include "libtorrent/extensions/ut_metadata.hpp"
|
||||||
|
|
||||||
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
enum flags_t
|
||||||
|
{
|
||||||
|
clear_files = 1,
|
||||||
|
|
||||||
|
// disconnect immediately after receiving the metadata (to test that
|
||||||
|
// edge case, it caused a crash once)
|
||||||
|
disconnect = 2,
|
||||||
|
|
||||||
|
// force encryption (to make sure the plugin uses the peer_connection
|
||||||
|
// API in a compatible way)
|
||||||
|
full_encryption = 4,
|
||||||
|
|
||||||
|
// have the downloader connect to the seeder
|
||||||
|
// (instead of the other way around)
|
||||||
|
reverse = 8,
|
||||||
|
|
||||||
|
// only use uTP
|
||||||
|
utp = 16,
|
||||||
|
|
||||||
|
// upload-only mode
|
||||||
|
upload_only = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
struct test_swarm_config : swarm_config
|
||||||
|
{
|
||||||
|
test_swarm_config(int flags
|
||||||
|
, boost::shared_ptr<torrent_plugin> (*plugin)(torrent_handle const&, void*))
|
||||||
|
: swarm_config()
|
||||||
|
, m_flags(flags)
|
||||||
|
, m_plugin(plugin)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// called for every session that's added
|
||||||
|
virtual libtorrent::settings_pack add_session(int idx) override
|
||||||
|
{
|
||||||
|
settings_pack s = swarm_config::add_session(idx);
|
||||||
|
|
||||||
|
fprintf(stderr, " session %d\n", idx);
|
||||||
|
|
||||||
|
fprintf(stderr, "\n==== test transfer: %s%s%s%s%s%s ====\n\n"
|
||||||
|
, (m_flags & clear_files) ? "clear-files " : ""
|
||||||
|
, (m_flags & disconnect) ? "disconnect " : ""
|
||||||
|
, (m_flags & full_encryption) ? "encryption " : ""
|
||||||
|
, (m_flags & reverse) ? "reverse " : ""
|
||||||
|
, (m_flags & utp) ? "utp " : ""
|
||||||
|
, (m_flags & upload_only) ? "upload_only " : "");
|
||||||
|
|
||||||
|
s.set_int(settings_pack::out_enc_policy, settings_pack::pe_forced);
|
||||||
|
s.set_int(settings_pack::in_enc_policy, settings_pack::pe_forced);
|
||||||
|
s.set_bool(settings_pack::prefer_rc4, m_flags & full_encryption);
|
||||||
|
|
||||||
|
if (m_flags & utp)
|
||||||
|
{
|
||||||
|
s.set_bool(settings_pack::utp_dynamic_sock_buf, true);
|
||||||
|
s.set_bool(settings_pack::enable_incoming_utp, true);
|
||||||
|
s.set_bool(settings_pack::enable_outgoing_utp, true);
|
||||||
|
s.set_bool(settings_pack::enable_incoming_tcp, false);
|
||||||
|
s.set_bool(settings_pack::enable_outgoing_tcp, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.set_bool(settings_pack::enable_incoming_utp, false);
|
||||||
|
s.set_bool(settings_pack::enable_outgoing_utp, false);
|
||||||
|
s.set_bool(settings_pack::enable_incoming_tcp, true);
|
||||||
|
s.set_bool(settings_pack::enable_outgoing_tcp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual libtorrent::add_torrent_params add_torrent(int idx) override
|
||||||
|
{
|
||||||
|
add_torrent_params p = swarm_config::add_torrent(idx);
|
||||||
|
|
||||||
|
if (m_flags & reverse)
|
||||||
|
{
|
||||||
|
p.save_path = save_path(1 - idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx == 1)
|
||||||
|
{
|
||||||
|
// this is the guy who should download the metadata.
|
||||||
|
p.info_hash = p.ti->info_hash();
|
||||||
|
p.ti.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_session_added(int idx, session& ses) override
|
||||||
|
{
|
||||||
|
ses.add_extension(m_plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool on_alert(libtorrent::alert const* alert
|
||||||
|
, int session_idx
|
||||||
|
, std::vector<libtorrent::torrent_handle> const& handles
|
||||||
|
, libtorrent::session& ses) override
|
||||||
|
{
|
||||||
|
// make sure this function can be called on
|
||||||
|
// torrents without metadata
|
||||||
|
if ((m_flags & disconnect) == 0)
|
||||||
|
{
|
||||||
|
handles[session_idx].status();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_flags & disconnect)
|
||||||
|
&& session_idx == 1
|
||||||
|
&& alert_cast<metadata_received_alert>(alert))
|
||||||
|
{
|
||||||
|
ses.remove_torrent(handles[session_idx]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void on_torrent_added(int idx, torrent_handle h) override
|
||||||
|
{
|
||||||
|
if (idx == 0) return;
|
||||||
|
|
||||||
|
if (m_flags & upload_only)
|
||||||
|
{
|
||||||
|
h.set_upload_mode(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void on_exit(std::vector<torrent_handle> const& torrents) override
|
||||||
|
{
|
||||||
|
// in this case we should have completed without downloading anything
|
||||||
|
// because the downloader had upload only set
|
||||||
|
if (m_flags & upload_only) return;
|
||||||
|
|
||||||
|
swarm_config::on_exit(torrents);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_flags;
|
||||||
|
boost::shared_ptr<torrent_plugin> (*m_plugin)(torrent_handle const&, void*);
|
||||||
|
};
|
||||||
|
|
||||||
|
TORRENT_TEST(ut_metadata_encryption_reverse)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(full_encryption | reverse, &create_ut_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ut_metadata_encryption_utp)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(full_encryption | utp, &create_ut_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ut_metadata_reverse)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(reverse, &create_ut_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(ut_metadata_upload_only)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(upload_only, &create_ut_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
|
|
||||||
|
// TODO: add more flags combinations?
|
||||||
|
|
||||||
|
TORRENT_TEST(metadata_encryption_reverse)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(full_encryption | reverse, &create_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(metadata_encryption_utp)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(full_encryption | utp, &create_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(metadata_reverse)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(reverse, &create_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(metadata_upload_only)
|
||||||
|
{
|
||||||
|
test_swarm_config cfg(upload_only, &create_metadata_plugin);
|
||||||
|
setup_swarm(2, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -105,7 +105,8 @@ struct swarm_config : swarm_setup_provider
|
||||||
// called for every alert. if the simulation is done, return true
|
// called for every alert. if the simulation is done, return true
|
||||||
virtual bool on_alert(libtorrent::alert const* alert
|
virtual bool on_alert(libtorrent::alert const* alert
|
||||||
, int session_idx
|
, int session_idx
|
||||||
, std::vector<libtorrent::torrent_handle> const& torrents)
|
, std::vector<libtorrent::torrent_handle> const& torrents
|
||||||
|
, libtorrent::session& ses) override
|
||||||
{
|
{
|
||||||
if (torrents.empty()) return false;
|
if (torrents.empty()) return false;
|
||||||
|
|
||||||
|
@ -126,7 +127,7 @@ struct swarm_config : swarm_setup_provider
|
||||||
// called for every torrent that's added (and every session that's started).
|
// called for every torrent that's added (and every session that's started).
|
||||||
// this is useful to give every session a unique save path and to make some
|
// this is useful to give every session a unique save path and to make some
|
||||||
// sessions seeds and others downloaders
|
// sessions seeds and others downloaders
|
||||||
virtual libtorrent::add_torrent_params add_torrent(int idx)
|
virtual libtorrent::add_torrent_params add_torrent(int idx) override
|
||||||
{
|
{
|
||||||
add_torrent_params p;
|
add_torrent_params p;
|
||||||
p.flags &= ~add_torrent_params::flag_paused;
|
p.flags &= ~add_torrent_params::flag_paused;
|
||||||
|
@ -148,7 +149,7 @@ struct swarm_config : swarm_setup_provider
|
||||||
}
|
}
|
||||||
|
|
||||||
// called for every session that's added
|
// called for every session that's added
|
||||||
virtual libtorrent::settings_pack add_session(int idx)
|
virtual libtorrent::settings_pack add_session(int idx) override
|
||||||
{
|
{
|
||||||
settings_pack pack = settings();
|
settings_pack pack = settings();
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,6 @@ test-suite libtorrent :
|
||||||
[ run test_http_connection.cpp ]
|
[ run test_http_connection.cpp ]
|
||||||
[ run test_torrent.cpp ]
|
[ run test_torrent.cpp ]
|
||||||
[ run test_transfer.cpp ]
|
[ run test_transfer.cpp ]
|
||||||
[ run test_metadata_extension.cpp ]
|
|
||||||
[ run test_trackers_extension.cpp ]
|
[ run test_trackers_extension.cpp ]
|
||||||
[ run test_time_critical.cpp ]
|
[ run test_time_critical.cpp ]
|
||||||
[ run test_pex.cpp ]
|
[ run test_pex.cpp ]
|
||||||
|
@ -201,7 +200,6 @@ alias win-tests :
|
||||||
test_torrent
|
test_torrent
|
||||||
test_transfer
|
test_transfer
|
||||||
test_time_critical
|
test_time_critical
|
||||||
test_metadata_extension
|
|
||||||
test_pex
|
test_pex
|
||||||
test_priority
|
test_priority
|
||||||
test_super_seeding
|
test_super_seeding
|
||||||
|
|
|
@ -13,7 +13,6 @@ test_programs = \
|
||||||
test_fast_extension \
|
test_fast_extension \
|
||||||
test_http_connection \
|
test_http_connection \
|
||||||
test_lsd \
|
test_lsd \
|
||||||
test_metadata_extension \
|
|
||||||
test_pe_crypto \
|
test_pe_crypto \
|
||||||
test_pex \
|
test_pex \
|
||||||
test_read_piece \
|
test_read_piece \
|
||||||
|
@ -170,7 +169,6 @@ test_checking_SOURCES = test_checking.cpp
|
||||||
test_fast_extension_SOURCES = test_fast_extension.cpp
|
test_fast_extension_SOURCES = test_fast_extension.cpp
|
||||||
test_http_connection_SOURCES = test_http_connection.cpp
|
test_http_connection_SOURCES = test_http_connection.cpp
|
||||||
test_lsd_SOURCES = test_lsd.cpp
|
test_lsd_SOURCES = test_lsd.cpp
|
||||||
test_metadata_extension_SOURCES = test_metadata_extension.cpp
|
|
||||||
test_pe_crypto_SOURCES = test_pe_crypto.cpp
|
test_pe_crypto_SOURCES = test_pe_crypto.cpp
|
||||||
test_pex_SOURCES = test_pex.cpp
|
test_pex_SOURCES = test_pex.cpp
|
||||||
test_read_piece_SOURCES = test_read_piece.cpp
|
test_read_piece_SOURCES = test_read_piece.cpp
|
||||||
|
|
|
@ -1,235 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
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 "test.hpp"
|
|
||||||
#include "setup_transfer.hpp"
|
|
||||||
#include "test_utils.hpp"
|
|
||||||
#include "test_utils.hpp"
|
|
||||||
|
|
||||||
#include "libtorrent/session.hpp"
|
|
||||||
#include "libtorrent/hasher.hpp"
|
|
||||||
#include "libtorrent/thread.hpp"
|
|
||||||
#include "libtorrent/extensions/metadata_transfer.hpp"
|
|
||||||
#include "libtorrent/extensions/ut_metadata.hpp"
|
|
||||||
|
|
||||||
#include <boost/tuple/tuple.hpp>
|
|
||||||
|
|
||||||
using boost::tuples::ignore;
|
|
||||||
|
|
||||||
enum flags_t
|
|
||||||
{
|
|
||||||
clear_files = 1,
|
|
||||||
|
|
||||||
// disconnect immediately after receiving the metadata (to test that
|
|
||||||
// edge case, it caused a crash once)
|
|
||||||
disconnect = 2,
|
|
||||||
|
|
||||||
// force encryption (to make sure the plugin uses the peer_connection
|
|
||||||
// API in a compatible way)
|
|
||||||
full_encryption = 4,
|
|
||||||
|
|
||||||
// have the downloader connect to the seeder
|
|
||||||
// (instead of the other way around)
|
|
||||||
reverse = 8,
|
|
||||||
|
|
||||||
// only use uTP
|
|
||||||
utp = 16,
|
|
||||||
|
|
||||||
// upload-only mode
|
|
||||||
upload_only = 32
|
|
||||||
};
|
|
||||||
|
|
||||||
void test_transfer(int flags
|
|
||||||
, boost::shared_ptr<libtorrent::torrent_plugin> (*constructor)(libtorrent::torrent_handle const&, void*)
|
|
||||||
, int timeout)
|
|
||||||
{
|
|
||||||
using namespace libtorrent;
|
|
||||||
namespace lt = libtorrent;
|
|
||||||
|
|
||||||
fprintf(stderr, "\n==== test transfer: timeout=%d %s%s%s%s%s%s ====\n\n"
|
|
||||||
, timeout
|
|
||||||
, (flags & clear_files) ? "clear-files " : ""
|
|
||||||
, (flags & disconnect) ? "disconnect " : ""
|
|
||||||
, (flags & full_encryption) ? "encryption " : ""
|
|
||||||
, (flags & reverse) ? "reverse " : ""
|
|
||||||
, (flags & utp) ? "utp " : ""
|
|
||||||
, (flags & upload_only) ? "upload_only " : "");
|
|
||||||
|
|
||||||
// these are declared before the session objects
|
|
||||||
// so that they are destructed last. This enables
|
|
||||||
// the sessions to destruct in parallel
|
|
||||||
session_proxy p1;
|
|
||||||
session_proxy p2;
|
|
||||||
|
|
||||||
settings_pack pack;
|
|
||||||
pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_forced);
|
|
||||||
pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_forced);
|
|
||||||
pack.set_bool(settings_pack::prefer_rc4, flags & full_encryption);
|
|
||||||
|
|
||||||
if (flags & utp)
|
|
||||||
{
|
|
||||||
pack.set_bool(settings_pack::utp_dynamic_sock_buf, true);
|
|
||||||
pack.set_bool(settings_pack::enable_incoming_utp, true);
|
|
||||||
pack.set_bool(settings_pack::enable_outgoing_utp, true);
|
|
||||||
pack.set_bool(settings_pack::enable_incoming_tcp, false);
|
|
||||||
pack.set_bool(settings_pack::enable_outgoing_tcp, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pack.set_bool(settings_pack::enable_incoming_utp, false);
|
|
||||||
pack.set_bool(settings_pack::enable_outgoing_utp, false);
|
|
||||||
pack.set_bool(settings_pack::enable_incoming_tcp, true);
|
|
||||||
pack.set_bool(settings_pack::enable_outgoing_tcp, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: it would be nice to test reversing
|
|
||||||
// which session is making the connection as well
|
|
||||||
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:48100");
|
|
||||||
lt::session ses1(pack);
|
|
||||||
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:49100");
|
|
||||||
lt::session ses2(pack);
|
|
||||||
ses1.add_extension(constructor);
|
|
||||||
ses2.add_extension(constructor);
|
|
||||||
torrent_handle tor1;
|
|
||||||
torrent_handle tor2;
|
|
||||||
|
|
||||||
lt::session* downloader = &ses2;
|
|
||||||
lt::session* seed = &ses1;
|
|
||||||
|
|
||||||
boost::tie(tor1, tor2, ignore) = setup_transfer(seed, downloader, NULL
|
|
||||||
, flags & clear_files, true, false, "_meta");
|
|
||||||
|
|
||||||
if (flags & upload_only)
|
|
||||||
{
|
|
||||||
tor2.set_upload_mode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & reverse)
|
|
||||||
{
|
|
||||||
error_code ec;
|
|
||||||
int port = seed->listen_port();
|
|
||||||
fprintf(stderr, "%s: downloader: connecting peer port: %d\n"
|
|
||||||
, time_now_string(), port);
|
|
||||||
tor2.connect_peer(tcp::endpoint(address::from_string("127.0.0.1", ec)
|
|
||||||
, port));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
error_code ec;
|
|
||||||
int port = downloader->listen_port();
|
|
||||||
fprintf(stderr, "%s: seed: connecting peer port: %d\n"
|
|
||||||
, time_now_string(), port);
|
|
||||||
tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1", ec)
|
|
||||||
, port));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < timeout * 10; ++i)
|
|
||||||
{
|
|
||||||
// make sure this function can be called on
|
|
||||||
// torrents without metadata
|
|
||||||
if ((flags & disconnect) == 0) tor2.status();
|
|
||||||
print_alerts(*seed, "seed", false, true);
|
|
||||||
print_alerts(*downloader, "downloader", false, true);
|
|
||||||
|
|
||||||
if ((flags & disconnect) && tor2.is_valid()) downloader->remove_torrent(tor2);
|
|
||||||
if ((flags & disconnect) == 0
|
|
||||||
&& tor2.status().has_metadata) break;
|
|
||||||
test_sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & disconnect) goto done;
|
|
||||||
|
|
||||||
TEST_CHECK(tor2.status().has_metadata);
|
|
||||||
|
|
||||||
if (flags & upload_only) goto done;
|
|
||||||
|
|
||||||
fprintf(stderr, "waiting for transfer to complete\n");
|
|
||||||
|
|
||||||
for (int i = 0; i < timeout * 10; ++i)
|
|
||||||
{
|
|
||||||
torrent_status st1 = tor1.status();
|
|
||||||
torrent_status st2 = tor2.status();
|
|
||||||
|
|
||||||
print_alerts(*seed, "seed", false, true);
|
|
||||||
print_alerts(*downloader, "downloader", false, true);
|
|
||||||
|
|
||||||
print_ses_rate(i / 10.f, &st1, &st2);
|
|
||||||
if (st2.is_seeding) break;
|
|
||||||
test_sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CHECK(tor2.status().is_seeding);
|
|
||||||
if (tor2.status().is_seeding) fprintf(stderr, "done\n");
|
|
||||||
|
|
||||||
done:
|
|
||||||
|
|
||||||
// this allows shutting down the sessions in parallel
|
|
||||||
p1 = seed->abort();
|
|
||||||
p2 = downloader->abort();
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
remove_all("tmp1_meta", ec);
|
|
||||||
remove_all("tmp2_meta", ec);
|
|
||||||
}
|
|
||||||
|
|
||||||
TORRENT_TEST(metadata_extension)
|
|
||||||
{
|
|
||||||
using namespace libtorrent;
|
|
||||||
|
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
|
|
||||||
#ifdef TORRENT_USE_VALGRIND
|
|
||||||
const int timeout = 8;
|
|
||||||
#else
|
|
||||||
const int timeout = 3;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
test_transfer(full_encryption | reverse, &create_ut_metadata_plugin, timeout);
|
|
||||||
test_transfer(full_encryption | utp, &create_ut_metadata_plugin, timeout);
|
|
||||||
test_transfer(reverse, &create_ut_metadata_plugin, timeout);
|
|
||||||
test_transfer(upload_only, &create_ut_metadata_plugin, timeout);
|
|
||||||
|
|
||||||
#ifndef TORRENT_NO_DEPRECATE
|
|
||||||
for (int f = 0; f <= (clear_files | disconnect | full_encryption); ++f)
|
|
||||||
test_transfer(f, &create_metadata_plugin, timeout * 2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int f = 0; f <= (clear_files | disconnect | full_encryption); ++f)
|
|
||||||
test_transfer(f, &create_ut_metadata_plugin, timeout);
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
remove_all("tmp1", ec);
|
|
||||||
remove_all("tmp2", ec);
|
|
||||||
|
|
||||||
#endif // TORRENT_NO_DEPRECATE
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue