void test_single_peer(int limit, bool torrent_limit) { std::cerr << "\ntest single peer " << limit << " " << torrent_limit << std::endl; bandwidth_manager manager(0); bandwidth_channel t1; global_bwc.throttle(0); if (torrent_limit) t1.throttle(limit); else global_bwc.throttle(limit); connections_t v; spawn_connections(v, manager, t1, 1, "p"); run_test(v, manager); float sum = 0.f; for (connections_t::iterator i = v.begin() , end(v.end()); i != end; ++i) { sum += (*i)->m_quota; } sum /= sample_time; std::cerr << sum << " target: " << limit << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit), 1000)); }
void do_change_rate(bandwidth_channel& t1, bandwidth_channel& t2, int limit) { static int counter = 10; --counter; if (counter == 0) { t1.throttle(limit); t2.throttle(limit); return; } t1.throttle(limit + limit / 2 * ((counter & 1)?-1:1)); t2.throttle(limit + limit / 2 * ((counter & 1)?1:-1)); }
void test_no_starvation(int limit) { std::cerr << "\ntest no starvation " << limit << std::endl; bandwidth_manager manager(0); bandwidth_channel t1; bandwidth_channel t2; global_bwc.throttle(limit); const int num_peers = 20; connections_t v1; spawn_connections(v1, manager, t1, num_peers, "p"); connections_t v; std::copy(v1.begin(), v1.end(), std::back_inserter(v)); boost::shared_ptr<peer_connection> p( new peer_connection(manager, t2, 1, false, "no-priority")); v.push_back(p); run_test(v, manager); float sum = 0.f; for (connections_t::iterator i = v.begin() , end(v.end()); i != end; ++i) { sum += (*i)->m_quota; } sum /= sample_time; std::cerr << sum << " target: " << limit << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit), 50)); std::cerr << "non-prioritized rate: " << p->m_quota / sample_time << " target: " << (limit / 200 / num_peers) << std::endl; TEST_CHECK(close_to(p->m_quota / sample_time, float(limit) / 200 / num_peers, 5)); }
void test_equal_connections(int num, int limit) { std::cerr << "\ntest equal connections " << num << " " << limit << std::endl; bandwidth_manager manager(0); global_bwc.throttle(limit); bandwidth_channel t1; connections_t v; spawn_connections(v, manager, t1, num, "p"); run_test(v, manager); float sum = 0.f; float err = (std::max)(limit / num * 0.3f, 1000.f); for (connections_t::iterator i = v.begin() , end(v.end()); i != end; ++i) { sum += (*i)->m_quota; std::cerr << (*i)->m_quota / sample_time << " target: " << (limit / num) << " eps: " << err << std::endl; TEST_CHECK(close_to((*i)->m_quota / sample_time, float(limit) / num, err)); } sum /= sample_time; std::cerr << "sum: " << sum << " target: " << limit << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit), 50)); }
void test_torrents(int num, int limit1, int limit2, int global_limit) { std::cerr << "\ntest equal torrents " << num << " l1: " << limit1 << " l2: " << limit2 << " g: " << global_limit << std::endl; bandwidth_manager manager(0); global_bwc.throttle(global_limit); bandwidth_channel t1; bandwidth_channel t2; t1.throttle(limit1); t2.throttle(limit2); connections_t v1; spawn_connections(v1, manager, t1, num, "t1p"); connections_t v2; spawn_connections(v2, manager, t2, num, "t2p"); connections_t v; std::copy(v1.begin(), v1.end(), std::back_inserter(v)); std::copy(v2.begin(), v2.end(), std::back_inserter(v)); run_test(v, manager); if (global_limit > 0 && global_limit < limit1 + limit2) { limit1 = (std::min)(limit1, global_limit / 2); limit2 = global_limit - limit1; } float sum = 0.f; for (connections_t::iterator i = v1.begin() , end(v1.end()); i != end; ++i) { sum += (*i)->m_quota; } sum /= sample_time; std::cerr << sum << " target: " << limit1 << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit1), 1000)); sum = 0.f; for (connections_t::iterator i = v2.begin() , end(v2.end()); i != end; ++i) { sum += (*i)->m_quota; } sum /= sample_time; std::cerr << sum << " target: " << limit2 << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit2), 1000)); }
void test_torrents_variable_rate(int num, int limit, int global_limit) { std::cerr << "\ntest torrents variable rate" << num << " l: " << limit << " g: " << global_limit << std::endl; bandwidth_manager manager(0); global_bwc.throttle(global_limit); bandwidth_channel t1; bandwidth_channel t2; t1.throttle(limit); t2.throttle(limit); connections_t v1; spawn_connections(v1, manager, t1, num, "t1p"); connections_t v2; spawn_connections(v2, manager, t2, num, "t2p"); connections_t v; std::copy(v1.begin(), v1.end(), std::back_inserter(v)); std::copy(v2.begin(), v2.end(), std::back_inserter(v)); run_test(v, manager, boost::bind(&do_change_rate, boost::ref(t1), boost::ref(t2), limit)); if (global_limit > 0 && global_limit < 2 * limit) limit = global_limit / 2; float sum = 0.f; for (connections_t::iterator i = v1.begin() , end(v1.end()); i != end; ++i) { sum += (*i)->m_quota; } sum /= sample_time; std::cerr << sum << " target: " << limit << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit), 1000)); sum = 0.f; for (connections_t::iterator i = v2.begin() , end(v2.end()); i != end; ++i) { sum += (*i)->m_quota; } sum /= sample_time; std::cerr << sum << " target: " << limit << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit), 1000)); }
void test_peer_priority(int limit, bool torrent_limit) { std::cout << "\ntest peer priority " << limit << " " << torrent_limit << std::endl; bandwidth_manager manager(0); bandwidth_channel t1; global_bwc.throttle(0); if (torrent_limit) t1.throttle(limit); else global_bwc.throttle(limit); connections_t v1; spawn_connections(v1, manager, t1, 10, "p"); connections_t v; std::copy(v1.begin(), v1.end(), std::back_inserter(v)); std::shared_ptr<peer_connection> p = std::make_shared<peer_connection>(manager, t1, 1, false, "no-priority"); v.push_back(p); run_test(v, manager); float sum = 0.f; for (connections_t::iterator i = v1.begin() , end(v1.end()); i != end; ++i) { sum += (*i)->m_quota; } sum /= sample_time; std::cout << sum << " target: " << limit << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit), 50)); std::cout << "non-prioritized rate: " << p->m_quota / sample_time << " target: " << (limit / 200 / 10) << std::endl; TEST_CHECK(close_to(p->m_quota / sample_time, float(limit) / 200 / 10, 5)); }
void test_connections_variable_rate(int num, int limit, int torrent_limit) { std::cerr << "\ntest connections variable rate" << num << " l: " << limit << " t: " << torrent_limit << std::endl; bandwidth_manager manager(0); global_bwc.throttle(0); bandwidth_channel t1; if (torrent_limit) t1.throttle(torrent_limit); connections_t v; spawn_connections(v, manager, t1, num, "p"); std::for_each(v.begin(), v.end() , boost::bind(&peer_connection::throttle, _1, limit)); run_test(v, manager, boost::bind(&do_change_peer_rate , boost::ref(v), limit)); if (torrent_limit > 0 && limit * num > torrent_limit) limit = torrent_limit / num; float sum = 0.f; float err = limit * 0.3f; for (connections_t::iterator i = v.begin() , end(v.end()); i != end; ++i) { sum += (*i)->m_quota; std::cerr << (*i)->m_quota / sample_time << " target: " << limit << " eps: " << err << std::endl; TEST_CHECK(close_to((*i)->m_quota / sample_time, float(limit), err)); } sum /= sample_time; std::cerr << "sum: " << sum << " target: " << (limit * num) << std::endl; TEST_CHECK(sum > 0); TEST_CHECK(close_to(sum, float(limit) * num, limit * 0.3f * num)); }