Merge pull request #175 from aldenml/dht-storage-peers-counter

Fix of dht_storage_counters::peers counter
This commit is contained in:
Arvid Norberg 2015-09-25 08:25:15 -07:00
commit fb19a672bc
9 changed files with 245 additions and 36 deletions

View File

@ -44,7 +44,7 @@ namespace libtorrent { namespace aux
// resolution of this timer is about 100 ms.
time_point const& time_now();
void update_time_now();
TORRENT_EXTRA_EXPORT void update_time_now();
} }

View File

@ -28,6 +28,7 @@ alias libtorrent-sims :
[ run test_super_seeding.cpp ]
[ run test_utp.cpp ]
[ run test_dht.cpp ]
[ run test_dht_storage.cpp ]
[ run test_pe_crypto.cpp ]
[ run test_metadata_extension.cpp ]
[ run test_trackers_extension.cpp ]

View File

@ -0,0 +1,157 @@
/*
Copyright (c) 2015, Alden Torres
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 "libtorrent/config.hpp"
#include "libtorrent/kademlia/node.hpp" // for verify_message
#include "libtorrent/kademlia/dht_storage.hpp"
#include "libtorrent/kademlia/item.hpp"
#include "libtorrent/io_service.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/aux_/time.hpp"
#include "simulator/simulator.hpp"
#include <functional>
using namespace libtorrent;
using namespace libtorrent::dht;
using namespace sim;
using namespace sim::chrono;
using namespace sim::asio;
using sim::simulation;
using sim::default_config;
namespace
{
dht_settings test_settings() {
dht_settings sett;
sett.max_torrents = 2;
sett.max_dht_items = 2;
sett.item_lifetime = seconds(120 * 60).count();
return sett;
}
static sha1_hash to_hash(char const *s) {
sha1_hash ret;
from_hex(s, 40, (char *) &ret[0]);
return ret;
}
}
void timer_tick(boost::shared_ptr<dht_storage_interface> s
, dht_storage_counters const& c
, boost::system::error_code const& ec)
{
libtorrent::aux::update_time_now();
s->tick();
TEST_EQUAL(s->counters().peers, c.peers);
TEST_EQUAL(s->counters().torrents, c.torrents);
TEST_EQUAL(s->counters().immutable_data, c.immutable_data);
TEST_EQUAL(s->counters().mutable_data, c.mutable_data);
}
void test_expiration(high_resolution_clock::duration const& expiry_time
, boost::shared_ptr<dht_storage_interface> s
, dht_storage_counters const& c)
{
default_config cfg;
simulation sim(cfg);
sim::asio::io_service ios(sim, asio::ip::address_v4::from_string("10.0.0.1"));
sim::asio::high_resolution_timer timer(ios);
timer.expires_from_now(expiry_time);
timer.async_wait(boost::bind(&timer_tick, s, c, _1));
boost::system::error_code ec;
sim.run(ec);
}
TORRENT_TEST(dht_storage_counters)
{
dht_settings sett = test_settings();
boost::shared_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");
tcp::endpoint p1 = tcp::endpoint(address::from_string("124.31.75.21"), 1);
tcp::endpoint p2 = tcp::endpoint(address::from_string("124.31.75.22"), 1);
tcp::endpoint p3 = tcp::endpoint(address::from_string("124.31.75.23"), 1);
tcp::endpoint p4 = tcp::endpoint(address::from_string("124.31.75.24"), 1);
s->announce_peer(n1, p1, "torrent_name", false);
s->announce_peer(n2, p2, "torrent_name1", false);
s->announce_peer(n2, p3, "torrent_name1", false);
s->announce_peer(n3, p4, "torrent_name2", false);
entry item;
s->put_immutable_item(n4, "123", 3, address::from_string("124.31.75.21"));
s->put_immutable_item(n1, "123", 3, address::from_string("124.31.75.21"));
s->put_immutable_item(n2, "123", 3, address::from_string("124.31.75.21"));
s->put_immutable_item(n3, "123", 3, address::from_string("124.31.75.21"));
char public_key[item_pk_len];
char signature[item_sig_len];
s->put_mutable_item(n4, "123", 3, signature, 1, public_key, "salt", 4, address::from_string("124.31.75.21"));
dht_storage_counters c;
// note that we are using the aux global timer
c.peers = 3;
c.torrents = 2;
c.immutable_data = 2;
c.mutable_data = 1;
test_expiration(minutes(30), s, c); // test expiration of torrents and peers
c.peers = 0;
c.torrents = 0;
c.immutable_data = 2;
c.mutable_data = 1;
test_expiration(minutes(80), s, c); // test expiration of items before 2 hours
c.peers = 0;
c.torrents = 0;
c.immutable_data = 0;
c.mutable_data = 0;
test_expiration(hours(1), s, c); // test expiration of everything after 3 hours
}

View File

@ -106,19 +106,6 @@ namespace
// TODO: 2 make this configurable in dht_settings
enum { announce_interval = 30 };
void purge_peers(std::set<peer_entry>& peers)
{
for (std::set<peer_entry>::iterator i = peers.begin()
, end(peers.end()); i != end;)
{
// the peer has timed out
if (i->added + minutes(int(announce_interval * 1.5f)) < aux::time_now())
peers.erase(i++);
else
++i;
}
}
struct dht_immutable_item
{
dht_immutable_item() : value(0), num_announcers(0), size(0) {}
@ -296,6 +283,7 @@ namespace
candidate = i;
}
m_map.erase(candidate);
m_counters.peers -= num_peers;
m_counters.torrents -= 1;
}
m_counters.torrents += 1;
@ -320,8 +308,13 @@ namespace
peer.added = aux::time_now();
peer.seed = seed;
std::set<peer_entry>::iterator i = v->peers.find(peer);
if (i != v->peers.end()) v->peers.erase(i++);
if (i != v->peers.end())
{
v->peers.erase(i++);
m_counters.peers -= 1;
}
v->peers.insert(i, peer);
m_counters.peers += 1;
}
bool get_immutable_item(sha1_hash const& target
@ -489,7 +482,7 @@ namespace
if (it != m_map.end())
{
m_map.erase(it);
m_counters.torrents -= 1;
m_counters.torrents -= 1;// peers is decreased by purge_peers
}
}
@ -540,6 +533,22 @@ namespace
table_t m_map;
dht_immutable_table_t m_immutable_table;
dht_mutable_table_t m_mutable_table;
void purge_peers(std::set<peer_entry>& peers)
{
for (std::set<peer_entry>::iterator i = peers.begin()
, end(peers.end()); i != end;)
{
// the peer has timed out
if (i->added + minutes(int(announce_interval * 1.5f)) < aux::time_now())
{
peers.erase(i++);
m_counters.peers -= 1;
}
else
++i;
}
}
};
}

View File

@ -906,3 +906,8 @@ void stop_web_server()
web_server_pid = 0;
}
tcp::endpoint ep(char const* ip, int port)
{
error_code ec;
return tcp::endpoint(address::from_string(ip, ec), port);
}

View File

@ -104,5 +104,7 @@ EXPORT int start_proxy(int type);
EXPORT void stop_proxy(int port);
EXPORT void stop_all_proxies();
EXPORT libtorrent::tcp::endpoint ep(char const* ip, int port);
#endif

View File

@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <numeric>
#include "test.hpp"
#include "setup_transfer.hpp"
using namespace libtorrent;
using namespace libtorrent::dht;
@ -61,6 +62,7 @@ namespace
dht_settings sett;
sett.max_torrents = 2;
sett.max_dht_items = 2;
sett.item_lifetime = seconds(120 * 60).count();
return sett;
}
@ -74,9 +76,9 @@ namespace
TORRENT_TEST(dht_storage)
{
dht_settings sett = test_settings();
dht_storage_interface* s = dht_default_storage_constructor(node_id(0), sett);
boost::scoped_ptr<dht_storage_interface> s(dht_default_storage_constructor(node_id(0), sett));
TEST_CHECK(s != NULL);
TEST_CHECK(s.get() != NULL);
sha1_hash n1 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee401");
sha1_hash n2 = to_hash("5fbfbff10c5d6a4ec8a88e4c6ab4c28b95eee402");
@ -89,10 +91,10 @@ TORRENT_TEST(dht_storage)
TEST_CHECK(peers["n"].string().empty())
TEST_CHECK(peers["values"].list().empty());
tcp::endpoint p1 = tcp::endpoint(address::from_string("124.31.75.21"), 1);
tcp::endpoint p2 = tcp::endpoint(address::from_string("124.31.75.22"), 1);
tcp::endpoint p3 = tcp::endpoint(address::from_string("124.31.75.23"), 1);
tcp::endpoint p4 = tcp::endpoint(address::from_string("124.31.75.24"), 1);
tcp::endpoint p1 = ep("124.31.75.21", 1);
tcp::endpoint p2 = ep("124.31.75.22", 1);
tcp::endpoint p3 = ep("124.31.75.23", 1);
tcp::endpoint p4 = ep("124.31.75.24", 1);
s->announce_peer(n1, p1, "torrent_name", false);
s->get_peers(n1, false, false, peers);
@ -127,8 +129,52 @@ TORRENT_TEST(dht_storage)
s->put_mutable_item(n4, "123", 3, signature, 1, public_key, "salt", 4, address::from_string("124.31.75.21"));
r = s->get_mutable_item(n4, 0, false, item);
TEST_CHECK(r);
delete s;
}
#endif
TORRENT_TEST(dht_storage_counters)
{
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");
TEST_EQUAL(s->counters().peers, 0);
TEST_EQUAL(s->counters().torrents, 0);
tcp::endpoint p1 = ep("124.31.75.21", 1);
tcp::endpoint p2 = ep("124.31.75.22", 1);
tcp::endpoint p3 = ep("124.31.75.23", 1);
tcp::endpoint p4 = ep("124.31.75.24", 1);
s->announce_peer(n1, p1, "torrent_name", false);
TEST_EQUAL(s->counters().peers, 1);
TEST_EQUAL(s->counters().torrents, 1);
s->announce_peer(n2, p2, "torrent_name1", false);
s->announce_peer(n2, p3, "torrent_name1", false);
s->announce_peer(n3, p4, "torrent_name2", false);
TEST_EQUAL(s->counters().peers, 3);
TEST_EQUAL(s->counters().torrents, 2);
entry item;
s->put_immutable_item(n4, "123", 3, address::from_string("124.31.75.21"));
TEST_EQUAL(s->counters().immutable_data, 1);
s->put_immutable_item(n1, "123", 3, address::from_string("124.31.75.21"));
s->put_immutable_item(n2, "123", 3, address::from_string("124.31.75.21"));
s->put_immutable_item(n3, "123", 3, address::from_string("124.31.75.21"));
TEST_EQUAL(s->counters().immutable_data, 2);
char public_key[item_pk_len];
char signature[item_sig_len];
s->put_mutable_item(n4, "123", 3, signature, 1, public_key, "salt", 4, address::from_string("124.31.75.21"));
TEST_EQUAL(s->counters().mutable_data, 1);
}
#endif

View File

@ -48,11 +48,6 @@ POSSIBILITY OF SUCH DAMAGE.
using namespace libtorrent;
static tcp::endpoint ep(char const* ip, int port)
{
return tcp::endpoint(address_v4::from_string(ip), port);
}
struct mock_torrent;
struct mock_peer_connection : peer_connection_interface

View File

@ -61,12 +61,6 @@ address_v6 v6(char const* str)
}
#endif
static tcp::endpoint ep(char const* ip, int port)
{
error_code ec;
return tcp::endpoint(address::from_string(ip, ec), port);
}
TORRENT_TEST(primitives)
{
using namespace libtorrent;