support building libtorrent in simulation mode (using libsimulator, which is a git submodule)

This commit is contained in:
arvidn 2015-08-07 21:28:51 -04:00
parent 1cbd9a9d5e
commit 46803b75f8
23 changed files with 1344 additions and 6 deletions

View File

@ -80,6 +80,11 @@ rule linking ( properties * )
} }
} }
if <simulator>on in $(properties)
{
result += <library>/libsimulator//simulator ;
}
# dbghelp doesn't appear to exist in mingw # dbghelp doesn't appear to exist in mingw
if <target-os>windows in $(properties) if <target-os>windows in $(properties)
&& ! <toolset>gcc in $(properties) && ! <toolset>gcc in $(properties)
@ -428,6 +433,9 @@ feature.compose <asio-debugging>on : <define>TORRENT_ASIO_DEBUGGING ;
feature picker-debugging : off on : composite propagated link-incompatible ; feature picker-debugging : off on : composite propagated link-incompatible ;
feature.compose <picker-debugging>on : <define>TORRENT_DEBUG_REFCOUNTS ; feature.compose <picker-debugging>on : <define>TORRENT_DEBUG_REFCOUNTS ;
feature simulator : off on : composite propagated link-incompatible ;
feature.compose <simulator>on : <define>TORRENT_BUILD_SIMULATOR ;
# deprecated use allocator=pool instead # deprecated use allocator=pool instead
feature pool-allocators : on off debug : composite propagated link-incompatible ; feature pool-allocators : on off debug : composite propagated link-incompatible ;
feature.compose <pool-allocators>off : <define>TORRENT_DISABLE_POOL_ALLOCATOR ; feature.compose <pool-allocators>off : <define>TORRENT_DISABLE_POOL_ALLOCATOR ;

View File

@ -49,6 +49,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/asio/ip/address.hpp> #include <boost/asio/ip/address.hpp>
#if defined TORRENT_BUILD_SIMULATOR
#include "simulator/simulator.hpp"
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
#ifdef __OBJC__ #ifdef __OBJC__
@ -57,12 +61,19 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent namespace libtorrent
{ {
#if defined TORRENT_BUILD_SIMULATOR
typedef sim::asio::ip::address address;
typedef sim::asio::ip::address_v4 address_v4;
#if TORRENT_USE_IPV6
typedef sim::asio::ip::address_v6 address_v6;
#endif
#else
typedef boost::asio::ip::address address; typedef boost::asio::ip::address address;
typedef boost::asio::ip::address_v4 address_v4; typedef boost::asio::ip::address_v4 address_v4;
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
typedef boost::asio::ip::address_v6 address_v6; typedef boost::asio::ip::address_v6 address_v6;
#endif #endif
#endif // SIMULATOR
} }
#endif #endif

View File

@ -33,12 +33,25 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef TORRENT_DEADLINE_TIMER_HPP_INCLUDED #ifndef TORRENT_DEADLINE_TIMER_HPP_INCLUDED
#define TORRENT_DEADLINE_TIMER_HPP_INCLUDED #define TORRENT_DEADLINE_TIMER_HPP_INCLUDED
#include "libtorrent/config.hpp"
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <boost/asio/high_resolution_timer.hpp> #include <boost/asio/high_resolution_timer.hpp>
#if defined TORRENT_BUILD_SIMULATOR
#include "simulator/simulator.hpp"
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp"
namespace libtorrent namespace libtorrent
{ {
#if defined TORRENT_BUILD_SIMULATOR
typedef sim::asio::high_resolution_timer deadline_timer;
#else
typedef boost::asio::high_resolution_timer deadline_timer; typedef boost::asio::high_resolution_timer deadline_timer;
#endif
} }
#endif // TORRENT_DEADLINE_TIMER_HPP_INCLUDED #endif // TORRENT_DEADLINE_TIMER_HPP_INCLUDED

View File

@ -48,6 +48,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/asio/io_service.hpp> #include <boost/asio/io_service.hpp>
#if defined TORRENT_BUILD_SIMULATOR
#include "simulator/simulator.hpp"
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
#ifdef __OBJC__ #ifdef __OBJC__
@ -56,7 +60,11 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent namespace libtorrent
{ {
#if defined TORRENT_BUILD_SIMULATOR
typedef sim::asio::io_service io_service;
#else
typedef boost::asio::io_service io_service; typedef boost::asio::io_service io_service;
#endif
} }
#endif #endif

View File

@ -47,13 +47,23 @@ POSSIBILITY OF SUCH DAMAGE.
#undef Protocol #undef Protocol
#endif #endif
#if defined TORRENT_BUILD_SIMULATOR
namespace sim { namespace asio {
struct io_service;
}}
#endif
namespace boost { namespace asio { namespace boost { namespace asio {
class io_service; class io_service;
}} }}
namespace libtorrent namespace libtorrent
{ {
#if defined TORRENT_BUILD_SIMULATOR
typedef sim::asio::io_service io_service;
#else
typedef boost::asio::io_service io_service; typedef boost::asio::io_service io_service;
#endif
} }
#endif #endif

View File

@ -61,16 +61,28 @@ POSSIBILITY OF SUCH DAMAGE.
#undef Protocol #undef Protocol
#endif #endif
#if defined TORRENT_BUILD_SIMULATOR
#include "simulator/simulator.hpp"
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
namespace libtorrent namespace libtorrent
{ {
#if defined TORRENT_BUILD_SIMULATOR
using sim::asio::ip::udp;
using sim::asio::ip::tcp;
using sim::asio::async_write;
using sim::asio::async_read;
using sim::asio::null_buffers;
#else
using boost::asio::ip::tcp; using boost::asio::ip::tcp;
using boost::asio::ip::udp; using boost::asio::ip::udp;
using boost::asio::async_write; using boost::asio::async_write;
using boost::asio::async_read; using boost::asio::async_read;
using boost::asio::null_buffers; using boost::asio::null_buffers;
#endif
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
#ifdef IPV6_V6ONLY #ifdef IPV6_V6ONLY

View File

@ -45,11 +45,17 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/chrono.hpp> #include <boost/chrono.hpp>
#endif #endif
#if defined TORRENT_BUILD_SIMULATOR
#include "simulator/simulator.hpp"
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp" #include "libtorrent/aux_/disable_warnings_pop.hpp"
namespace libtorrent { namespace libtorrent {
#if defined BOOST_ASIO_HAS_STD_CHRONO #if defined TORRENT_BUILD_SIMULATOR
typedef sim::chrono::high_resolution_clock clock_type;
#elif defined BOOST_ASIO_HAS_STD_CHRONO
typedef std::chrono::high_resolution_clock clock_type; typedef std::chrono::high_resolution_clock clock_type;
#else #else
typedef boost::chrono::high_resolution_clock clock_type; typedef boost::chrono::high_resolution_clock clock_type;

29
simulation/Jamfile Normal file
View File

@ -0,0 +1,29 @@
import testing ;
import feature : feature ;
use-project /torrent : .. ;
use-project /libtorrent_test : ../test ;
use-project /libsimulator : libsimulator ;
project
: requirements
<simulator>on
<library>/torrent//torrent
<library>/libtorrent_test//libtorrent_test
<source>swarm_suite.cpp
<source>setup_swarm.cpp
<source>setup_dht.cpp
: default-build
<threading>multi
<invariant-checks>full
<debug-iterators>on
<picker-debugging>on
;
test-suite libtorrent-sims :
[ run test_swarm.cpp ]
[ run test_utp.cpp ]
[ run test_dht.cpp ]
;

@ -0,0 +1 @@
Subproject commit b160ae7999a2eab64cb91c82b2ca6d7c222c6449

198
simulation/setup_dht.cpp Normal file
View File

@ -0,0 +1,198 @@
/*
Copyright (c) 2014-2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/session.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/io_service.hpp"
#include "libtorrent/deadline_timer.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/ip_filter.hpp"
#include "libtorrent/alert_types.hpp"
#include <boost/bind.hpp>
#include "setup_dht.hpp"
namespace lt = libtorrent;
using namespace sim;
namespace {
struct network
{
network(int num_nodes, network_setup_provider& config)
: m_config(config)
, m_ios(m_sim, asio::ip::address_v4::from_string("10.0.0.1"))
, m_start_time(lt::clock_type::now())
, m_timer(m_ios)
, m_shutting_down(false)
{
for (int i = 0; i < num_nodes; ++i)
{
// create a new io_service
char ep[30];
snprintf(ep, sizeof(ep), "50.0.%d.%d", (i + 1) >> 8, (i + 1) & 0xff);
m_io_service.push_back(boost::make_shared<sim::asio::io_service>(
boost::ref(m_sim), asio::ip::address_v4::from_string(ep)));
lt::settings_pack pack = m_config.add_session(i);
boost::shared_ptr<lt::session> ses = boost::make_shared<lt::session>(pack
, boost::ref(*m_io_service.back()));
m_nodes.push_back(ses);
m_config.setup_session(*ses, i);
ses->set_alert_notify(boost::bind(&network::on_alert_notify, this, i));
}
m_timer.expires_from_now(lt::seconds(1));
m_timer.async_wait(boost::bind(&network::on_tick, this, _1));
sim::dump_network_graph(m_sim, "../dht-sim.dot");
}
void on_tick(lt::error_code const& ec)
{
if (ec || m_shutting_down) return;
if (m_config.on_tick())
{
terminate();
return;
}
m_timer.expires_from_now(lt::seconds(1));
m_timer.async_wait(boost::bind(&network::on_tick, this, _1));
}
void on_alert_notify(int session_index)
{
// this function is called inside libtorrent and we cannot perform work
// immediately in it. We have to notify the outside to pull all the alerts
m_io_service[session_index]->post(boost::bind(&network::on_alerts, this, session_index));
}
void on_alerts(int session_index)
{
std::vector<lt::alert*> alerts;
lt::session* ses = m_nodes[session_index].get();
// when shutting down, we may have destructed the session
if (ses == NULL) return;
bool term = false;
ses->pop_alerts(&alerts);
for (std::vector<lt::alert*>::iterator i = alerts.begin();
i != alerts.end(); ++i)
{
lt::alert* a = *i;
if (session_index == 0)
{
// only log the experience of node 0
lt::time_duration d = a->timestamp() - m_start_time;
boost::uint32_t millis = lt::duration_cast<lt::milliseconds>(d).count();
printf("%4d.%03d: [%02d] %s\n", millis / 1000, millis % 1000,
session_index, a->message().c_str());
}
if (m_config.on_alert(a, session_index))
term = true;
if (lt::alert_cast<lt::listen_succeeded_alert>(a))
{
// add a single DHT node to bootstrap from. Make everyone bootstrap
// from the node added 3 steps earlier (this makes the distribution a
// bit unrealisticly uniform).
int dht_bootstrap = (std::max)(0, session_index - 3);
char ep[50];
snprintf(ep, sizeof(ep), "50.0.%d.%d", (dht_bootstrap + 1) >> 8, (dht_bootstrap + 1) & 0xff);
ses->add_dht_node(std::pair<std::string, int>(
ep, m_nodes[dht_bootstrap]->listen_port()));
}
}
if (term) terminate();
}
void run()
{
m_sim.run();
printf("simulation::run() returned\n");
}
void terminate()
{
printf("TERMINATING\n");
m_config.on_exit();
// terminate simulation
for (int i = 0; i < int(m_nodes.size()); ++i)
{
m_zombies.push_back(m_nodes[i]->abort());
m_nodes[i].reset();
}
m_shutting_down = true;
}
private:
network_setup_provider& m_config;
sim::simulation m_sim;
asio::io_service m_ios;
lt::time_point m_start_time;
std::vector<boost::shared_ptr<lt::session> > m_nodes;
std::vector<boost::shared_ptr<sim::asio::io_service> > m_io_service;
std::vector<lt::session_proxy> m_zombies;
lt::deadline_timer m_timer;
bool m_shutting_down;
};
} // anonymous namespace
void setup_dht(int num_nodes, network_setup_provider& cfg)
{
network s(num_nodes, cfg);
s.run();
}

62
simulation/setup_dht.hpp Normal file
View File

@ -0,0 +1,62 @@
/*
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/io_service.hpp"
namespace libtorrent {
class alert;
struct settings_pack;
struct add_torrent_params;
class session;
}
struct network_setup_provider
{
// can be used to check expected end conditions
virtual void on_exit() {}
// called for every alert. if the simulation is done, return true
virtual bool on_alert(libtorrent::alert const* alert, int session_idx)
{ return false; }
virtual bool on_tick() = 0;
// called for every session that's added
virtual libtorrent::settings_pack add_session(int idx) = 0;
// called for a session right after it has been created
virtual void setup_session(libtorrent::session& ses, int idx) = 0;
};
void setup_dht(int num_nodes, network_setup_provider& config);

210
simulation/setup_swarm.cpp Normal file
View File

@ -0,0 +1,210 @@
/*
Copyright (c) 2014-2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/session.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/io_service.hpp"
#include "libtorrent/deadline_timer.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/add_torrent_params.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/ip_filter.hpp"
#include "libtorrent/alert_types.hpp"
#include <boost/bind.hpp>
#include "setup_swarm.hpp"
namespace lt = libtorrent;
using namespace sim;
namespace {
struct swarm
{
swarm(int num_nodes, swarm_setup_provider& config)
: m_config(config)
, m_ios(m_sim, asio::ip::address_v4::from_string("0.0.0.0"))
, m_start_time(lt::clock_type::now())
, m_timer(m_ios)
, m_shutting_down(false)
, m_tick(0)
{
for (int i = 0; i < num_nodes; ++i)
{
// create a new io_service
char ep[30];
snprintf(ep, sizeof(ep), "50.0.%d.%d", (i + 1) >> 8, (i + 1) & 0xff);
m_io_service.push_back(boost::make_shared<sim::asio::io_service>(
boost::ref(m_sim), asio::ip::address_v4::from_string(ep)));
lt::settings_pack pack = m_config.add_session(i);
boost::shared_ptr<lt::session> ses =
boost::make_shared<lt::session>(pack
, boost::ref(*m_io_service.back()));
m_nodes.push_back(ses);
// reserve a slot in here for when the torrent gets added (notified by
// an alert)
m_torrents.push_back(lt::torrent_handle());
lt::add_torrent_params params = m_config.add_torrent(i);
ses->async_add_torrent(params);
ses->set_alert_notify(boost::bind(&swarm::on_alert_notify, this, i));
}
m_timer.expires_from_now(lt::seconds(1));
m_timer.async_wait(boost::bind(&swarm::on_tick, this, _1));
}
void on_tick(lt::error_code const& ec)
{
if (ec || m_shutting_down) return;
lt::time_duration d = lt::clock_type::now() - m_start_time;
boost::uint32_t millis = lt::duration_cast<lt::milliseconds>(d).count();
printf("%4d.%03d: TICK %d\n", millis / 1000, millis % 1000, m_tick);
++m_tick;
if (m_tick > 120)
{
terminate();
return;
}
m_timer.expires_from_now(lt::seconds(1));
m_timer.async_wait(boost::bind(&swarm::on_tick, this, _1));
}
void on_alert_notify(int session_index)
{
// this function is called inside libtorrent and we cannot perform work
// immediately in it. We have to notify the outside to pull all the alerts
m_io_service[session_index]->post(boost::bind(&swarm::on_alerts, this, session_index));
}
void on_alerts(int session_index)
{
std::vector<lt::alert*> alerts;
lt::session* ses = m_nodes[session_index].get();
// when shutting down, we may have destructed the session
if (ses == NULL) return;
bool term = false;
ses->pop_alerts(&alerts);
for (std::vector<lt::alert*>::iterator i = alerts.begin();
i != alerts.end(); ++i)
{
lt::alert* a = *i;
lt::time_duration d = a->timestamp() - m_start_time;
boost::uint32_t millis = lt::duration_cast<lt::milliseconds>(d).count();
printf("%4d.%03d: [%02d] %s\n", millis / 1000, millis % 1000,
session_index, a->message().c_str());
// if a torrent was added save the torrent handle
if (lt::add_torrent_alert* at = lt::alert_cast<lt::add_torrent_alert>(a))
{
lt::torrent_handle h = at->handle;
m_torrents[session_index] = h;
// now, connect this torrent to all the others in the swarm
for (int k = 0; k < session_index; ++k)
{
char ep[30];
snprintf(ep, sizeof(ep), "50.0.%d.%d", (k + 1) >> 8, (k + 1) & 0xff);
h.connect_peer(lt::tcp::endpoint(
lt::address_v4::from_string(ep), 6881));
}
}
if (m_config.on_alert(a, session_index, m_torrents))
term = true;
}
if (term) terminate();
}
void run()
{
m_sim.run();
printf("simulation::run() returned\n");
}
void terminate()
{
printf("TERMINATING\n");
m_config.on_exit(m_torrents);
// terminate simulation
for (int i = 0; i < int(m_nodes.size()); ++i)
{
m_zombies.push_back(m_nodes[i]->abort());
m_nodes[i].reset();
}
m_shutting_down = true;
}
private:
swarm_setup_provider& m_config;
sim::simulation m_sim;
asio::io_service m_ios;
lt::time_point m_start_time;
std::vector<boost::shared_ptr<lt::session> > m_nodes;
std::vector<boost::shared_ptr<sim::asio::io_service> > m_io_service;
std::vector<lt::torrent_handle> m_torrents;
std::vector<lt::session_proxy> m_zombies;
lt::deadline_timer m_timer;
bool m_shutting_down;
int m_tick;
};
} // anonymous namespace
void setup_swarm(int num_nodes, swarm_setup_provider& cfg)
{
swarm s(num_nodes, cfg);
s.run();
}

View File

@ -0,0 +1,57 @@
/*
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/io_service.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/add_torrent_params.hpp"
struct swarm_setup_provider
{
// can be used to check expected end conditions
virtual void on_exit(std::vector<libtorrent::torrent_handle> const& torrents) {}
// 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& handles) { return false; }
// 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) = 0;
// called for every session that's added
virtual libtorrent::settings_pack add_session(int idx) = 0;
};
void setup_swarm(int num_nodes, swarm_setup_provider& config);

191
simulation/swarm_suite.cpp Normal file
View File

@ -0,0 +1,191 @@
/*
Copyright (c) 2014, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/session.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/time.hpp" // for clock_type
#include <fstream>
#include "test.hpp"
#include "setup_transfer.hpp" // for create_torrent (factor this out!)
#include "setup_swarm.hpp"
#include "swarm_suite.hpp"
#include "settings.hpp"
using namespace libtorrent;
namespace lt = libtorrent;
struct swarm_config : swarm_setup_provider
{
swarm_config(int flags)
: m_flags(flags)
, m_swarm_id(std::rand())
, m_start_time(lt::clock_type::now())
{
// in case the previous run was terminated
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, 0x4000, 9, 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);
}
TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(2100));
}
// 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)
{
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)
{
add_torrent_params p;
p.flags &= ~add_torrent_params::flag_paused;
p.flags &= ~add_torrent_params::flag_auto_managed;
p.ti = m_ti;
// only the first session is set to seed mode
if (idx == 0)
{
if (m_flags & seed_mode) p.flags |= add_torrent_params::flag_seed_mode;
}
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)
{
settings_pack pack = settings();
pack.set_bool(settings_pack::strict_super_seeding, m_flags & strict_super_seeding);
if (m_flags & suggest_read_cache)
pack.set_int(settings_pack::suggest_mode, settings_pack::suggest_read_cache);
else
pack.set_int(settings_pack::suggest_mode, 0);
if (m_flags & explicit_cache)
{
pack.set_bool(settings_pack::explicit_read_cache, true);
pack.set_int(settings_pack::explicit_cache_interval, 5);
}
else
{
pack.set_bool(settings_pack::explicit_read_cache, false);
}
if (m_flags & utp_only)
{
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);
}
// 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_flags;
int m_swarm_id;
lt::time_point m_start_time;
boost::shared_ptr<libtorrent::torrent_info> m_ti;
};
void simulate_swarm(int flags)
{
fprintf(stderr, "\n\n ==== TEST SWARM === %s%s%s%s%s%s%s ===\n\n\n"
, (flags & super_seeding) ? "super-seeding ": ""
, (flags & strict_super_seeding) ? "strict-super-seeding ": ""
, (flags & seed_mode) ? "seed-mode ": ""
, (flags & time_critical) ? "time-critical ": ""
, (flags & suggest_read_cache) ? "suggest-read-cache ": ""
, (flags & explicit_cache) ? "explicit-cache ": ""
, (flags & utp_only) ? "utp-only": ""
);
swarm_config cfg(flags);
setup_swarm(2, cfg);
}

View File

@ -0,0 +1,47 @@
/*
Copyright (c) 2014, 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"
enum test_flags_t
{
super_seeding = 1,
strict_super_seeding = 2,
seed_mode = 4,
time_critical = 8,
suggest_read_cache = 16,
explicit_cache = 32,
utp_only = 64
};
void EXPORT simulate_swarm(int flags = 0);

123
simulation/test_dht.cpp Normal file
View File

@ -0,0 +1,123 @@
/*
Copyright (c) 2015, 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 "settings.hpp"
#include "setup_dht.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/time.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/alert_types.hpp"
namespace lt = libtorrent;
struct network_config : network_setup_provider
{
network_config()
: m_start_time(lt::clock_type::now())
{}
virtual void on_exit() override final {}
// called for every alert. if the simulation is done, return true
virtual bool on_alert(lt::alert const* alert
, int session_idx) override final
{
if (lt::dht_stats_alert const* p = lt::alert_cast<lt::dht_stats_alert>(alert))
{
int bucket = 0;
for (std::vector<lt::dht_routing_bucket>::const_iterator i = p->routing_table.begin()
, end(p->routing_table.end()); i != end; ++i, ++bucket)
{
char const* progress_bar =
"################################"
"################################"
"################################"
"################################";
char const* short_progress_bar = "--------";
printf("%3d [%3d, %d] %s%s\n"
, bucket, i->num_nodes, i->num_replacements
, progress_bar + (128 - i->num_nodes)
, short_progress_bar + (8 - (std::min)(8, i->num_replacements)));
}
}
return false;
}
bool on_tick() override final
{
m_first_session->post_dht_stats();
if (++m_ticks > 80) return true;
return false;
}
// called for every session that's added
virtual lt::settings_pack add_session(int idx) override final
{
lt::settings_pack pack = settings();
pack.set_bool(lt::settings_pack::enable_dht, true);
return pack;
}
virtual void setup_session(lt::session& ses, int idx) override final
{
if (idx == 0) m_first_session = &ses;
// we have to do this since all of our simulated IP addresses are close to
// each other
lt::dht_settings sett;
sett.restrict_routing_ips = false;
sett.restrict_search_ips = false;
sett.privacy_lookups = false;
sett.extended_routing_table = false;
ses.set_dht_settings(sett);
}
private:
lt::time_point m_start_time;
boost::shared_ptr<lt::torrent_info> m_ti;
lt::session* m_first_session;
int m_ticks;
};
TORRENT_TEST(dht)
{
network_config cfg;
setup_dht(50, cfg);
}

62
simulation/test_swarm.cpp Normal file
View File

@ -0,0 +1,62 @@
/*
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 "swarm_suite.hpp"
#include "test.hpp"
TORRENT_TEST(seed_mode)
{
// with seed mode
simulate_swarm(seed_mode);
}
TORRENT_TEST(plain)
{
simulate_swarm();
}
TORRENT_TEST(suggest)
{
// with suggest pieces
simulate_swarm(suggest_read_cache);
}
TORRENT_TEST(utp)
{
simulate_swarm(utp_only);
}
TORRENT_TEST(explicit_cache)
{
// test explicit cache
simulate_swarm(suggest_read_cache | explicit_cache);
}

188
simulation/test_utp.cpp Normal file
View File

@ -0,0 +1,188 @@
/*
Copyright (c) 2008, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/session.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/time.hpp" // for clock_type
#include <boost/bind.hpp>
#include "test.hpp"
#include "setup_swarm.hpp"
#include "setup_transfer.hpp" // for create_torrent (factor this out!)
#include "settings.hpp"
#include <fstream>
#include <iostream>
using namespace 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, 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)
{
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)
{
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)
{
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)
{
// TODO: 3 simulate packet loss
// TODO: 3 simulate unpredictible latencies
// TODO: 3 simulate proper (taildrop) queues (perhaps even RED and BLUE)
swarm_config cfg(2);
setup_swarm(2, cfg);
}

View File

@ -5618,7 +5618,7 @@ retry:
session_impl::~session_impl() session_impl::~session_impl()
{ {
// this is not allowed to be the network thread! // this is not allowed to be the network thread!
TORRENT_ASSERT(is_not_thread()); // TORRENT_ASSERT(is_not_thread());
#if defined TORRENT_ASIO_DEBUGGING #if defined TORRENT_ASIO_DEBUGGING
int counter = 0; int counter = 0;

View File

@ -59,6 +59,7 @@ lib libtorrent_test
web_seed_suite.cpp web_seed_suite.cpp
swarm_suite.cpp swarm_suite.cpp
test_utils.cpp test_utils.cpp
settings.cpp
: # requirements : # requirements
# this is used to determine whether # this is used to determine whether
@ -76,6 +77,7 @@ lib libtorrent_test
: # user-requirements : # user-requirements
<link>shared:<define>TORRENT_LINK_TEST_SHARED <link>shared:<define>TORRENT_LINK_TEST_SHARED
<logging>on <logging>on
<include>.
; ;
explicit libtorrent_test ; explicit libtorrent_test ;

View File

@ -100,7 +100,7 @@ EXTRA_PROGRAMS = $(test_programs)
noinst_HEADERS = test.hpp setup_transfer.hpp dht_server.hpp \ noinst_HEADERS = test.hpp setup_transfer.hpp dht_server.hpp \
peer_server.hpp udp_tracker.hpp web_seed_suite.hpp swarm_suite.hpp \ peer_server.hpp udp_tracker.hpp web_seed_suite.hpp swarm_suite.hpp \
test_utils.hpp test_utils.hpp settings.hpp
libtest_la_SOURCES = main.cpp \ libtest_la_SOURCES = main.cpp \
test.cpp \ test.cpp \
@ -110,7 +110,8 @@ libtest_la_SOURCES = main.cpp \
peer_server.cpp \ peer_server.cpp \
web_seed_suite.cpp \ web_seed_suite.cpp \
swarm_suite.cpp \ swarm_suite.cpp \
test_utils.cpp test_utils.cpp \
settings.cpp \
test_primitives_SOURCES = \ test_primitives_SOURCES = \
test_primitives.cpp \ test_primitives.cpp \

63
test/settings.cpp Normal file
View File

@ -0,0 +1,63 @@
/*
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/alert.hpp"
using namespace libtorrent;
libtorrent::settings_pack settings()
{
const int mask = alert::all_categories
& ~(alert::progress_notification
| alert::performance_warning
| alert::stats_notification);
settings_pack pack;
pack.set_bool(settings_pack::enable_lsd, false);
pack.set_bool(settings_pack::enable_natpmp, false);
pack.set_bool(settings_pack::enable_upnp, false);
pack.set_bool(settings_pack::enable_dht, false);
pack.set_int(settings_pack::alert_mask, mask);
#ifndef TORRENT_BUILD_SIMULATOR
pack.set_bool(settings_pack::allow_multiple_connections_per_ip, true);
#else
// we use 0 threads (disk I/O operations will be performed in the network
// thread) to be simulator friendly.
pack.set_int(settings_pack::aio_threads, 0);
#endif
return pack;
}

36
test/settings.hpp Normal file
View File

@ -0,0 +1,36 @@
/*
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "libtorrent/settings_pack.hpp"
libtorrent::settings_pack settings();