diff --git a/src/torrent/tracker.cc b/src/torrent/tracker.cc index 0de87bf71..2ab95f496 100644 --- a/src/torrent/tracker.cc +++ b/src/torrent/tracker.cc @@ -22,10 +22,7 @@ Tracker::Tracker(TrackerList* parent, const std::string& url, int flags) : m_url(url), m_request_time_last(torrent::cachedTime.seconds()) { - // TODO: Not needed when EVENT_NONE is default. - auto tracker_state = TrackerState{}; - tracker_state.m_latest_event = EVENT_NONE; - m_state.store(tracker_state); + m_state.m_latest_event = EVENT_NONE; } void @@ -78,34 +75,27 @@ Tracker::inc_request_counter() { void Tracker::clear_intervals() { - auto state = m_state.load(); + std::lock_guard lock(m_state_mutex); - state.m_normal_interval = 0; - state.m_min_interval = 0; - - m_state.store(state); + m_state.m_normal_interval = 0; + m_state.m_min_interval = 0; } void Tracker::clear_stats() { - auto state = m_state.load(); - - state.m_latest_new_peers = 0; - state.m_latest_sum_peers = 0; - state.m_success_counter = 0; - state.m_failed_counter = 0; - state.m_scrape_counter = 0; + std::lock_guard lock(m_state_mutex); - m_state.store(state); + m_state.m_latest_new_peers = 0; + m_state.m_latest_sum_peers = 0; + m_state.m_success_counter = 0; + m_state.m_failed_counter = 0; + m_state.m_scrape_counter = 0; } void Tracker::set_latest_event(int v) { - auto state = m_state.load(); - - state.m_latest_event = v; - - m_state.store(state); + std::lock_guard lock(m_state_mutex); + m_state.m_latest_event = v; } void @@ -113,13 +103,12 @@ Tracker::update_tracker_id(const std::string& id) { if (id.empty()) return; - if (tracker_id() == id) - return; + std::lock_guard lock(m_state_mutex); - auto new_id = std::array{}; - std::copy_n(id.begin(), std::min(id.size(), size_t(63)), new_id.begin()); + if (m_tracker_id == id) + return; - m_tracker_id.store(new_id); + m_tracker_id = id; } } diff --git a/src/torrent/tracker.h b/src/torrent/tracker.h index 2f5557439..0181e492c 100644 --- a/src/torrent/tracker.h +++ b/src/torrent/tracker.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -54,12 +55,12 @@ class LIBTORRENT_EXPORT Tracker { bool is_enabled() const { return (m_flags & flag_enabled); } bool is_extra_tracker() const { return (m_flags & flag_extra_tracker); } - bool is_in_use() const { return is_enabled() && m_state.load().success_counter() != 0; } + bool is_in_use() const { return is_enabled() && state().success_counter() != 0; } bool can_scrape() const { return (m_flags & flag_can_scrape); } virtual bool is_busy() const = 0; - bool is_busy_not_scrape() const { return m_state.load().latest_event() != EVENT_SCRAPE && is_busy(); } + bool is_busy_not_scrape() const { return state().latest_event() != EVENT_SCRAPE && is_busy(); } virtual bool is_usable() const { return is_enabled(); } bool can_request_state() const; @@ -75,9 +76,8 @@ class LIBTORRENT_EXPORT Tracker { const std::string& url() const { return m_url; } void set_url(const std::string& url) { m_url = url; } - std::string tracker_id() const { return std::string(m_tracker_id.load().data()); } - - TrackerState state() const { return m_state.load(); } + std::string tracker_id() const; + TrackerState state() const;; virtual void get_status(char* buffer, [[maybe_unused]] int length) { buffer[0] = 0; } @@ -104,6 +104,7 @@ class LIBTORRENT_EXPORT Tracker { void clear_stats(); void set_latest_event(int v); + void set_state(const TrackerState& state); void update_tracker_id(const std::string& id); int m_flags; @@ -111,15 +112,18 @@ class LIBTORRENT_EXPORT Tracker { TrackerList* m_parent; uint32_t m_group{0}; - std::string m_url; - std::atomic> m_tracker_id{{}}; + std::string m_url; // Timing of the last request, and a counter for how many requests // there's been in the recent past. uint32_t m_request_time_last; uint32_t m_request_counter{0}; - std::atomic m_state; +private: + // Only the tracker thread should change state. + mutable std::mutex m_state_mutex; + TrackerState m_state; + std::string m_tracker_id; }; inline bool @@ -127,6 +131,24 @@ Tracker::can_request_state() const { return !(is_busy() && state().latest_event() != EVENT_SCRAPE) && is_usable(); } +inline std::string +Tracker::tracker_id() const { + std::lock_guard lock(m_state_mutex); + return m_tracker_id; +} + +inline TrackerState +Tracker::state() const { + std::lock_guard lock(m_state_mutex); + return m_state; +} + +inline void +Tracker::set_state(const TrackerState& state) { + std::lock_guard lock(m_state_mutex); + m_state = state; +} + } #endif diff --git a/src/torrent/tracker/tracker_state.h b/src/torrent/tracker/tracker_state.h index 71172fb98..fb9bf5574 100644 --- a/src/torrent/tracker/tracker_state.h +++ b/src/torrent/tracker/tracker_state.h @@ -4,6 +4,8 @@ #include #include +class TrackerTest; + namespace torrent { class TrackerDht; @@ -17,6 +19,7 @@ class TrackerState { friend class TrackerDht; friend class TrackerHttp; friend class TrackerList; + friend class ::TrackerTest; friend class TrackerUdp; static constexpr int default_min_interval = 600; diff --git a/src/torrent/tracker_list.cc b/src/torrent/tracker_list.cc index 5bbfce8fe..b56a4d421 100644 --- a/src/torrent/tracker_list.cc +++ b/src/torrent/tracker_list.cc @@ -301,7 +301,7 @@ TrackerList::receive_success(Tracker* tracker, AddressList* l) { tracker_state.m_latest_sum_peers = l->size(); tracker_state.m_latest_new_peers = m_slot_success(tracker, l); - tracker->m_state.store(tracker_state); + tracker->set_state(tracker_state); } void @@ -318,7 +318,7 @@ TrackerList::receive_failed(Tracker* tracker, const std::string& msg) { tracker_state.m_failed_time_last = cachedTime.seconds(); tracker_state.m_failed_counter++; - tracker->m_state.store(tracker_state); + tracker->set_state(tracker_state); m_slot_failed(tracker, msg); } @@ -337,7 +337,7 @@ TrackerList::receive_scrape_success(Tracker* tracker) { tracker_state.m_scrape_time_last = cachedTime.seconds(); tracker_state.m_scrape_counter++; - tracker->m_state.store(tracker_state); + tracker->set_state(tracker_state); if (m_slot_scrape_success) m_slot_scrape_success(tracker); diff --git a/src/tracker/tracker_dht.cc b/src/tracker/tracker_dht.cc index 183e3c1bb..edd1b762a 100644 --- a/src/tracker/tracker_dht.cc +++ b/src/tracker/tracker_dht.cc @@ -73,7 +73,7 @@ TrackerDht::send_state(int new_state) { auto tracker_state = state(); tracker_state.set_normal_interval(20 * 60); tracker_state.set_min_interval(0); - m_state.store(tracker_state); + set_state(tracker_state); } void diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc index 6bed66c80..f54175ad7 100644 --- a/src/tracker/tracker_http.cc +++ b/src/tracker/tracker_http.cc @@ -90,7 +90,8 @@ TrackerHttp::send_state(int new_state) { char localId[61]; - DownloadInfo* info = m_parent->info(); + auto info = m_parent->info(); + auto tracker_id = this->tracker_id(); request_prefix(&s, m_url); @@ -101,8 +102,8 @@ TrackerHttp::send_state(int new_state) { if (m_parent->key()) s << "&key=" << std::hex << std::setw(8) << std::setfill('0') << m_parent->key() << std::dec; - if (!m_tracker_id.load().empty()) - s << "&trackerid=" << rak::copy_escape_html(tracker_id()); + if (!tracker_id.empty()) + s << "&trackerid=" << rak::copy_escape_html(tracker_id); const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address()); @@ -324,12 +325,12 @@ TrackerHttp::process_failure(const Object& object) { if (object.has_key_value("downloaded")) tracker_state.m_scrape_downloaded = std::max(object.get_key_value("downloaded"), 0); - m_state.store(tracker_state); + set_state(tracker_state); } void TrackerHttp::process_success(const Object& object) { - auto tracker_state = m_state.load(); + auto tracker_state = state(); if (object.has_key_value("interval")) tracker_state.set_normal_interval(object.get_key_value("interval")); @@ -353,7 +354,7 @@ TrackerHttp::process_success(const Object& object) { if (object.has_key_value("downloaded")) tracker_state.m_scrape_downloaded = std::max(object.get_key_value("downloaded"), 0); - m_state.store(tracker_state); + set_state(tracker_state); if (!object.has_key("peers") && !object.has_key("peers6")) return receive_failed("No peers returned"); @@ -395,7 +396,7 @@ TrackerHttp::process_scrape(const Object& object) { const Object& stats = files.get_key(m_parent->info()->hash().str()); - auto tracker_state = m_state.load(); + auto tracker_state = state(); if (stats.has_key_value("complete")) tracker_state.m_scrape_complete = std::max(stats.get_key_value("complete"), 0); @@ -406,7 +407,7 @@ TrackerHttp::process_scrape(const Object& object) { if (stats.has_key_value("downloaded")) tracker_state.m_scrape_downloaded = std::max(stats.get_key_value("downloaded"), 0); - m_state.store(tracker_state); + set_state(tracker_state); LT_LOG_TRACKER(INFO, "Tracker scrape for %u torrents: complete:%u incomplete:%u downloaded:%u.", files.as_map().size(), tracker_state.m_scrape_complete, tracker_state.m_scrape_incomplete, tracker_state.m_scrape_downloaded); diff --git a/src/tracker/tracker_udp.cc b/src/tracker/tracker_udp.cc index 0c192f2fc..ffd732608 100644 --- a/src/tracker/tracker_udp.cc +++ b/src/tracker/tracker_udp.cc @@ -350,7 +350,7 @@ TrackerUdp::process_announce_output() { tracker_state.m_scrape_complete = m_readBuffer->read_32(); // seeders tracker_state.m_scrape_time_last = rak::timer::current().seconds(); - m_state.store(tracker_state); + set_state(tracker_state); AddressList l; diff --git a/test/torrent/net/Makefile.am b/test/torrent/net/Makefile.am deleted file mode 100644 index 8a531cc1a..000000000 --- a/test/torrent/net/Makefile.am +++ /dev/null @@ -1,44 +0,0 @@ -TESTS = LibTorrentTestTorrentNet -AUTOMAKE_OPTIONS = subdir-objects - -check_PROGRAMS = $(TESTS) -LibTorrentTestTorrentNet_LDADD = \ - ../../../src/libtorrent.la \ - ../../../src/torrent/libsub_torrent.la \ - ../../../src/torrent/data/libsub_torrentdata.la \ - ../../../src/torrent/download/libsub_torrentdownload.la \ - ../../../src/torrent/peer/libsub_torrentpeer.la \ - ../../../src/data/libsub_data.la \ - ../../../src/dht/libsub_dht.la \ - ../../../src/net/libsub_net.la \ - ../../../src/protocol/libsub_protocol.la \ - ../../../src/download/libsub_download.la \ - ../../../src/tracker/libsub_tracker.la \ - ../../../src/utils/libsub_utils.la \ - ../../../src/torrent/utils/libsub_torrentutils.la - -LibTorrentTestTorrentNet_SOURCES = \ - ../../helpers/expect_fd.h \ - ../../helpers/expect_utils.h \ - ../../helpers/mock_compare.h \ - ../../helpers/mock_function.cc \ - ../../helpers/mock_function.h \ - ../../helpers/network.h \ - ../../helpers/progress_listener.cc \ - ../../helpers/progress_listener.h \ - ../../helpers/test_fixture.cc \ - ../../helpers/test_fixture.h \ - \ - test_address_info.cc \ - test_address_info.h \ - test_fd.cc \ - test_fd.h \ - test_socket_address.cc \ - test_socket_address.h \ - \ - ../../main.cc - -LibTorrentTestTorrentNet_CXXFLAGS = $(CPPUNIT_CFLAGS) -LibTorrentTestTorrentNet_LDFLAGS = $(CPPUNIT_LIBS) -ldl - -AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/test diff --git a/test/torrent/tracker_controller_features.cc b/test/torrent/tracker_controller_features.cc index 2651c13c5..65f9ae324 100644 --- a/test/torrent/tracker_controller_features.cc +++ b/test/torrent/tracker_controller_features.cc @@ -46,7 +46,7 @@ tracker_controller_features::test_requesting_basic() { CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, 30)); TEST_MULTI3_IS_BUSY("00000", "00000"); - CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->min_interval() - 30)); + CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->state().min_interval() - 30)); TEST_MULTI3_IS_BUSY("10111", "10111"); CPPUNIT_ASSERT(tracker_0_0->trigger_success()); @@ -109,7 +109,7 @@ tracker_controller_features::test_promiscious_timeout() { CPPUNIT_ASSERT(!tracker_controller.task_timeout()->is_queued()); CPPUNIT_ASSERT(tracker_3_0->trigger_success()); - CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->normal_interval())); + CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->state().normal_interval())); TEST_MULTIPLE_END(4, 0); } @@ -157,24 +157,24 @@ tracker_controller_features::test_scrape_basic() { tracker_0_1->set_can_scrape(); tracker_0_2->set_can_scrape(); tracker_2_0->set_can_scrape(); - + tracker_controller.scrape_request(0); TEST_GROUP_IS_BUSY("000000", "000000"); CPPUNIT_ASSERT(!tracker_controller.task_timeout()->is_queued()); CPPUNIT_ASSERT(tracker_controller.task_scrape()->is_queued()); - CPPUNIT_ASSERT(tracker_0_1->latest_event() == torrent::Tracker::EVENT_NONE); - CPPUNIT_ASSERT(tracker_0_2->latest_event() == torrent::Tracker::EVENT_NONE); - CPPUNIT_ASSERT(tracker_2_0->latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_0_1->state().latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_0_2->state().latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_2_0->state().latest_event() == torrent::Tracker::EVENT_NONE); TEST_GOTO_NEXT_SCRAPE(0); TEST_GROUP_IS_BUSY("010001", "010001"); CPPUNIT_ASSERT(!tracker_controller.task_timeout()->is_queued()); CPPUNIT_ASSERT(!tracker_controller.task_scrape()->is_queued()); - CPPUNIT_ASSERT(tracker_0_1->latest_event() == torrent::Tracker::EVENT_SCRAPE); - CPPUNIT_ASSERT(tracker_0_2->latest_event() == torrent::Tracker::EVENT_NONE); - CPPUNIT_ASSERT(tracker_2_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_0_1->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_0_2->state().latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_2_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); CPPUNIT_ASSERT(tracker_0_1->trigger_scrape()); CPPUNIT_ASSERT(tracker_2_0->trigger_scrape()); @@ -183,9 +183,9 @@ tracker_controller_features::test_scrape_basic() { CPPUNIT_ASSERT(!tracker_controller.task_timeout()->is_queued()); CPPUNIT_ASSERT(!tracker_controller.task_scrape()->is_queued()); - CPPUNIT_ASSERT(tracker_0_1->scrape_time_last() != 0); - CPPUNIT_ASSERT(tracker_0_2->scrape_time_last() == 0); - CPPUNIT_ASSERT(tracker_2_0->scrape_time_last() != 0); + CPPUNIT_ASSERT(tracker_0_1->state().scrape_time_last() != 0); + CPPUNIT_ASSERT(tracker_0_2->state().scrape_time_last() == 0); + CPPUNIT_ASSERT(tracker_2_0->state().scrape_time_last() != 0); TEST_MULTIPLE_END(0, 0); } @@ -201,13 +201,13 @@ tracker_controller_features::test_scrape_priority() { TEST_GOTO_NEXT_SCRAPE(0); CPPUNIT_ASSERT(tracker_0_0->is_busy()); - CPPUNIT_ASSERT(tracker_0_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_0_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); // Check the other event types too? tracker_controller.send_update_event(); CPPUNIT_ASSERT(tracker_0_0->is_busy()); - CPPUNIT_ASSERT(tracker_0_0->latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_0_0->state().latest_event() == torrent::Tracker::EVENT_NONE); CPPUNIT_ASSERT(tracker_controller.task_timeout()->is_queued()); CPPUNIT_ASSERT(!tracker_controller.task_scrape()->is_queued()); @@ -223,12 +223,12 @@ tracker_controller_features::test_scrape_priority() { TEST_GOTO_NEXT_SCRAPE(0); CPPUNIT_ASSERT(tracker_0_0->is_busy()); - CPPUNIT_ASSERT(tracker_0_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_0_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, 1)); CPPUNIT_ASSERT(tracker_0_0->is_busy()); - CPPUNIT_ASSERT(tracker_0_0->latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_0_0->state().latest_event() == torrent::Tracker::EVENT_NONE); TEST_SINGLE_END(2, 0); } @@ -256,7 +256,7 @@ tracker_controller_features::test_groups_requesting() { // Next timeout should be soon... CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, 30)); TEST_GROUP_IS_BUSY("000000", "000000"); - CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->min_interval() - 30)); + CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->state().min_interval() - 30)); TEST_GROUP_IS_BUSY("100101", "100101"); CPPUNIT_ASSERT(tracker_0_0->trigger_success()); @@ -285,17 +285,17 @@ tracker_controller_features::test_groups_scrape() { tracker_2_0->set_can_scrape(); CPPUNIT_ASSERT(!tracker_controller.task_scrape()->is_queued()); - + tracker_controller.scrape_request(0); TEST_GROUP_IS_BUSY("000000", "000000"); TEST_GOTO_NEXT_SCRAPE(0); - CPPUNIT_ASSERT(tracker_0_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); - CPPUNIT_ASSERT(tracker_0_1->latest_event() == torrent::Tracker::EVENT_NONE); - CPPUNIT_ASSERT(tracker_0_2->latest_event() == torrent::Tracker::EVENT_NONE); - CPPUNIT_ASSERT(tracker_1_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); - CPPUNIT_ASSERT(tracker_1_1->latest_event() == torrent::Tracker::EVENT_NONE); - CPPUNIT_ASSERT(tracker_2_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_0_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_0_1->state().latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_0_2->state().latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_1_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_1_1->state().latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_2_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); TEST_GROUP_IS_BUSY("100101", "100101"); CPPUNIT_ASSERT(tracker_0_0->trigger_scrape()); diff --git a/test/torrent/tracker_controller_test.cc b/test/torrent/tracker_controller_test.cc index 4d0067f45..f0f1cee38 100644 --- a/test/torrent/tracker_controller_test.cc +++ b/test/torrent/tracker_controller_test.cc @@ -247,7 +247,7 @@ tracker_controller_test::test_send_update_normal() { CPPUNIT_ASSERT((tracker_controller.flags() & torrent::TrackerController::mask_send) == torrent::TrackerController::flag_send_update); CPPUNIT_ASSERT(tracker_controller.task_timeout()->is_queued()); - CPPUNIT_ASSERT(tracker_0_0->latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_0_0->state().latest_event() == torrent::Tracker::EVENT_NONE); CPPUNIT_ASSERT(tracker_0_0->trigger_success()); @@ -305,18 +305,18 @@ tracker_controller_test::test_multiple_success() { CPPUNIT_ASSERT(tracker_0_0->trigger_success()); - CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->normal_interval())); + CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->state().normal_interval())); TEST_MULTI3_IS_BUSY("10000", "10000"); CPPUNIT_ASSERT(tracker_0_0->trigger_success()); - - CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->normal_interval())); + + CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_0->state().normal_interval())); TEST_MULTI3_IS_BUSY("10000", "10000"); CPPUNIT_ASSERT(tracker_0_0->trigger_success()); CPPUNIT_ASSERT(!tracker_list.has_active()); - CPPUNIT_ASSERT(tracker_0_0->success_counter() == 3); + CPPUNIT_ASSERT(tracker_0_0->state().success_counter() == 3); TEST_MULTIPLE_END(3, 0); } @@ -328,13 +328,13 @@ tracker_controller_test::test_multiple_failure() { CPPUNIT_ASSERT(tracker_0_0->trigger_failure()); CPPUNIT_ASSERT(!tracker_controller.is_failure_mode()); - + TEST_MULTI3_IS_BUSY("01000", "01000"); CPPUNIT_ASSERT(tracker_0_1->trigger_failure()); TEST_MULTI3_IS_BUSY("00100", "00100"); CPPUNIT_ASSERT(tracker_1_0->trigger_success()); - CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_1_0->normal_interval())); + CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_1_0->state().normal_interval())); TEST_MULTI3_IS_BUSY("10000", "10000"); CPPUNIT_ASSERT(tracker_0_0->trigger_failure()); TEST_MULTI3_IS_BUSY("01000", "01000"); @@ -365,7 +365,7 @@ tracker_controller_test::test_multiple_failure() { CPPUNIT_ASSERT(tracker_1_0->trigger_success()); CPPUNIT_ASSERT(!tracker_controller.is_failure_mode()); - // CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_list[0]->normal_interval())); + // CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_list[0]->state().normal_interval())); // TEST_MULTI3_IS_BUSY("01000", "10000"); // CPPUNIT_ASSERT(tracker_0_1->trigger_success()); @@ -382,8 +382,8 @@ tracker_controller_test::test_multiple_cycle() { CPPUNIT_ASSERT(tracker_0_1->trigger_success()); CPPUNIT_ASSERT(tracker_list.front() == tracker_0_1); - CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_1->normal_interval())); - + CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, tracker_0_1->state().normal_interval())); + TEST_MULTI3_IS_BUSY("01000", "10000"); CPPUNIT_ASSERT(tracker_0_1->trigger_success()); @@ -541,13 +541,13 @@ tracker_controller_test::test_new_peers() { tracker_list.send_state_idx(0, torrent::Tracker::EVENT_NONE); CPPUNIT_ASSERT(tracker_0->trigger_success(10)); - CPPUNIT_ASSERT(tracker_0->latest_new_peers() == 10); + CPPUNIT_ASSERT(tracker_0->state().latest_new_peers() == 10); tracker_controller.enable(); CPPUNIT_ASSERT(test_goto_next_timeout(&tracker_controller, 0)); CPPUNIT_ASSERT(tracker_0->trigger_success(20)); - CPPUNIT_ASSERT(tracker_0->latest_new_peers() == 20); + CPPUNIT_ASSERT(tracker_0->state().latest_new_peers() == 20); } // Add new function for finding the first tracker that will time out, diff --git a/test/torrent/tracker_list_features_test.cc b/test/torrent/tracker_list_features_test.cc index 5257b1a76..83c8797fa 100644 --- a/test/torrent/tracker_list_features_test.cc +++ b/test/torrent/tracker_list_features_test.cc @@ -26,23 +26,23 @@ void tracker_list_features_test::test_new_peers() { TRACKER_SETUP(); TRACKER_INSERT(0, tracker_0); - - CPPUNIT_ASSERT(tracker_0->latest_new_peers() == 0); - CPPUNIT_ASSERT(tracker_0->latest_sum_peers() == 0); + + CPPUNIT_ASSERT(tracker_0->state().latest_new_peers() == 0); + CPPUNIT_ASSERT(tracker_0->state().latest_sum_peers() == 0); tracker_list.send_state_idx(0, torrent::Tracker::EVENT_NONE); CPPUNIT_ASSERT(tracker_0->trigger_success(10, 20)); - CPPUNIT_ASSERT(tracker_0->latest_new_peers() == 10); - CPPUNIT_ASSERT(tracker_0->latest_sum_peers() == 20); + CPPUNIT_ASSERT(tracker_0->state().latest_new_peers() == 10); + CPPUNIT_ASSERT(tracker_0->state().latest_sum_peers() == 20); tracker_list.send_state_idx(0, torrent::Tracker::EVENT_NONE); CPPUNIT_ASSERT(tracker_0->trigger_failure()); - CPPUNIT_ASSERT(tracker_0->latest_new_peers() == 10); - CPPUNIT_ASSERT(tracker_0->latest_sum_peers() == 20); + CPPUNIT_ASSERT(tracker_0->state().latest_new_peers() == 10); + CPPUNIT_ASSERT(tracker_0->state().latest_sum_peers() == 20); tracker_list.clear_stats(); - CPPUNIT_ASSERT(tracker_0->latest_new_peers() == 0); - CPPUNIT_ASSERT(tracker_0->latest_sum_peers() == 0); + CPPUNIT_ASSERT(tracker_0->state().latest_new_peers() == 0); + CPPUNIT_ASSERT(tracker_0->state().latest_sum_peers() == 0); } // test last_connect timer. @@ -101,7 +101,7 @@ tracker_list_features_test::test_find_next_to_request() { tracker_0->enable(); tracker_0->set_failed(1, torrent::cachedTime.seconds() - 0); CPPUNIT_ASSERT(tracker_list.find_next_to_request(tracker_list.begin()) == tracker_list.begin() + 1); - + tracker_1->set_failed(1, torrent::cachedTime.seconds() - 0); tracker_2->set_failed(1, torrent::cachedTime.seconds() - 0); CPPUNIT_ASSERT(tracker_list.find_next_to_request(tracker_list.begin()) == tracker_list.begin() + 3); @@ -118,7 +118,7 @@ tracker_list_features_test::test_find_next_to_request() { tracker_1->set_failed(0, torrent::cachedTime.seconds() - 1); tracker_1->set_success(1, torrent::cachedTime.seconds() - 1); CPPUNIT_ASSERT(tracker_list.find_next_to_request(tracker_list.begin()) == tracker_list.begin() + 0); - tracker_1->set_success(1, torrent::cachedTime.seconds() - (tracker_1->normal_interval() - 1)); + tracker_1->set_success(1, torrent::cachedTime.seconds() - (tracker_1->state().normal_interval() - 1)); CPPUNIT_ASSERT(tracker_list.find_next_to_request(tracker_list.begin()) == tracker_list.begin() + 1); } @@ -203,41 +203,41 @@ tracker_list_features_test::test_request_safeguard() { for (unsigned int i = 0; i < 9; i++) { CPPUNIT_ASSERT(verify_did_internal_error(std::bind(&torrent::TrackerList::send_state, &tracker_list, tracker_1, 1), false)); CPPUNIT_ASSERT(tracker_1->trigger_success()); - CPPUNIT_ASSERT(tracker_1->success_counter() == (i + 1)); + CPPUNIT_ASSERT(tracker_1->state().success_counter() == (i + 1)); } CPPUNIT_ASSERT(verify_did_internal_error(std::bind(&torrent::TrackerList::send_state, &tracker_list, tracker_1, 1), true)); CPPUNIT_ASSERT(tracker_1->trigger_success()); - + torrent::cachedTime += rak::timer::from_seconds(1000); for (unsigned int i = 0; i < 9; i++) { CPPUNIT_ASSERT(verify_did_internal_error(std::bind(&torrent::TrackerList::send_state, &tracker_list, tracker_foo, 1), false)); CPPUNIT_ASSERT(tracker_foo->trigger_success()); - CPPUNIT_ASSERT(tracker_foo->success_counter() == (i + 1)); + CPPUNIT_ASSERT(tracker_foo->state().success_counter() == (i + 1)); CPPUNIT_ASSERT(tracker_foo->is_usable()); } CPPUNIT_ASSERT(verify_did_internal_error(std::bind(&torrent::TrackerList::send_state, &tracker_list, tracker_foo, 1), true)); CPPUNIT_ASSERT(tracker_foo->trigger_success()); - + for (unsigned int i = 0; i < 40; i++) { CPPUNIT_ASSERT(verify_did_internal_error(std::bind(&torrent::TrackerList::send_state, &tracker_list, tracker_2, 1), false)); CPPUNIT_ASSERT(tracker_2->trigger_success()); - CPPUNIT_ASSERT(tracker_2->success_counter() == (i + 1)); + CPPUNIT_ASSERT(tracker_2->state().success_counter() == (i + 1)); torrent::cachedTime += rak::timer::from_seconds(1); } - + for (unsigned int i = 0; i < 17; i++) { CPPUNIT_ASSERT(verify_did_internal_error(std::bind(&torrent::TrackerList::send_state, &tracker_list, tracker_3, 1), false)); CPPUNIT_ASSERT(tracker_3->trigger_success()); - CPPUNIT_ASSERT(tracker_3->success_counter() == (i + 1)); + CPPUNIT_ASSERT(tracker_3->state().success_counter() == (i + 1)); if (i % 2) torrent::cachedTime += rak::timer::from_seconds(1); } - + CPPUNIT_ASSERT(verify_did_internal_error(std::bind(&torrent::TrackerList::send_state, &tracker_list, tracker_3, 1), true)); CPPUNIT_ASSERT(tracker_3->trigger_success()); } diff --git a/test/torrent/tracker_list_test.cc b/test/torrent/tracker_list_test.cc index c4708eeb3..1645041d7 100644 --- a/test/torrent/tracker_list_test.cc +++ b/test/torrent/tracker_list_test.cc @@ -22,6 +22,70 @@ class http_get : public torrent::Http { torrent::Http* http_factory() { return new http_get; } +void +TrackerTest::set_success(uint32_t counter, uint32_t time_last) { + auto tracker_state = state(); + tracker_state.m_success_counter = counter; + tracker_state.m_success_time_last = time_last; + tracker_state.set_normal_interval(default_normal_interval); + tracker_state.set_min_interval(default_min_interval); + set_state(tracker_state); +} + +void +TrackerTest::set_failed(uint32_t counter, uint32_t time_last) { + auto tracker_state = state(); + tracker_state.m_failed_counter = counter; + tracker_state.m_failed_time_last = time_last; + tracker_state.m_normal_interval = 0; + tracker_state.m_min_interval = 0; + set_state(tracker_state); +} + +void +TrackerTest::set_latest_new_peers(uint32_t peers) { + auto tracker_state = state(); + tracker_state.m_latest_new_peers = peers; + set_state(tracker_state); +} + +void +TrackerTest::set_latest_sum_peers(uint32_t peers) { + auto tracker_state = state(); + tracker_state.m_latest_sum_peers = peers; + set_state(tracker_state); +} + +void +TrackerTest::set_new_normal_interval(uint32_t timeout) { + auto tracker_state = state(); + tracker_state.set_normal_interval(timeout); + set_state(tracker_state); +} + +void +TrackerTest::set_new_min_interval(uint32_t timeout) { + auto tracker_state = state(); + tracker_state.set_min_interval(timeout); + set_state(tracker_state); +} + +void +TrackerTest::send_state(int state) { + m_busy = true; + m_open = true; + m_requesting_state = state; + set_latest_event(state); +} + +void +TrackerTest::send_scrape() { + m_busy = true; + m_open = true; + m_requesting_state = torrent::Tracker::EVENT_SCRAPE; + set_latest_event(torrent::Tracker::EVENT_SCRAPE); +} + bool TrackerTest::trigger_success(uint32_t new_peers, uint32_t sum_peers) { torrent::TrackerList::address_list address_list; @@ -43,11 +107,14 @@ TrackerTest::trigger_success(torrent::TrackerList::address_list* address_list, u m_open = !(m_flags & flag_close_on_done); return_new_peers = new_peers; - if (m_latest_event == EVENT_SCRAPE) { + if (state().latest_event() == EVENT_SCRAPE) { parent()->receive_scrape_success(this); } else { - set_normal_interval(default_normal_interval); - set_min_interval(default_min_interval); + auto tracker_state = state(); + tracker_state.set_normal_interval(default_normal_interval); + tracker_state.set_min_interval(default_min_interval); + set_state(tracker_state); + parent()->receive_success(this, address_list); } @@ -64,11 +131,14 @@ TrackerTest::trigger_failure() { m_open = !(m_flags & flag_close_on_done); return_new_peers = 0; - if (m_latest_event == EVENT_SCRAPE) { + if (state().latest_event() == EVENT_SCRAPE) { parent()->receive_scrape_failed(this, "failed"); } else { - set_normal_interval(0); - set_min_interval(0); + auto tracker_state = state(); + tracker_state.set_normal_interval(0); + tracker_state.set_min_interval(0); + set_state(tracker_state); + parent()->receive_failed(this, "failed"); } @@ -81,7 +151,7 @@ TrackerTest::trigger_scrape() { if (parent() == NULL || !is_busy() || !is_open()) return false; - if (m_latest_event != EVENT_SCRAPE) + if (state().latest_event() != EVENT_SCRAPE) return false; return trigger_success(); @@ -253,7 +323,7 @@ tracker_list_test::test_single_success() { CPPUNIT_ASSERT(!tracker_0->is_busy_not_scrape()); CPPUNIT_ASSERT(!tracker_0->is_open()); CPPUNIT_ASSERT(tracker_0->requesting_state() == -1); - CPPUNIT_ASSERT(tracker_0->latest_event() == torrent::Tracker::EVENT_NONE); + CPPUNIT_ASSERT(tracker_0->state().latest_event() == torrent::Tracker::EVENT_NONE); tracker_list.send_state_idx(0, torrent::Tracker::EVENT_STARTED); @@ -261,7 +331,7 @@ tracker_list_test::test_single_success() { CPPUNIT_ASSERT(tracker_0->is_busy_not_scrape()); CPPUNIT_ASSERT(tracker_0->is_open()); CPPUNIT_ASSERT(tracker_0->requesting_state() == torrent::Tracker::EVENT_STARTED); - CPPUNIT_ASSERT(tracker_0->latest_event() == torrent::Tracker::EVENT_STARTED); + CPPUNIT_ASSERT(tracker_0->state().latest_event() == torrent::Tracker::EVENT_STARTED); CPPUNIT_ASSERT(tracker_0->trigger_success()); @@ -269,11 +339,11 @@ tracker_list_test::test_single_success() { CPPUNIT_ASSERT(!tracker_0->is_busy_not_scrape()); CPPUNIT_ASSERT(!tracker_0->is_open()); CPPUNIT_ASSERT(tracker_0->requesting_state() == -1); - CPPUNIT_ASSERT(tracker_0->latest_event() == torrent::Tracker::EVENT_STARTED); - + CPPUNIT_ASSERT(tracker_0->state().latest_event() == torrent::Tracker::EVENT_STARTED); + CPPUNIT_ASSERT(success_counter == 1 && failure_counter == 0); - CPPUNIT_ASSERT(tracker_0->success_counter() == 1); - CPPUNIT_ASSERT(tracker_0->failed_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().success_counter() == 1); + CPPUNIT_ASSERT(tracker_0->state().failed_counter() == 0); } void @@ -289,15 +359,15 @@ tracker_list_test::test_single_failure() { CPPUNIT_ASSERT(tracker_0->requesting_state() == -1); CPPUNIT_ASSERT(success_counter == 0 && failure_counter == 1); - CPPUNIT_ASSERT(tracker_0->success_counter() == 0); - CPPUNIT_ASSERT(tracker_0->failed_counter() == 1); + CPPUNIT_ASSERT(tracker_0->state().success_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().failed_counter() == 1); tracker_list.send_state_idx(0, 1); CPPUNIT_ASSERT(tracker_0->trigger_success()); CPPUNIT_ASSERT(success_counter == 1 && failure_counter == 1); - CPPUNIT_ASSERT(tracker_0->success_counter() == 1); - CPPUNIT_ASSERT(tracker_0->failed_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().success_counter() == 1); + CPPUNIT_ASSERT(tracker_0->state().failed_counter() == 0); } void @@ -320,8 +390,8 @@ tracker_list_test::test_single_closing() { tracker_list.clear_stats(); CPPUNIT_ASSERT(!tracker_0->is_open()); - CPPUNIT_ASSERT(tracker_0->success_counter() == 0); - CPPUNIT_ASSERT(tracker_0->failed_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().success_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().failed_counter() == 0); } void @@ -380,7 +450,7 @@ void tracker_list_test::test_scrape_success() { TRACKER_SETUP(); TRACKER_INSERT(0, tracker_0); - + tracker_0->set_can_scrape(); tracker_list.send_scrape(tracker_0); @@ -388,7 +458,7 @@ tracker_list_test::test_scrape_success() { CPPUNIT_ASSERT(!tracker_0->is_busy_not_scrape()); CPPUNIT_ASSERT(tracker_0->is_open()); CPPUNIT_ASSERT(tracker_0->requesting_state() == torrent::Tracker::EVENT_SCRAPE); - CPPUNIT_ASSERT(tracker_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(tracker_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); CPPUNIT_ASSERT(tracker_0->trigger_scrape()); @@ -396,20 +466,20 @@ tracker_list_test::test_scrape_success() { CPPUNIT_ASSERT(!tracker_0->is_busy_not_scrape()); CPPUNIT_ASSERT(!tracker_0->is_open()); CPPUNIT_ASSERT(tracker_0->requesting_state() == -1); - CPPUNIT_ASSERT(tracker_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); - + CPPUNIT_ASSERT(tracker_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(success_counter == 0 && failure_counter == 0); CPPUNIT_ASSERT(scrape_success_counter == 1 && scrape_failure_counter == 0); - CPPUNIT_ASSERT(tracker_0->success_counter() == 0); - CPPUNIT_ASSERT(tracker_0->failed_counter() == 0); - CPPUNIT_ASSERT(tracker_0->scrape_counter() == 1); + CPPUNIT_ASSERT(tracker_0->state().success_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().failed_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().scrape_counter() == 1); } void tracker_list_test::test_scrape_failure() { TRACKER_SETUP(); TRACKER_INSERT(0, tracker_0); - + tracker_0->set_can_scrape(); tracker_list.send_scrape(tracker_0); @@ -418,13 +488,13 @@ tracker_list_test::test_scrape_failure() { CPPUNIT_ASSERT(!tracker_0->is_busy()); CPPUNIT_ASSERT(!tracker_0->is_open()); CPPUNIT_ASSERT(tracker_0->requesting_state() == -1); - CPPUNIT_ASSERT(tracker_0->latest_event() == torrent::Tracker::EVENT_SCRAPE); - + CPPUNIT_ASSERT(tracker_0->state().latest_event() == torrent::Tracker::EVENT_SCRAPE); + CPPUNIT_ASSERT(success_counter == 0 && failure_counter == 0); CPPUNIT_ASSERT(scrape_success_counter == 0 && scrape_failure_counter == 1); - CPPUNIT_ASSERT(tracker_0->success_counter() == 0); - CPPUNIT_ASSERT(tracker_0->failed_counter() == 0); - CPPUNIT_ASSERT(tracker_0->scrape_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().success_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().failed_counter() == 0); + CPPUNIT_ASSERT(tracker_0->state().scrape_counter() == 0); } bool diff --git a/test/torrent/tracker_list_test.h b/test/torrent/tracker_list_test.h index 12db429dd..a9b6c8f3a 100644 --- a/test/torrent/tracker_list_test.h +++ b/test/torrent/tracker_list_test.h @@ -77,16 +77,16 @@ class TrackerTest : public torrent::Tracker { void set_scrape_on_success(bool state) { if (state) m_flags |= flag_scrape_on_success; else m_flags &= ~flag_scrape_on_success; } void set_can_scrape() { m_flags |= flag_can_scrape; } - void set_success(uint32_t counter, uint32_t time_last) { m_success_counter = counter; m_success_time_last = time_last; set_normal_interval(default_normal_interval); set_min_interval(default_min_interval);} - void set_failed(uint32_t counter, uint32_t time_last) { m_failed_counter = counter; m_failed_time_last = time_last; m_normal_interval = 0; m_min_interval = 0; } - void set_latest_new_peers(uint32_t peers) { m_latest_new_peers = peers; } - void set_latest_sum_peers(uint32_t peers) { m_latest_sum_peers = peers; } + void set_success(uint32_t counter, uint32_t time_last); + void set_failed(uint32_t counter, uint32_t time_last); + void set_latest_new_peers(uint32_t peers); + void set_latest_sum_peers(uint32_t peers); - void set_new_normal_interval(uint32_t timeout) { set_normal_interval(timeout); } - void set_new_min_interval(uint32_t timeout) { set_min_interval(timeout); } + void set_new_normal_interval(uint32_t timeout); + void set_new_min_interval(uint32_t timeout); - virtual void send_state(int state) { m_busy = true; m_open = true; m_requesting_state = m_latest_event = state; } - virtual void send_scrape() { m_busy = true; m_open = true; m_requesting_state = m_latest_event = torrent::Tracker::EVENT_SCRAPE; } + virtual void send_state(int state); + virtual void send_scrape(); virtual void close() { m_busy = false; m_open = false; m_requesting_state = -1; } virtual void disown() { m_busy = false; m_open = false; m_requesting_state = -1; } diff --git a/test/torrent/tracker_timeout_test.cc b/test/torrent/tracker_timeout_test.cc index 59fc76c7c..9dcaeb0cd 100644 --- a/test/torrent/tracker_timeout_test.cc +++ b/test/torrent/tracker_timeout_test.cc @@ -25,17 +25,17 @@ void tracker_timeout_test::test_set_timeout() { TrackerTest tracker(NULL, ""); - CPPUNIT_ASSERT(tracker.normal_interval() == 0); + CPPUNIT_ASSERT(tracker.state().normal_interval() == 0); tracker.set_new_normal_interval(100); - CPPUNIT_ASSERT(tracker.normal_interval() == 600); + CPPUNIT_ASSERT(tracker.state().normal_interval() == 600); tracker.set_new_normal_interval(8 * 4000); - CPPUNIT_ASSERT(tracker.normal_interval() == 8 * 3600); + CPPUNIT_ASSERT(tracker.state().normal_interval() == 8 * 3600); tracker.set_new_min_interval(100); - CPPUNIT_ASSERT_EQUAL((uint32_t)300, tracker.min_interval()); + CPPUNIT_ASSERT_EQUAL((uint32_t)300, tracker.state().min_interval()); tracker.set_new_min_interval(4 * 4000); - CPPUNIT_ASSERT(tracker.min_interval() == 4 * 3600); + CPPUNIT_ASSERT(tracker.state().min_interval() == 4 * 3600); } void