@@ -119,12 +119,7 @@ pub enum PeersWanted {
119119impl PeersWanted {
120120 #[ must_use]
121121 pub fn only ( limit : u32 ) -> Self {
122- let amount: usize = match limit. try_into ( ) {
123- Ok ( amount) => amount,
124- Err ( _) => TORRENT_PEERS_LIMIT ,
125- } ;
126-
127- Self :: Only { amount }
122+ limit. into ( )
128123 }
129124
130125 fn limit ( & self ) -> usize {
@@ -137,13 +132,29 @@ impl PeersWanted {
137132
138133impl From < i32 > for PeersWanted {
139134 fn from ( value : i32 ) -> Self {
140- if value > 0 {
141- match value. try_into ( ) {
142- Ok ( peers_wanted) => Self :: Only { amount : peers_wanted } ,
143- Err ( _) => Self :: All ,
144- }
145- } else {
146- Self :: All
135+ if value <= 0 {
136+ return PeersWanted :: All ;
137+ }
138+
139+ // This conversion is safe because `value > 0`
140+ let amount = usize:: try_from ( value) . unwrap ( ) ;
141+
142+ PeersWanted :: Only {
143+ amount : amount. min ( TORRENT_PEERS_LIMIT ) ,
144+ }
145+ }
146+ }
147+
148+ impl From < u32 > for PeersWanted {
149+ fn from ( value : u32 ) -> Self {
150+ if value == 0 {
151+ return PeersWanted :: All ;
152+ }
153+
154+ let amount = value as usize ;
155+
156+ PeersWanted :: Only {
157+ amount : amount. min ( TORRENT_PEERS_LIMIT ) ,
147158 }
148159 }
149160}
@@ -210,14 +221,27 @@ mod tests {
210221 }
211222 }
212223
224+ /// Sample peer when for tests that need more than two peer
225+ fn sample_peer_3 ( ) -> Peer {
226+ Peer {
227+ peer_id : PeerId ( * b"-qB00000000000000003" ) ,
228+ peer_addr : SocketAddr :: new ( IpAddr :: V4 ( Ipv4Addr :: new ( 126 , 0 , 0 , 3 ) ) , 8082 ) ,
229+ updated : DurationSinceUnixEpoch :: new ( 1_669_397_478_934 , 0 ) ,
230+ uploaded : NumberOfBytes :: new ( 0 ) ,
231+ downloaded : NumberOfBytes :: new ( 0 ) ,
232+ left : NumberOfBytes :: new ( 0 ) ,
233+ event : AnnounceEvent :: Completed ,
234+ }
235+ }
236+
213237 mod for_all_tracker_config_modes {
214238
215239 mod handling_an_announce_request {
216240
217241 use std:: sync:: Arc ;
218242
219243 use crate :: announce_handler:: tests:: the_announce_handler:: {
220- peer_ip, public_tracker, sample_peer_1, sample_peer_2,
244+ peer_ip, public_tracker, sample_peer_1, sample_peer_2, sample_peer_3 ,
221245 } ;
222246 use crate :: announce_handler:: PeersWanted ;
223247 use crate :: core_tests:: { sample_info_hash, sample_peer} ;
@@ -349,6 +373,38 @@ mod tests {
349373 assert_eq ! ( announce_data. peers, vec![ Arc :: new( previously_announced_peer) ] ) ;
350374 }
351375
376+ #[ tokio:: test]
377+ async fn it_should_allow_peers_to_get_only_a_subset_of_the_peers_in_the_swarm ( ) {
378+ let ( announce_handler, _scrape_handler) = public_tracker ( ) ;
379+
380+ let mut previously_announced_peer_1 = sample_peer_1 ( ) ;
381+ announce_handler. announce (
382+ & sample_info_hash ( ) ,
383+ & mut previously_announced_peer_1,
384+ & peer_ip ( ) ,
385+ & PeersWanted :: All ,
386+ ) ;
387+
388+ let mut previously_announced_peer_2 = sample_peer_2 ( ) ;
389+ announce_handler. announce (
390+ & sample_info_hash ( ) ,
391+ & mut previously_announced_peer_2,
392+ & peer_ip ( ) ,
393+ & PeersWanted :: All ,
394+ ) ;
395+
396+ let mut peer = sample_peer_3 ( ) ;
397+ let announce_data =
398+ announce_handler. announce ( & sample_info_hash ( ) , & mut peer, & peer_ip ( ) , & PeersWanted :: only ( 1 ) ) ;
399+
400+ // It should return only one peer. There is no guarantee on
401+ // which peer will be returned.
402+ assert ! (
403+ announce_data. peers == vec![ Arc :: new( previously_announced_peer_1) ]
404+ || announce_data. peers == vec![ Arc :: new( previously_announced_peer_2) ]
405+ ) ;
406+ }
407+
352408 mod it_should_update_the_swarm_stats_for_the_torrent {
353409
354410 use crate :: announce_handler:: tests:: the_announce_handler:: { peer_ip, public_tracker} ;
@@ -461,5 +517,95 @@ mod tests {
461517 assert ! ( torrent_entry. peers_is_empty( ) ) ;
462518 }
463519 }
520+
521+ mod should_allow_the_client_peers_to_specified_the_number_of_peers_wanted {
522+
523+ use torrust_tracker_configuration:: TORRENT_PEERS_LIMIT ;
524+
525+ use crate :: announce_handler:: PeersWanted ;
526+
527+ #[ test]
528+ fn it_should_return_the_maximin_number_of_peers_by_default ( ) {
529+ let peers_wanted = PeersWanted :: default ( ) ;
530+
531+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
532+ }
533+
534+ #[ test]
535+ fn it_should_return_74_at_the_most_if_the_client_wants_them_all ( ) {
536+ let peers_wanted = PeersWanted :: All ;
537+
538+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
539+ }
540+
541+ #[ test]
542+ fn it_should_allow_limiting_the_peer_list ( ) {
543+ let peers_wanted = PeersWanted :: only ( 10 ) ;
544+
545+ assert_eq ! ( peers_wanted. limit( ) , 10 ) ;
546+ }
547+
548+ fn maximum_as_u32 ( ) -> u32 {
549+ u32:: try_from ( TORRENT_PEERS_LIMIT ) . unwrap ( )
550+ }
551+
552+ fn maximum_as_i32 ( ) -> i32 {
553+ i32:: try_from ( TORRENT_PEERS_LIMIT ) . unwrap ( )
554+ }
555+
556+ #[ test]
557+ fn it_should_return_the_maximum_when_wanting_more_than_the_maximum ( ) {
558+ let peers_wanted = PeersWanted :: only ( maximum_as_u32 ( ) + 1 ) ;
559+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
560+ }
561+
562+ #[ test]
563+ fn it_should_return_the_maximum_when_wanting_only_zero ( ) {
564+ let peers_wanted = PeersWanted :: only ( 0 ) ;
565+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
566+ }
567+
568+ #[ test]
569+ fn it_should_convert_the_peers_wanted_number_from_i32 ( ) {
570+ // Negative. It should return the maximum
571+ let peers_wanted: PeersWanted = ( -1i32 ) . into ( ) ;
572+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
573+
574+ // Zero. It should return the maximum
575+ let peers_wanted: PeersWanted = 0i32 . into ( ) ;
576+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
577+
578+ // Greater than the maximum. It should return the maximum
579+ let peers_wanted: PeersWanted = ( maximum_as_i32 ( ) + 1 ) . into ( ) ;
580+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
581+
582+ // The maximum
583+ let peers_wanted: PeersWanted = ( maximum_as_i32 ( ) ) . into ( ) ;
584+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
585+
586+ // Smaller than the maximum
587+ let peers_wanted: PeersWanted = ( maximum_as_i32 ( ) - 1 ) . into ( ) ;
588+ assert_eq ! ( i32 :: try_from( peers_wanted. limit( ) ) . unwrap( ) , maximum_as_i32( ) - 1 ) ;
589+ }
590+
591+ #[ test]
592+ fn it_should_convert_the_peers_wanted_number_from_u32 ( ) {
593+ // Zero. It should return the maximum
594+ let peers_wanted: PeersWanted = 0u32 . into ( ) ;
595+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
596+
597+ // Greater than the maximum. It should return the maximum
598+ let peers_wanted: PeersWanted = ( maximum_as_u32 ( ) + 1 ) . into ( ) ;
599+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
600+
601+ // The maximum
602+ let peers_wanted: PeersWanted = ( maximum_as_u32 ( ) ) . into ( ) ;
603+ assert_eq ! ( peers_wanted. limit( ) , TORRENT_PEERS_LIMIT ) ;
604+
605+ // Smaller than the maximum
606+ let peers_wanted: PeersWanted = ( maximum_as_u32 ( ) - 1 ) . into ( ) ;
607+ assert_eq ! ( i32 :: try_from( peers_wanted. limit( ) ) . unwrap( ) , maximum_as_i32( ) - 1 ) ;
608+ }
609+ }
464610 }
465611}
0 commit comments