Skip to content

Commit b2fc663

Browse files
committed
test: [#1247] add tests for bittorrent_tracker_core::announce_handler
1 parent 4043962 commit b2fc663

File tree

1 file changed

+160
-14
lines changed

1 file changed

+160
-14
lines changed

packages/tracker-core/src/announce_handler.rs

Lines changed: 160 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,7 @@ pub enum PeersWanted {
119119
impl 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

138133
impl 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

Comments
 (0)