diff --git a/src/command_throttle.cc b/src/command_throttle.cc index f9431c87..50e23fed 100644 --- a/src/command_throttle.cc +++ b/src/command_throttle.cc @@ -89,6 +89,24 @@ throttle_update(const char* variable, int64_t value) { return torrent::Object(); } +static unsigned int +throttle_rate_to_kb(int64_t rate) { + if (rate < 0 || rate > std::numeric_limits::max() - 1) + throw torrent::input_error("Throttle rate must be between 0 and 4294967294."); + + return static_cast(rate >> 10); +} + +static void +set_up_throttle_i64(ui::Root* root, int64_t rate) { + root->set_up_throttle(throttle_rate_to_kb(rate)); +} + +static void +set_down_throttle_i64(ui::Root* root, int64_t rate) { + root->set_down_throttle(throttle_rate_to_kb(rate)); +} + void initialize_command_throttle() { CMD2_ANY ("throttle.unchoked_uploads", std::bind(&torrent::ResourceManager::currently_upload_unchoked, torrent::resource_manager())); @@ -125,13 +143,13 @@ initialize_command_throttle() { CMD2_ANY ("throttle.global_up.rate", std::bind(&torrent::Rate::rate, torrent::up_rate())); CMD2_ANY ("throttle.global_up.total", std::bind(&torrent::Rate::total, torrent::up_rate())); CMD2_ANY ("throttle.global_up.max_rate", std::bind(&torrent::Throttle::max_rate, torrent::up_throttle_global())); - CMD2_ANY_VALUE_V ("throttle.global_up.max_rate.set", std::bind(&ui::Root::set_up_throttle_i64, control->ui(), std::placeholders::_2)); - CMD2_ANY_VALUE_KB("throttle.global_up.max_rate.set_kb", std::bind(&ui::Root::set_up_throttle_i64, control->ui(), std::placeholders::_2)); + CMD2_ANY_VALUE_V ("throttle.global_up.max_rate.set", std::bind(&set_up_throttle_i64, control->ui(), std::placeholders::_2)); + CMD2_ANY_VALUE_KB("throttle.global_up.max_rate.set_kb", std::bind(&set_up_throttle_i64, control->ui(), std::placeholders::_2)); CMD2_ANY ("throttle.global_down.rate", std::bind(&torrent::Rate::rate, torrent::down_rate())); CMD2_ANY ("throttle.global_down.total", std::bind(&torrent::Rate::total, torrent::down_rate())); CMD2_ANY ("throttle.global_down.max_rate", std::bind(&torrent::Throttle::max_rate, torrent::down_throttle_global())); - CMD2_ANY_VALUE_V ("throttle.global_down.max_rate.set", std::bind(&ui::Root::set_down_throttle_i64, control->ui(), std::placeholders::_2)); - CMD2_ANY_VALUE_KB("throttle.global_down.max_rate.set_kb", std::bind(&ui::Root::set_down_throttle_i64, control->ui(), std::placeholders::_2)); + CMD2_ANY_VALUE_V ("throttle.global_down.max_rate.set", std::bind(&set_down_throttle_i64, control->ui(), std::placeholders::_2)); + CMD2_ANY_VALUE_KB("throttle.global_down.max_rate.set_kb", std::bind(&set_down_throttle_i64, control->ui(), std::placeholders::_2)); // Temporary names, need to change this to accept real rates rather // than kB. diff --git a/src/ui/root.h b/src/ui/root.h index 95c4cbca..a716463b 100644 --- a/src/ui/root.h +++ b/src/ui/root.h @@ -70,10 +70,6 @@ public: void set_down_throttle(unsigned int throttle); void set_up_throttle(unsigned int throttle); - // Rename to raw or something, make base function. - void set_down_throttle_i64(int64_t throttle) { set_down_throttle(throttle >> 10); } - void set_up_throttle_i64(int64_t throttle) { set_up_throttle(throttle >> 10); } - void adjust_down_throttle(int throttle); void adjust_up_throttle(int throttle); diff --git a/test/Makefile.am b/test/Makefile.am index bec78661..0a6f3897 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -67,6 +67,8 @@ rtorrent_Test_Src_SOURCES = $(rtorrent_Test_Common) \ src/test_command_path.h \ src/test_command_string.cc \ src/test_command_string.h \ + src/test_command_throttle.cc \ + src/test_command_throttle.h \ src/test_setup.cc \ src/test_setup.h \ src/test_ui_download_list.cc \ diff --git a/test/src/test_command_throttle.cc b/test/src/test_command_throttle.cc new file mode 100644 index 00000000..c042ab9c --- /dev/null +++ b/test/src/test_command_throttle.cc @@ -0,0 +1,102 @@ +#include "config.h" + +#include "test/src/test_command_throttle.h" + +#include +#include + +#include "core/manager.h" +#include "control.h" +#include "globals.h" +#include "rpc/parse_commands.h" + +CPPUNIT_TEST_SUITE_REGISTRATION(TestCommandThrottle); + +void initialize_command_throttle(); + +static void +call_set(const char* key, const char* value) { + rpc::commands.call_command(key, torrent::Object(std::string(value))); +} + +static void +call_named(const char* key, const char* name, const char* value) { + torrent::Object::list_type args; + args.push_back(torrent::Object(std::string(name))); + args.push_back(torrent::Object(std::string(value))); + + rpc::commands.call_command(key, torrent::Object::create_list_range(args.begin(), args.end())); +} + +static uint64_t +down_rate() { + return torrent::down_throttle_global()->max_rate(); +} + +void +TestCommandThrottle::setUp() { + torrent::initialize_main_thread(); + torrent::initialize(); + + if (control == nullptr) + control = new Control; + + if (!rpc::commands.has("throttle.global_down.max_rate.set_kb")) + initialize_command_throttle(); +} + +void +TestCommandThrottle::tearDown() { + torrent::cleanup(); +} + +void +TestCommandThrottle::test_global_rate_in_range() { + call_set("throttle.global_down.max_rate.set_kb", "1024"); + CPPUNIT_ASSERT_EQUAL(uint64_t{1048576}, down_rate()); + + call_set("throttle.global_down.max_rate.set_kb", "4194303"); + CPPUNIT_ASSERT_EQUAL(uint64_t{4294966272}, down_rate()); + + call_set("throttle.global_down.max_rate.set", "4294966272"); + CPPUNIT_ASSERT_EQUAL(uint64_t{4294966272}, down_rate()); +} + +void +TestCommandThrottle::test_global_rate_kb_out_of_range() { + call_set("throttle.global_down.max_rate.set_kb", "1024"); + + CPPUNIT_ASSERT_THROW(call_set("throttle.global_down.max_rate.set_kb", "4194304"), torrent::input_error); + CPPUNIT_ASSERT_EQUAL(uint64_t{1048576}, down_rate()); +} + +void +TestCommandThrottle::test_global_rate_bytes_out_of_range() { + call_set("throttle.global_down.max_rate.set", "1048576"); + + CPPUNIT_ASSERT_THROW(call_set("throttle.global_down.max_rate.set", "4294967296"), torrent::input_error); + CPPUNIT_ASSERT_EQUAL(uint64_t{1048576}, down_rate()); +} + +void +TestCommandThrottle::test_global_rate_negative() { + call_set("throttle.global_down.max_rate.set", "1048576"); + + CPPUNIT_ASSERT_THROW(call_set("throttle.global_down.max_rate.set", "-1"), torrent::input_error); + CPPUNIT_ASSERT_EQUAL(uint64_t{1048576}, down_rate()); +} + +void +TestCommandThrottle::test_named_rate_in_range() { + call_named("throttle.down", "test_named_in_range", "1024"); + + auto itr = control->core()->throttles().find("test_named_in_range"); + + CPPUNIT_ASSERT(itr != control->core()->throttles().end()); + CPPUNIT_ASSERT_EQUAL(uint64_t{1048576}, itr->second.second->max_rate()); +} + +void +TestCommandThrottle::test_named_rate_out_of_range() { + CPPUNIT_ASSERT_THROW(call_named("throttle.down", "test_named_out_of_range", "18014398509481984"), torrent::input_error); +} diff --git a/test/src/test_command_throttle.h b/test/src/test_command_throttle.h new file mode 100644 index 00000000..5dd6f85f --- /dev/null +++ b/test/src/test_command_throttle.h @@ -0,0 +1,25 @@ +#include "test/helpers/test_fixture.h" + +class TestCommandThrottle : public test_fixture { + CPPUNIT_TEST_SUITE(TestCommandThrottle); + + CPPUNIT_TEST(test_global_rate_in_range); + CPPUNIT_TEST(test_global_rate_kb_out_of_range); + CPPUNIT_TEST(test_global_rate_bytes_out_of_range); + CPPUNIT_TEST(test_global_rate_negative); + CPPUNIT_TEST(test_named_rate_in_range); + CPPUNIT_TEST(test_named_rate_out_of_range); + + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp(); + void tearDown(); + + void test_global_rate_in_range(); + void test_global_rate_kb_out_of_range(); + void test_global_rate_bytes_out_of_range(); + void test_global_rate_negative(); + void test_named_rate_in_range(); + void test_named_rate_out_of_range(); +};