port sim tests to use the new setup_swarm API
This commit is contained in:
parent
1f453bf159
commit
d505f93d7a
|
@ -243,7 +243,8 @@ namespace libtorrent
|
||||||
|
|
||||||
// set to true when this torrent has been paused but
|
// set to true when this torrent has been paused but
|
||||||
// is waiting to finish all current download requests
|
// is waiting to finish all current download requests
|
||||||
// before actually closing all connections
|
// before actually closing all connections, When in graceful pause mode,
|
||||||
|
// m_allow_peers is also false.
|
||||||
bool m_graceful_pause_mode:1;
|
bool m_graceful_pause_mode:1;
|
||||||
|
|
||||||
// state subscription. If set, a pointer to this torrent
|
// state subscription. If set, a pointer to this torrent
|
||||||
|
|
|
@ -52,14 +52,6 @@ using namespace sim;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
std::string save_path(int swarm_id, int idx)
|
|
||||||
{
|
|
||||||
char path[200];
|
|
||||||
snprintf(path, sizeof(path), "swarm-%04d-peer-%02d"
|
|
||||||
, swarm_id, idx);
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
int transfer_rate(lt::address ip)
|
int transfer_rate(lt::address ip)
|
||||||
{
|
{
|
||||||
// in order to get a heterogeneous network, the last digit in the IP
|
// in order to get a heterogeneous network, the last digit in the IP
|
||||||
|
@ -104,9 +96,22 @@ sim::route dsl_config::outgoing_route(asio::ip::address ip)
|
||||||
return sim::route().append(it->second);
|
return sim::route().append(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_extra_peers(lt::session* ses)
|
std::string save_path(int swarm_id, int idx)
|
||||||
{
|
{
|
||||||
auto handles = ses->get_torrents();
|
char path[200];
|
||||||
|
snprintf(path, sizeof(path), "swarm-%04d-peer-%02d"
|
||||||
|
, swarm_id, idx);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
lt::address addr(char const* str)
|
||||||
|
{
|
||||||
|
return lt::address::from_string(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_extra_peers(lt::session& ses)
|
||||||
|
{
|
||||||
|
auto handles = ses.get_torrents();
|
||||||
TEST_EQUAL(handles.size(), 1);
|
TEST_EQUAL(handles.size(), 1);
|
||||||
auto h = handles[0];
|
auto h = handles[0];
|
||||||
|
|
||||||
|
@ -114,45 +119,72 @@ void add_extra_peers(lt::session* ses)
|
||||||
{
|
{
|
||||||
char ep[30];
|
char ep[30];
|
||||||
snprintf(ep, sizeof(ep), "60.0.0.%d", i + 1);
|
snprintf(ep, sizeof(ep), "60.0.0.%d", i + 1);
|
||||||
h.connect_peer(lt::tcp::endpoint(
|
h.connect_peer(lt::tcp::endpoint(addr(ep), 6881));
|
||||||
lt::address_v4::from_string(ep), 6881));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lt::torrent_status get_status(lt::session* ses)
|
lt::torrent_status get_status(lt::session& ses)
|
||||||
{
|
{
|
||||||
auto handles = ses->get_torrents();
|
auto handles = ses.get_torrents();
|
||||||
TEST_EQUAL(handles.size(), 1);
|
TEST_EQUAL(handles.size(), 1);
|
||||||
auto h = handles[0];
|
auto h = handles[0];
|
||||||
return h.status();
|
return h.status();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_seed(lt::session* ses)
|
bool has_metadata(lt::session& ses)
|
||||||
{
|
{
|
||||||
auto handles = ses->get_torrents();
|
auto handles = ses.get_torrents();
|
||||||
|
TEST_EQUAL(handles.size(), 1);
|
||||||
|
auto h = handles[0];
|
||||||
|
return h.status().has_metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_seed(lt::session& ses)
|
||||||
|
{
|
||||||
|
auto handles = ses.get_torrents();
|
||||||
TEST_EQUAL(handles.size(), 1);
|
TEST_EQUAL(handles.size(), 1);
|
||||||
auto h = handles[0];
|
auto h = handles[0];
|
||||||
return h.status().is_seeding;
|
return h.status().is_seeding;
|
||||||
}
|
}
|
||||||
|
|
||||||
int completed_pieces(lt::session* ses)
|
int completed_pieces(lt::session& ses)
|
||||||
{
|
{
|
||||||
auto handles = ses->get_torrents();
|
auto handles = ses.get_torrents();
|
||||||
TEST_EQUAL(handles.size(), 1);
|
TEST_EQUAL(handles.size(), 1);
|
||||||
auto h = handles[0];
|
auto h = handles[0];
|
||||||
return h.status().num_pieces;
|
return h.status().num_pieces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void utp_only(lt::settings_pack& p)
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
p.set_bool(settings_pack::enable_outgoing_tcp, false);
|
||||||
|
p.set_bool(settings_pack::enable_incoming_tcp, false);
|
||||||
|
p.set_bool(settings_pack::enable_outgoing_utp, true);
|
||||||
|
p.set_bool(settings_pack::enable_incoming_utp, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void enable_enc(lt::settings_pack& p)
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
p.set_bool(settings_pack::prefer_rc4, true);
|
||||||
|
p.set_int(settings_pack::in_enc_policy, settings_pack::pe_forced);
|
||||||
|
p.set_int(settings_pack::out_enc_policy, settings_pack::pe_forced);
|
||||||
|
p.set_int(settings_pack::allowed_enc_level, settings_pack::pe_both);
|
||||||
|
}
|
||||||
|
|
||||||
void setup_swarm(int num_nodes
|
void setup_swarm(int num_nodes
|
||||||
, swarm_test type
|
, swarm_test type
|
||||||
, std::function<void(lt::settings_pack&)> new_session
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
, std::function<void(lt::add_torrent_params&)> add_torrent
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
, std::function<void(lt::alert const*, lt::session*)> on_alert
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
, std::function<int(int, lt::session*)> terminate)
|
, std::function<int(int, lt::session&)> terminate)
|
||||||
{
|
{
|
||||||
dsl_config network_cfg;
|
dsl_config network_cfg;
|
||||||
sim::simulation sim{network_cfg};
|
sim::simulation sim{network_cfg};
|
||||||
setup_swarm(num_nodes, type, sim, new_session, add_torrent, on_alert, terminate);
|
|
||||||
|
setup_swarm(num_nodes, type, sim, new_session
|
||||||
|
, add_torrent, on_alert, terminate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup_swarm(int num_nodes
|
void setup_swarm(int num_nodes
|
||||||
|
@ -160,10 +192,51 @@ void setup_swarm(int num_nodes
|
||||||
, sim::simulation& sim
|
, sim::simulation& sim
|
||||||
, std::function<void(lt::settings_pack&)> new_session
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
, std::function<void(lt::add_torrent_params&)> add_torrent
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
, std::function<void(lt::alert const*, lt::session*)> on_alert
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
, std::function<int(int, lt::session*)> terminate)
|
, std::function<int(int, lt::session&)> terminate)
|
||||||
{
|
{
|
||||||
asio::io_service ios(sim, asio::ip::address_v4::from_string("0.0.0.0"));
|
lt::settings_pack pack = settings();
|
||||||
|
|
||||||
|
lt::add_torrent_params p;
|
||||||
|
p.flags &= ~lt::add_torrent_params::flag_paused;
|
||||||
|
p.flags &= ~lt::add_torrent_params::flag_auto_managed;
|
||||||
|
|
||||||
|
setup_swarm(num_nodes, type, sim, pack, p, new_session
|
||||||
|
, add_torrent, on_alert, terminate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_swarm(int num_nodes
|
||||||
|
, swarm_test type
|
||||||
|
, sim::simulation& sim
|
||||||
|
, lt::settings_pack const& default_settings
|
||||||
|
, lt::add_torrent_params const& default_add_torrent
|
||||||
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
|
, std::function<int(int, lt::session&)> terminate)
|
||||||
|
{
|
||||||
|
setup_swarm(num_nodes, type, sim
|
||||||
|
, default_settings
|
||||||
|
, default_add_torrent
|
||||||
|
, [](lt::session&) {}
|
||||||
|
, new_session
|
||||||
|
, add_torrent
|
||||||
|
, on_alert
|
||||||
|
, terminate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup_swarm(int num_nodes
|
||||||
|
, swarm_test type
|
||||||
|
, sim::simulation& sim
|
||||||
|
, lt::settings_pack const& default_settings
|
||||||
|
, lt::add_torrent_params const& default_add_torrent
|
||||||
|
, std::function<void(lt::session&)> init_session
|
||||||
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
|
, std::function<int(int, lt::session&)> terminate)
|
||||||
|
{
|
||||||
|
asio::io_service ios(sim, addr("0.0.0.0"));
|
||||||
lt::time_point start_time(lt::clock_type::now());
|
lt::time_point start_time(lt::clock_type::now());
|
||||||
|
|
||||||
std::vector<boost::shared_ptr<lt::session> > nodes;
|
std::vector<boost::shared_ptr<lt::session> > nodes;
|
||||||
|
@ -189,9 +262,9 @@ void setup_swarm(int num_nodes
|
||||||
char ep[30];
|
char ep[30];
|
||||||
snprintf(ep, sizeof(ep), "50.0.%d.%d", (i + 1) >> 8, (i + 1) & 0xff);
|
snprintf(ep, sizeof(ep), "50.0.%d.%d", (i + 1) >> 8, (i + 1) & 0xff);
|
||||||
io_service.push_back(boost::make_shared<sim::asio::io_service>(
|
io_service.push_back(boost::make_shared<sim::asio::io_service>(
|
||||||
boost::ref(sim), asio::ip::address_v4::from_string(ep)));
|
boost::ref(sim), addr(ep)));
|
||||||
|
|
||||||
lt::settings_pack pack = settings();
|
lt::settings_pack pack = default_settings;
|
||||||
|
|
||||||
// make sure the sessions have different peer ids
|
// make sure the sessions have different peer ids
|
||||||
lt::peer_id pid;
|
lt::peer_id pid;
|
||||||
|
@ -202,25 +275,19 @@ void setup_swarm(int num_nodes
|
||||||
boost::shared_ptr<lt::session> ses =
|
boost::shared_ptr<lt::session> ses =
|
||||||
boost::make_shared<lt::session>(pack
|
boost::make_shared<lt::session>(pack
|
||||||
, boost::ref(*io_service.back()));
|
, boost::ref(*io_service.back()));
|
||||||
|
init_session(*ses);
|
||||||
nodes.push_back(ses);
|
nodes.push_back(ses);
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
// the other sessions should not talk to each other
|
// the other sessions should not talk to each other
|
||||||
lt::ip_filter filter;
|
lt::ip_filter filter;
|
||||||
filter.add_rule(lt::address::from_string("0.0.0.0")
|
filter.add_rule(addr("0.0.0.0"), addr("255.255.255.255"), lt::ip_filter::blocked);
|
||||||
, lt::address::from_string("255.255.255.255"), lt::ip_filter::blocked);
|
filter.add_rule(addr("50.0.0.1"), addr("50.0.0.1"), 0);
|
||||||
|
|
||||||
filter.add_rule(lt::address::from_string("50.0.0.1")
|
|
||||||
, lt::address::from_string("50.0.0.1"), 0);
|
|
||||||
|
|
||||||
ses->set_ip_filter(filter);
|
ses->set_ip_filter(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
lt::add_torrent_params p;
|
lt::add_torrent_params p = default_add_torrent;
|
||||||
p.flags &= ~lt::add_torrent_params::flag_paused;
|
|
||||||
p.flags &= ~lt::add_torrent_params::flag_auto_managed;
|
|
||||||
|
|
||||||
if (type == swarm_test::download)
|
if (type == swarm_test::download)
|
||||||
{
|
{
|
||||||
// in download tests, session 0 is a downloader and every other session
|
// in download tests, session 0 is a downloader and every other session
|
||||||
|
@ -269,16 +336,19 @@ void setup_swarm(int num_nodes
|
||||||
lt::torrent_handle h = at->handle;
|
lt::torrent_handle h = at->handle;
|
||||||
|
|
||||||
// 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 < num_nodes; ++k)
|
// start at 1 to avoid self-connects
|
||||||
|
for (int k = 1; k < num_nodes; ++k)
|
||||||
{
|
{
|
||||||
|
// TODO: the pattern of creating an address from a format
|
||||||
|
// string and an integer is common. It should probably be
|
||||||
|
// factored out into its own function
|
||||||
char ep[30];
|
char ep[30];
|
||||||
snprintf(ep, sizeof(ep), "50.0.%d.%d", (k + 1) >> 8, (k + 1) & 0xff);
|
snprintf(ep, sizeof(ep), "50.0.%d.%d", (k + 1) >> 8, (k + 1) & 0xff);
|
||||||
h.connect_peer(lt::tcp::endpoint(
|
h.connect_peer(lt::tcp::endpoint(addr(ep), 6881));
|
||||||
lt::address_v4::from_string(ep), 6881));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
on_alert(a, ses);
|
on_alert(a, *ses);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -290,13 +360,13 @@ void setup_swarm(int num_nodes
|
||||||
{
|
{
|
||||||
if (ec) return;
|
if (ec) return;
|
||||||
|
|
||||||
bool shut_down = terminate(tick, nodes[0].get());
|
bool shut_down = terminate(tick, *nodes[0]);
|
||||||
|
|
||||||
if (type == swarm_test::upload)
|
if (type == swarm_test::upload)
|
||||||
{
|
{
|
||||||
shut_down |= std::all_of(nodes.begin() + 1, nodes.end()
|
shut_down |= std::all_of(nodes.begin() + 1, nodes.end()
|
||||||
, [](boost::shared_ptr<lt::session> const& s)
|
, [](boost::shared_ptr<lt::session> const& s)
|
||||||
{ return is_seed(s.get()); });
|
{ return is_seed(*s); });
|
||||||
|
|
||||||
if (tick > 70 * (num_nodes - 1) && !shut_down)
|
if (tick > 70 * (num_nodes - 1) && !shut_down)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,21 +55,54 @@ void setup_swarm(int num_nodes
|
||||||
, swarm_test type
|
, swarm_test type
|
||||||
, std::function<void(lt::settings_pack&)> new_session
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
, std::function<void(lt::add_torrent_params&)> add_torrent
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
, std::function<void(lt::alert const*, lt::session*)> on_alert
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
, std::function<int(int, lt::session*)> terminate);
|
, std::function<int(int, lt::session&)> terminate);
|
||||||
|
|
||||||
void setup_swarm(int num_nodes
|
void setup_swarm(int num_nodes
|
||||||
, swarm_test type
|
, swarm_test type
|
||||||
, sim::simulation& sim
|
, sim::simulation& sim
|
||||||
, std::function<void(lt::settings_pack&)> new_session
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
, std::function<void(lt::add_torrent_params&)> add_torrent
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
, std::function<void(lt::alert const*, lt::session*)> on_alert
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
, std::function<int(int, lt::session*)> terminate);
|
, std::function<int(int, lt::session&)> terminate);
|
||||||
|
|
||||||
bool is_seed(lt::session* ses);
|
void setup_swarm(int num_nodes
|
||||||
int completed_pieces(lt::session* ses);
|
, swarm_test type
|
||||||
void add_extra_peers(lt::session* ses);
|
, sim::simulation& sim
|
||||||
lt::torrent_status get_status(lt::session* ses);
|
, lt::settings_pack const& default_settings
|
||||||
|
, lt::add_torrent_params const& default_add_torrent
|
||||||
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
|
, std::function<int(int, lt::session&)> terminate);
|
||||||
|
|
||||||
|
void setup_swarm(int num_nodes
|
||||||
|
, swarm_test type
|
||||||
|
, sim::simulation& sim
|
||||||
|
, lt::settings_pack const& default_settings
|
||||||
|
, lt::add_torrent_params const& default_add_torrent
|
||||||
|
, std::function<void(lt::session&)> init_session
|
||||||
|
, std::function<void(lt::settings_pack&)> new_session
|
||||||
|
, std::function<void(lt::add_torrent_params&)> add_torrent
|
||||||
|
, std::function<void(lt::alert const*, lt::session&)> on_alert
|
||||||
|
, std::function<int(int, lt::session&)> terminate);
|
||||||
|
|
||||||
|
bool has_metadata(lt::session& ses);
|
||||||
|
bool is_seed(lt::session& ses);
|
||||||
|
int completed_pieces(lt::session& ses);
|
||||||
|
void add_extra_peers(lt::session& ses);
|
||||||
|
lt::torrent_status get_status(lt::session& ses);
|
||||||
|
|
||||||
|
std::string save_path(int swarm_id, int idx);
|
||||||
|
|
||||||
|
// construct an address from string
|
||||||
|
lt::address addr(char const* str);
|
||||||
|
|
||||||
|
// disable TCP and enable uTP
|
||||||
|
void utp_only(lt::settings_pack& pack);
|
||||||
|
|
||||||
|
// force encrypted connections
|
||||||
|
void enable_enc(lt::settings_pack& pack);
|
||||||
|
|
||||||
struct dsl_config : sim::default_config
|
struct dsl_config : sim::default_config
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,15 +35,16 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/settings_pack.hpp"
|
#include "libtorrent/settings_pack.hpp"
|
||||||
#include "libtorrent/alert_types.hpp"
|
#include "libtorrent/alert_types.hpp"
|
||||||
#include "libtorrent/deadline_timer.hpp"
|
#include "libtorrent/deadline_timer.hpp"
|
||||||
#include "swarm_config.hpp"
|
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "create_torrent.hpp"
|
#include "create_torrent.hpp"
|
||||||
#include "simulator/simulator.hpp"
|
#include "simulator/simulator.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace sim;
|
using namespace sim;
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
const int num_torrents = 10;
|
const int num_torrents = 10;
|
||||||
|
namespace lt = libtorrent;
|
||||||
|
|
||||||
using sim::asio::ip::address_v4;
|
using sim::asio::ip::address_v4;
|
||||||
|
|
||||||
|
@ -96,11 +97,11 @@ void run_test(Settings const& sett, Setup const& setup, Test const& test)
|
||||||
TORRENT_TEST(dont_count_slow_torrents)
|
TORRENT_TEST(dont_count_slow_torrents)
|
||||||
{
|
{
|
||||||
run_test(
|
run_test(
|
||||||
[](settings_pack& sett) {
|
[](lt::settings_pack& sett) {
|
||||||
// session settings
|
// session settings
|
||||||
sett.set_bool(settings_pack::dont_count_slow_torrents, true);
|
sett.set_bool(lt::settings_pack::dont_count_slow_torrents, true);
|
||||||
sett.set_int(settings_pack::active_downloads, 1);
|
sett.set_int(lt::settings_pack::active_downloads, 1);
|
||||||
sett.set_int(settings_pack::active_seeds, 1);
|
sett.set_int(lt::settings_pack::active_seeds, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
[](lt::session& ses) {
|
[](lt::session& ses) {
|
||||||
|
@ -108,8 +109,8 @@ TORRENT_TEST(dont_count_slow_torrents)
|
||||||
for (int i = 0; i < num_torrents; ++i)
|
for (int i = 0; i < num_torrents; ++i)
|
||||||
{
|
{
|
||||||
lt::add_torrent_params params = create_torrent(i, false);
|
lt::add_torrent_params params = create_torrent(i, false);
|
||||||
params.flags |= add_torrent_params::flag_auto_managed;
|
params.flags |= lt::add_torrent_params::flag_auto_managed;
|
||||||
params.flags |= add_torrent_params::flag_paused;
|
params.flags |= lt::add_torrent_params::flag_paused;
|
||||||
ses.async_add_torrent(params);
|
ses.async_add_torrent(params);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,7 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "setup_swarm.hpp"
|
#include "setup_swarm.hpp"
|
||||||
#include "swarm_config.hpp"
|
|
||||||
#include "simulator/simulator.hpp"
|
#include "simulator/simulator.hpp"
|
||||||
#include "simulator/http_server.hpp"
|
#include "simulator/http_server.hpp"
|
||||||
#include "simulator/socks_server.hpp"
|
#include "simulator/socks_server.hpp"
|
||||||
|
|
|
@ -32,218 +32,139 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
#include "test_utils.hpp"
|
#include "test_utils.hpp"
|
||||||
#include "swarm_config.hpp"
|
#include "settings.hpp"
|
||||||
|
#include "setup_swarm.hpp"
|
||||||
|
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
#include "libtorrent/hasher.hpp"
|
|
||||||
#include "libtorrent/alert_types.hpp"
|
#include "libtorrent/alert_types.hpp"
|
||||||
#include "libtorrent/torrent_info.hpp"
|
#include "libtorrent/torrent_info.hpp"
|
||||||
#include "libtorrent/thread.hpp"
|
#include "libtorrent/add_torrent_params.hpp"
|
||||||
|
#include "libtorrent/magnet_uri.hpp"
|
||||||
#include "libtorrent/extensions/metadata_transfer.hpp"
|
#include "libtorrent/extensions/metadata_transfer.hpp"
|
||||||
#include "libtorrent/extensions/ut_metadata.hpp"
|
#include "libtorrent/extensions/ut_metadata.hpp"
|
||||||
|
|
||||||
#include <boost/tuple/tuple.hpp>
|
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
namespace lt = libtorrent;
|
||||||
|
|
||||||
enum flags_t
|
enum flags_t
|
||||||
{
|
{
|
||||||
clear_files = 1,
|
|
||||||
|
|
||||||
// disconnect immediately after receiving the metadata (to test that
|
// disconnect immediately after receiving the metadata (to test that
|
||||||
// edge case, it caused a crash once)
|
// edge case, it caused a crash once)
|
||||||
disconnect = 2,
|
disconnect = 1,
|
||||||
|
|
||||||
// force encryption (to make sure the plugin uses the peer_connection
|
// force encryption (to make sure the plugin uses the peer_connection
|
||||||
// API in a compatible way)
|
// API in a compatible way)
|
||||||
full_encryption = 4,
|
full_encryption = 2,
|
||||||
|
|
||||||
// have the downloader connect to the seeder
|
// have the downloader connect to the seeder
|
||||||
// (instead of the other way around)
|
// (instead of the other way around)
|
||||||
reverse = 8,
|
reverse = 4,
|
||||||
|
|
||||||
// only use uTP
|
// only use uTP
|
||||||
utp = 16,
|
utp = 8,
|
||||||
|
|
||||||
// upload-only mode
|
// upload-only mode
|
||||||
upload_only = 32
|
upload_only = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
struct test_swarm_config : swarm_config
|
void run_metadata_test(int flags)
|
||||||
{
|
{
|
||||||
test_swarm_config(int flags
|
int metadata_alerts = 0;
|
||||||
, boost::shared_ptr<torrent_plugin> (*plugin)(torrent_handle const&, void*))
|
|
||||||
: swarm_config()
|
|
||||||
, m_flags(flags)
|
|
||||||
, m_plugin(plugin)
|
|
||||||
, m_metadata_alerts(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// called for every session that's added
|
sim::default_config cfg;
|
||||||
virtual libtorrent::settings_pack add_session(int idx) override
|
sim::simulation sim{cfg};
|
||||||
|
|
||||||
|
lt::settings_pack default_settings = settings();
|
||||||
|
|
||||||
|
if (flags & full_encryption)
|
||||||
{
|
{
|
||||||
settings_pack s = swarm_config::add_session(idx);
|
enable_enc(default_settings);
|
||||||
|
|
||||||
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::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;
|
if (flags & utp)
|
||||||
|
{
|
||||||
|
utp_only(default_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual libtorrent::add_torrent_params add_torrent(int idx) override
|
lt::add_torrent_params default_add_torrent;
|
||||||
|
if (flags & upload_only)
|
||||||
{
|
{
|
||||||
add_torrent_params p = swarm_config::add_torrent(idx);
|
default_add_torrent.flags |= add_torrent_params::flag_upload_mode;
|
||||||
|
|
||||||
if (m_flags & reverse)
|
|
||||||
{
|
|
||||||
p.save_path = save_path(1 - idx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idx == 1)
|
setup_swarm(2, (flags & reverse) ? swarm_test::upload : swarm_test::download
|
||||||
{
|
// add session
|
||||||
// this is the guy who should download the metadata.
|
, [](lt::settings_pack& pack) {}
|
||||||
p.info_hash = p.ti->info_hash();
|
// add torrent
|
||||||
p.ti.reset();
|
, [](lt::add_torrent_params& params) {
|
||||||
|
// we want to add the torrent via magnet link
|
||||||
|
params.url = lt::make_magnet_uri(*params.ti);
|
||||||
|
params.ti.reset();
|
||||||
|
params.flags &= ~add_torrent_params::flag_upload_mode;
|
||||||
}
|
}
|
||||||
|
// on alert
|
||||||
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
|
||||||
return p;
|
if (alert_cast<metadata_received_alert>(a))
|
||||||
|
{
|
||||||
|
metadata_alerts += 1;
|
||||||
|
|
||||||
|
if (flags & disconnect)
|
||||||
|
{
|
||||||
|
ses.remove_torrent(ses.get_torrents()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
{
|
|
||||||
if (alert_cast<metadata_received_alert>(alert))
|
|
||||||
{
|
|
||||||
m_metadata_alerts += 1;
|
|
||||||
}
|
}
|
||||||
|
// terminate
|
||||||
// make sure this function can be called on
|
, [&](int ticks, lt::session& ses) -> bool
|
||||||
// torrents without metadata
|
|
||||||
if ((m_flags & disconnect) == 0)
|
|
||||||
{
|
{
|
||||||
handles[session_idx].status();
|
if (flags & reverse)
|
||||||
}
|
|
||||||
|
|
||||||
if ((m_flags & disconnect)
|
|
||||||
&& session_idx == 1
|
|
||||||
&& alert_cast<metadata_received_alert>(alert))
|
|
||||||
{
|
{
|
||||||
ses.remove_torrent(handles[session_idx]);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ticks > 70)
|
||||||
|
{
|
||||||
|
TEST_ERROR("timeout");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if ((flags & upload_only) && has_metadata(ses))
|
||||||
|
{
|
||||||
|
// the other peer is in upload mode and should not have sent any
|
||||||
|
// actual payload to us
|
||||||
|
TEST_CHECK(!is_seed(ses));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_seed(ses))
|
||||||
|
{
|
||||||
|
TEST_CHECK((flags & upload_only) == 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
});
|
||||||
|
|
||||||
virtual void on_torrent_added(int idx, torrent_handle h) override
|
TEST_EQUAL(metadata_alerts, 1);
|
||||||
{
|
}
|
||||||
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
|
|
||||||
{
|
|
||||||
TEST_EQUAL(m_metadata_alerts, 1);
|
|
||||||
// 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*);
|
|
||||||
int m_metadata_alerts;
|
|
||||||
};
|
|
||||||
|
|
||||||
TORRENT_TEST(ut_metadata_encryption_reverse)
|
TORRENT_TEST(ut_metadata_encryption_reverse)
|
||||||
{
|
{
|
||||||
test_swarm_config cfg(full_encryption | reverse, &create_ut_metadata_plugin);
|
run_metadata_test(full_encryption | reverse);
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(ut_metadata_encryption_utp)
|
TORRENT_TEST(ut_metadata_encryption_utp)
|
||||||
{
|
{
|
||||||
test_swarm_config cfg(full_encryption | utp, &create_ut_metadata_plugin);
|
run_metadata_test(full_encryption | utp);
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(ut_metadata_reverse)
|
TORRENT_TEST(ut_metadata_reverse)
|
||||||
{
|
{
|
||||||
test_swarm_config cfg(reverse, &create_ut_metadata_plugin);
|
run_metadata_test(reverse);
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(ut_metadata_upload_only)
|
TORRENT_TEST(ut_metadata_upload_only)
|
||||||
{
|
{
|
||||||
test_swarm_config cfg(upload_only, &create_ut_metadata_plugin);
|
run_metadata_test(upload_only);
|
||||||
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
|
|
||||||
|
|
||||||
|
|
|
@ -33,14 +33,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "libtorrent/hasher.hpp"
|
|
||||||
#include "libtorrent/pe_crypto.hpp"
|
#include "libtorrent/pe_crypto.hpp"
|
||||||
#include "libtorrent/session.hpp"
|
#include "libtorrent/session.hpp"
|
||||||
#include "libtorrent/random.hpp"
|
|
||||||
|
|
||||||
#include "setup_transfer.hpp"
|
#include "setup_transfer.hpp"
|
||||||
#include "swarm_config.hpp"
|
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
|
#include "setup_swarm.hpp"
|
||||||
|
|
||||||
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
#if !defined(TORRENT_DISABLE_ENCRYPTION) && !defined(TORRENT_DISABLE_EXTENSIONS)
|
||||||
|
|
||||||
|
@ -49,18 +48,14 @@ namespace lt = libtorrent;
|
||||||
|
|
||||||
char const* pe_policy(boost::uint8_t policy)
|
char const* pe_policy(boost::uint8_t policy)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
|
||||||
|
|
||||||
if (policy == settings_pack::pe_disabled) return "disabled";
|
if (policy == settings_pack::pe_disabled) return "disabled";
|
||||||
else if (policy == settings_pack::pe_enabled) return "enabled";
|
else if (policy == settings_pack::pe_enabled) return "enabled";
|
||||||
else if (policy == settings_pack::pe_forced) return "forced";
|
else if (policy == settings_pack::pe_forced) return "forced";
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
void display_settings(libtorrent::settings_pack const& s)
|
void display_pe_settings(libtorrent::settings_pack const& s)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
|
||||||
|
|
||||||
fprintf(stderr, "out_enc_policy - %s\tin_enc_policy - %s\n"
|
fprintf(stderr, "out_enc_policy - %s\tin_enc_policy - %s\n"
|
||||||
, pe_policy(s.get_int(settings_pack::out_enc_policy))
|
, pe_policy(s.get_int(settings_pack::out_enc_policy))
|
||||||
, pe_policy(s.get_int(settings_pack::in_enc_policy)));
|
, pe_policy(s.get_int(settings_pack::in_enc_policy)));
|
||||||
|
@ -72,108 +67,126 @@ void display_settings(libtorrent::settings_pack const& s)
|
||||||
, s.get_bool(settings_pack::prefer_rc4) ? "true": "false");
|
, s.get_bool(settings_pack::prefer_rc4) ? "true": "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct test_swarm_config : swarm_config
|
void test_transfer(int enc_policy, int level, bool prefer_rc4)
|
||||||
{
|
{
|
||||||
test_swarm_config(libtorrent::settings_pack::enc_policy policy
|
lt::settings_pack default_settings = settings();
|
||||||
, libtorrent::settings_pack::enc_level level
|
default_settings.set_bool(settings_pack::prefer_rc4, prefer_rc4);
|
||||||
, bool prefer_rc4)
|
default_settings.set_int(settings_pack::in_enc_policy, enc_policy);
|
||||||
: swarm_config()
|
default_settings.set_int(settings_pack::out_enc_policy, enc_policy);
|
||||||
, m_policy(policy)
|
default_settings.set_int(settings_pack::allowed_enc_level, level);
|
||||||
, m_level(level)
|
display_pe_settings(default_settings);
|
||||||
, m_prefer_rc4(prefer_rc4)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// called for every session that's added
|
sim::default_config cfg;
|
||||||
virtual libtorrent::settings_pack add_session(int idx) override
|
sim::simulation sim{cfg};
|
||||||
{
|
|
||||||
settings_pack s = swarm_config::add_session(idx);
|
|
||||||
|
|
||||||
fprintf(stderr, " session %d\n", idx);
|
lt::add_torrent_params default_add_torrent;
|
||||||
|
default_add_torrent.flags &= ~lt::add_torrent_params::flag_paused;
|
||||||
s.set_int(settings_pack::out_enc_policy, settings_pack::pe_enabled);
|
default_add_torrent.flags &= ~lt::add_torrent_params::flag_auto_managed;
|
||||||
s.set_int(settings_pack::in_enc_policy, settings_pack::pe_enabled);
|
setup_swarm(2, swarm_test::download, sim, default_settings, default_add_torrent
|
||||||
s.set_int(settings_pack::allowed_enc_level, settings_pack::pe_both);
|
// add session
|
||||||
|
, [](lt::settings_pack& pack) {
|
||||||
if (idx == 1)
|
pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_enabled);
|
||||||
{
|
pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_enabled);
|
||||||
s.set_int(settings_pack::out_enc_policy, m_policy);
|
pack.set_int(settings_pack::allowed_enc_level, settings_pack::pe_both);
|
||||||
s.set_int(settings_pack::in_enc_policy, m_policy);
|
pack.set_bool(settings_pack::prefer_rc4, false);
|
||||||
s.set_int(settings_pack::allowed_enc_level, m_level);
|
|
||||||
s.set_bool(settings_pack::prefer_rc4, m_prefer_rc4);
|
|
||||||
}
|
}
|
||||||
|
// add torrent
|
||||||
display_settings(s);
|
, [](lt::add_torrent_params& params) {}
|
||||||
|
// on alert
|
||||||
return s;
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
|
// terminate
|
||||||
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
|
{
|
||||||
|
if (ticks > 20)
|
||||||
|
{
|
||||||
|
TEST_ERROR("timeout");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return is_seed(ses);
|
||||||
private:
|
});
|
||||||
libtorrent::settings_pack::enc_policy m_policy;
|
}
|
||||||
libtorrent::settings_pack::enc_level m_level;
|
|
||||||
bool m_prefer_rc4;
|
|
||||||
};
|
|
||||||
|
|
||||||
TORRENT_TEST(pe_disabled)
|
TORRENT_TEST(pe_disabled)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_disabled, settings_pack::pe_plaintext, false);
|
||||||
test_swarm_config cfg(settings_pack::pe_disabled, settings_pack::pe_both, false);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(forced_plaintext)
|
TORRENT_TEST(forced_plaintext)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_forced, settings_pack::pe_plaintext, false);
|
||||||
test_swarm_config cfg(settings_pack::pe_forced, settings_pack::pe_both, false);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(forced_rc4)
|
TORRENT_TEST(forced_rc4)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_forced, settings_pack::pe_rc4, true);
|
||||||
test_swarm_config cfg(settings_pack::pe_forced, settings_pack::pe_rc4, false);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(forced_both)
|
TORRENT_TEST(forced_both)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_forced, settings_pack::pe_both, false);
|
||||||
test_swarm_config cfg(settings_pack::pe_forced, settings_pack::pe_both, false);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(forced_both_prefer_rc4)
|
TORRENT_TEST(forced_both_prefer_rc4)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_forced, settings_pack::pe_both, true);
|
||||||
test_swarm_config cfg(settings_pack::pe_forced, settings_pack::pe_both, true);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(enabled_plaintext)
|
TORRENT_TEST(enabled_plaintext)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_forced, settings_pack::pe_plaintext, false);
|
||||||
test_swarm_config cfg(settings_pack::pe_enabled, settings_pack::pe_plaintext, false);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(enabled_rc4)
|
TORRENT_TEST(enabled_rc4)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_enabled, settings_pack::pe_rc4, false);
|
||||||
test_swarm_config cfg(settings_pack::pe_enabled, settings_pack::pe_rc4, false);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(enabled_both)
|
TORRENT_TEST(enabled_both)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_enabled, settings_pack::pe_both, false);
|
||||||
test_swarm_config cfg(settings_pack::pe_enabled, settings_pack::pe_both, false);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(enabled_both_prefer_rc4)
|
TORRENT_TEST(enabled_both_prefer_rc4)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
test_transfer(settings_pack::pe_enabled, settings_pack::pe_both, true);
|
||||||
test_swarm_config cfg(settings_pack::pe_enabled, settings_pack::pe_both, true);
|
}
|
||||||
setup_swarm(2, cfg);
|
|
||||||
|
// make sure that a peer with encryption disabled cannot talk to a peer with
|
||||||
|
// encryption forced
|
||||||
|
TORRENT_TEST(disabled_failing)
|
||||||
|
{
|
||||||
|
lt::settings_pack default_settings = settings();
|
||||||
|
default_settings.set_bool(settings_pack::prefer_rc4, false);
|
||||||
|
default_settings.set_int(settings_pack::in_enc_policy, settings_pack::pe_disabled);
|
||||||
|
default_settings.set_int(settings_pack::out_enc_policy, settings_pack::pe_disabled);
|
||||||
|
default_settings.set_int(settings_pack::allowed_enc_level, settings_pack::pe_both);
|
||||||
|
display_pe_settings(default_settings);
|
||||||
|
|
||||||
|
sim::default_config cfg;
|
||||||
|
sim::simulation sim{cfg};
|
||||||
|
|
||||||
|
lt::add_torrent_params default_add_torrent;
|
||||||
|
default_add_torrent.flags &= ~lt::add_torrent_params::flag_paused;
|
||||||
|
default_add_torrent.flags &= ~lt::add_torrent_params::flag_auto_managed;
|
||||||
|
setup_swarm(2, swarm_test::download, sim, default_settings, default_add_torrent
|
||||||
|
// add session
|
||||||
|
, [](lt::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_int(settings_pack::allowed_enc_level, settings_pack::pe_both);
|
||||||
|
pack.set_bool(settings_pack::prefer_rc4, true);
|
||||||
|
}
|
||||||
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {}
|
||||||
|
// on alert
|
||||||
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
|
// terminate
|
||||||
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
|
{
|
||||||
|
// this download should never succeed
|
||||||
|
TEST_CHECK(!is_seed(ses));
|
||||||
|
return ticks > 120;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
TORRENT_TEST(disabled)
|
TORRENT_TEST(disabled)
|
||||||
|
|
|
@ -47,9 +47,9 @@ TORRENT_TEST(super_seeding)
|
||||||
params.flags |= add_torrent_params::flag_super_seeding;
|
params.flags |= add_torrent_params::flag_super_seeding;
|
||||||
}
|
}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{ return true; });
|
{ return true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,9 +65,9 @@ TORRENT_TEST(strict_super_seeding)
|
||||||
params.flags |= add_torrent_params::flag_super_seeding;
|
params.flags |= add_torrent_params::flag_super_seeding;
|
||||||
}
|
}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{ return true; });
|
{ return true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,9 @@ TORRENT_TEST(seed_mode)
|
||||||
params.flags |= add_torrent_params::flag_seed_mode;
|
params.flags |= add_torrent_params::flag_seed_mode;
|
||||||
}
|
}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{ return true; });
|
{ return true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ TORRENT_TEST(plain)
|
||||||
// add torrent
|
// add torrent
|
||||||
, [](lt::add_torrent_params& params) {}
|
, [](lt::add_torrent_params& params) {}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{
|
{
|
||||||
if (ticks > 75)
|
if (ticks > 75)
|
||||||
{
|
{
|
||||||
|
@ -88,9 +88,9 @@ TORRENT_TEST(suggest)
|
||||||
// add torrent
|
// add torrent
|
||||||
, [](lt::add_torrent_params& params) {}
|
, [](lt::add_torrent_params& params) {}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{
|
{
|
||||||
if (ticks > 75)
|
if (ticks > 75)
|
||||||
{
|
{
|
||||||
|
@ -116,9 +116,9 @@ TORRENT_TEST(utp_only)
|
||||||
// add torrent
|
// add torrent
|
||||||
, [](lt::add_torrent_params& params) {}
|
, [](lt::add_torrent_params& params) {}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{
|
{
|
||||||
if (ticks > 75)
|
if (ticks > 75)
|
||||||
{
|
{
|
||||||
|
@ -137,11 +137,18 @@ void test_stop_start_download(swarm_test type, bool graceful)
|
||||||
|
|
||||||
setup_swarm(3, type
|
setup_swarm(3, type
|
||||||
// add session
|
// add session
|
||||||
, [](lt::settings_pack& pack) {}
|
, [](lt::settings_pack& pack) {
|
||||||
|
// this test will pause and resume the torrent immediately, we expect
|
||||||
|
// to reconnect immediately too, so disable the min reconnect time
|
||||||
|
// limit.
|
||||||
|
pack.set_int(settings_pack::min_reconnect_time, 0);
|
||||||
|
}
|
||||||
// add torrent
|
// add torrent
|
||||||
, [](lt::add_torrent_params& params) {}
|
, [](lt::add_torrent_params& params) {
|
||||||
|
|
||||||
|
}
|
||||||
// on alert
|
// on alert
|
||||||
, [&](lt::alert const* a, lt::session* ses) {
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
|
||||||
if (lt::alert_cast<lt::torrent_added_alert>(a))
|
if (lt::alert_cast<lt::torrent_added_alert>(a))
|
||||||
add_extra_peers(ses);
|
add_extra_peers(ses);
|
||||||
|
@ -149,12 +156,13 @@ void test_stop_start_download(swarm_test type, bool graceful)
|
||||||
if (auto tp = lt::alert_cast<lt::torrent_paused_alert>(a))
|
if (auto tp = lt::alert_cast<lt::torrent_paused_alert>(a))
|
||||||
{
|
{
|
||||||
TEST_EQUAL(resumed, false);
|
TEST_EQUAL(resumed, false);
|
||||||
|
printf("\nSTART\n\n");
|
||||||
tp->handle.resume();
|
tp->handle.resume();
|
||||||
resumed = true;
|
resumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// terminate
|
// terminate
|
||||||
, [&](int ticks, lt::session* ses) -> bool
|
, [&](int ticks, lt::session& ses) -> bool
|
||||||
{
|
{
|
||||||
if (paused_once == false)
|
if (paused_once == false)
|
||||||
{
|
{
|
||||||
|
@ -165,14 +173,16 @@ void test_stop_start_download(swarm_test type, bool graceful)
|
||||||
|
|
||||||
if (limit_reached)
|
if (limit_reached)
|
||||||
{
|
{
|
||||||
auto h = ses->get_torrents()[0];
|
printf("\nSTOP\n\n");
|
||||||
|
auto h = ses.get_torrents()[0];
|
||||||
h.pause(graceful ? torrent_handle::graceful_pause : 0);
|
h.pause(graceful ? torrent_handle::graceful_pause : 0);
|
||||||
paused_once = true;
|
paused_once = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int timeout = (type == swarm_test::upload) ? 64 : 20;
|
printf("tick: %d\n", ticks);
|
||||||
|
|
||||||
|
const int timeout = type == swarm_test::download ? 20 : 91;
|
||||||
if (ticks > timeout)
|
if (ticks > timeout)
|
||||||
{
|
{
|
||||||
TEST_ERROR("timeout");
|
TEST_ERROR("timeout");
|
||||||
|
@ -198,6 +208,51 @@ TORRENT_TEST(stop_start_download_graceful)
|
||||||
test_stop_start_download(swarm_test::download, true);
|
test_stop_start_download(swarm_test::download, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TORRENT_TEST(stop_start_download_graceful_no_peers)
|
||||||
|
{
|
||||||
|
bool paused_once = false;
|
||||||
|
bool resumed = false;
|
||||||
|
|
||||||
|
setup_swarm(1, swarm_test::download
|
||||||
|
// add session
|
||||||
|
, [](lt::settings_pack& pack) {}
|
||||||
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {}
|
||||||
|
// on alert
|
||||||
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
if (auto tp = lt::alert_cast<lt::torrent_paused_alert>(a))
|
||||||
|
{
|
||||||
|
TEST_EQUAL(resumed, false);
|
||||||
|
printf("\nSTART\n\n");
|
||||||
|
tp->handle.resume();
|
||||||
|
resumed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// terminate
|
||||||
|
, [&](int ticks, lt::session& ses) -> bool
|
||||||
|
{
|
||||||
|
if (paused_once == false
|
||||||
|
&& ticks == 6)
|
||||||
|
{
|
||||||
|
printf("\nSTOP\n\n");
|
||||||
|
auto h = ses.get_torrents()[0];
|
||||||
|
h.pause(torrent_handle::graceful_pause);
|
||||||
|
paused_once = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("tick: %d\n", ticks);
|
||||||
|
|
||||||
|
// when there's only one node (i.e. no peers) we won't ever download
|
||||||
|
// the torrent. It's just a test to make sure we still get the
|
||||||
|
// torrent_paused_alert
|
||||||
|
return ticks > 60;
|
||||||
|
});
|
||||||
|
|
||||||
|
TEST_EQUAL(paused_once, true);
|
||||||
|
TEST_EQUAL(resumed, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TORRENT_TEST(stop_start_seed)
|
TORRENT_TEST(stop_start_seed)
|
||||||
{
|
{
|
||||||
test_stop_start_download(swarm_test::upload, false);
|
test_stop_start_download(swarm_test::upload, false);
|
||||||
|
@ -220,9 +275,9 @@ TORRENT_TEST(explicit_cache)
|
||||||
// add torrent
|
// add torrent
|
||||||
, [](lt::add_torrent_params& params) {}
|
, [](lt::add_torrent_params& params) {}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{
|
{
|
||||||
if (ticks > 75)
|
if (ticks > 75)
|
||||||
{
|
{
|
||||||
|
@ -242,9 +297,9 @@ TORRENT_TEST(shutdown)
|
||||||
// add torrent
|
// add torrent
|
||||||
, [](lt::add_torrent_params& params) {}
|
, [](lt::add_torrent_params& params) {}
|
||||||
// on alert
|
// on alert
|
||||||
, [](lt::alert const* a, lt::session* ses) {}
|
, [](lt::alert const* a, lt::session& ses) {}
|
||||||
// terminate
|
// terminate
|
||||||
, [](int ticks, lt::session* ses) -> bool
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
{
|
{
|
||||||
if (completed_pieces(ses) == 0) return false;
|
if (completed_pieces(ses) == 0) return false;
|
||||||
TEST_EQUAL(is_seed(ses), false);
|
TEST_EQUAL(is_seed(ses), false);
|
||||||
|
@ -256,4 +311,8 @@ TORRENT_TEST(shutdown)
|
||||||
// outgoing connections
|
// outgoing connections
|
||||||
// TODO: add test that makes sure a torrent in graceful pause mode won't accept
|
// TODO: add test that makes sure a torrent in graceful pause mode won't accept
|
||||||
// incoming connections
|
// incoming connections
|
||||||
|
// TODO: test allow-fast
|
||||||
|
// TODO: test the different storage allocation modes
|
||||||
|
// TODO: test contiguous buffers
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
#include "swarm_config.hpp"
|
#include "setup_swarm.hpp"
|
||||||
#include "simulator/simulator.hpp"
|
#include "simulator/simulator.hpp"
|
||||||
#include "libtorrent/alert_types.hpp"
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
|
||||||
|
@ -40,40 +40,45 @@ using namespace sim;
|
||||||
namespace lt = libtorrent;
|
namespace lt = libtorrent;
|
||||||
|
|
||||||
// this is a test for torrent_status time counters are correct
|
// this is a test for torrent_status time counters are correct
|
||||||
struct test_swarm_config : swarm_config
|
TORRENT_TEST(status_timers)
|
||||||
{
|
{
|
||||||
test_swarm_config()
|
lt::time_point start_time;
|
||||||
: swarm_config()
|
lt::torrent_handle handle;
|
||||||
{}
|
|
||||||
|
|
||||||
bool on_alert(libtorrent::alert const* alert
|
setup_swarm(1, swarm_test::upload
|
||||||
, int session_idx
|
// add session
|
||||||
, std::vector<libtorrent::torrent_handle> const& handles
|
, [](lt::settings_pack& pack) {}
|
||||||
, libtorrent::session& ses) override
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {}
|
||||||
|
// on alert
|
||||||
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
if (auto ta = alert_cast<torrent_added_alert>(a))
|
||||||
{
|
{
|
||||||
if (torrent_added_alert const* ta = alert_cast<torrent_added_alert>(alert))
|
TEST_CHECK(!handle.is_valid());
|
||||||
{
|
start_time = lt::clock_type::now();
|
||||||
TEST_CHECK(!m_handle.is_valid());
|
handle = ta->handle;
|
||||||
m_start_time = lt::clock_type::now();
|
|
||||||
m_handle = ta->handle;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
// terminate
|
||||||
virtual void on_exit(std::vector<torrent_handle> const& torrents) override {}
|
, [&](int ticks, lt::session& ses) -> bool
|
||||||
|
|
||||||
virtual bool tick(int t) override
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// simulate 20 hours of uptime. Currently, the session_time and internal
|
||||||
|
// peer timestamps are 16 bits counting seconds, so they can only
|
||||||
|
// represent about 18 hours. The clock steps forward in 4 hour increments
|
||||||
|
// to stay within that range
|
||||||
|
if (ticks > 20 * 60 * 60)
|
||||||
|
return true;
|
||||||
|
|
||||||
// once an hour, verify that the timers seem correct
|
// once an hour, verify that the timers seem correct
|
||||||
if ((t % 3600) == 0)
|
if ((ticks % 3600) == 0)
|
||||||
{
|
{
|
||||||
lt::time_point now = lt::clock_type::now();
|
lt::time_point now = lt::clock_type::now();
|
||||||
int since_start = total_seconds(now - m_start_time) - 1;
|
int since_start = total_seconds(now - start_time) - 1;
|
||||||
torrent_status st = m_handle.status();
|
torrent_status st = handle.status();
|
||||||
TEST_EQUAL(st.active_time, since_start);
|
TEST_EQUAL(st.active_time, since_start);
|
||||||
TEST_EQUAL(st.seeding_time, since_start);
|
TEST_EQUAL(st.seeding_time, since_start);
|
||||||
TEST_EQUAL(st.finished_time, since_start);
|
TEST_EQUAL(st.finished_time, since_start);
|
||||||
|
|
||||||
TEST_EQUAL(st.last_scrape, -1);
|
TEST_EQUAL(st.last_scrape, -1);
|
||||||
TEST_EQUAL(st.time_since_upload, -1);
|
TEST_EQUAL(st.time_since_upload, -1);
|
||||||
|
|
||||||
|
@ -89,24 +94,7 @@ struct test_swarm_config : swarm_config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// simulate 20 hours of uptime. Currently, the session_time and internal
|
return false;
|
||||||
// peer timestamps are 16 bits counting seconds, so they can only
|
});
|
||||||
// represent about 18 hours. The clock steps forward in 4 hour increments
|
|
||||||
// to stay within that range
|
|
||||||
return t > 20 * 60 * 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
lt::time_point m_start_time;
|
|
||||||
lt::torrent_handle m_handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
TORRENT_TEST(status_timers)
|
|
||||||
{
|
|
||||||
sim::default_config network_cfg;
|
|
||||||
sim::simulation sim{network_cfg};
|
|
||||||
|
|
||||||
test_swarm_config cfg;
|
|
||||||
setup_swarm(1, sim, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "setup_swarm.hpp"
|
#include "setup_swarm.hpp"
|
||||||
#include "swarm_config.hpp"
|
|
||||||
#include "simulator/simulator.hpp"
|
#include "simulator/simulator.hpp"
|
||||||
#include "simulator/http_server.hpp"
|
#include "simulator/http_server.hpp"
|
||||||
#include "libtorrent/alert_types.hpp"
|
#include "libtorrent/alert_types.hpp"
|
||||||
#include "libtorrent/announce_entry.hpp"
|
#include "libtorrent/announce_entry.hpp"
|
||||||
|
#include "libtorrent/session.hpp"
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
using namespace sim;
|
using namespace sim;
|
||||||
|
@ -48,82 +48,6 @@ using chrono::duration_cast;
|
||||||
// seconds
|
// seconds
|
||||||
const int duration = 10000;
|
const int duration = 10000;
|
||||||
|
|
||||||
struct test_swarm_config : swarm_config
|
|
||||||
{
|
|
||||||
test_swarm_config(int num_torrents, std::vector<std::string>* announces=NULL)
|
|
||||||
: swarm_config()
|
|
||||||
, m_announces(announces)
|
|
||||||
, m_num_torrents(num_torrents)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void on_session_added(int idx, session& ses) override
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual libtorrent::add_torrent_params add_torrent(int idx) override
|
|
||||||
{
|
|
||||||
add_torrent_params p = swarm_config::add_torrent(idx);
|
|
||||||
|
|
||||||
// add the tracker to the last torrent (if there's only one, it will be a
|
|
||||||
// seed from the start, if there are more than one, it will be a torrent
|
|
||||||
// that downloads the torrent and turns into a seed)
|
|
||||||
if (m_num_torrents - 1 == idx)
|
|
||||||
{
|
|
||||||
p.trackers.push_back("http://2.2.2.2:8080/announce");
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool on_alert(libtorrent::alert const* alert
|
|
||||||
, int session_idx
|
|
||||||
, std::vector<libtorrent::torrent_handle> const& handles
|
|
||||||
, libtorrent::session& ses) override
|
|
||||||
{
|
|
||||||
if (m_announces == NULL) return false;
|
|
||||||
|
|
||||||
char type = 0;
|
|
||||||
if (lt::alert_cast<lt::tracker_announce_alert>(alert))
|
|
||||||
{
|
|
||||||
type = 'A';
|
|
||||||
}
|
|
||||||
else if (lt::alert_cast<lt::tracker_error_alert>(alert))
|
|
||||||
{
|
|
||||||
type = 'E';
|
|
||||||
}
|
|
||||||
else if (lt::alert_cast<lt::tracker_warning_alert>(alert))
|
|
||||||
{
|
|
||||||
type = 'W';
|
|
||||||
}
|
|
||||||
else if (lt::alert_cast<lt::tracker_reply_alert>(alert))
|
|
||||||
{
|
|
||||||
type = 'R';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char msg[500];
|
|
||||||
snprintf(msg, sizeof(msg), "%c: %d %s", type
|
|
||||||
, int(duration_cast<chrono::seconds>(alert->timestamp().time_since_epoch()).count())
|
|
||||||
, alert->message().c_str());
|
|
||||||
m_announces->push_back(msg);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void on_exit(std::vector<torrent_handle> const& torrents) override
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool tick(int t) override { return t > duration; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::string>* m_announces;
|
|
||||||
int m_num_torrents;
|
|
||||||
};
|
|
||||||
|
|
||||||
void test_interval(int interval)
|
void test_interval(int interval)
|
||||||
{
|
{
|
||||||
using sim::asio::ip::address_v4;
|
using sim::asio::ip::address_v4;
|
||||||
|
@ -152,19 +76,42 @@ void test_interval(int interval)
|
||||||
return sim::send_response(200, "OK", size) + response;
|
return sim::send_response(200, "OK", size) + response;
|
||||||
});
|
});
|
||||||
|
|
||||||
std::vector<std::string> announce_alerts;
|
std::vector<int> announce_alerts;
|
||||||
test_swarm_config cfg(1, &announce_alerts);
|
|
||||||
setup_swarm(1, sim, cfg);
|
lt::settings_pack default_settings = settings();
|
||||||
|
lt::add_torrent_params default_add_torrent;
|
||||||
|
|
||||||
|
setup_swarm(1, swarm_test::upload, sim, default_settings, default_add_torrent
|
||||||
|
// add session
|
||||||
|
, [](lt::settings_pack& pack) { }
|
||||||
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {
|
||||||
|
params.trackers.push_back("http://2.2.2.2:8080/announce");
|
||||||
|
}
|
||||||
|
// on alert
|
||||||
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
|
||||||
|
if (lt::alert_cast<lt::tracker_announce_alert>(a))
|
||||||
|
{
|
||||||
|
boost::uint32_t seconds = chrono::duration_cast<lt::seconds>(
|
||||||
|
a->timestamp() - start).count();
|
||||||
|
|
||||||
|
announce_alerts.push_back(seconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// terminate
|
||||||
|
, [](int ticks, lt::session& ses) -> bool { return ticks > duration; });
|
||||||
|
|
||||||
|
TEST_EQUAL(announce_alerts.size(), announces.size());
|
||||||
|
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
for (int i = 0; i < int(announces.size()); ++i)
|
for (int i = 0; i < int(announces.size()); ++i)
|
||||||
{
|
{
|
||||||
TEST_EQUAL(announces[i], counter);
|
TEST_EQUAL(announces[i], counter);
|
||||||
|
TEST_EQUAL(announce_alerts[i], counter);
|
||||||
counter += interval;
|
counter += interval;
|
||||||
if (counter > duration + 1) counter = duration + 1;
|
if (counter > duration + 1) counter = duration + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: verify that announce_alerts seem right as well
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(event_completed)
|
TORRENT_TEST(event_completed)
|
||||||
|
@ -173,38 +120,64 @@ TORRENT_TEST(event_completed)
|
||||||
sim::default_config network_cfg;
|
sim::default_config network_cfg;
|
||||||
sim::simulation sim{network_cfg};
|
sim::simulation sim{network_cfg};
|
||||||
|
|
||||||
lt::time_point start = lt::clock_type::now();
|
|
||||||
|
|
||||||
sim::asio::io_service web_server(sim, address_v4::from_string("2.2.2.2"));
|
sim::asio::io_service web_server(sim, address_v4::from_string("2.2.2.2"));
|
||||||
// listen on port 8080
|
// listen on port 8080
|
||||||
sim::http_server http(web_server, 8080);
|
sim::http_server http(web_server, 8080);
|
||||||
|
|
||||||
// the timestamps (in seconds) of all announces
|
// the request strings of all announces
|
||||||
std::vector<std::string> announces;
|
std::vector<std::pair<int, std::string>> announces;
|
||||||
|
|
||||||
const int interval = 500;
|
const int interval = 500;
|
||||||
|
lt::time_point start = lt::clock_type::now();
|
||||||
|
|
||||||
http.register_handler("/announce"
|
http.register_handler("/announce"
|
||||||
, [&announces,interval,start](std::string method, std::string req
|
, [&](std::string method, std::string req
|
||||||
, std::map<std::string, std::string>&)
|
, std::map<std::string, std::string>&)
|
||||||
{
|
{
|
||||||
TEST_EQUAL(method, "GET");
|
TEST_EQUAL(method, "GET");
|
||||||
announces.push_back(req);
|
int timestamp = chrono::duration_cast<lt::seconds>(
|
||||||
|
lt::clock_type::now() - start).count();
|
||||||
|
announces.push_back({timestamp, req});
|
||||||
|
|
||||||
char response[500];
|
char response[500];
|
||||||
int size = snprintf(response, sizeof(response), "d8:intervali%de5:peers0:e", interval);
|
int size = snprintf(response, sizeof(response), "d8:intervali%de5:peers0:e", interval);
|
||||||
return sim::send_response(200, "OK", size) + response;
|
return sim::send_response(200, "OK", size) + response;
|
||||||
});
|
});
|
||||||
|
|
||||||
test_swarm_config cfg(2);
|
lt::settings_pack default_settings = settings();
|
||||||
setup_swarm(2, sim, cfg);
|
lt::add_torrent_params default_add_torrent;
|
||||||
|
|
||||||
|
int completion = -1;
|
||||||
|
|
||||||
|
setup_swarm(2, swarm_test::download, sim, default_settings, default_add_torrent
|
||||||
|
// add session
|
||||||
|
, [](lt::settings_pack& pack) { }
|
||||||
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {
|
||||||
|
params.trackers.push_back("http://2.2.2.2:8080/announce");
|
||||||
|
}
|
||||||
|
// on alert
|
||||||
|
, [&](lt::alert const* a, lt::session& ses) {}
|
||||||
|
// terminate
|
||||||
|
, [&](int ticks, lt::session& ses) -> bool
|
||||||
|
{
|
||||||
|
if (completion == -1 && is_seed(ses))
|
||||||
|
{
|
||||||
|
completion = chrono::duration_cast<lt::seconds>(
|
||||||
|
lt::clock_type::now() - start).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ticks > duration;
|
||||||
|
});
|
||||||
|
|
||||||
// the first announce should be event=started, the second should be
|
// the first announce should be event=started, the second should be
|
||||||
// event=completed, then all but the last should have no event and the last
|
// event=completed, then all but the last should have no event and the last
|
||||||
// be event=stopped.
|
// be event=stopped.
|
||||||
for (int i = 0; i < int(announces.size()); ++i)
|
for (int i = 0; i < int(announces.size()); ++i)
|
||||||
{
|
{
|
||||||
std::string const& str = announces[i];
|
std::string const& str = announces[i].second;
|
||||||
|
int timestamp = announces[i].first;
|
||||||
|
|
||||||
const bool has_start = str.find("&event=started")
|
const bool has_start = str.find("&event=started")
|
||||||
!= std::string::npos;
|
!= std::string::npos;
|
||||||
const bool has_completed = str.find("&event=completed")
|
const bool has_completed = str.find("&event=completed")
|
||||||
|
@ -217,6 +190,7 @@ TORRENT_TEST(event_completed)
|
||||||
|
|
||||||
fprintf(stderr, "- %s\n", str.c_str());
|
fprintf(stderr, "- %s\n", str.c_str());
|
||||||
|
|
||||||
|
// there is exactly 0 or 1 events.
|
||||||
TEST_EQUAL(int(has_start) + int(has_completed) + int(has_stopped)
|
TEST_EQUAL(int(has_start) + int(has_completed) + int(has_stopped)
|
||||||
, int(has_event));
|
, int(has_event));
|
||||||
|
|
||||||
|
@ -226,8 +200,13 @@ TORRENT_TEST(event_completed)
|
||||||
TEST_CHECK(has_start);
|
TEST_CHECK(has_start);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
{
|
||||||
|
// the announce should have come approximately the same time we
|
||||||
|
// completed
|
||||||
|
TEST_CHECK(abs(completion - timestamp) <= 1);
|
||||||
TEST_CHECK(has_completed);
|
TEST_CHECK(has_completed);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
if (i == int(announces.size()) - 1)
|
if (i == int(announces.size()) - 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,98 +31,126 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "setup_swarm.hpp"
|
#include "setup_swarm.hpp"
|
||||||
#include "swarm_config.hpp"
|
|
||||||
#include "libtorrent/alert.hpp"
|
#include "libtorrent/alert.hpp"
|
||||||
#include "libtorrent/announce_entry.hpp"
|
#include "libtorrent/announce_entry.hpp"
|
||||||
|
#include "libtorrent/settings_pack.hpp"
|
||||||
|
#include "libtorrent/add_torrent_params.hpp"
|
||||||
|
#include "libtorrent/alert_types.hpp"
|
||||||
#include "libtorrent/extensions/lt_trackers.hpp"
|
#include "libtorrent/extensions/lt_trackers.hpp"
|
||||||
|
#include "libtorrent/session.hpp"
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
|
#include "settings.hpp"
|
||||||
|
|
||||||
enum flags
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
TORRENT_TEST(plain)
|
||||||
{
|
{
|
||||||
no_metadata = 1
|
dsl_config network_cfg;
|
||||||
};
|
sim::simulation sim{network_cfg};
|
||||||
|
|
||||||
struct test_swarm_config : swarm_config
|
settings_pack pack = settings();
|
||||||
{
|
|
||||||
test_swarm_config(int flags)
|
|
||||||
: swarm_config()
|
|
||||||
, m_flags(flags)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void on_session_added(int idx, session& ses) override
|
add_torrent_params p;
|
||||||
{
|
p.flags &= ~lt::add_torrent_params::flag_paused;
|
||||||
ses.add_extension(create_lt_trackers_plugin);
|
p.flags &= ~lt::add_torrent_params::flag_auto_managed;
|
||||||
}
|
|
||||||
|
// the default torrent has one tracker
|
||||||
virtual libtorrent::add_torrent_params add_torrent(int idx) override
|
// we remove this from session 0 (the one under test)
|
||||||
{
|
p.trackers.push_back("http://test.non-existent.com/announce");
|
||||||
add_torrent_params p = swarm_config::add_torrent(idx);
|
|
||||||
|
bool connected = false;
|
||||||
if (m_flags & no_metadata)
|
|
||||||
{
|
setup_swarm(2, swarm_test::upload
|
||||||
p.info_hash = sha1_hash("aaaaaaaaaaaaaaaaaaaa");
|
, sim , pack, p
|
||||||
p.ti.reset();
|
// init session
|
||||||
|
, [](lt::session& ses) {
|
||||||
|
ses.add_extension(&create_lt_trackers_plugin);
|
||||||
}
|
}
|
||||||
|
// add session
|
||||||
|
, [](lt::settings_pack& pack) {}
|
||||||
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {
|
||||||
|
|
||||||
// make sure neither peer has any content
|
// make sure neither peer has any content
|
||||||
// TODO: it would be more efficient to not create the content in the first
|
// TODO: it would be more efficient to not create the content in the first
|
||||||
// place
|
// place
|
||||||
p.save_path = save_path(1);
|
params.save_path = save_path(test_counter(), 1);
|
||||||
|
|
||||||
if (idx == 1)
|
// the test is whether this peer will receive the tracker or not
|
||||||
{
|
params.trackers.clear();
|
||||||
p.trackers.push_back("http://test.non-existent.com/announce");
|
|
||||||
}
|
}
|
||||||
|
// on alert
|
||||||
return p;
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
if (alert_cast<lt::peer_connect_alert>(a))
|
||||||
|
connected = true;
|
||||||
}
|
}
|
||||||
|
// terminate
|
||||||
bool on_alert(libtorrent::alert const* alert
|
, [&](int ticks, lt::session& ses) -> bool {
|
||||||
, int session_idx
|
if (ticks > 10)
|
||||||
, std::vector<libtorrent::torrent_handle> const& handles
|
|
||||||
, libtorrent::session& ses) override
|
|
||||||
{
|
{
|
||||||
|
TEST_ERROR("timeout");
|
||||||
if ((m_flags & no_metadata) == 0)
|
|
||||||
{
|
|
||||||
if (handles[0].trackers().size() == 1
|
|
||||||
&& handles[1].trackers().size() == 1)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return connected && ses.get_torrents()[0].trackers().size() > 0;
|
||||||
}
|
});
|
||||||
|
|
||||||
virtual void on_exit(std::vector<torrent_handle> const& torrents) override
|
TEST_EQUAL(connected, true);
|
||||||
{
|
|
||||||
TEST_CHECK(torrents.size() > 0);
|
|
||||||
|
|
||||||
// a peer that does not have metadata should not exchange trackers, since
|
|
||||||
// it may be a private torrent
|
|
||||||
if (m_flags & no_metadata)
|
|
||||||
{
|
|
||||||
TEST_EQUAL(torrents[0].trackers().size(), 0);
|
|
||||||
TEST_EQUAL(torrents[1].trackers().size(), 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TEST_EQUAL(torrents[0].trackers().size(), 1);
|
|
||||||
TEST_EQUAL(torrents[1].trackers().size(), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
TORRENT_TEST(plain)
|
|
||||||
{
|
|
||||||
test_swarm_config cfg(0);
|
|
||||||
setup_swarm(2, cfg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(no_metadata)
|
TORRENT_TEST(no_metadata)
|
||||||
{
|
{
|
||||||
test_swarm_config cfg(no_metadata);
|
dsl_config network_cfg;
|
||||||
setup_swarm(2, cfg);
|
sim::simulation sim{network_cfg};
|
||||||
|
|
||||||
|
settings_pack pack = settings();
|
||||||
|
|
||||||
|
add_torrent_params p;
|
||||||
|
p.flags &= ~lt::add_torrent_params::flag_paused;
|
||||||
|
p.flags &= ~lt::add_torrent_params::flag_auto_managed;
|
||||||
|
|
||||||
|
// the default torrent has one tracker
|
||||||
|
// we remove this from session 0 (the one under test)
|
||||||
|
p.trackers.push_back("http://test.non-existent.com/announce");
|
||||||
|
|
||||||
|
bool connected = false;
|
||||||
|
|
||||||
|
setup_swarm(2, swarm_test::upload
|
||||||
|
, sim , pack, p
|
||||||
|
// init session
|
||||||
|
, [](lt::session& ses) {
|
||||||
|
ses.add_extension(&create_lt_trackers_plugin);
|
||||||
|
}
|
||||||
|
// add session
|
||||||
|
, [](lt::settings_pack& pack) {}
|
||||||
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {
|
||||||
|
|
||||||
|
// make sure neither peer has any content
|
||||||
|
// TODO: it would be more efficient to not create the content in the first
|
||||||
|
// place
|
||||||
|
params.save_path = save_path(test_counter(), 1);
|
||||||
|
|
||||||
|
// the test is whether this peer will receive the tracker or not
|
||||||
|
params.trackers.clear();
|
||||||
|
|
||||||
|
// if we don't have metadata, the other peer should not send the
|
||||||
|
// tracker to us
|
||||||
|
params.info_hash = sha1_hash("aaaaaaaaaaaaaaaaaaaa");
|
||||||
|
params.ti.reset();
|
||||||
|
}
|
||||||
|
// on alert
|
||||||
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
if (alert_cast<lt::peer_connect_alert>(a))
|
||||||
|
connected = true;
|
||||||
|
}
|
||||||
|
// terminate
|
||||||
|
, [](int ticks, lt::session& ses) -> bool {
|
||||||
|
if (ticks < 10)
|
||||||
|
return false;
|
||||||
|
TEST_EQUAL(ses.get_torrents()[0].trackers().size(), 0);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
TEST_EQUAL(connected, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/settings_pack.hpp"
|
#include "libtorrent/settings_pack.hpp"
|
||||||
#include "simulator/simulator.hpp"
|
#include "simulator/simulator.hpp"
|
||||||
#include "simulator/socks_server.hpp"
|
#include "simulator/socks_server.hpp"
|
||||||
|
#include "setup_swarm.hpp"
|
||||||
|
|
||||||
using namespace sim;
|
using namespace sim;
|
||||||
|
|
||||||
|
@ -53,11 +54,6 @@ enum flags_t
|
||||||
ipv6 = 1,
|
ipv6 = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
asio::ip::address addr(char const* str)
|
|
||||||
{
|
|
||||||
return asio::ip::address::from_string(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Setup, typename HandleAlerts, typename Test>
|
template <typename Setup, typename HandleAlerts, typename Test>
|
||||||
void run_test(
|
void run_test(
|
||||||
Setup const& setup
|
Setup const& setup
|
||||||
|
@ -173,14 +169,11 @@ void run_test(
|
||||||
sim.run();
|
sim.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_utp(lt::session& ses)
|
void utp_only(lt::session& ses)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
settings_pack p;
|
settings_pack p;
|
||||||
p.set_bool(settings_pack::enable_outgoing_tcp, false);
|
utp_only(p);
|
||||||
p.set_bool(settings_pack::enable_incoming_tcp, false);
|
|
||||||
p.set_bool(settings_pack::enable_outgoing_utp, true);
|
|
||||||
p.set_bool(settings_pack::enable_incoming_utp, true);
|
|
||||||
ses.apply_settings(p);
|
ses.apply_settings(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,10 +181,7 @@ void enable_enc(lt::session& ses)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
settings_pack p;
|
settings_pack p;
|
||||||
p.set_bool(settings_pack::prefer_rc4, true);
|
enable_enc(p);
|
||||||
p.set_int(settings_pack::in_enc_policy, settings_pack::pe_forced);
|
|
||||||
p.set_int(settings_pack::out_enc_policy, settings_pack::pe_forced);
|
|
||||||
p.set_int(settings_pack::allowed_enc_level, settings_pack::pe_both);
|
|
||||||
ses.apply_settings(p);
|
ses.apply_settings(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,12 +215,6 @@ void set_proxy(lt::session& ses, int proxy_type, int flags = 0, bool proxy_peer_
|
||||||
ses.apply_settings(p);
|
ses.apply_settings(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_seed(lt::session& ses)
|
|
||||||
{
|
|
||||||
lt::torrent_handle h = ses.get_torrents()[0];
|
|
||||||
return h.status().is_seeding;
|
|
||||||
}
|
|
||||||
|
|
||||||
TORRENT_TEST(socks4_tcp)
|
TORRENT_TEST(socks4_tcp)
|
||||||
{
|
{
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
@ -346,10 +330,6 @@ TORRENT_TEST(no_proxy_utp)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test allow-fast
|
|
||||||
// TODO: test the different storage allocation modes
|
|
||||||
// TODO: test contiguous buffers
|
|
||||||
|
|
||||||
// TODO: the socks server does not support UDP yet
|
// TODO: the socks server does not support UDP yet
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -358,7 +338,7 @@ TORRENT_TEST(encryption_utp)
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
run_test(
|
run_test(
|
||||||
[](lt::session& ses0, lt::session& ses1)
|
[](lt::session& ses0, lt::session& ses1)
|
||||||
{ enable_enc(ses0); enable_enc(ses1); enable_utp(ses0); },
|
{ enable_enc(ses0); enable_enc(ses1); utp_only(ses0); },
|
||||||
[](lt::session& ses, lt::alert const* alert) {},
|
[](lt::session& ses, lt::alert const* alert) {},
|
||||||
[](std::shared_ptr<lt::session> ses[2]) {
|
[](std::shared_ptr<lt::session> ses[2]) {
|
||||||
TEST_EQUAL(is_seed(*ses[0]), true);
|
TEST_EQUAL(is_seed(*ses[0]), true);
|
||||||
|
@ -373,7 +353,7 @@ TORRENT_TEST(socks5_utp)
|
||||||
[](lt::session& ses0, lt::session& ses1)
|
[](lt::session& ses0, lt::session& ses1)
|
||||||
{
|
{
|
||||||
set_proxy(ses0, settings_pack::socks5);
|
set_proxy(ses0, settings_pack::socks5);
|
||||||
enable_utp(ses0);
|
utp_only(ses0);
|
||||||
filter_ips(ses1);
|
filter_ips(ses1);
|
||||||
},
|
},
|
||||||
[](lt::session& ses, lt::alert const* alert) {},
|
[](lt::session& ses, lt::alert const* alert) {},
|
||||||
|
|
|
@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "test.hpp"
|
#include "test.hpp"
|
||||||
#include "setup_swarm.hpp"
|
#include "setup_swarm.hpp"
|
||||||
#include "setup_transfer.hpp" // for create_torrent (factor this out!)
|
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -46,144 +45,45 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
namespace lt = libtorrent;
|
namespace lt = libtorrent;
|
||||||
|
|
||||||
// TODO: a lot of this class is boiler plate. Factor out into a reusable unit
|
|
||||||
struct swarm_config : swarm_setup_provider
|
|
||||||
{
|
|
||||||
swarm_config(int num_peers)
|
|
||||||
: m_swarm_id(std::rand())
|
|
||||||
, m_start_time(lt::clock_type::now())
|
|
||||||
{
|
|
||||||
// in case the previous run did not exit gracefully
|
|
||||||
clear_download_directories(num_peers);
|
|
||||||
|
|
||||||
error_code ec;
|
|
||||||
char save_path[200];
|
|
||||||
snprintf(save_path, sizeof(save_path), "swarm-%04d-peer-%02d"
|
|
||||||
, m_swarm_id, 0);
|
|
||||||
|
|
||||||
create_directory(save_path, ec);
|
|
||||||
std::ofstream file(combine_path(save_path, "temporary").c_str());
|
|
||||||
m_ti = ::create_torrent(&file, "temporary", 0x4000, 90, false);
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void on_exit(std::vector<torrent_handle> const& torrents)
|
|
||||||
{
|
|
||||||
TEST_CHECK(torrents.size() > 0);
|
|
||||||
for (int i = 0; i < int(torrents.size()); ++i)
|
|
||||||
{
|
|
||||||
torrent_status st = torrents[i].status();
|
|
||||||
TEST_CHECK(st.is_seeding);
|
|
||||||
TEST_CHECK(st.total_upload > 0 || st.total_download > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if this check fails, there is a performance regression in the protocol,
|
|
||||||
// either uTP or bittorrent itself. Be careful with the download request
|
|
||||||
// queue size (and make sure it can grow fast enough, to keep up with
|
|
||||||
// slow-start) and the send buffer watermark
|
|
||||||
TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(8500));
|
|
||||||
|
|
||||||
// clean up the download directories to make the next run start from
|
|
||||||
// scratch.
|
|
||||||
clear_download_directories(int(torrents.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_download_directories(int num_peers)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < num_peers; ++i)
|
|
||||||
{
|
|
||||||
error_code ec;
|
|
||||||
char save_path[200];
|
|
||||||
snprintf(save_path, sizeof(save_path), "swarm-%04d-peer-%02d"
|
|
||||||
, m_swarm_id, i);
|
|
||||||
|
|
||||||
// in case the previous run did not exit gracefully
|
|
||||||
remove_all(save_path, ec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// called for every alert. if the simulation is done, return true
|
|
||||||
virtual bool on_alert(libtorrent::alert const* alert
|
|
||||||
, int session_idx
|
|
||||||
, std::vector<libtorrent::torrent_handle> const& torrents
|
|
||||||
, libtorrent::session& ses) override
|
|
||||||
{
|
|
||||||
if (torrents.empty()) return false;
|
|
||||||
|
|
||||||
bool all_are_seeding = true;
|
|
||||||
for (int i = 0; i < int(torrents.size()); ++i)
|
|
||||||
{
|
|
||||||
if (torrents[i].status().is_seeding)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
all_are_seeding = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if all torrents are seeds, terminate the simulation, we're done
|
|
||||||
return all_are_seeding;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// sessions seeds and others downloaders
|
|
||||||
virtual libtorrent::add_torrent_params add_torrent(int idx) override
|
|
||||||
{
|
|
||||||
add_torrent_params p;
|
|
||||||
p.flags &= ~add_torrent_params::flag_paused;
|
|
||||||
p.flags &= ~add_torrent_params::flag_auto_managed;
|
|
||||||
|
|
||||||
if (idx == 0)
|
|
||||||
{
|
|
||||||
// skip checking up front, and get started with the transfer sooner
|
|
||||||
p.flags |= add_torrent_params::flag_seed_mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.ti = m_ti;
|
|
||||||
|
|
||||||
char save_path[200];
|
|
||||||
snprintf(save_path, sizeof(save_path), "swarm-%04d-peer-%02d"
|
|
||||||
, m_swarm_id, idx);
|
|
||||||
p.save_path = save_path;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
// called for every session that's added
|
|
||||||
virtual libtorrent::settings_pack add_session(int idx) override
|
|
||||||
{
|
|
||||||
settings_pack pack = settings();
|
|
||||||
|
|
||||||
// force uTP connection
|
|
||||||
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);
|
|
||||||
|
|
||||||
// the encryption handshake adds several round-trips to the bittorrent
|
|
||||||
// handshake, and slows it down significantly
|
|
||||||
pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_disabled);
|
|
||||||
pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_disabled);
|
|
||||||
|
|
||||||
// make sure the sessions have different peer ids
|
|
||||||
lt::peer_id pid;
|
|
||||||
std::generate(&pid[0], &pid[0] + 20, &random_byte);
|
|
||||||
pack.set_str(lt::settings_pack::peer_fingerprint, pid.to_string());
|
|
||||||
|
|
||||||
return pack;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_swarm_id;
|
|
||||||
lt::time_point m_start_time;
|
|
||||||
boost::shared_ptr<libtorrent::torrent_info> m_ti;
|
|
||||||
};
|
|
||||||
|
|
||||||
TORRENT_TEST(utp)
|
TORRENT_TEST(utp)
|
||||||
{
|
{
|
||||||
// TODO: 3 simulate packet loss
|
// TODO: 3 simulate packet loss
|
||||||
// TODO: 3 simulate unpredictible latencies
|
// TODO: 3 simulate unpredictible latencies
|
||||||
// TODO: 3 simulate proper (taildrop) queues (perhaps even RED and BLUE)
|
// TODO: 3 simulate proper (taildrop) queues (perhaps even RED and BLUE)
|
||||||
swarm_config cfg(2);
|
lt::time_point start_time = lt::clock_type::now();
|
||||||
setup_swarm(2, cfg);
|
|
||||||
|
sim::default_config cfg;
|
||||||
|
sim::simulation sim{cfg};
|
||||||
|
|
||||||
|
setup_swarm(2, swarm_test::upload, sim
|
||||||
|
// add session
|
||||||
|
, [](lt::settings_pack& pack) {
|
||||||
|
// force uTP connection
|
||||||
|
utp_only(pack);
|
||||||
|
}
|
||||||
|
// add torrent
|
||||||
|
, [](lt::add_torrent_params& params) {
|
||||||
|
params.flags |= add_torrent_params::flag_seed_mode;
|
||||||
|
}
|
||||||
|
// on alert
|
||||||
|
, [&](lt::alert const* a, lt::session& ses) {
|
||||||
|
if (!is_seed(ses)) return;
|
||||||
|
|
||||||
|
// if this check fails, there is a performance regression in the protocol,
|
||||||
|
// either uTP or bittorrent itself. Be careful with the download request
|
||||||
|
// queue size (and make sure it can grow fast enough, to keep up with
|
||||||
|
// slow-start) and the send buffer watermark
|
||||||
|
TEST_CHECK(lt::clock_type::now() < start_time + lt::milliseconds(8500));
|
||||||
|
}
|
||||||
|
// terminate
|
||||||
|
, [](int ticks, lt::session& ses) -> bool
|
||||||
|
{
|
||||||
|
if (ticks > 100)
|
||||||
|
{
|
||||||
|
TEST_ERROR("timeout");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -259,15 +259,14 @@ namespace libtorrent { namespace
|
||||||
if (m_tp.num_tex_trackers() >= 50)
|
if (m_tp.num_tex_trackers() >= 50)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
|
m_pc.peer_log(peer_log_alert::info, "LT_TEX", "adding: %s", e.url.c_str());
|
||||||
|
#endif
|
||||||
e.fail_limit = 1;
|
e.fail_limit = 1;
|
||||||
e.send_stats = false;
|
e.send_stats = false;
|
||||||
e.source = announce_entry::source_tex;
|
e.source = announce_entry::source_tex;
|
||||||
if (m_torrent.add_tracker(e))
|
if (m_torrent.add_tracker(e))
|
||||||
m_tp.increment_tracker_counter();
|
m_tp.increment_tracker_counter();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
|
||||||
m_pc.peer_log(peer_log_alert::info, "LT_TEX", "added: %s", e.url.c_str());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4092,7 +4092,10 @@ namespace libtorrent
|
||||||
|
|
||||||
// we cannot do this in a constructor
|
// we cannot do this in a constructor
|
||||||
TORRENT_ASSERT(m_in_constructor == false);
|
TORRENT_ASSERT(m_in_constructor == false);
|
||||||
if (error > 0) m_failed = true;
|
if (error > 0)
|
||||||
|
{
|
||||||
|
m_failed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_connected)
|
if (m_connected)
|
||||||
m_counters.inc_stats_counter(counters::num_peers_connected, -1);
|
m_counters.inc_stats_counter(counters::num_peers_connected, -1);
|
||||||
|
|
|
@ -9610,20 +9610,13 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(is_single_thread());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (!m_allow_peers) return;
|
if (m_allow_peers)
|
||||||
set_allow_peers(graceful ? true : false, graceful);
|
{
|
||||||
|
|
||||||
m_announce_to_dht = false;
|
|
||||||
m_announce_to_trackers = false;
|
|
||||||
m_announce_to_lsd = false;
|
|
||||||
|
|
||||||
// we need to save this new state
|
// we need to save this new state
|
||||||
set_need_save_resume();
|
set_need_save_resume();
|
||||||
state_updated();
|
}
|
||||||
|
|
||||||
update_gauge();
|
set_allow_peers(false, graceful);
|
||||||
update_want_peers();
|
|
||||||
update_want_scrape();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::do_pause()
|
void torrent::do_pause()
|
||||||
|
@ -9699,20 +9692,14 @@ namespace libtorrent
|
||||||
// disconnect all peers with no outstanding data to receive
|
// disconnect all peers with no outstanding data to receive
|
||||||
// and choke all remaining peers to prevent responding to new
|
// and choke all remaining peers to prevent responding to new
|
||||||
// requests
|
// requests
|
||||||
bool update_ticks = false;
|
std::vector<peer_connection*> to_disconnect;
|
||||||
for (peer_iterator i = m_connections.begin();
|
for (peer_iterator i = m_connections.begin();
|
||||||
i != m_connections.end();)
|
i != m_connections.end(); ++i)
|
||||||
{
|
{
|
||||||
peer_iterator j = i++;
|
peer_connection* p = *i;
|
||||||
boost::shared_ptr<peer_connection> p = (*j)->self();
|
|
||||||
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
|
TORRENT_ASSERT(p->associated_torrent().lock().get() == this);
|
||||||
|
|
||||||
if (p->is_disconnecting())
|
if (p->is_disconnecting()) continue;
|
||||||
{
|
|
||||||
i = m_connections.erase(j);
|
|
||||||
update_ticks = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->outstanding_bytes() > 0)
|
if (p->outstanding_bytes() > 0)
|
||||||
{
|
{
|
||||||
|
@ -9726,21 +9713,19 @@ namespace libtorrent
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
to_disconnect.push_back(p);
|
||||||
|
}
|
||||||
|
for (peer_iterator i = to_disconnect.begin(); i != to_disconnect.end(); ++i)
|
||||||
|
{
|
||||||
|
peer_connection* p = *i;
|
||||||
|
|
||||||
|
// since we're currently in graceful pause mode, the last peer to
|
||||||
|
// disconnect (assuming all peers end up begin disconnected here)
|
||||||
|
// will post the torrent_paused_alert
|
||||||
#ifndef TORRENT_DISABLE_LOGGING
|
#ifndef TORRENT_DISABLE_LOGGING
|
||||||
p->peer_log(peer_log_alert::info, "CLOSING_CONNECTION", "torrent_paused");
|
p->peer_log(peer_log_alert::info, "CLOSING_CONNECTION", "torrent_paused");
|
||||||
#endif
|
#endif
|
||||||
p->disconnect(errors::torrent_paused, op_bittorrent);
|
p->disconnect(errors::torrent_paused, op_bittorrent);
|
||||||
i = j;
|
|
||||||
}
|
|
||||||
if (m_connections.empty())
|
|
||||||
{
|
|
||||||
if (alerts().should_post<torrent_paused_alert>())
|
|
||||||
alerts().emplace_alert<torrent_paused_alert>(get_handle());
|
|
||||||
}
|
|
||||||
if (update_ticks)
|
|
||||||
{
|
|
||||||
update_want_peers();
|
|
||||||
update_want_tick();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9792,12 +9777,20 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(is_single_thread());
|
TORRENT_ASSERT(is_single_thread());
|
||||||
|
|
||||||
|
// if there are no peers, there is no point in a graceful pause mode. In
|
||||||
|
// fact, the promise to post the torrent_paused_alert exactly once is
|
||||||
|
// maintained by the last peer to be disconnected in graceful pause mode,
|
||||||
|
// if there are no peers, we must not enter graceful pause mode, and post
|
||||||
|
// the torrent_paused_alert immediately instead.
|
||||||
|
if (m_connections.empty())
|
||||||
|
graceful = false;
|
||||||
|
|
||||||
if (m_allow_peers == b)
|
if (m_allow_peers == b)
|
||||||
{
|
{
|
||||||
// there is one special case here. If we are
|
// there is one special case here. If we are
|
||||||
// currently in graceful pause mode, and we just turned into regular
|
// currently in graceful pause mode, and we just turned into regular
|
||||||
// paused mode, we need to actually pause the torrent properly
|
// paused mode, we need to actually pause the torrent properly
|
||||||
if (m_allow_peers == true
|
if (m_allow_peers == false
|
||||||
&& m_graceful_pause_mode == true
|
&& m_graceful_pause_mode == true
|
||||||
&& graceful == false)
|
&& graceful == false)
|
||||||
{
|
{
|
||||||
|
@ -9812,21 +9805,28 @@ namespace libtorrent
|
||||||
if (!m_ses.is_paused())
|
if (!m_ses.is_paused())
|
||||||
m_graceful_pause_mode = graceful;
|
m_graceful_pause_mode = graceful;
|
||||||
|
|
||||||
update_gauge();
|
|
||||||
update_want_scrape();
|
|
||||||
update_state_list();
|
|
||||||
|
|
||||||
if (!b)
|
if (!b)
|
||||||
{
|
{
|
||||||
m_announce_to_dht = false;
|
m_announce_to_dht = false;
|
||||||
m_announce_to_trackers = false;
|
m_announce_to_trackers = false;
|
||||||
m_announce_to_lsd = false;
|
m_announce_to_lsd = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_gauge();
|
||||||
|
update_want_scrape();
|
||||||
|
update_want_peers();
|
||||||
|
update_state_list();
|
||||||
|
state_updated();
|
||||||
|
|
||||||
|
if (!b)
|
||||||
|
{
|
||||||
do_pause();
|
do_pause();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
do_resume();
|
do_resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::resume()
|
void torrent::resume()
|
||||||
|
|
|
@ -50,6 +50,11 @@ libtorrent::settings_pack settings()
|
||||||
pack.set_bool(settings_pack::enable_upnp, false);
|
pack.set_bool(settings_pack::enable_upnp, false);
|
||||||
pack.set_bool(settings_pack::enable_dht, false);
|
pack.set_bool(settings_pack::enable_dht, false);
|
||||||
|
|
||||||
|
pack.set_bool(settings_pack::prefer_rc4, false);
|
||||||
|
pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_disabled);
|
||||||
|
pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_disabled);
|
||||||
|
pack.set_int(settings_pack::allowed_enc_level, settings_pack::pe_both);
|
||||||
|
|
||||||
pack.set_int(settings_pack::alert_mask, mask);
|
pack.set_int(settings_pack::alert_mask, mask);
|
||||||
|
|
||||||
#ifndef TORRENT_BUILD_SIMULATOR
|
#ifndef TORRENT_BUILD_SIMULATOR
|
||||||
|
|
Loading…
Reference in New Issue