From c0d6b20634b5f46ef7682420a8c5c5197920fc95 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 20 Nov 2015 00:51:58 -0500 Subject: [PATCH 1/2] extend swarm simulation test to include stopping and starting and graceful pause --- include/libtorrent/alert.hpp | 7 +-- simulation/swarm_suite.cpp | 84 +++++++++++++++++++++++++++++++++++- simulation/swarm_suite.hpp | 5 ++- simulation/test_swarm.cpp | 15 +++++++ src/torrent.cpp | 10 +++++ 5 files changed, 115 insertions(+), 6 deletions(-) diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp index 29844ca11..d977091b8 100644 --- a/include/libtorrent/alert.hpp +++ b/include/libtorrent/alert.hpp @@ -54,8 +54,8 @@ POSSIBILITY OF SUCH DAMAGE. // alerts (warnings, messages and errors from libtorrent). If no alerts have // been posted by libtorrent pop_alerts() will return an empty list. // -// By default, only errors are reported. set_alert_mask() can be used to -// specify which kinds of events should be reported. The alert mask is +// By default, only errors are reported. session_settings::alert_mask can be +// used to specify which kinds of events should be reported. The alert mask is // comprised by bits from the category_t enum. // // Every alert belongs to one or more category. There is a cost associated with @@ -105,7 +105,8 @@ namespace libtorrent { enum severity_t { debug, info, warning, critical, fatal, none }; #endif - // these are bits for the alert_mask used by the session. See set_alert_mask(). + // these are bits for the alert_mask used by the session. See + // settings_pack::alert_mask. enum category_t { // Enables alerts that report an error. This includes: diff --git a/simulation/swarm_suite.cpp b/simulation/swarm_suite.cpp index 4c3342c02..6c4ef3163 100644 --- a/simulation/swarm_suite.cpp +++ b/simulation/swarm_suite.cpp @@ -50,13 +50,87 @@ struct test_swarm_config : swarm_config test_swarm_config(int flags) : swarm_config() , m_flags(flags) + , m_paused_once(false) + , m_resumed_once(false) {} virtual void on_exit(std::vector const& torrents) override { swarm_config::on_exit(torrents); - TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(2100)); + // if we stopped and started again, we loose some time and need a bit + // more slack for completion + if (m_flags & stop_start_seed) + { + TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(3700)); + } + else if (m_flags & stop_start_download) + { + TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(2800)); + } + else + { + TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(2100)); + } + } + + virtual bool on_alert(libtorrent::alert const* alert + , int session_idx + , std::vector const& torrents + , libtorrent::session& ses) override + { + if (((m_flags & stop_start_download) + || (m_flags & stop_start_seed)) + && m_paused_once == false) + { + torrent_status st_seed = torrents[0].status(); + torrent_status st_dl = torrents[1].status(); + + int flags = 0; + if (m_flags & graceful_pause) + flags = torrent_handle::graceful_pause; + + if (m_flags & stop_start_download) + { + if (st_dl.total_wanted_done > st_dl.total_wanted / 2 + && st_dl.paused == false) + { + m_paused_once = true; + torrents[1].auto_managed(false); + torrents[1].pause(flags); + } + } + + if (m_flags & stop_start_seed) + { + if (st_dl.total_wanted_done > st_dl.total_wanted / 2 + && st_seed.paused == false) + { + m_paused_once = true; + torrents[0].auto_managed(false); + torrents[0].pause(flags); + } + } + } + + if (alert_cast(alert)) + { + TEST_EQUAL(m_resumed_once, false); + + if (m_flags & stop_start_download) + { + torrents[1].resume(); + m_resumed_once = true; + } + + if (m_flags & stop_start_seed) + { + torrents[0].resume(); + m_resumed_once = true; + } + } + + return swarm_config::on_alert(alert, session_idx, torrents, ses); } // called for every torrent that's added (and every session that's started). @@ -112,16 +186,19 @@ struct test_swarm_config : swarm_config pack.set_bool(settings_pack::enable_outgoing_tcp, true); } + pack.set_int(settings_pack::alert_mask, alert::all_categories); return pack; } private: int m_flags; + bool m_paused_once; + bool m_resumed_once; }; void simulate_swarm(int flags) { - fprintf(stderr, "\n\n ==== TEST SWARM === %s%s%s%s%s%s%s ===\n\n\n" + fprintf(stderr, "\n\n ==== TEST SWARM === %s%s%s%s%s%s%s%s%s%s===\n\n\n" , (flags & super_seeding) ? "super-seeding ": "" , (flags & strict_super_seeding) ? "strict-super-seeding ": "" , (flags & seed_mode) ? "seed-mode ": "" @@ -129,6 +206,9 @@ void simulate_swarm(int flags) , (flags & suggest_read_cache) ? "suggest-read-cache ": "" , (flags & explicit_cache) ? "explicit-cache ": "" , (flags & utp_only) ? "utp-only": "" + , (flags & stop_start_download) ? "stop-start-download ": "" + , (flags & stop_start_seed) ? "stop-start-seed ": "" + , (flags & stop_start_seed) ? "graceful-pause ": "" ); test_swarm_config cfg(flags); diff --git a/simulation/swarm_suite.hpp b/simulation/swarm_suite.hpp index 76bd88bac..87eee58c1 100644 --- a/simulation/swarm_suite.hpp +++ b/simulation/swarm_suite.hpp @@ -40,7 +40,10 @@ enum test_flags_t time_critical = 8, suggest_read_cache = 16, explicit_cache = 32, - utp_only = 64 + utp_only = 64, + stop_start_download = 128, + stop_start_seed = 256, + graceful_pause = 1024 }; void EXPORT simulate_swarm(int flags = 0); diff --git a/simulation/test_swarm.cpp b/simulation/test_swarm.cpp index 8b53569e8..509efa6d4 100644 --- a/simulation/test_swarm.cpp +++ b/simulation/test_swarm.cpp @@ -54,6 +54,21 @@ TORRENT_TEST(utp) { simulate_swarm(utp_only); } + +TORRENT_TEST(stop_start_download) +{ + simulate_swarm(stop_start_download); +} +TORRENT_TEST(stop_start_download_graceful) +{ + simulate_swarm(stop_start_download | graceful_pause); +} + +TORRENT_TEST(stop_start_seed) +{ + simulate_swarm(stop_start_seed); +} + TORRENT_TEST(explicit_cache) { // test explicit cache diff --git a/src/torrent.cpp b/src/torrent.cpp index 1837d47d8..d2d14a75a 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -6086,6 +6086,16 @@ namespace libtorrent p->set_peer_info(0); TORRENT_ASSERT(i != m_connections.end()); m_connections.erase(i); + + if (m_graceful_pause_mode && m_connections.empty()) + { + // we're in graceful pause mode and this was the last peer we + // disconnected. This will clear the graceful_pause_mode and post the + // torrent_paused_alert. + TORRENT_ASSERT(is_paused()); + set_allow_peers(false); + } + update_want_peers(); update_want_tick(); } From 4a30653084668310c1acecda0e22df80824dc5d2 Mon Sep 17 00:00:00 2001 From: arvidn Date: Fri, 20 Nov 2015 22:22:15 -0500 Subject: [PATCH 2/2] improve coverage of stop-start-test --- simulation/swarm_suite.cpp | 16 +++++++++++++++- simulation/swarm_suite.hpp | 3 ++- simulation/test_swarm.cpp | 11 ++++++++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/simulation/swarm_suite.cpp b/simulation/swarm_suite.cpp index 6c4ef3163..1a7b0b527 100644 --- a/simulation/swarm_suite.cpp +++ b/simulation/swarm_suite.cpp @@ -62,7 +62,7 @@ struct test_swarm_config : swarm_config // more slack for completion if (m_flags & stop_start_seed) { - TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(3700)); + TEST_CHECK(lt::clock_type::now() < m_start_time + lt::milliseconds(4700)); } else if (m_flags & stop_start_download) { @@ -133,6 +133,20 @@ struct test_swarm_config : swarm_config return swarm_config::on_alert(alert, session_idx, torrents, ses); } + virtual void on_torrent_added(int session_index, torrent_handle h) override + { + if (m_flags & add_extra_peers) + { + for (int i = 0; i < 30; ++i) + { + char ep[30]; + snprintf(ep, sizeof(ep), "60.0.0.%d", i + 1); + h.connect_peer(lt::tcp::endpoint( + lt::address_v4::from_string(ep), 6881)); + } + } + } + // called for every torrent that's added (and every session that's started). // this is useful to give every session a unique save path and to make some // sessions seeds and others downloaders diff --git a/simulation/swarm_suite.hpp b/simulation/swarm_suite.hpp index 87eee58c1..0021c89ca 100644 --- a/simulation/swarm_suite.hpp +++ b/simulation/swarm_suite.hpp @@ -43,7 +43,8 @@ enum test_flags_t utp_only = 64, stop_start_download = 128, stop_start_seed = 256, - graceful_pause = 1024 + graceful_pause = 1024, + add_extra_peers = 2048 }; void EXPORT simulate_swarm(int flags = 0); diff --git a/simulation/test_swarm.cpp b/simulation/test_swarm.cpp index 509efa6d4..3548ab590 100644 --- a/simulation/test_swarm.cpp +++ b/simulation/test_swarm.cpp @@ -57,16 +57,21 @@ TORRENT_TEST(utp) TORRENT_TEST(stop_start_download) { - simulate_swarm(stop_start_download); + simulate_swarm(stop_start_download | add_extra_peers); } TORRENT_TEST(stop_start_download_graceful) { - simulate_swarm(stop_start_download | graceful_pause); + simulate_swarm(stop_start_download | graceful_pause | add_extra_peers); } TORRENT_TEST(stop_start_seed) { - simulate_swarm(stop_start_seed); + simulate_swarm(stop_start_seed | add_extra_peers); +} + +TORRENT_TEST(stop_start_seed_graceful) +{ + simulate_swarm(stop_start_seed | graceful_pause | add_extra_peers); } TORRENT_TEST(explicit_cache)