Files
libtorrent/test/test_settings_pack.cpp
2026-06-08 22:17:44 +02:00

327 lines
10 KiB
C++

/*
Copyright (c) 2010, 2014-2020, 2022, Arvid Norberg
Copyright (c) 2016-2017, Alden Torres
All rights reserved.
You may use, distribute and modify this code under the terms of the BSD license,
see LICENSE file.
*/
#include "test.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/aux_/session_settings.hpp"
#include "libtorrent/entry.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/bdecode.hpp"
#include <iostream>
using namespace lt;
using namespace lt::aux;
TORRENT_TEST(default_settings)
{
aux::session_settings sett;
entry e;
save_settings_to_dict(non_default_settings(sett), e.dict());
// all default values are supposed to be skipped
// by save_settings
TEST_EQUAL(e.dict().size(), 0);
#if TORRENT_USE_IOSTREAM
if (e.dict().size() > 0)
std::cout << e << std::endl;
#endif
}
TORRENT_TEST(default_settings2)
{
aux::session_settings sett;
settings_pack def = default_settings();
for (int i = 0; i < settings_pack::num_string_settings; ++i)
{
TEST_EQUAL(sett.get_str(settings_pack::string_type_base + i)
, def.get_str(settings_pack::string_type_base + i));
}
for (int i = 0; i < settings_pack::num_int_settings; ++i)
{
TEST_EQUAL(sett.get_int(settings_pack::int_type_base + i)
, def.get_int(settings_pack::int_type_base + i));
}
for (int i = 0; i < settings_pack::num_bool_settings; ++i)
{
TEST_EQUAL(sett.get_bool(settings_pack::bool_type_base + i)
, def.get_bool(settings_pack::bool_type_base + i));
}
}
TORRENT_TEST(apply_pack)
{
aux::session_settings sett;
settings_pack sp;
sp.set_int(settings_pack::max_out_request_queue, 1337);
TEST_CHECK(sett.get_int(settings_pack::max_out_request_queue) != 1337);
apply_pack(&sp, sett);
TEST_EQUAL(sett.get_int(settings_pack::max_out_request_queue), 1337);
entry e;
save_settings_to_dict(non_default_settings(sett), e.dict());
TEST_EQUAL(e.dict().size(), 1);
std::string out;
bencode(std::back_inserter(out), e);
TEST_EQUAL(out, "d21:max_out_request_queuei1337ee");
}
TORRENT_TEST(sparse_pack)
{
settings_pack pack;
TEST_EQUAL(pack.has_val(settings_pack::send_redundant_have), false);
pack.set_bool(settings_pack::send_redundant_have, true);
TEST_EQUAL(pack.has_val(settings_pack::send_redundant_have), true);
TEST_EQUAL(pack.has_val(settings_pack::user_agent), false);
TEST_EQUAL(pack.get_bool(settings_pack::send_redundant_have), true);
}
TORRENT_TEST(test_name)
{
#define TEST_NAME(n) \
TEST_EQUAL(setting_by_name(#n), settings_pack:: n); \
TEST_EQUAL(name_for_setting(settings_pack:: n), std::string(#n))
#if TORRENT_ABI_VERSION == 1
TEST_NAME(contiguous_recv_buffer);
#endif
TEST_NAME(choking_algorithm);
TEST_NAME(seeding_piece_quota);
#if TORRENT_ABI_VERSION == 1
TEST_NAME(half_open_limit);
TEST_NAME(mmap_cache);
#endif
TEST_NAME(peer_turnover_interval);
TEST_NAME(peer_fingerprint);
TEST_NAME(proxy_tracker_connections);
TEST_NAME(predictive_piece_announce);
TEST_NAME(max_metadata_size);
TEST_NAME(num_optimistic_unchoke_slots);
TEST_EQUAL(name_for_setting(settings_pack::peer_tos), std::string("peer_dscp"));
TEST_EQUAL(setting_by_name("peer_tos"), settings_pack::peer_dscp); \
}
TORRENT_TEST(clear)
{
settings_pack pack;
TEST_EQUAL(pack.has_val(settings_pack::send_redundant_have), false);
pack.set_bool(settings_pack::send_redundant_have, true);
TEST_EQUAL(pack.has_val(settings_pack::send_redundant_have), true);
TEST_EQUAL(pack.has_val(settings_pack::user_agent), false);
TEST_EQUAL(pack.get_bool(settings_pack::send_redundant_have), true);
pack.clear();
TEST_EQUAL(pack.has_val(settings_pack::send_redundant_have), false);
TEST_EQUAL(pack.has_val(settings_pack::user_agent), false);
}
TORRENT_TEST(clear_single_int)
{
settings_pack sp;
sp.set_int(settings_pack::max_out_request_queue, 1337);
TEST_EQUAL(sp.get_int(settings_pack::max_out_request_queue), 1337);
sp.clear(settings_pack::max_out_request_queue);
// when cleared, we'll get the default value
TEST_EQUAL(sp.get_int(settings_pack::max_out_request_queue), 500);
}
TORRENT_TEST(clear_single_bool)
{
settings_pack sp;
sp.set_bool(settings_pack::send_redundant_have, false);
TEST_EQUAL(sp.get_bool(settings_pack::send_redundant_have), false);
sp.clear(settings_pack::send_redundant_have);
// when cleared, we'll get the default value
TEST_EQUAL(sp.get_bool(settings_pack::send_redundant_have), true);
}
TORRENT_TEST(clear_single_string)
{
settings_pack sp;
sp.set_str(settings_pack::user_agent, "foobar");
TEST_EQUAL(sp.get_str(settings_pack::user_agent), "foobar");
sp.clear(settings_pack::user_agent);
// when cleared, we'll get the default value
TEST_EQUAL(sp.get_str(settings_pack::user_agent), "libtorrent/2.1.0.0");
}
TORRENT_TEST(duplicates)
{
settings_pack p;
p.set_str(settings_pack::peer_fingerprint, "abc");
p.set_str(settings_pack::peer_fingerprint, "cde");
p.set_str(settings_pack::peer_fingerprint, "efg");
p.set_str(settings_pack::peer_fingerprint, "hij");
TEST_EQUAL(p.get_str(settings_pack::peer_fingerprint), "hij");
}
TORRENT_TEST(load_pack_from_dict)
{
aux::session_settings p1;
p1.set_str(settings_pack::peer_fingerprint, "abc");
p1.set_int(settings_pack::max_out_request_queue, 1337);
p1.set_bool(settings_pack::send_redundant_have, false);
entry e;
save_settings_to_dict(non_default_settings(p1), e.dict());
std::string s;
bencode(std::back_inserter(s), e);
bdecode_node n;
error_code ec;
int ret = bdecode(s.data(), s.data() + int(s.size()), n, ec);
TEST_EQUAL(ret, 0);
TEST_CHECK(!ec);
settings_pack p2 = load_pack_from_dict(n);
TEST_EQUAL(p2.get_str(settings_pack::peer_fingerprint), "abc");
TEST_EQUAL(p2.get_int(settings_pack::max_out_request_queue), 1337);
TEST_EQUAL(p2.get_bool(settings_pack::send_redundant_have), false);
}
TORRENT_TEST(settings_pack_abi)
{
// make sure enum values are preserved across libtorrent versions
// for ABI compatibility
// These values are only allowed to change across major versions
TEST_EQUAL(settings_pack::string_type_base, 0x0000);
TEST_EQUAL(settings_pack::int_type_base, 0x4000);
TEST_EQUAL(settings_pack::bool_type_base, 0x8000);
TEST_EQUAL(settings_pack::type_mask, 0xc000);
// strings
TEST_EQUAL(settings_pack::outgoing_interfaces, settings_pack::string_type_base + 4);
TEST_EQUAL(settings_pack::dht_bootstrap_nodes, settings_pack::string_type_base + 11);
// bool
TEST_EQUAL(settings_pack::use_dht_as_fallback, settings_pack::bool_type_base + 4);
TEST_EQUAL(settings_pack::auto_manage_prefer_seeds, settings_pack::bool_type_base + 12);
TEST_EQUAL(settings_pack::proxy_tracker_connections, settings_pack::bool_type_base + 67);
// ints
TEST_EQUAL(settings_pack::tracker_completion_timeout, settings_pack::int_type_base + 0);
TEST_EQUAL(settings_pack::tracker_receive_timeout, settings_pack::int_type_base + 1);
TEST_EQUAL(settings_pack::stop_tracker_timeout, settings_pack::int_type_base + 2);
TEST_EQUAL(settings_pack::max_suggest_pieces, settings_pack::int_type_base + 66);
TEST_EQUAL(settings_pack::connections_slack, settings_pack::int_type_base + 86);
TEST_EQUAL(settings_pack::aio_threads, settings_pack::int_type_base + 104);
TEST_EQUAL(settings_pack::max_http_recv_buffer_size, settings_pack::int_type_base + 115);
TEST_EQUAL(settings_pack::web_seed_name_lookup_retry, settings_pack::int_type_base + 128);
TEST_EQUAL(settings_pack::close_file_interval, settings_pack::int_type_base + 129);
TEST_EQUAL(settings_pack::max_web_seed_connections, settings_pack::int_type_base + 131);
TEST_EQUAL(settings_pack::resolver_cache_timeout, settings_pack::int_type_base + 132);
}
namespace {
bool empty_pack(settings_pack const& sp)
{
for (std::uint16_t i = 0; i < settings_pack::num_string_settings; ++i)
if (sp.has_val(i | settings_pack::string_type_base)) return false;
for (std::uint16_t i = 0; i < settings_pack::num_int_settings; ++i)
if (sp.has_val(i | settings_pack::int_type_base)) return false;
for (std::uint16_t i = 0; i < settings_pack::num_bool_settings; ++i)
if (sp.has_val(i | settings_pack::bool_type_base)) return false;
return true;
}
}
TORRENT_TEST(non_default_settings)
{
aux::session_settings def;
settings_pack const p = non_default_settings(def);
TEST_CHECK(empty_pack(p));
}
TORRENT_TEST(non_default_settings2)
{
aux::session_settings def;
def.set_int(settings_pack::max_out_request_queue, 1337);
settings_pack const p = non_default_settings(def);
TEST_EQUAL(p.get_int(settings_pack::max_out_request_queue), 1337);
}
TORRENT_TEST(save_settings_to_dict)
{
settings_pack p;
p.set_str(settings_pack::peer_fingerprint, "abc");
p.set_int(settings_pack::max_out_request_queue, 1337);
p.set_bool(settings_pack::send_redundant_have, false);
entry e;
save_settings_to_dict(p, e.dict());
std::string buf;
bencode(std::back_inserter(buf), e);
TEST_EQUAL(buf, "d21:max_out_request_queuei1337e16:peer_fingerprint3:abc19:send_redundant_havei0ee");
}
// MSVC doesn't support making these arrays constexpr yet (which is required to
// initialize them before global constructors)
#if !defined _MSC_VER
namespace {
// make sure a global constructor has access to the default values, to
// initialize itself with
lt::aux::session_settings g_sett;
}
TORRENT_TEST(global_constructors)
{
TEST_CHECK(g_sett.get_int(lt::settings_pack::aio_threads) > 0);
}
#endif
TORRENT_TEST(i2p_tunnel_variance_settings)
{
#if TORRENT_USE_I2P
lt::settings_pack pack;
// Default values should be 0
TEST_EQUAL(pack.get_int(lt::settings_pack::i2p_inbound_length_variance), 0);
TEST_EQUAL(pack.get_int(lt::settings_pack::i2p_outbound_length_variance), 0);
pack.set_int(lt::settings_pack::i2p_inbound_length_variance, 2);
pack.set_int(lt::settings_pack::i2p_outbound_length_variance, -3);
TEST_EQUAL(pack.get_int(lt::settings_pack::i2p_inbound_length_variance), 2);
TEST_EQUAL(pack.get_int(lt::settings_pack::i2p_outbound_length_variance), -3);
// After clearing, it should go back to defaults
pack.clear(lt::settings_pack::i2p_inbound_length_variance);
pack.clear(lt::settings_pack::i2p_outbound_length_variance);
TEST_EQUAL(pack.get_int(lt::settings_pack::i2p_inbound_length_variance), 0);
TEST_EQUAL(pack.get_int(lt::settings_pack::i2p_outbound_length_variance), 0);
#endif
}