fix pex unit test and shave off a few seconds for pex

This commit is contained in:
Arvid Norberg 2011-03-24 03:34:06 +00:00
parent 29a523401e
commit 929c31a757
2 changed files with 81 additions and 28 deletions

View File

@ -55,6 +55,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/extensions/ut_pex.hpp" #include "libtorrent/extensions/ut_pex.hpp"
#ifdef TORRENT_VERBOSE_LOGGING
#include "libtorrent/lazy_entry.hpp"
#endif
namespace libtorrent { namespace namespace libtorrent { namespace
{ {
const char extension_name[] = "ut_pex"; const char extension_name[] = "ut_pex";
@ -77,7 +81,9 @@ namespace libtorrent { namespace
struct ut_pex_plugin: torrent_plugin struct ut_pex_plugin: torrent_plugin
{ {
ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(55), m_peers_in_message(0) {} // randomize when we rebuild the pex message
// to evenly spread it out across all torrents
ut_pex_plugin(torrent& t): m_torrent(t), m_1_minute(random() % 60), m_peers_in_message(0) {}
virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection* pc); virtual boost::shared_ptr<peer_plugin> new_connection(peer_connection* pc);
@ -217,7 +223,7 @@ namespace libtorrent { namespace
: m_torrent(t) : m_torrent(t)
, m_pc(pc) , m_pc(pc)
, m_tp(tp) , m_tp(tp)
, m_1_minute(55) , m_1_minute(60)
, m_message_index(0) , m_message_index(0)
, m_first_time(true) , m_first_time(true)
{ {
@ -262,7 +268,7 @@ namespace libtorrent { namespace
if (body.left() < length) return true; if (body.left() < length) return true;
ptime now = time_now_hires(); //#error TEMP! ptime now = time_now();
if (now - m_last_pex[0] < seconds(60)) if (now - m_last_pex[0] < seconds(60))
{ {
// this client appears to be trying to flood us // this client appears to be trying to flood us
@ -288,8 +294,9 @@ namespace libtorrent { namespace
lazy_entry const* p = pex_msg.dict_find_string("dropped"); lazy_entry const* p = pex_msg.dict_find_string("dropped");
#ifdef TORRENT_VERBOSE_LOGGING #ifdef TORRENT_VERBOSE_LOGGING
(*m_pc.m_logger) << time_now_string() << " <== PEX [" int num_dropped = 0;
" dropped:" << (p?p->string_length():0); int num_added = 0;
if (p) num_dropped += p->string_length()/6;
#endif #endif
if (p) if (p)
{ {
@ -309,7 +316,7 @@ namespace libtorrent { namespace
lazy_entry const* pf = pex_msg.dict_find_string("added.f"); lazy_entry const* pf = pex_msg.dict_find_string("added.f");
#ifdef TORRENT_VERBOSE_LOGGING #ifdef TORRENT_VERBOSE_LOGGING
(*m_pc.m_logger) << " added:" << (p?p->string_length():0) << " ]\n"; if (p) num_added += p->string_length() / 6;
#endif #endif
if (p != 0 if (p != 0
&& pf != 0 && pf != 0
@ -343,6 +350,9 @@ namespace libtorrent { namespace
#if TORRENT_USE_IPV6 #if TORRENT_USE_IPV6
lazy_entry const* p6 = pex_msg.dict_find("dropped6"); lazy_entry const* p6 = pex_msg.dict_find("dropped6");
#ifdef TORRENT_VERBOSE_LOGGING
if (p6) num_dropped += p->string_length() / 18;
#endif
if (p6 != 0 && p6->type() == lazy_entry::string_t) if (p6 != 0 && p6->type() == lazy_entry::string_t)
{ {
int num_peers = p6->string_length() / 18; int num_peers = p6->string_length() / 18;
@ -358,6 +368,9 @@ namespace libtorrent { namespace
} }
p6 = pex_msg.dict_find("added6"); p6 = pex_msg.dict_find("added6");
#ifdef TORRENT_VERBOSE_LOGGING
if (p6) num_added += p->string_length() / 18;
#endif
lazy_entry const* p6f = pex_msg.dict_find("added6.f"); lazy_entry const* p6f = pex_msg.dict_find("added6.f");
if (p6 != 0 if (p6 != 0
&& p6f != 0 && p6f != 0
@ -387,6 +400,10 @@ namespace libtorrent { namespace
p.add_peer(adr, pid, peer_info::pex, flags); p.add_peer(adr, pid, peer_info::pex, flags);
} }
} }
#endif
#ifdef TORRENT_VERBOSE_LOGGING
m_pc.peer_log("<== PEX [ dropped: %d added: %d ]"
, num_dropped, num_added);
#endif #endif
return true; return true;
} }
@ -426,6 +443,27 @@ namespace libtorrent { namespace
i.begin += pex_msg.size(); i.begin += pex_msg.size();
TORRENT_ASSERT(i.begin == i.end); TORRENT_ASSERT(i.begin == i.end);
#ifdef TORRENT_VERBOSE_LOGGING
lazy_entry m;
error_code ec;
int ret = lazy_bdecode(&pex_msg[0], &pex_msg[0] + pex_msg.size(), m, ec);
TORRENT_ASSERT(ret == 0);
TORRENT_ASSERT(!ec);
int num_dropped = 0;
int num_added = 0;
lazy_entry const* e = m.dict_find_string("added");
if (e) num_added += e->string_length() / 6;
e = m.dict_find_string("dropped");
if (e) num_dropped += e->string_length() / 6;
e = m.dict_find_string("added6");
if (e) num_added += e->string_length() / 18;
e = m.dict_find_string("dropped6");
if (e) num_dropped += e->string_length() / 18;
m_pc.peer_log("==> PEX_DIFF [ dropped: %d added: %d msg_size: %d ]"
, num_dropped, num_added, int(pex_msg.size()));
#endif
m_pc.setup_send(); m_pc.setup_send();
} }
@ -498,6 +536,11 @@ namespace libtorrent { namespace
i.begin += pex_msg.size(); i.begin += pex_msg.size();
TORRENT_ASSERT(i.begin == i.end); TORRENT_ASSERT(i.begin == i.end);
#ifdef TORRENT_VERBOSE_LOGGING
m_pc.peer_log("==> PEX_FULL [ added: %d msg_size: %d ]", num_added, int(pex_msg.size()));
#endif
m_pc.setup_send(); m_pc.setup_send();
} }

View File

@ -49,29 +49,45 @@ void test_pex()
session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49200, 50000), "0.0.0.0", 0); session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49200, 50000), "0.0.0.0", 0);
session ses3(fingerprint("LT", 0, 1, 0, 0), std::make_pair(50200, 51000), "0.0.0.0", 0); session ses3(fingerprint("LT", 0, 1, 0, 0), std::make_pair(50200, 51000), "0.0.0.0", 0);
ses1.add_extension(create_ut_pex_plugin);
ses2.add_extension(create_ut_pex_plugin);
torrent_handle tor1;
torrent_handle tor2;
torrent_handle tor3;
boost::tie(tor1, tor2, tor3) = setup_transfer(&ses1, &ses2, &ses3, true, false, false, "_pex");
int mask = alert::all_categories
& ~(alert::progress_notification
| alert::performance_warning
| alert::stats_notification);
ses1.set_alert_mask(mask);
ses2.set_alert_mask(mask);
ses3.set_alert_mask(mask);
// this is to avoid everything finish from a single peer // this is to avoid everything finish from a single peer
// immediately. To make the swarm actually connect all // immediately. To make the swarm actually connect all
// three peers before finishing. // three peers before finishing.
float rate_limit = 1000;
session_settings set = ses1.settings(); session_settings set = ses1.settings();
set.upload_rate_limit = rate_limit; set.download_rate_limit = 0;
set.upload_rate_limit = 0;
ses1.set_settings(set); ses1.set_settings(set);
// make the peer connecting the two worthless to transfer // make the peer connecting the two worthless to transfer
// data, to force peer 3 to connect directly to peer 1 through pex // data, to force peer 3 to connect directly to peer 1 through pex
set = ses2.settings(); set = ses2.settings();
set.download_rate_limit = rate_limit; set.download_rate_limit = 2000;
set.upload_rate_limit = 2000; set.upload_rate_limit = 2000;
set.ignore_limits_on_local_network = false;
set.rate_limit_utp = true;
ses2.set_settings(set); ses2.set_settings(set);
set = ses3.settings(); set = ses3.settings();
set.download_rate_limit = rate_limit; set.download_rate_limit = 0;
set.upload_rate_limit = rate_limit / 2; set.upload_rate_limit = 0;
ses3.set_settings(set); ses3.set_settings(set);
ses1.add_extension(&create_ut_pex_plugin);
ses2.add_extension(&create_ut_pex_plugin);
#ifndef TORRENT_DISABLE_ENCRYPTION #ifndef TORRENT_DISABLE_ENCRYPTION
pe_settings pes; pe_settings pes;
pes.out_enc_policy = pe_settings::forced; pes.out_enc_policy = pe_settings::forced;
@ -81,18 +97,7 @@ void test_pex()
ses3.set_pe_settings(pes); ses3.set_pe_settings(pes);
#endif #endif
torrent_handle tor1; test_sleep(100);
torrent_handle tor2;
torrent_handle tor3;
boost::tie(tor1, tor2, tor3) = setup_transfer(&ses1, &ses2, &ses3, true, false, false, "_pex");
int mask = alert::all_categories & ~(alert::progress_notification | alert::performance_warning);
ses1.set_alert_mask(mask);
ses2.set_alert_mask(mask);
ses3.set_alert_mask(mask);
test_sleep(1000);
// in this test, ses1 is a seed, ses2 is connected to ses1 and ses3. // in this test, ses1 is a seed, ses2 is connected to ses1 and ses3.
// the expected behavior is that ses2 will introduce ses1 and ses3 to each other // the expected behavior is that ses2 will introduce ses1 and ses3 to each other
@ -103,7 +108,7 @@ void test_pex()
torrent_status st1; torrent_status st1;
torrent_status st2; torrent_status st2;
torrent_status st3; torrent_status st3;
for (int i = 0; i < 90; ++i) for (int i = 0; i < 10; ++i)
{ {
print_alerts(ses1, "ses1"); print_alerts(ses1, "ses1");
print_alerts(ses2, "ses2"); print_alerts(ses2, "ses2");
@ -126,10 +131,15 @@ void test_pex()
<< st3.num_peers << st3.num_peers
<< std::endl; << std::endl;
// this is the success condition
if (st1.num_peers == 2 && st2.num_peers == 2 && st3.num_peers == 2) if (st1.num_peers == 2 && st2.num_peers == 2 && st3.num_peers == 2)
break; break;
// this suggests that we failed. If session 3 completes without
// actually connecting to session 1, everything was transferred
// through session 2
if (st3.state == torrent_status::seeding) break; if (st3.state == torrent_status::seeding) break;
test_sleep(1000); test_sleep(1000);
} }