@@ -103,302 +103,3 @@ impl Entry for EntrySingle {
103
103
. retain ( |_, peer| peer:: ReadInfo :: get_updated ( peer) > current_cutoff) ;
104
104
}
105
105
}
106
-
107
- #[ cfg( test) ]
108
- mod tests {
109
- mod torrent_entry {
110
-
111
- use std:: net:: { IpAddr , Ipv4Addr , SocketAddr } ;
112
- use std:: ops:: Sub ;
113
- use std:: sync:: Arc ;
114
- use std:: time:: Duration ;
115
-
116
- use torrust_tracker_clock:: clock:: stopped:: Stopped as _;
117
- use torrust_tracker_clock:: clock:: { self , Time } ;
118
- use torrust_tracker_configuration:: TORRENT_PEERS_LIMIT ;
119
- use torrust_tracker_primitives:: announce_event:: AnnounceEvent ;
120
- use torrust_tracker_primitives:: { peer, DurationSinceUnixEpoch , NumberOfBytes } ;
121
-
122
- use crate :: entry:: Entry ;
123
- use crate :: { CurrentClock , EntrySingle } ;
124
-
125
- struct TorrentPeerBuilder {
126
- peer : peer:: Peer ,
127
- }
128
-
129
- impl TorrentPeerBuilder {
130
- pub fn default ( ) -> TorrentPeerBuilder {
131
- let default_peer = peer:: Peer {
132
- peer_id : peer:: Id ( [ 0u8 ; 20 ] ) ,
133
- peer_addr : SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8080 ) ,
134
- updated : CurrentClock :: now ( ) ,
135
- uploaded : NumberOfBytes ( 0 ) ,
136
- downloaded : NumberOfBytes ( 0 ) ,
137
- left : NumberOfBytes ( 0 ) ,
138
- event : AnnounceEvent :: Started ,
139
- } ;
140
- TorrentPeerBuilder { peer : default_peer }
141
- }
142
-
143
- pub fn with_event_completed ( mut self ) -> Self {
144
- self . peer . event = AnnounceEvent :: Completed ;
145
- self
146
- }
147
-
148
- pub fn with_peer_address ( mut self , peer_addr : SocketAddr ) -> Self {
149
- self . peer . peer_addr = peer_addr;
150
- self
151
- }
152
-
153
- pub fn with_peer_id ( mut self , peer_id : peer:: Id ) -> Self {
154
- self . peer . peer_id = peer_id;
155
- self
156
- }
157
-
158
- pub fn with_number_of_bytes_left ( mut self , left : i64 ) -> Self {
159
- self . peer . left = NumberOfBytes ( left) ;
160
- self
161
- }
162
-
163
- pub fn updated_at ( mut self , updated : DurationSinceUnixEpoch ) -> Self {
164
- self . peer . updated = updated;
165
- self
166
- }
167
-
168
- pub fn into ( self ) -> peer:: Peer {
169
- self . peer
170
- }
171
- }
172
-
173
- /// A torrent seeder is a peer with 0 bytes left to download which
174
- /// has not announced it has stopped
175
- fn a_torrent_seeder ( ) -> peer:: Peer {
176
- TorrentPeerBuilder :: default ( )
177
- . with_number_of_bytes_left ( 0 )
178
- . with_event_completed ( )
179
- . into ( )
180
- }
181
-
182
- /// A torrent leecher is a peer that is not a seeder.
183
- /// Leecher: left > 0 OR event = Stopped
184
- fn a_torrent_leecher ( ) -> peer:: Peer {
185
- TorrentPeerBuilder :: default ( )
186
- . with_number_of_bytes_left ( 1 )
187
- . with_event_completed ( )
188
- . into ( )
189
- }
190
-
191
- #[ test]
192
- fn the_default_torrent_entry_should_contain_an_empty_list_of_peers ( ) {
193
- let torrent_entry = EntrySingle :: default ( ) ;
194
-
195
- assert_eq ! ( torrent_entry. get_peers( None ) . len( ) , 0 ) ;
196
- }
197
-
198
- #[ test]
199
- fn a_new_peer_can_be_added_to_a_torrent_entry ( ) {
200
- let mut torrent_entry = EntrySingle :: default ( ) ;
201
- let torrent_peer = TorrentPeerBuilder :: default ( ) . into ( ) ;
202
-
203
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Add the peer
204
-
205
- assert_eq ! ( * torrent_entry. get_peers( None ) [ 0 ] , torrent_peer) ;
206
- assert_eq ! ( torrent_entry. get_peers( None ) . len( ) , 1 ) ;
207
- }
208
-
209
- #[ test]
210
- fn a_torrent_entry_should_contain_the_list_of_peers_that_were_added_to_the_torrent ( ) {
211
- let mut torrent_entry = EntrySingle :: default ( ) ;
212
- let torrent_peer = TorrentPeerBuilder :: default ( ) . into ( ) ;
213
-
214
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Add the peer
215
-
216
- assert_eq ! ( torrent_entry. get_peers( None ) , vec![ Arc :: new( torrent_peer) ] ) ;
217
- }
218
-
219
- #[ test]
220
- fn a_peer_can_be_updated_in_a_torrent_entry ( ) {
221
- let mut torrent_entry = EntrySingle :: default ( ) ;
222
- let mut torrent_peer = TorrentPeerBuilder :: default ( ) . into ( ) ;
223
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Add the peer
224
-
225
- torrent_peer. event = AnnounceEvent :: Completed ; // Update the peer
226
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Update the peer in the torrent entry
227
-
228
- assert_eq ! ( torrent_entry. get_peers( None ) [ 0 ] . event, AnnounceEvent :: Completed ) ;
229
- }
230
-
231
- #[ test]
232
- fn a_peer_should_be_removed_from_a_torrent_entry_when_the_peer_announces_it_has_stopped ( ) {
233
- let mut torrent_entry = EntrySingle :: default ( ) ;
234
- let mut torrent_peer = TorrentPeerBuilder :: default ( ) . into ( ) ;
235
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Add the peer
236
-
237
- torrent_peer. event = AnnounceEvent :: Stopped ; // Update the peer
238
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Update the peer in the torrent entry
239
-
240
- assert_eq ! ( torrent_entry. get_peers( None ) . len( ) , 0 ) ;
241
- }
242
-
243
- #[ test]
244
- fn torrent_stats_change_when_a_previously_known_peer_announces_it_has_completed_the_torrent ( ) {
245
- let mut torrent_entry = EntrySingle :: default ( ) ;
246
- let mut torrent_peer = TorrentPeerBuilder :: default ( ) . into ( ) ;
247
-
248
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Add the peer
249
-
250
- torrent_peer. event = AnnounceEvent :: Completed ; // Update the peer
251
- let stats_have_changed = torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Update the peer in the torrent entry
252
-
253
- assert ! ( stats_have_changed) ;
254
- }
255
-
256
- #[ test]
257
- fn torrent_stats_should_not_change_when_a_peer_announces_it_has_completed_the_torrent_if_it_is_the_first_announce_from_the_peer (
258
- ) {
259
- let mut torrent_entry = EntrySingle :: default ( ) ;
260
- let torrent_peer_announcing_complete_event = TorrentPeerBuilder :: default ( ) . with_event_completed ( ) . into ( ) ;
261
-
262
- // Add a peer that did not exist before in the entry
263
- let torrent_stats_have_not_changed = !torrent_entry. insert_or_update_peer ( & torrent_peer_announcing_complete_event) ;
264
-
265
- assert ! ( torrent_stats_have_not_changed) ;
266
- }
267
-
268
- #[ test]
269
- fn a_torrent_entry_should_return_the_list_of_peers_for_a_given_peer_filtering_out_the_client_that_is_making_the_request ( )
270
- {
271
- let mut torrent_entry = EntrySingle :: default ( ) ;
272
- let peer_socket_address = SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) , 8080 ) ;
273
- let torrent_peer = TorrentPeerBuilder :: default ( ) . with_peer_address ( peer_socket_address) . into ( ) ;
274
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Add peer
275
-
276
- // Get peers excluding the one we have just added
277
- let peers = torrent_entry. get_peers_for_peer ( & torrent_peer, None ) ;
278
-
279
- assert_eq ! ( peers. len( ) , 0 ) ;
280
- }
281
-
282
- #[ test]
283
- fn two_peers_with_the_same_ip_but_different_port_should_be_considered_different_peers ( ) {
284
- let mut torrent_entry = EntrySingle :: default ( ) ;
285
-
286
- let peer_ip = IpAddr :: V4 ( Ipv4Addr :: new ( 127 , 0 , 0 , 1 ) ) ;
287
-
288
- // Add peer 1
289
- let torrent_peer_1 = TorrentPeerBuilder :: default ( )
290
- . with_peer_address ( SocketAddr :: new ( peer_ip, 8080 ) )
291
- . into ( ) ;
292
- torrent_entry. insert_or_update_peer ( & torrent_peer_1) ;
293
-
294
- // Add peer 2
295
- let torrent_peer_2 = TorrentPeerBuilder :: default ( )
296
- . with_peer_address ( SocketAddr :: new ( peer_ip, 8081 ) )
297
- . into ( ) ;
298
- torrent_entry. insert_or_update_peer ( & torrent_peer_2) ;
299
-
300
- // Get peers for peer 1
301
- let peers = torrent_entry. get_peers_for_peer ( & torrent_peer_1, None ) ;
302
-
303
- // The peer 2 using the same IP but different port should be included
304
- assert_eq ! ( peers[ 0 ] . peer_addr. ip( ) , Ipv4Addr :: new( 127 , 0 , 0 , 1 ) ) ;
305
- assert_eq ! ( peers[ 0 ] . peer_addr. port( ) , 8081 ) ;
306
- }
307
-
308
- fn peer_id_from_i32 ( number : i32 ) -> peer:: Id {
309
- let peer_id = number. to_le_bytes ( ) ;
310
- peer:: Id ( [
311
- 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , 0u8 , peer_id[ 0 ] , peer_id[ 1 ] ,
312
- peer_id[ 2 ] , peer_id[ 3 ] ,
313
- ] )
314
- }
315
-
316
- #[ test]
317
- fn the_tracker_should_limit_the_list_of_peers_to_74_when_clients_scrape_torrents ( ) {
318
- let mut torrent_entry = EntrySingle :: default ( ) ;
319
-
320
- // We add one more peer than the scrape limit
321
- for peer_number in 1 ..=74 + 1 {
322
- let torrent_peer = TorrentPeerBuilder :: default ( )
323
- . with_peer_id ( peer_id_from_i32 ( peer_number) )
324
- . into ( ) ;
325
- torrent_entry. insert_or_update_peer ( & torrent_peer) ;
326
- }
327
-
328
- let peers = torrent_entry. get_peers ( Some ( TORRENT_PEERS_LIMIT ) ) ;
329
-
330
- assert_eq ! ( peers. len( ) , 74 ) ;
331
- }
332
-
333
- #[ test]
334
- fn torrent_stats_should_have_the_number_of_seeders_for_a_torrent ( ) {
335
- let mut torrent_entry = EntrySingle :: default ( ) ;
336
- let torrent_seeder = a_torrent_seeder ( ) ;
337
-
338
- torrent_entry. insert_or_update_peer ( & torrent_seeder) ; // Add seeder
339
-
340
- assert_eq ! ( torrent_entry. get_stats( ) . complete, 1 ) ;
341
- }
342
-
343
- #[ test]
344
- fn torrent_stats_should_have_the_number_of_leechers_for_a_torrent ( ) {
345
- let mut torrent_entry = EntrySingle :: default ( ) ;
346
- let torrent_leecher = a_torrent_leecher ( ) ;
347
-
348
- torrent_entry. insert_or_update_peer ( & torrent_leecher) ; // Add leecher
349
-
350
- assert_eq ! ( torrent_entry. get_stats( ) . incomplete, 1 ) ;
351
- }
352
-
353
- #[ test]
354
- fn torrent_stats_should_have_the_number_of_peers_that_having_announced_at_least_two_events_the_latest_one_is_the_completed_event (
355
- ) {
356
- let mut torrent_entry = EntrySingle :: default ( ) ;
357
- let mut torrent_peer = TorrentPeerBuilder :: default ( ) . into ( ) ;
358
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Add the peer
359
-
360
- // Announce "Completed" torrent download event.
361
- torrent_peer. event = AnnounceEvent :: Completed ;
362
- torrent_entry. insert_or_update_peer ( & torrent_peer) ; // Update the peer
363
-
364
- let number_of_previously_known_peers_with_completed_torrent = torrent_entry. get_stats ( ) . complete ;
365
-
366
- assert_eq ! ( number_of_previously_known_peers_with_completed_torrent, 1 ) ;
367
- }
368
-
369
- #[ test]
370
- fn torrent_stats_should_not_include_a_peer_in_the_completed_counter_if_the_peer_has_announced_only_one_event ( ) {
371
- let mut torrent_entry = EntrySingle :: default ( ) ;
372
- let torrent_peer_announcing_complete_event = TorrentPeerBuilder :: default ( ) . with_event_completed ( ) . into ( ) ;
373
-
374
- // Announce "Completed" torrent download event.
375
- // It's the first event announced from this peer.
376
- torrent_entry. insert_or_update_peer ( & torrent_peer_announcing_complete_event) ; // Add the peer
377
-
378
- let number_of_peers_with_completed_torrent = torrent_entry. get_stats ( ) . downloaded ;
379
-
380
- assert_eq ! ( number_of_peers_with_completed_torrent, 0 ) ;
381
- }
382
-
383
- #[ test]
384
- fn a_torrent_entry_should_remove_a_peer_not_updated_after_a_timeout_in_seconds ( ) {
385
- let mut torrent_entry = EntrySingle :: default ( ) ;
386
-
387
- let timeout = 120u32 ;
388
-
389
- let now = clock:: Working :: now ( ) ;
390
- clock:: Stopped :: local_set ( & now) ;
391
-
392
- let timeout_seconds_before_now = now. sub ( Duration :: from_secs ( u64:: from ( timeout) ) ) ;
393
- let inactive_peer = TorrentPeerBuilder :: default ( )
394
- . updated_at ( timeout_seconds_before_now. sub ( Duration :: from_secs ( 1 ) ) )
395
- . into ( ) ;
396
- torrent_entry. insert_or_update_peer ( & inactive_peer) ; // Add the peer
397
-
398
- let current_cutoff = CurrentClock :: now_sub ( & Duration :: from_secs ( u64:: from ( timeout) ) ) . unwrap_or_default ( ) ;
399
- torrent_entry. remove_inactive_peers ( current_cutoff) ;
400
-
401
- assert_eq ! ( torrent_entry. get_peers_len( ) , 0 ) ;
402
- }
403
- }
404
- }
0 commit comments