From 1925d1e7aadd483fb1c2f79cba56efbc6304d1cf Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 17 May 2017 23:04:50 -0400 Subject: [PATCH] add test for recent duplicate add bug (#2003) --- test/setup_transfer.cpp | 27 ++++++++++++++++++++------- test/setup_transfer.hpp | 5 ++++- test/test_session.cpp | 37 +++++++++++++++++++++++++++++++++++++ test/test_storage.cpp | 19 ++++++++++++++----- 4 files changed, 75 insertions(+), 13 deletions(-) diff --git a/test/setup_transfer.cpp b/test/setup_transfer.cpp index 9a857d421..504ca7d1e 100644 --- a/test/setup_transfer.cpp +++ b/test/setup_transfer.cpp @@ -174,8 +174,16 @@ bool should_print(lt::alert* a) return true; } } -alert const* wait_for_alert(lt::session& ses, int type, char const* name, int num) +alert const* wait_for_alert(lt::session& ses, int type, char const* name + , pop_alerts const p) { + // we pop alerts in batches, but we wait for individual messages. This is a + // cache to keep around alerts that came *after* the one we're waiting for. + // To let subsequent calls to this function be able to pick those up, despite + // already being popped off the sessions alert queue. + static std::map> cache; + auto& alerts = cache[&ses]; + time_point end_time = lt::clock_type::now() + seconds(10); while (true) { @@ -184,11 +192,14 @@ alert const* wait_for_alert(lt::session& ses, int type, char const* name, int nu alert const* ret = nullptr; - ses.wait_for_alert(end_time - now); - std::vector alerts; - ses.pop_alerts(&alerts); - for (auto a : alerts) + if (alerts.empty()) { + ses.wait_for_alert(end_time - now); + ses.pop_alerts(&alerts); + } + for (auto i = alerts.begin(); i != alerts.end(); ++i) + { + auto a = *i; if (should_print(a)) { std::printf("%s: %s: [%s] %s\n", time_now_string(), name @@ -197,10 +208,12 @@ alert const* wait_for_alert(lt::session& ses, int type, char const* name, int nu if (a->type() == type) { ret = a; - --num; + if (p == pop_alerts::pop_all) alerts.clear(); + else alerts.erase(alerts.begin(), std::next(i)); + return ret; } } - if (num == 0) return ret; + alerts.clear(); } } diff --git a/test/setup_transfer.hpp b/test/setup_transfer.hpp index 471b877ab..f2927be1c 100644 --- a/test/setup_transfer.hpp +++ b/test/setup_transfer.hpp @@ -62,8 +62,11 @@ EXPORT lt::sha1_hash to_hash(char const* s); EXPORT std::map get_counters(lt::session& s); +enum class pop_alerts { pop_all, cache_alerts }; + EXPORT lt::alert const* wait_for_alert( - lt::session& ses, int type, char const* name = "", int num = 1); + lt::session& ses, int type, char const* name = "" + , pop_alerts const p = pop_alerts::pop_all); EXPORT void print_ses_rate(float time , lt::torrent_status const* st1 diff --git a/test/test_session.cpp b/test/test_session.cpp index 9b52be68c..952194547 100644 --- a/test/test_session.cpp +++ b/test/test_session.cpp @@ -151,6 +151,43 @@ TORRENT_TEST(async_add_torrent_duplicate) TEST_CHECK(!a->error); } +TORRENT_TEST(async_add_torrent_duplicate_back_to_back) +{ + settings_pack p = settings(); + p.set_int(settings_pack::alert_mask, ~0); + lt::session ses(p); + + add_torrent_params atp; + atp.info_hash.assign("abababababababababab"); + atp.save_path = "."; + atp.flags |= add_torrent_params::flag_paused; + atp.flags &= ~add_torrent_params::flag_apply_ip_filter; + atp.flags &= ~add_torrent_params::flag_auto_managed; + ses.async_add_torrent(atp); + + atp.flags &= ~add_torrent_params::flag_duplicate_is_error; + ses.async_add_torrent(atp); + + auto* a = alert_cast(wait_for_alert(ses + , add_torrent_alert::alert_type, "ses", pop_alerts::cache_alerts)); + TEST_CHECK(a); + if (a == nullptr) return; + torrent_handle h = a->handle; + TEST_CHECK(!a->error); + + a = alert_cast(wait_for_alert(ses + , add_torrent_alert::alert_type, "ses", pop_alerts::cache_alerts)); + TEST_CHECK(a); + if (a == nullptr) return; + TEST_CHECK(a->handle == h); + TEST_CHECK(!a->error); + + torrent_status st = h.status(); + TEST_CHECK(st.paused); + TEST_CHECK(!st.ip_filter_applies); + TEST_CHECK(!st.auto_managed); +} + TORRENT_TEST(load_empty_file) { settings_pack p = settings(); diff --git a/test/test_storage.cpp b/test/test_storage.cpp index ac345a67e..d79c61171 100644 --- a/test/test_storage.cpp +++ b/test/test_storage.cpp @@ -770,8 +770,13 @@ TORRENT_TEST(rename_file) h.add_piece(i, &tmp[0]); // wait for the files to have been written - alert const* pf = wait_for_alert(ses, piece_finished_alert::alert_type, "ses", info->num_pieces()); - TEST_CHECK(pf); + + for (int i = 0; i < info->num_pieces(); ++i) + { + alert const* pf = wait_for_alert(ses, piece_finished_alert::alert_type + , "ses", pop_alerts::cache_alerts); + TEST_CHECK(pf); + } // now rename them. This is the test for (file_index_t i(0); i < fs.end_file(); ++i) @@ -780,9 +785,13 @@ TORRENT_TEST(rename_file) h.rename_file(i, "temp_storage__" + name.substr(12)); } - // wait fir the files to have been renamed - alert const* fra = wait_for_alert(ses, file_renamed_alert::alert_type, "ses", info->num_files()); - TEST_CHECK(fra); + // wait for the files to have been renamed + for (int i = 0; i < info->num_files(); ++i) + { + alert const* fra = wait_for_alert(ses, file_renamed_alert::alert_type + , "ses", pop_alerts::cache_alerts); + TEST_CHECK(fra); + } TEST_CHECK(exists(info->name() + "__"));