merged RC_1_1 into master
This commit is contained in:
commit
78a344bd8b
|
@ -88,6 +88,9 @@
|
|||
* resume data no longer has timestamps of files
|
||||
* require C++11 to build libtorrent
|
||||
|
||||
* add option to ignore min-interval from trackers on force-reannounce
|
||||
* raise default setting for active_limit
|
||||
* fall back to copy+remove if rename_file fails
|
||||
* improve handling of filesystems not supporting fallocate()
|
||||
* force-proxy no longer disables DHT
|
||||
* improve connect-boost feature, to make new torrents quickly connect peers
|
||||
|
|
|
@ -411,6 +411,7 @@ void bind_converters()
|
|||
to_python_converter<lt::file_flags_t, from_bitfield_flag<lt::file_flags_t>>();
|
||||
to_python_converter<lt::create_flags_t, from_bitfield_flag<lt::create_flags_t>>();
|
||||
to_python_converter<lt::pex_flags_t, from_bitfield_flag<lt::pex_flags_t>>();
|
||||
to_python_converter<lt::reannounce_flags_t, from_bitfield_flag<lt::reannounce_flags_t>>();
|
||||
to_python_converter<lt::string_view, from_string_view>();
|
||||
|
||||
// work-around types
|
||||
|
@ -494,4 +495,5 @@ void bind_converters()
|
|||
to_bitfield_flag<lt::file_flags_t>();
|
||||
to_bitfield_flag<lt::create_flags_t>();
|
||||
to_bitfield_flag<lt::pex_flags_t>();
|
||||
to_bitfield_flag<lt::reannounce_flags_t>();
|
||||
}
|
||||
|
|
|
@ -431,12 +431,13 @@ class dummy4 {};
|
|||
class dummy6 {};
|
||||
class dummy7 {};
|
||||
class dummy8 {};
|
||||
class dummy15 {};
|
||||
|
||||
using by_value = return_value_policy<return_by_value>;
|
||||
void bind_torrent_handle()
|
||||
{
|
||||
// arguments are: number of seconds and tracker index
|
||||
void (torrent_handle::*force_reannounce0)(int, int) const = &torrent_handle::force_reannounce;
|
||||
void (torrent_handle::*force_reannounce0)(int, int, reannounce_flags_t) const = &torrent_handle::force_reannounce;
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
bool (torrent_handle::*super_seeding0)() const = &torrent_handle::super_seeding;
|
||||
|
@ -474,7 +475,8 @@ void bind_torrent_handle()
|
|||
;
|
||||
#endif
|
||||
|
||||
class_<torrent_handle>("torrent_handle")
|
||||
{
|
||||
scope s = class_<torrent_handle>("torrent_handle")
|
||||
.def(self == self)
|
||||
.def(self != self)
|
||||
.def(self < self)
|
||||
|
@ -524,7 +526,7 @@ void bind_torrent_handle()
|
|||
.def("save_resume_data", _(&torrent_handle::save_resume_data), arg("flags") = 0)
|
||||
.def("need_save_resume_data", _(&torrent_handle::need_save_resume_data))
|
||||
.def("force_reannounce", _(force_reannounce0)
|
||||
, (arg("seconds") = 0, arg("tracker_idx") = -1))
|
||||
, (arg("seconds") = 0, arg("tracker_idx") = -1, arg("flags") = reannounce_flags_t{}))
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
.def("force_dht_announce", _(&torrent_handle::force_dht_announce))
|
||||
#endif
|
||||
|
@ -580,6 +582,21 @@ void bind_torrent_handle()
|
|||
#endif
|
||||
;
|
||||
|
||||
s.attr("ignore_min_interval") = torrent_handle::ignore_min_interval;
|
||||
s.attr("overwrite_existing") = torrent_handle::overwrite_existing;
|
||||
s.attr("piece_granularity") = int(torrent_handle::piece_granularity);
|
||||
s.attr("graceful_pause") = torrent_handle::graceful_pause;
|
||||
s.attr("flush_disk_cache") = torrent_handle::flush_disk_cache;
|
||||
s.attr("save_info_dict") = torrent_handle::save_info_dict;
|
||||
s.attr("only_if_modified") = torrent_handle::only_if_modified;
|
||||
s.attr("alert_when_available") = torrent_handle::alert_when_available;
|
||||
s.attr("query_distributed_copies") = torrent_handle::query_distributed_copies;
|
||||
s.attr("query_accurate_download_counters") = torrent_handle::query_accurate_download_counters;
|
||||
s.attr("query_last_seen_complete") = torrent_handle::query_last_seen_complete;
|
||||
s.attr("query_pieces") = torrent_handle::query_pieces;
|
||||
s.attr("query_verified_pieces") = torrent_handle::query_verified_pieces;
|
||||
}
|
||||
|
||||
class_<open_file_state>("open_file_state")
|
||||
.add_property("file_index", make_getter((&open_file_state::file_index), by_value()))
|
||||
.def_readonly("last_use", &open_file_state::last_use)
|
||||
|
@ -621,6 +638,11 @@ void bind_torrent_handle()
|
|||
s.attr("only_if_modified") = torrent_handle::only_if_modified;
|
||||
}
|
||||
|
||||
{
|
||||
scope s = class_<dummy15>("reannounce_flags_t");
|
||||
s.attr("ignore_min_interval") = torrent_handle::ignore_min_interval;
|
||||
}
|
||||
|
||||
{
|
||||
scope s = class_<dummy8>("deadline_flags_t");
|
||||
s.attr("alert_when_available") = torrent_handle::alert_when_available;
|
||||
|
|
|
@ -301,7 +301,7 @@ namespace aux {
|
|||
|
||||
// returns a pretty-printed string representation
|
||||
// of the bencoded structure, with JSON-style syntax
|
||||
std::string to_string() const;
|
||||
std::string to_string(bool single_line = false) const;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -311,7 +311,7 @@ namespace aux {
|
|||
|
||||
private:
|
||||
|
||||
void to_string_impl(std::string& out, int indent) const;
|
||||
void to_string_impl(std::string& out, int indent, bool single_line) const;
|
||||
|
||||
aux::aligned_union<1
|
||||
#if TORRENT_COMPLETE_TYPES_REQUIRED
|
||||
|
|
|
@ -747,7 +747,7 @@ namespace libtorrent {
|
|||
void do_connect_boost();
|
||||
|
||||
// forcefully sets next_announce to the current time
|
||||
void force_tracker_request(time_point, int tracker_idx);
|
||||
void force_tracker_request(time_point, int tracker_idx, reannounce_flags_t flags);
|
||||
void scrape_tracker(int idx, bool user_triggered);
|
||||
void announce_with_tracker(std::uint8_t e
|
||||
= tracker_request::none);
|
||||
|
|
|
@ -80,6 +80,7 @@ namespace aux {
|
|||
using pause_flags_t = flags::bitfield_flag<std::uint8_t, struct pause_flags_tag>;
|
||||
using deadline_flags_t = flags::bitfield_flag<std::uint8_t, struct deadline_flags_tag>;
|
||||
using resume_data_flags_t = flags::bitfield_flag<std::uint8_t, struct resume_data_flags_tag>;
|
||||
using reannounce_flags_t = flags::bitfield_flag<std::uint8_t, struct reannounce_flags_tag>;
|
||||
using queue_position_t = aux::strong_typedef<int, struct queue_position_tag>;
|
||||
|
||||
// holds the state of a block in a piece. Who we requested
|
||||
|
@ -1020,6 +1021,11 @@ namespace aux {
|
|||
std::vector<int> file_priorities() const;
|
||||
#endif
|
||||
|
||||
// by default, force-reannounce will still honor the min-interval
|
||||
// published by the tracker. If this flag is set, it will be ignored
|
||||
// and the tracker is announced immediately.
|
||||
static constexpr reannounce_flags_t ignore_min_interval = 0_bit;
|
||||
|
||||
// ``force_reannounce()`` will force this torrent to do another tracker
|
||||
// request, to receive new peers. The ``seconds`` argument specifies how
|
||||
// many seconds from now to issue the tracker announces.
|
||||
|
@ -1032,9 +1038,12 @@ namespace aux {
|
|||
// The ``tracker_index`` argument specifies which tracker to re-announce.
|
||||
// If set to -1 (which is the default), all trackers are re-announce.
|
||||
//
|
||||
// The ``flags`` argument can be used to affect the re-announce. See
|
||||
// ignore_min_interval.
|
||||
//
|
||||
// ``force_dht_announce`` will announce the torrent to the DHT
|
||||
// immediately.
|
||||
void force_reannounce(int seconds = 0, int tracker_index = -1) const;
|
||||
void force_reannounce(int seconds = 0, int tracker_index = -1, reannounce_flags_t = {}) const;
|
||||
void force_dht_announce() const;
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
|
|
|
@ -169,7 +169,7 @@ namespace libtorrent {
|
|||
{
|
||||
tracker_response()
|
||||
: interval(1800)
|
||||
, min_interval(120)
|
||||
, min_interval(1)
|
||||
, complete(-1)
|
||||
, incomplete(-1)
|
||||
, downloaders(-1)
|
||||
|
|
|
@ -1679,7 +1679,7 @@ namespace {
|
|||
if (should_log(peer_log_alert::incoming_message))
|
||||
{
|
||||
peer_log(peer_log_alert::incoming_message, "EXTENDED_HANDSHAKE"
|
||||
, "%s", print_entry(root).c_str());
|
||||
, "%s", print_entry(root, true).c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2166,7 +2166,7 @@ namespace {
|
|||
if (should_log(peer_log_alert::outgoing_message))
|
||||
{
|
||||
peer_log(peer_log_alert::outgoing_message, "EXTENDED_HANDSHAKE"
|
||||
, "%s", handshake.to_string().c_str());
|
||||
, "%s", handshake.to_string(true).c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1138,6 +1138,15 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
|
|||
|
||||
std::shared_ptr<storage_interface> storage = j->storage;
|
||||
|
||||
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||
if (j->storage)
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_cache_mutex);
|
||||
auto const& pieces = j->storage->cached_pieces();
|
||||
for (auto const& p : pieces)
|
||||
TORRENT_ASSERT(p.storage == j->storage);
|
||||
}
|
||||
#endif
|
||||
// TODO: 4 instead of doing this. pass in the settings to each storage_interface
|
||||
// call. Each disk thread could hold its most recent understanding of the settings
|
||||
// in a shared_ptr, and update it every time it wakes up from a job. That way
|
||||
|
@ -1835,6 +1844,14 @@ constexpr disk_job_flags_t disk_interface::cache_hit;
|
|||
j->storage = m_torrents[storage]->shared_from_this();
|
||||
j->callback = std::move(handler);
|
||||
|
||||
#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_cache_mutex);
|
||||
auto const& pieces = j->storage->cached_pieces();
|
||||
for (auto const& p : pieces)
|
||||
TORRENT_ASSERT(p.storage == j->storage);
|
||||
}
|
||||
#endif
|
||||
add_fence_job(j);
|
||||
}
|
||||
|
||||
|
|
|
@ -662,86 +662,81 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
std::string entry::to_string() const
|
||||
std::string entry::to_string(bool const single_line) const
|
||||
{
|
||||
std::string ret;
|
||||
if (type() == dictionary_t) ret.reserve(280);
|
||||
to_string_impl(ret, 0);
|
||||
to_string_impl(ret, 0, single_line);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void entry::to_string_impl(std::string& out, int const indent) const
|
||||
namespace {
|
||||
bool is_binary(std::string const& str)
|
||||
{
|
||||
for (char const c : str)
|
||||
{
|
||||
if (!is_print(c)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void add_indent(std::string& out, int const indent)
|
||||
{
|
||||
out.resize(out.size() + size_t(indent), ' ');
|
||||
}
|
||||
}
|
||||
|
||||
void entry::to_string_impl(std::string& out, int const indent
|
||||
, bool const single_line) const
|
||||
{
|
||||
TORRENT_ASSERT(indent >= 0);
|
||||
for (int i = 0; i < indent; ++i) out += ' ';
|
||||
switch (type())
|
||||
switch (m_type)
|
||||
{
|
||||
case int_t:
|
||||
out += libtorrent::to_string(integer()).data();
|
||||
out += '\n';
|
||||
break;
|
||||
case string_t:
|
||||
{
|
||||
bool binary_string = false;
|
||||
for (auto const i : string())
|
||||
{
|
||||
if (!is_print(i))
|
||||
{
|
||||
binary_string = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (binary_string)
|
||||
{
|
||||
out += aux::to_hex(string());
|
||||
out += '\n';
|
||||
}
|
||||
else
|
||||
{
|
||||
out += string();
|
||||
out += '\n';
|
||||
}
|
||||
out += "'";
|
||||
if (is_binary(string())) out += aux::to_hex(string());
|
||||
else out += string();
|
||||
out += "'";
|
||||
} break;
|
||||
case list_t:
|
||||
{
|
||||
out += "list\n";
|
||||
for (auto const& i : list())
|
||||
out += single_line ? "[ " : "[\n";
|
||||
bool first = true;
|
||||
for (list_type::const_iterator i = list().begin(); i != list().end(); ++i)
|
||||
{
|
||||
i.to_string_impl(out, indent + 1);
|
||||
if (!first) out += single_line ? ", " : ",\n";
|
||||
first = false;
|
||||
if (!single_line) add_indent(out, indent+1);
|
||||
i->to_string_impl(out, indent+1, single_line);
|
||||
}
|
||||
out += " ]";
|
||||
} break;
|
||||
case dictionary_t:
|
||||
{
|
||||
out += "dictionary\n";
|
||||
for (auto const& i : dict())
|
||||
out += single_line ? "{ " : "{\n";
|
||||
bool first = true;
|
||||
for (dictionary_type::const_iterator i = dict().begin(); i != dict().end(); ++i)
|
||||
{
|
||||
bool binary_string = false;
|
||||
for (auto const k : i.first)
|
||||
{
|
||||
if (!is_print(k))
|
||||
{
|
||||
binary_string = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < indent + 1; ++j) out += ' ';
|
||||
out += '[';
|
||||
if (binary_string) out += aux::to_hex(i.first);
|
||||
else out += i.first;
|
||||
out += ']';
|
||||
if (!first) out += single_line ? ", " : ",\n";
|
||||
first = false;
|
||||
if (!single_line) add_indent(out, indent+1);
|
||||
out += "'";
|
||||
if (is_binary(i->first)) out += aux::to_hex(i->first);
|
||||
else out += i->first;
|
||||
out += "': ";
|
||||
|
||||
if (i.second.type() != entry::string_t
|
||||
&& i.second.type() != entry::int_t)
|
||||
out += '\n';
|
||||
else out += ' ';
|
||||
i.second.to_string_impl(out, indent + 2);
|
||||
i->second.to_string_impl(out, indent+2, single_line);
|
||||
}
|
||||
out += " }";
|
||||
} break;
|
||||
case preformatted_t:
|
||||
out += "<preformatted>\n";
|
||||
out += "<preformatted>";
|
||||
break;
|
||||
case undefined_t:
|
||||
out += "<uninitialized>\n";
|
||||
out += "<uninitialized>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1748,14 +1748,13 @@ namespace libtorrent {
|
|||
t->unchoke_peer(*this);
|
||||
}
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
else
|
||||
else if (should_log(peer_log_alert::info))
|
||||
{
|
||||
if (should_log(peer_log_alert::info))
|
||||
{
|
||||
peer_log(peer_log_alert::info, "UNCHOKE", "did not unchoke, the number of uploads (%d) "
|
||||
"is more than or equal to the limit (%d)"
|
||||
, m_ses.num_uploads(), m_settings.get_int(settings_pack::unchoke_slots_limit));
|
||||
}
|
||||
peer_log(peer_log_alert::info, "UNCHOKE", "did not unchoke, the number of uploads (%d) "
|
||||
"is more than or equal to the available slots (%d), limit (%d)"
|
||||
, int(m_counters[counters::num_peers_up_unchoked])
|
||||
, int(m_counters[counters::num_unchoke_slots])
|
||||
, m_settings.get_int(settings_pack::unchoke_slots_limit));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -248,7 +248,7 @@ namespace {
|
|||
set.set_int(settings_pack::peer_timeout, 20);
|
||||
set.set_int(settings_pack::inactivity_timeout, 20);
|
||||
|
||||
set.set_int(settings_pack::active_limit, 2000);
|
||||
set.set_int(settings_pack::active_limit, 20000);
|
||||
set.set_int(settings_pack::active_tracker_limit, 2000);
|
||||
set.set_int(settings_pack::active_dht_limit, 600);
|
||||
set.set_int(settings_pack::active_seeds, 2000);
|
||||
|
|
|
@ -258,7 +258,7 @@ constexpr int CLOSE_FILE_INTERVAL = 0;
|
|||
SET(active_dht_limit, 88, nullptr),
|
||||
SET(active_tracker_limit, 1600, nullptr),
|
||||
SET(active_lsd_limit, 60, nullptr),
|
||||
SET(active_limit, 15, &session_impl::trigger_auto_manage),
|
||||
SET(active_limit, 500, &session_impl::trigger_auto_manage),
|
||||
DEPRECATED_SET(active_loaded_limit, 0, &session_impl::trigger_auto_manage),
|
||||
SET(auto_manage_interval, 30, nullptr),
|
||||
SET(seed_time_limit, 24 * 60 * 60, nullptr),
|
||||
|
|
|
@ -398,9 +398,18 @@ namespace libtorrent {
|
|||
|
||||
if (ec)
|
||||
{
|
||||
ec.file(index);
|
||||
ec.operation = operation_t::file_rename;
|
||||
return;
|
||||
ec.ec.clear();
|
||||
copy_file(old_name, new_path, ec.ec);
|
||||
|
||||
if (ec)
|
||||
{
|
||||
ec.file(index);
|
||||
ec.operation = operation_t::file_rename;
|
||||
return;
|
||||
}
|
||||
|
||||
error_code ignore;
|
||||
remove(old_name, ignore);
|
||||
}
|
||||
}
|
||||
else if (ec.ec)
|
||||
|
|
|
@ -3147,10 +3147,12 @@ bool is_downloading_state(int const st)
|
|||
}
|
||||
debug_log("TRACKER RESPONSE\n"
|
||||
"interval: %d\n"
|
||||
"min-interval: %d\n"
|
||||
"external ip: %s\n"
|
||||
"resolved to: %s\n"
|
||||
"we connected to: %s\n"
|
||||
, interval.count()
|
||||
, resp.min_interval.count()
|
||||
, print_address(resp.external_ip).c_str()
|
||||
, resolved_to.c_str()
|
||||
, print_address(tracker_ip).c_str());
|
||||
|
@ -3325,7 +3327,8 @@ bool is_downloading_state(int const st)
|
|||
// this is the entry point for the client to force a re-announce. It's
|
||||
// considered a client-initiated announce (as opposed to the regular ones,
|
||||
// issued by libtorrent)
|
||||
void torrent::force_tracker_request(time_point const t, int const tracker_idx)
|
||||
void torrent::force_tracker_request(time_point const t, int const tracker_idx
|
||||
, reannounce_flags_t const flags)
|
||||
{
|
||||
TORRENT_ASSERT_PRECOND((tracker_idx >= 0
|
||||
&& tracker_idx < int(m_trackers.size()))
|
||||
|
@ -3338,8 +3341,10 @@ bool is_downloading_state(int const st)
|
|||
{
|
||||
for (auto& aep : e.endpoints)
|
||||
{
|
||||
aep.next_announce = std::max(time_point_cast<seconds32>(t)
|
||||
, aep.min_announce) + seconds(1);
|
||||
aep.next_announce = (flags & torrent_handle::ignore_min_interval)
|
||||
? time_point_cast<seconds32>(t) + seconds32(1)
|
||||
: std::max(time_point_cast<seconds32>(t), aep.min_announce) + seconds32(1);
|
||||
aep.min_announce = aep.next_announce;
|
||||
aep.triggered_manually = true;
|
||||
}
|
||||
}
|
||||
|
@ -3351,8 +3356,10 @@ bool is_downloading_state(int const st)
|
|||
announce_entry& e = m_trackers[tracker_idx];
|
||||
for (auto& aep : e.endpoints)
|
||||
{
|
||||
aep.next_announce = std::max(time_point_cast<seconds32>(t)
|
||||
, aep.min_announce) + seconds32(1);
|
||||
aep.next_announce = (flags & torrent_handle::ignore_min_interval)
|
||||
? time_point_cast<seconds32>(t) + seconds32(1)
|
||||
: std::max(time_point_cast<seconds32>(t), aep.min_announce) + seconds32(1);
|
||||
aep.min_announce = aep.next_announce;
|
||||
aep.triggered_manually = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ namespace libtorrent {
|
|||
constexpr pause_flags_t torrent_handle::graceful_pause;
|
||||
constexpr pause_flags_t torrent_handle::clear_disk_cache;
|
||||
constexpr deadline_flags_t torrent_handle::alert_when_available;
|
||||
constexpr reannounce_flags_t torrent_handle::ignore_min_interval;
|
||||
|
||||
constexpr status_flags_t torrent_handle::query_distributed_copies;
|
||||
constexpr status_flags_t torrent_handle::query_accurate_download_counters;
|
||||
|
@ -732,7 +733,7 @@ namespace libtorrent {
|
|||
boost::posix_time::time_duration duration) const
|
||||
{
|
||||
async_call(&torrent::force_tracker_request, aux::time_now()
|
||||
+ seconds(duration.total_seconds()), -1);
|
||||
+ seconds(duration.total_seconds()), -1, reannounce_flags_t{});
|
||||
}
|
||||
|
||||
void torrent_handle::file_status(std::vector<open_file_state>& status) const
|
||||
|
@ -753,9 +754,9 @@ namespace libtorrent {
|
|||
#endif
|
||||
}
|
||||
|
||||
void torrent_handle::force_reannounce(int s, int idx) const
|
||||
void torrent_handle::force_reannounce(int s, int idx, reannounce_flags_t const flags) const
|
||||
{
|
||||
async_call(&torrent::force_tracker_request, aux::time_now() + seconds(s), idx);
|
||||
async_call(&torrent::force_tracker_request, aux::time_now() + seconds(s), idx, flags);
|
||||
}
|
||||
|
||||
std::vector<open_file_state> torrent_handle::file_status() const
|
||||
|
|
|
@ -263,8 +263,6 @@ namespace libtorrent {
|
|||
TORRENT_ASSERT(req.num_want >= 0);
|
||||
TORRENT_ASSERT(!m_abort || req.event == tracker_request::stopped);
|
||||
if (m_abort && req.event != tracker_request::stopped) return;
|
||||
if (req.event == tracker_request::stopped)
|
||||
req.num_want = 0;
|
||||
|
||||
#ifndef TORRENT_DISABLE_LOGGING
|
||||
std::shared_ptr<request_callback> cb = c.lock();
|
||||
|
|
|
@ -147,6 +147,87 @@ TORRENT_TEST(implicit_construct)
|
|||
}
|
||||
|
||||
#if TORRENT_ABI_VERSION == 1
|
||||
TORRENT_TEST(print_dict_single_line)
|
||||
{
|
||||
entry e;
|
||||
e["foo"] = "bar";
|
||||
e["bar"] = "foo";
|
||||
TEST_EQUAL(e.to_string(true), "{ 'bar': 'foo', 'foo': 'bar' }");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_dict)
|
||||
{
|
||||
entry e;
|
||||
e["foo"] = "bar";
|
||||
e["bar"] = "foo";
|
||||
TEST_EQUAL(e.to_string(), "{\n 'bar': 'foo',\n 'foo': 'bar' }");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_list_single_line)
|
||||
{
|
||||
entry e;
|
||||
e.list().push_back(entry("foo"));
|
||||
e.list().push_back(entry("bar"));
|
||||
TEST_EQUAL(e.to_string(true), "[ 'foo', 'bar' ]");
|
||||
}
|
||||
|
||||
|
||||
TORRENT_TEST(print_list)
|
||||
{
|
||||
entry e;
|
||||
e.list().push_back(entry("foo"));
|
||||
e.list().push_back(entry("bar"));
|
||||
TEST_EQUAL(e.to_string(), "[\n 'foo',\n 'bar' ]");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_int_single_line)
|
||||
{
|
||||
entry e(1337);
|
||||
TEST_EQUAL(e.to_string(true), "1337");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_int)
|
||||
{
|
||||
entry e(1337);
|
||||
TEST_EQUAL(e.to_string(), "1337");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_string_single_line)
|
||||
{
|
||||
entry e("foobar");
|
||||
TEST_EQUAL(e.to_string(true), "'foobar'");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_string)
|
||||
{
|
||||
entry e("foobar");
|
||||
TEST_EQUAL(e.to_string(), "'foobar'");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_deep_dict_single_line)
|
||||
{
|
||||
entry e;
|
||||
e["strings"].list().push_back(entry("foo"));
|
||||
e["strings"].list().push_back(entry("bar"));
|
||||
e["ints"].list().push_back(entry(1));
|
||||
e["ints"].list().push_back(entry(2));
|
||||
e["ints"].list().push_back(entry(3));
|
||||
e["a"] = "foobar";
|
||||
TEST_EQUAL(e.to_string(true), "{ 'a': 'foobar', 'ints': [ 1, 2, 3 ], 'strings': [ 'foo', 'bar' ] }");
|
||||
}
|
||||
|
||||
TORRENT_TEST(print_deep_dict)
|
||||
{
|
||||
entry e;
|
||||
e["strings"].list().push_back(entry("foo"));
|
||||
e["strings"].list().push_back(entry("bar"));
|
||||
e["ints"].list().push_back(entry(1));
|
||||
e["ints"].list().push_back(entry(2));
|
||||
e["ints"].list().push_back(entry(3));
|
||||
e["a"] = "foobar";
|
||||
TEST_EQUAL(e.to_string(), "{\n 'a': 'foobar',\n 'ints': [\n 1,\n 2,\n 3 ],\n 'strings': [\n 'foo',\n 'bar' ] }");
|
||||
}
|
||||
|
||||
TORRENT_TEST(lazy_entry)
|
||||
{
|
||||
{
|
||||
|
|
|
@ -132,7 +132,7 @@ void test_remove_torrent(remove_flags_t const remove_options
|
|||
|| st2.state == torrent_status::checking_resume_data);
|
||||
|
||||
// if nothing is being transferred after 3 seconds, we're failing the test
|
||||
if (st1.upload_payload_rate == 0 && i > 30)
|
||||
if (st1.total_payload_upload == 0 && i > 30)
|
||||
{
|
||||
TEST_ERROR("no transfer");
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue