@@ -6,12 +6,15 @@ use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes, PeerId};
66use bittorrent_primitives:: info_hash:: InfoHash ;
77use bittorrent_tracker_core:: announce_handler:: PeersWanted ;
88use bittorrent_tracker_core:: container:: TrackerCoreContainer ;
9- use torrust_tracker_configuration:: Core ;
9+ use tokio:: task:: yield_now;
10+ use torrust_tracker_configuration:: { AnnouncePolicy , Core } ;
1011use torrust_tracker_primitives:: core:: AnnounceData ;
1112use torrust_tracker_primitives:: peer:: Peer ;
13+ use torrust_tracker_primitives:: swarm_metadata:: SwarmMetadata ;
1214use torrust_tracker_primitives:: DurationSinceUnixEpoch ;
1315use torrust_tracker_test_helpers:: configuration:: ephemeral_sqlite_database;
1416use torrust_tracker_torrent_repository:: container:: TorrentRepositoryContainer ;
17+ use torrust_tracker_torrent_repository:: Swarms ;
1518
1619/// # Panics
1720///
@@ -56,52 +59,114 @@ fn remote_client_ip() -> IpAddr {
5659 IpAddr :: V4 ( Ipv4Addr :: from_str ( "126.0.0.1" ) . unwrap ( ) )
5760}
5861
59- fn initialize ( ) -> ( Arc < Core > , Arc < TrackerCoreContainer > , InfoHash , Peer ) {
60- let config = Arc :: new ( ephemeral_configuration ( ) ) ;
61-
62- let torrent_repository_container = Arc :: new ( TorrentRepositoryContainer :: initialize ( config. tracker_usage_statistics . into ( ) ) ) ;
63-
64- let container = Arc :: new ( TrackerCoreContainer :: initialize_from ( & config, & torrent_repository_container) ) ;
62+ async fn initialize_test_env ( core_config : Core ) -> ( Arc < Core > , Arc < TrackerCoreContainer > , Arc < Swarms > , InfoHash , Peer ) {
63+ let config = Arc :: new ( core_config) ;
6564
6665 let info_hash = sample_info_hash ( ) ;
6766
6867 let peer = sample_peer ( ) ;
6968
70- ( config, container, info_hash, peer)
69+ let ( container, swarms) = start ( & config) . await ;
70+
71+ ( config, container, swarms, info_hash, peer)
72+ }
73+
74+ async fn start ( core_config : & Arc < Core > ) -> ( Arc < TrackerCoreContainer > , Arc < Swarms > ) {
75+ let torrent_repository_container = Arc :: new ( TorrentRepositoryContainer :: initialize (
76+ core_config. tracker_usage_statistics . into ( ) ,
77+ ) ) ;
78+
79+ let container = Arc :: new ( TrackerCoreContainer :: initialize_from (
80+ core_config,
81+ & torrent_repository_container,
82+ ) ) ;
83+
84+ let mut jobs = vec ! [ ] ;
85+
86+ let job = torrust_tracker_torrent_repository:: statistics:: event:: listener:: run_event_listener (
87+ torrent_repository_container. event_bus . receiver ( ) ,
88+ & torrent_repository_container. stats_repository ,
89+ ) ;
90+
91+ jobs. push ( job) ;
92+
93+ let job = bittorrent_tracker_core:: statistics:: event:: listener:: run_event_listener (
94+ torrent_repository_container. event_bus . receiver ( ) ,
95+ & container. db_torrent_repository ,
96+ ) ;
97+
98+ jobs. push ( job) ;
99+
100+ // Give the event listeners some time to start
101+ // todo: they should notify when they are ready
102+ tokio:: time:: sleep ( std:: time:: Duration :: from_millis ( 100 ) ) . await ;
103+
104+ ( container, torrent_repository_container. swarms . clone ( ) )
71105}
72106
73107async fn announce_peer_started ( container : & Arc < TrackerCoreContainer > , peer : & mut Peer , info_hash : & InfoHash ) -> AnnounceData {
74108 peer. event = AnnounceEvent :: Started ;
75109
76- container
110+ let announce_data = container
77111 . announce_handler
78112 . announce ( info_hash, peer, & remote_client_ip ( ) , & PeersWanted :: AsManyAsPossible )
79113 . await
80- . unwrap ( )
114+ . unwrap ( ) ;
115+
116+ // Give time to the event listeners to process the event
117+ yield_now ( ) . await ;
118+
119+ announce_data
81120}
82121
83- async fn _announce_peer_completed ( container : & Arc < TrackerCoreContainer > , peer : & mut Peer , info_hash : & InfoHash ) -> AnnounceData {
122+ async fn announce_peer_completed ( container : & Arc < TrackerCoreContainer > , peer : & mut Peer , info_hash : & InfoHash ) -> AnnounceData {
84123 peer. event = AnnounceEvent :: Completed ;
85124
86- container
125+ let announce_data = container
87126 . announce_handler
88127 . announce ( info_hash, peer, & remote_client_ip ( ) , & PeersWanted :: AsManyAsPossible )
89128 . await
90- . unwrap ( )
129+ . unwrap ( ) ;
130+
131+ // Give time to the event listeners to process the event
132+ yield_now ( ) . await ;
133+
134+ announce_data
135+ }
136+
137+ async fn increase_number_of_downloads ( container : & Arc < TrackerCoreContainer > , peer : & mut Peer , info_hash : & InfoHash ) {
138+ let _announce_data = announce_peer_started ( container, peer, info_hash) . await ;
139+ let announce_data = announce_peer_completed ( container, peer, info_hash) . await ;
140+
141+ assert_eq ! ( announce_data. stats. downloads( ) , 1 ) ;
91142}
92143
93144#[ tokio:: test]
94145async fn it_should_handle_the_announce_request ( ) {
95- let ( _config, container, info_hash, mut peer) = initialize ( ) ;
146+ let ( _config, container, _swarms , info_hash, mut peer) = initialize_test_env ( ephemeral_configuration ( ) ) . await ;
96147
97148 let announce_data = announce_peer_started ( & container, & mut peer, & info_hash) . await ;
98149
99- assert_eq ! ( announce_data, AnnounceData :: default ( ) ) ;
150+ assert_eq ! (
151+ announce_data,
152+ AnnounceData {
153+ peers: vec![ ] ,
154+ stats: SwarmMetadata {
155+ downloaded: 0 ,
156+ complete: 1 ,
157+ incomplete: 0
158+ } ,
159+ policy: AnnouncePolicy {
160+ interval: 120 ,
161+ interval_min: 120
162+ }
163+ }
164+ ) ;
100165}
101166
102167#[ tokio:: test]
103168async fn it_should_not_return_the_peer_making_the_announce_request ( ) {
104- let ( _config, container, info_hash, mut peer) = initialize ( ) ;
169+ let ( _config, container, _swarms , info_hash, mut peer) = initialize_test_env ( ephemeral_configuration ( ) ) . await ;
105170
106171 let announce_data = announce_peer_started ( & container, & mut peer, & info_hash) . await ;
107172
@@ -110,11 +175,33 @@ async fn it_should_not_return_the_peer_making_the_announce_request() {
110175
111176#[ tokio:: test]
112177async fn it_should_handle_the_scrape_request ( ) {
113- let ( _config, container, info_hash, mut peer) = initialize ( ) ;
178+ let ( _config, container, _swarms , info_hash, mut peer) = initialize_test_env ( ephemeral_configuration ( ) ) . await ;
114179
115180 let _announce_data = announce_peer_started ( & container, & mut peer, & info_hash) . await ;
116181
117182 let scrape_data = container. scrape_handler . scrape ( & vec ! [ info_hash] ) . await . unwrap ( ) ;
118183
119184 assert ! ( scrape_data. files. contains_key( & info_hash) ) ;
120185}
186+
187+ #[ tokio:: test]
188+ async fn it_should_persist_the_number_of_completed_peers_for_all_torrents_into_the_database ( ) {
189+ let mut core_config = ephemeral_configuration ( ) ;
190+ core_config. tracker_policy . persistent_torrent_completed_stat = true ;
191+
192+ let ( _config, container, swarms, info_hash, mut peer) = initialize_test_env ( core_config) . await ;
193+
194+ increase_number_of_downloads ( & container, & mut peer, & info_hash) . await ;
195+
196+ assert ! ( swarms. get_swarm_metadata( & info_hash) . await . unwrap( ) . unwrap( ) . downloads( ) == 1 ) ;
197+
198+ swarms. remove ( & info_hash) . await . unwrap ( ) ;
199+
200+ // Make sure the swarm metadata is removed
201+ assert ! ( swarms. get_swarm_metadata( & info_hash) . await . unwrap( ) . is_none( ) ) ;
202+
203+ // Load torrents from the database to ensure the completed stats are persisted
204+ container. torrents_manager . load_torrents_from_database ( ) . unwrap ( ) ;
205+
206+ assert ! ( swarms. get_swarm_metadata( & info_hash) . await . unwrap( ) . unwrap( ) . downloads( ) == 1 ) ;
207+ }
0 commit comments