Merge pull request #339 from arvidn/dht-storage-test

extend the unit test of dht_storage
This commit is contained in:
Arvid Norberg 2015-12-20 02:02:56 -05:00
commit 03e90d45d8
5 changed files with 145 additions and 39 deletions

View File

@ -1393,6 +1393,7 @@ namespace libtorrent
, max_fail_count(20)
, max_torrents(2000)
, max_dht_items(700)
, max_peers(5000)
, max_torrent_search_reply(20)
, restrict_routing_ips(true)
, restrict_search_ips(true)
@ -1436,6 +1437,9 @@ namespace libtorrent
// max number of items the DHT will store
int max_dht_items;
// the max number of peers to store per torrent (for the DHT)
int max_peers;
// the max number of torrents to return in a torrent search query to the
// DHT
int max_torrent_search_reply;

View File

@ -303,7 +303,7 @@ namespace
if (!name.empty() && v->name.empty())
{
std::string tname = name;
if (tname.size() > 50) tname.resize(50);
if (tname.size() > 100) tname.resize(100);
v->name = tname;
}
@ -317,6 +317,16 @@ namespace
v->peers.erase(i++);
m_counters.peers -= 1;
}
else if (v->peers.size() >= m_settings.max_peers)
{
// when we're at capacity, there's a 50/50 chance of dropping the
// announcing peer or an existing peer
if (random() & 1) return;
i = v->peers.lower_bound(peer);
if (i == v->peers.end()) --i;
v->peers.erase(i++);
m_counters.peers -= 1;
}
v->peers.insert(i, peer);
m_counters.peers += 1;
}
@ -413,10 +423,13 @@ namespace
{
// delete the least important one (i.e. the one
// the fewest peers are announcing)
// TODO: c++11 use a lambda here instead
dht_mutable_table_t::iterator j = std::min_element(m_mutable_table.begin()
, m_mutable_table.end()
, boost::bind(&dht_immutable_item::num_announcers
, boost::bind(&dht_mutable_table_t::value_type::second, _1)));
, boost::bind(&dht_mutable_table_t::value_type::second, _1))
< boost::bind(&dht_immutable_item::num_announcers
, boost::bind(&dht_mutable_table_t::value_type::second, _2)));
TORRENT_ASSERT(j != m_mutable_table.end());
free(j->second.value);
free(j->second.salt);
@ -475,20 +488,18 @@ namespace
for (table_t::iterator i = m_map.begin(), end(m_map.end()); i != end;)
{
torrent_entry& t = i->second;
node_id const& key = i->first;
++i;
purge_peers(t.peers);
if (!t.peers.empty()) continue;
if (!t.peers.empty())
{
++i;
continue;
}
// if there are no more peers, remove the entry altogether
table_t::iterator it = m_map.find(key);
if (it != m_map.end())
{
m_map.erase(it);
m_map.erase(i++);
m_counters.torrents -= 1;// peers is decreased by purge_peers
}
}
if (0 == m_settings.item_lifetime) return;

View File

@ -94,6 +94,14 @@ address rand_v4()
return address_v4(g_addr);
}
sha1_hash rand_hash()
{
sha1_hash ret;
for (int i = 0; i < 20; ++i)
ret[i] = lt::random();
return ret;
}
#if TORRENT_USE_IPV6
address rand_v6()
{

View File

@ -59,6 +59,8 @@ EXPORT libtorrent::address rand_v6();
EXPORT libtorrent::tcp::endpoint rand_tcp_ep();
EXPORT libtorrent::udp::endpoint rand_udp_ep();
EXPORT libtorrent::sha1_hash rand_hash();
EXPORT std::map<std::string, boost::int64_t> get_counters(libtorrent::session& s);
EXPORT libtorrent::alert const* wait_for_alert(

View File

@ -47,6 +47,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/kademlia/routing_table.hpp"
#include "libtorrent/kademlia/item.hpp"
#include "libtorrent/kademlia/dht_observer.hpp"
#include "libtorrent/random.hpp"
#include "libtorrent/ed25519.hpp"
#include <numeric>
@ -83,18 +84,17 @@ namespace
}
}
TORRENT_TEST(dht_storage)
const sha1_hash n1 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee401");
const sha1_hash n2 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee402");
const sha1_hash n3 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee403");
const sha1_hash n4 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee404");
TORRENT_TEST(announce_peer)
{
dht_settings sett = test_settings();
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
TEST_CHECK(s.get() != NULL);
sha1_hash n1 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee401");
sha1_hash n2 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee402");
sha1_hash n3 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee403");
sha1_hash n4 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee404");
entry peers;
s->get_peers(n1, false, false, peers);
@ -116,9 +116,16 @@ TORRENT_TEST(dht_storage)
s->announce_peer(n3, p4, "torrent_name2", false);
bool r = s->get_peers(n1, false, false, peers);
TEST_CHECK(!r);
}
TORRENT_TEST(put_immutable_item)
{
dht_settings sett = test_settings();
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
TEST_CHECK(s.get() != NULL);
entry item;
r = s->get_immutable_item(n4, item);
bool r = s->get_immutable_item(n4, item);
TEST_CHECK(!r);
s->put_immutable_item(n4, "123", 3, address::from_string("124.31.75.21"));
@ -141,7 +148,7 @@ TORRENT_TEST(dht_storage)
TEST_CHECK(r);
}
TORRENT_TEST(dht_storage_counters)
TORRENT_TEST(counters)
{
dht_settings sett = test_settings();
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
@ -187,13 +194,14 @@ TORRENT_TEST(dht_storage_counters)
TEST_EQUAL(s->counters().mutable_data, 1);
}
TORRENT_TEST(dht_storage_set_custom)
TORRENT_TEST(set_custom)
{
g_storage_constructor_invoked = false;
settings_pack p;
p.set_bool(settings_pack::enable_dht, false);
lt::session ses(p);
TEST_EQUAL(g_storage_constructor_invoked, false);
bool r = ses.is_dht_running();
TEST_CHECK(!r);
@ -206,7 +214,7 @@ TORRENT_TEST(dht_storage_set_custom)
TEST_EQUAL(g_storage_constructor_invoked, true);
}
TORRENT_TEST(dht_storage_default_set_custom)
TORRENT_TEST(default_set_custom)
{
g_storage_constructor_invoked = false;
settings_pack p;
@ -233,4 +241,77 @@ TORRENT_TEST(dht_storage_default_set_custom)
TEST_EQUAL(g_storage_constructor_invoked, true);
}
TORRENT_TEST(peer_limit)
{
dht_settings sett = test_settings();
sett.max_peers = 42;
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
TEST_CHECK(s.get() != NULL);
for (int i = 0; i < 200; ++i)
{
s->announce_peer(n1, tcp::endpoint(rand_v4(), lt::random())
, "torrent_name", false);
dht_storage_counters cnt = s->counters();
TEST_CHECK(cnt.peers <= 42);
}
dht_storage_counters cnt = s->counters();
TEST_EQUAL(cnt.peers, 42);
}
TORRENT_TEST(torrent_limit)
{
dht_settings sett = test_settings();
sett.max_torrents = 42;
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
TEST_CHECK(s.get() != NULL);
for (int i = 0; i < 200; ++i)
{
s->announce_peer(rand_hash(), tcp::endpoint(rand_v4(), lt::random())
, "", false);
dht_storage_counters cnt = s->counters();
TEST_CHECK(cnt.torrents <= 42);
}
dht_storage_counters cnt = s->counters();
TEST_EQUAL(cnt.torrents, 42);
}
TORRENT_TEST(immutable_item_limit)
{
dht_settings sett = test_settings();
sett.max_dht_items = 42;
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
TEST_CHECK(s.get() != NULL);
for (int i = 0; i < 200; ++i)
{
s->put_immutable_item(rand_hash(), "123", 3, rand_v4());
dht_storage_counters cnt = s->counters();
TEST_CHECK(cnt.immutable_data <= 42);
}
dht_storage_counters cnt = s->counters();
TEST_EQUAL(cnt.immutable_data, 42);
}
TORRENT_TEST(mutable_item_limit)
{
dht_settings sett = test_settings();
sett.max_dht_items = 42;
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
TEST_CHECK(s.get() != NULL);
char public_key[item_pk_len];
char signature[item_sig_len];
for (int i = 0; i < 200; ++i)
{
s->put_mutable_item(rand_hash(), "123", 3, signature, 1, public_key, "salt", 4, rand_v4());
dht_storage_counters cnt = s->counters();
TEST_CHECK(cnt.mutable_data <= 42);
}
dht_storage_counters cnt = s->counters();
TEST_EQUAL(cnt.mutable_data, 42);
}
#endif