removed connecting_to_tracker state
[libtorrent.git] / test / test_bandwidth_limiter.cpp
blob7da7cd78f8af0e917411a10b09503ec7f2f23c19
1 /*
3 Copyright (c) 2008, Arvid Norberg
4 All rights reserved.
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
10 * Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the distribution.
15 * Neither the name of the author nor the names of its
16 contributors may be used to endorse or promote products derived
17 from this software without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 POSSIBILITY OF SUCH DAMAGE.
33 #include "test.hpp"
35 #include "libtorrent/bandwidth_manager.hpp"
36 #include "libtorrent/bandwidth_queue_entry.hpp"
37 #include "libtorrent/bandwidth_limit.hpp"
38 #include "libtorrent/socket.hpp"
39 #include "libtorrent/stat.hpp"
40 #include "libtorrent/time.hpp"
41 #include "libtorrent/intrusive_ptr_base.hpp"
43 #include <boost/lexical_cast.hpp>
45 struct torrent;
46 struct peer_connection;
48 using namespace libtorrent;
50 const float sample_time = 6.f; // seconds
52 //#define VERBOSE_LOGGING
55 struct peer_connection: intrusive_ptr_base<peer_connection>
57 typedef torrent torrent_type;
59 peer_connection(io_service& ios, boost::shared_ptr<torrent> const& t
60 , int prio, bool ignore_limits, std::string name);
62 bool ignore_bandwidth_limits() { return m_ignore_limits; }
63 int max_assignable_bandwidth(int channel) const
64 { return m_bandwidth_limit[channel].max_assignable(); }
65 boost::weak_ptr<torrent> associated_torrent() const
66 { return m_torrent; }
67 bool is_disconnecting() const { return m_abort; }
68 void assign_bandwidth(int channel, int amount);
69 void on_transfer(int channel, int amount);
70 void start();
71 void stop() { m_abort = true; }
72 void expire_bandwidth(int channel, int amount);
73 void tick();
75 int bandwidth_throttle(int channel) const
76 { return m_bandwidth_limit[channel].throttle(); }
78 void throttle(int limit) { m_bandwidth_limit[0].throttle(limit); }
80 bandwidth_limit m_bandwidth_limit[1];
81 boost::weak_ptr<torrent> m_torrent;
82 int m_priority;
83 bool m_ignore_limits;
84 bool m_abort;
85 libtorrent::stat m_stats;
86 io_service& m_ios;
87 std::string m_name;
88 bool m_writing;
91 struct torrent
93 torrent(bandwidth_manager<peer_connection, torrent>& m)
94 : m_bandwidth_manager(m)
97 void assign_bandwidth(int channel, int amount, int max_block_size)
99 #ifdef VERBOSE_LOGGING
100 std::cerr << time_now_string()
101 << ": assign bandwidth, " << amount << " blk: " << max_block_size << std::endl;
102 #endif
103 TEST_CHECK(amount > 0);
104 TEST_CHECK(amount <= max_block_size);
105 if (amount < max_block_size)
106 expire_bandwidth(channel, max_block_size - amount);
109 int bandwidth_throttle(int channel) const
110 { return m_bandwidth_limit[channel].throttle(); }
112 int max_assignable_bandwidth(int channel) const
113 { return m_bandwidth_limit[channel].max_assignable(); }
115 void request_bandwidth(int channel
116 , boost::intrusive_ptr<peer_connection> const& p
117 , int max_block_size
118 , int priority)
120 TORRENT_ASSERT(max_block_size > 0);
121 TORRENT_ASSERT(m_bandwidth_limit[channel].throttle() > 0);
122 int block_size = (std::min)(m_bandwidth_limit[channel].throttle() / 10
123 , max_block_size);
124 if (block_size <= 0) block_size = 1;
126 if (m_bandwidth_limit[channel].max_assignable() > 0)
128 #ifdef VERBOSE_LOGGING
129 std::cerr << time_now_string()
130 << ": request bandwidth " << block_size << std::endl;
131 #endif
132 perform_bandwidth_request(channel, p, block_size, priority);
134 else
136 #ifdef VERBOSE_LOGGING
137 std::cerr << time_now_string()
138 << ": queue bandwidth request" << block_size << std::endl;
139 #endif
140 // skip forward in the queue until we find a prioritized peer
141 // or hit the front of it.
142 queue_t::reverse_iterator i = m_bandwidth_queue[channel].rbegin();
143 while (i != m_bandwidth_queue[channel].rend() && priority > i->priority)
145 ++i->priority;
146 ++i;
148 m_bandwidth_queue[channel].insert(i.base(), bw_queue_entry<peer_connection, torrent>(
149 p, block_size, priority));
153 void expire_bandwidth(int channel, int amount);
155 void perform_bandwidth_request(int channel
156 , boost::intrusive_ptr<peer_connection> const& p
157 , int block_size
158 , int priority)
160 m_bandwidth_manager.request_bandwidth(p
161 , block_size, priority);
162 m_bandwidth_limit[channel].assign(block_size);
164 bandwidth_limit m_bandwidth_limit[1];
165 typedef std::deque<bw_queue_entry<peer_connection, torrent> > queue_t;
166 queue_t m_bandwidth_queue[1];
167 bandwidth_manager<peer_connection, torrent>& m_bandwidth_manager;
170 peer_connection::peer_connection(io_service& ios, boost::shared_ptr<torrent> const& t
171 , int prio, bool ignore_limits, std::string name)
172 : m_torrent(t)
173 , m_priority(prio)
174 , m_ignore_limits(ignore_limits)
175 , m_abort(false)
176 , m_ios(ios)
177 , m_name(name)
178 , m_writing(false)
181 void peer_connection::assign_bandwidth(int channel, int amount)
183 TEST_CHECK(m_writing);
184 #ifdef VERBOSE_LOGGING
185 std::cerr << time_now_string() << ": [" << m_name
186 << "] assign bandwidth, " << amount << std::endl;
187 #endif
188 TEST_CHECK(amount > 0);
189 m_bandwidth_limit[channel].assign(amount);
190 m_ios.post(boost::bind(&peer_connection::on_transfer, self(), channel, amount));
193 void peer_connection::on_transfer(int channel, int amount)
195 TEST_CHECK(m_writing);
196 m_writing = false;
197 m_stats.sent_bytes(amount, 0);
199 boost::shared_ptr<torrent> t = m_torrent.lock();
200 if (!t) return;
201 if (m_bandwidth_limit[channel].max_assignable() > 0)
203 m_writing = true;
204 t->request_bandwidth(0, this, 32 * 1024, m_priority);
208 void peer_connection::start()
210 boost::shared_ptr<torrent> t = m_torrent.lock();
211 if (!t) return;
212 m_writing = true;
213 t->request_bandwidth(0, this, 32 * 1024, m_priority);
216 void peer_connection::expire_bandwidth(int channel, int amount)
218 TEST_CHECK(amount > 0);
219 #ifdef VERBOSE_LOGGING
220 std::cerr << time_now_string() << ": [" << m_name
221 << "] expire bandwidth, " << amount << std::endl;
222 #endif
223 m_bandwidth_limit[channel].expire(amount);
225 if (!m_writing && m_bandwidth_limit[channel].max_assignable() > 0)
227 boost::shared_ptr<torrent> t = m_torrent.lock();
228 if (!t) return;
229 m_writing = true;
230 t->request_bandwidth(0, this, 32 * 1024, m_priority);
234 void peer_connection::tick()
236 #ifdef VERBOSE_LOGGING
237 std::cerr << time_now_string() << ": [" << m_name
238 << "] tick, rate: " << m_stats.upload_rate() << std::endl;
239 #endif
240 m_stats.second_tick(1.f);
244 void torrent::expire_bandwidth(int channel, int amount)
246 #ifdef VERBOSE_LOGGING
247 std::cerr << time_now_string()
248 << ": expire bandwidth, " << amount << std::endl;
249 #endif
250 TEST_CHECK(amount > 0);
251 m_bandwidth_limit[channel].expire(amount);
252 queue_t tmp;
253 while (!m_bandwidth_queue[channel].empty())
255 bw_queue_entry<peer_connection, torrent> qe = m_bandwidth_queue[channel].front();
256 if (m_bandwidth_limit[channel].max_assignable() == 0)
257 break;
258 m_bandwidth_queue[channel].pop_front();
259 if (qe.peer->max_assignable_bandwidth(channel) <= 0)
261 if (!qe.peer->is_disconnecting()) tmp.push_back(qe);
262 continue;
264 perform_bandwidth_request(channel, qe.peer
265 , qe.max_block_size, qe.priority);
267 m_bandwidth_queue[channel].insert(m_bandwidth_queue[channel].begin(), tmp.begin(), tmp.end());
270 typedef std::vector<boost::intrusive_ptr<peer_connection> > connections_t;
272 bool abort_tick = false;
274 void do_tick(error_code const&e, deadline_timer& tick, connections_t& v)
276 if (e || abort_tick)
278 std::cerr << " tick aborted" << std::endl;
279 return;
281 std::for_each(v.begin(), v.end()
282 , boost::bind(&peer_connection::tick, _1));
283 tick.expires_from_now(seconds(1));
284 tick.async_wait(boost::bind(&do_tick, _1, boost::ref(tick), boost::ref(v)));
287 void do_stop(deadline_timer& tick, connections_t& v)
289 abort_tick = true;
290 tick.cancel();
291 std::for_each(v.begin(), v.end()
292 , boost::bind(&peer_connection::stop, _1));
293 std::cerr << " stopping..." << std::endl;
296 void do_change_rate(error_code const&e, deadline_timer& tick
297 , boost::shared_ptr<torrent> t1
298 , boost::shared_ptr<torrent> t2
299 , int limit
300 , int counter)
302 TEST_CHECK(!e);
303 if (e) return;
305 if (counter == 0)
307 t1->m_bandwidth_limit[0].throttle(limit);
308 t2->m_bandwidth_limit[0].throttle(limit);
309 return;
312 t1->m_bandwidth_limit[0].throttle(limit + limit / 2 * ((counter & 1)?-1:1));
313 t2->m_bandwidth_limit[0].throttle(limit + limit / 2 * ((counter & 1)?1:-1));
315 tick.expires_from_now(milliseconds(1600));
316 tick.async_wait(boost::bind(&do_change_rate, _1, boost::ref(tick), t1, t2, limit, counter-1));
319 void do_change_peer_rate(error_code const&e, deadline_timer& tick
320 , connections_t& v
321 , int limit
322 , int counter)
324 TEST_CHECK(!e);
325 if (e) return;
327 if (counter == 0)
329 std::for_each(v.begin(), v.end()
330 , boost::bind(&peer_connection::throttle, _1, limit));
331 return;
334 int c = counter;
335 for (connections_t::iterator i = v.begin(); i != v.end(); ++i, ++c)
336 i->get()->throttle(limit + limit / 2 * ((c & 1)?-1:1));
338 tick.expires_from_now(milliseconds(1100));
339 tick.async_wait(boost::bind(&do_change_peer_rate, _1, boost::ref(tick), boost::ref(v), limit, counter-1));
342 void run_test(io_service& ios, connections_t& v)
344 abort_tick = false;
345 std::cerr << "-------------" << std::endl;
346 deadline_timer tick(ios);
347 tick.expires_from_now(seconds(1));
348 tick.async_wait(boost::bind(&do_tick, _1, boost::ref(tick), boost::ref(v)));
350 deadline_timer complete(ios);
351 complete.expires_from_now(milliseconds(int(sample_time * 1000)));
352 complete.async_wait(boost::bind(&do_stop, boost::ref(tick), boost::ref(v)));
354 std::for_each(v.begin(), v.end()
355 , boost::bind(&peer_connection::start, _1));
357 ios.run();
360 bool close_to(float val, float comp, float err)
362 return fabs(val - comp) <= err;
365 void spawn_connections(connections_t& v, io_service& ios
366 , boost::shared_ptr<torrent> t, int num, char const* prefix)
368 for (int i = 0; i < num; ++i)
370 v.push_back(new peer_connection(ios, t, 200, false
371 , prefix + boost::lexical_cast<std::string>(i)));
375 void test_equal_connections(int num, int limit)
377 std::cerr << "\ntest equal connections " << num << " " << limit << std::endl;
378 io_service ios;
379 bandwidth_manager<peer_connection, torrent> manager(ios, 0);
380 manager.throttle(limit);
382 boost::shared_ptr<torrent> t1(new torrent(manager));
384 connections_t v;
385 spawn_connections(v, ios, t1, num, "p");
386 run_test(ios, v);
388 float sum = 0.f;
389 float err = (std::max)(limit / num * 0.3f, 1000.f);
390 for (connections_t::iterator i = v.begin()
391 , end(v.end()); i != end; ++i)
393 sum += (*i)->m_stats.total_payload_upload();
395 std::cerr << (*i)->m_stats.total_payload_upload() / sample_time
396 << " target: " << (limit / num) << " eps: " << err << std::endl;
397 TEST_CHECK(close_to((*i)->m_stats.total_payload_upload() / sample_time, limit / num, err));
399 sum /= sample_time;
400 std::cerr << "sum: " << sum << " target: " << limit << std::endl;
401 TEST_CHECK(sum > 0);
402 TEST_CHECK(close_to(sum, limit, 50));
405 void test_connections_variable_rate(int num, int limit, int torrent_limit)
407 std::cerr << "\ntest connections variable rate" << num
408 << " l: " << limit
409 << " t: " << torrent_limit
410 << std::endl;
411 io_service ios;
412 bandwidth_manager<peer_connection, torrent> manager(ios, 0);
414 boost::shared_ptr<torrent> t1(new torrent(manager));
415 if (torrent_limit)
416 t1->m_bandwidth_limit[0].throttle(torrent_limit);
418 connections_t v;
419 spawn_connections(v, ios, t1, num, "p");
420 std::for_each(v.begin(), v.end()
421 , boost::bind(&peer_connection::throttle, _1, limit));
423 deadline_timer change_rate(ios);
424 change_rate.expires_from_now(milliseconds(1600));
425 change_rate.async_wait(boost::bind(&do_change_peer_rate, _1, boost::ref(change_rate)
426 , boost::ref(v), limit, 9));
427 run_test(ios, v);
429 if (torrent_limit > 0 && limit * num > torrent_limit)
430 limit = torrent_limit / num;
432 float sum = 0.f;
433 float err = limit * 0.3f;
434 for (connections_t::iterator i = v.begin()
435 , end(v.end()); i != end; ++i)
437 sum += (*i)->m_stats.total_payload_upload();
439 std::cerr << (*i)->m_stats.total_payload_upload() / sample_time
440 << " target: " << limit << " eps: " << err << std::endl;
441 TEST_CHECK(close_to((*i)->m_stats.total_payload_upload() / sample_time, limit, err));
443 sum /= sample_time;
444 std::cerr << "sum: " << sum << " target: " << (limit * num) << std::endl;
445 TEST_CHECK(sum > 0);
446 TEST_CHECK(close_to(sum, limit * num, limit * 0.3f * num));
449 void test_single_peer(int limit, bool torrent_limit)
451 std::cerr << "\ntest single peer " << limit << " " << torrent_limit << std::endl;
452 io_service ios;
453 bandwidth_manager<peer_connection, torrent> manager(ios, 0);
454 boost::shared_ptr<torrent> t1(new torrent(manager));
456 if (torrent_limit)
457 t1->m_bandwidth_limit[0].throttle(limit);
458 else
459 manager.throttle(limit);
461 connections_t v;
462 spawn_connections(v, ios, t1, 1, "p");
463 run_test(ios, v);
465 float sum = 0.f;
466 for (connections_t::iterator i = v.begin()
467 , end(v.end()); i != end; ++i)
469 sum += (*i)->m_stats.total_payload_upload();
471 sum /= sample_time;
472 std::cerr << sum << " target: " << limit << std::endl;
473 TEST_CHECK(sum > 0);
474 TEST_CHECK(close_to(sum, limit, 1000));
477 void test_torrents(int num, int limit1, int limit2, int global_limit)
479 std::cerr << "\ntest equal torrents " << num
480 << " l1: " << limit1
481 << " l2: " << limit2
482 << " g: " << global_limit << std::endl;
483 io_service ios;
484 bandwidth_manager<peer_connection, torrent> manager(ios, 0);
485 if (global_limit > 0)
486 manager.throttle(global_limit);
488 boost::shared_ptr<torrent> t1(new torrent(manager));
489 boost::shared_ptr<torrent> t2(new torrent(manager));
491 t1->m_bandwidth_limit[0].throttle(limit1);
492 t2->m_bandwidth_limit[0].throttle(limit2);
494 connections_t v1;
495 spawn_connections(v1, ios, t1, num, "t1p");
496 connections_t v2;
497 spawn_connections(v2, ios, t2, num, "t2p");
498 connections_t v;
499 std::copy(v1.begin(), v1.end(), std::back_inserter(v));
500 std::copy(v2.begin(), v2.end(), std::back_inserter(v));
501 run_test(ios, v);
503 if (global_limit > 0 && global_limit < limit1 + limit2)
505 limit1 = (std::min)(limit1, global_limit / 2);
506 limit2 = global_limit - limit1;
508 float sum = 0.f;
509 for (connections_t::iterator i = v1.begin()
510 , end(v1.end()); i != end; ++i)
512 sum += (*i)->m_stats.total_payload_upload();
514 sum /= sample_time;
515 std::cerr << sum << " target: " << limit1 << std::endl;
516 TEST_CHECK(sum > 0);
517 TEST_CHECK(close_to(sum, limit1, 1000));
519 sum = 0.f;
520 for (connections_t::iterator i = v2.begin()
521 , end(v2.end()); i != end; ++i)
523 sum += (*i)->m_stats.total_payload_upload();
525 sum /= sample_time;
526 std::cerr << sum << " target: " << limit2 << std::endl;
527 TEST_CHECK(sum > 0);
528 TEST_CHECK(close_to(sum, limit2, 1000));
531 void test_torrents_variable_rate(int num, int limit, int global_limit)
533 std::cerr << "\ntest torrents variable rate" << num
534 << " l: " << limit
535 << " g: " << global_limit << std::endl;
536 io_service ios;
537 bandwidth_manager<peer_connection, torrent> manager(ios, 0);
538 if (global_limit > 0)
539 manager.throttle(global_limit);
541 boost::shared_ptr<torrent> t1(new torrent(manager));
542 boost::shared_ptr<torrent> t2(new torrent(manager));
544 t1->m_bandwidth_limit[0].throttle(limit);
545 t2->m_bandwidth_limit[0].throttle(limit);
547 connections_t v1;
548 spawn_connections(v1, ios, t1, num, "t1p");
549 connections_t v2;
550 spawn_connections(v2, ios, t2, num, "t2p");
551 connections_t v;
552 std::copy(v1.begin(), v1.end(), std::back_inserter(v));
553 std::copy(v2.begin(), v2.end(), std::back_inserter(v));
555 deadline_timer change_rate(ios);
556 change_rate.expires_from_now(milliseconds(1100));
557 change_rate.async_wait(boost::bind(&do_change_rate, _1, boost::ref(change_rate), t1, t2, limit, 9));
559 run_test(ios, v);
561 if (global_limit > 0 && global_limit < 2 * limit)
562 limit = global_limit / 2;
564 float sum = 0.f;
565 for (connections_t::iterator i = v1.begin()
566 , end(v1.end()); i != end; ++i)
568 sum += (*i)->m_stats.total_payload_upload();
570 sum /= sample_time;
571 std::cerr << sum << " target: " << limit << std::endl;
572 TEST_CHECK(sum > 0);
573 TEST_CHECK(close_to(sum, limit, 1000));
575 sum = 0.f;
576 for (connections_t::iterator i = v2.begin()
577 , end(v2.end()); i != end; ++i)
579 sum += (*i)->m_stats.total_payload_upload();
581 sum /= sample_time;
582 std::cerr << sum << " target: " << limit << std::endl;
583 TEST_CHECK(sum > 0);
584 TEST_CHECK(close_to(sum, limit, 1000));
587 void test_peer_priority(int limit, bool torrent_limit)
589 std::cerr << "\ntest peer priority " << limit << " " << torrent_limit << std::endl;
590 io_service ios;
591 bandwidth_manager<peer_connection, torrent> manager(ios, 0);
592 boost::shared_ptr<torrent> t1(new torrent(manager));
594 if (torrent_limit)
595 t1->m_bandwidth_limit[0].throttle(limit);
596 else
597 manager.throttle(limit);
599 connections_t v1;
600 spawn_connections(v1, ios, t1, 10, "p");
601 connections_t v;
602 std::copy(v1.begin(), v1.end(), std::back_inserter(v));
603 boost::intrusive_ptr<peer_connection> p(
604 new peer_connection(ios, t1, 0, false, "no-priority"));
605 v.push_back(p);
606 run_test(ios, v);
608 float sum = 0.f;
609 for (connections_t::iterator i = v1.begin()
610 , end(v1.end()); i != end; ++i)
612 sum += (*i)->m_stats.total_payload_upload();
614 sum /= sample_time;
615 std::cerr << sum << " target: " << limit << std::endl;
616 TEST_CHECK(sum > 0);
617 TEST_CHECK(close_to(sum, limit, 50));
619 std::cerr << "non-prioritized rate: " << p->m_stats.total_payload_upload() / sample_time << std::endl;
620 TEST_CHECK(p->m_stats.total_payload_upload() / sample_time < 10);
623 void test_no_starvation(int limit)
625 std::cerr << "\ntest no starvation " << limit << std::endl;
626 io_service ios;
627 bandwidth_manager<peer_connection, torrent> manager(ios, 0);
628 boost::shared_ptr<torrent> t1(new torrent(manager));
629 boost::shared_ptr<torrent> t2(new torrent(manager));
631 manager.throttle(limit);
633 const int num_peers = 20;
635 connections_t v1;
636 spawn_connections(v1, ios, t1, num_peers, "p");
637 connections_t v;
638 std::copy(v1.begin(), v1.end(), std::back_inserter(v));
639 boost::intrusive_ptr<peer_connection> p(
640 new peer_connection(ios, t2, 0, false, "no-priority"));
641 v.push_back(p);
642 run_test(ios, v);
644 float sum = 0.f;
645 for (connections_t::iterator i = v.begin()
646 , end(v.end()); i != end; ++i)
648 sum += (*i)->m_stats.total_payload_upload();
650 sum /= sample_time;
651 std::cerr << sum << " target: " << limit << std::endl;
652 TEST_CHECK(sum > 0);
653 TEST_CHECK(close_to(sum, limit, 50));
655 std::cerr << "non-prioritized rate: " << p->m_stats.total_payload_upload() / sample_time << std::endl;
656 TEST_CHECK(close_to(p->m_stats.total_payload_upload() / sample_time, limit / (num_peers + 1), 1000));
659 int test_main()
661 using namespace libtorrent;
663 test_equal_connections(2, 20);
664 test_equal_connections(2, 2000);
665 test_equal_connections(2, 20000);
666 test_equal_connections(3, 20000);
667 test_equal_connections(5, 20000);
668 test_equal_connections(7, 20000);
669 test_equal_connections(33, 60000);
670 test_equal_connections(33, 500000);
671 test_connections_variable_rate(2, 20, 0);
672 test_connections_variable_rate(5, 20000, 0);
673 test_connections_variable_rate(3, 2000, 6000);
674 test_connections_variable_rate(5, 2000, 30000);
675 test_connections_variable_rate(33, 500000, 0);
676 test_torrents(2, 400, 400, 0);
677 test_torrents(2, 100, 500, 0);
678 test_torrents(2, 3000, 3000, 6000);
679 test_torrents(1, 40000, 40000, 0);
680 test_torrents(24, 50000, 50000, 0);
681 test_torrents(5, 6000, 6000, 3000);
682 test_torrents(5, 6000, 5000, 4000);
683 test_torrents(5, 20000, 20000, 30000);
684 test_torrents_variable_rate(5, 6000, 3000);
685 test_torrents_variable_rate(5, 20000, 30000);
686 test_single_peer(40000, true);
687 test_single_peer(40000, false);
688 test_peer_priority(40000, false);
689 test_peer_priority(40000, true);
690 test_no_starvation(40000);
692 return 0;