Skip to content

Commit f7f4f37

Browse files
committed
dev: improve torrent entry tests
1 parent 5ed94e3 commit f7f4f37

File tree

12 files changed

+325
-341
lines changed

12 files changed

+325
-341
lines changed

packages/torrent-repository/src/entry/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::fmt::Debug;
2+
use std::net::SocketAddr;
23
use std::sync::Arc;
34

45
//use serde::{Deserialize, Serialize};
@@ -33,7 +34,7 @@ pub trait Entry {
3334
///
3435
/// It filters out the input peer, typically because we want to return this
3536
/// list of peers to that client peer.
36-
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
37+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
3738

3839
/// It updates a peer and returns true if the number of complete downloads have increased.
3940
///
@@ -55,7 +56,7 @@ pub trait EntrySync {
5556
fn peers_is_empty(&self) -> bool;
5657
fn get_peers_len(&self) -> usize;
5758
fn get_peers(&self, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
58-
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
59+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>>;
5960
fn insert_or_update_peer(&self, peer: &peer::Peer) -> bool;
6061
fn insert_or_update_peer_and_get_stats(&self, peer: &peer::Peer) -> (bool, SwarmMetadata);
6162
fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch);
@@ -68,9 +69,9 @@ pub trait EntryAsync {
6869
fn peers_is_empty(&self) -> impl std::future::Future<Output = bool> + Send;
6970
fn get_peers_len(&self) -> impl std::future::Future<Output = usize> + Send;
7071
fn get_peers(&self, limit: Option<usize>) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
71-
fn get_peers_for_peer(
72+
fn get_peers_for_client(
7273
&self,
73-
client: &peer::Peer,
74+
client: &SocketAddr,
7475
limit: Option<usize>,
7576
) -> impl std::future::Future<Output = Vec<Arc<peer::Peer>>> + Send;
7677
fn insert_or_update_peer(self, peer: &peer::Peer) -> impl std::future::Future<Output = bool> + Send;

packages/torrent-repository/src/entry/mutex_std.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::net::SocketAddr;
12
use std::sync::Arc;
23

34
use torrust_tracker_configuration::TrackerPolicy;
@@ -28,8 +29,8 @@ impl EntrySync for EntryMutexStd {
2829
self.lock().expect("it should get lock").get_peers(limit)
2930
}
3031

31-
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
32-
self.lock().expect("it should get lock").get_peers_for_peer(client, limit)
32+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
33+
self.lock().expect("it should get lock").get_peers_for_client(client, limit)
3334
}
3435

3536
fn insert_or_update_peer(&self, peer: &peer::Peer) -> bool {

packages/torrent-repository/src/entry/mutex_tokio.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::net::SocketAddr;
12
use std::sync::Arc;
23

34
use torrust_tracker_configuration::TrackerPolicy;
@@ -28,8 +29,8 @@ impl EntryAsync for EntryMutexTokio {
2829
self.lock().await.get_peers(limit)
2930
}
3031

31-
async fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
32-
self.lock().await.get_peers_for_peer(client, limit)
32+
async fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
33+
self.lock().await.get_peers_for_client(client, limit)
3334
}
3435

3536
async fn insert_or_update_peer(self, peer: &peer::Peer) -> bool {

packages/torrent-repository/src/entry/single.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::net::SocketAddr;
12
use std::sync::Arc;
23

34
use torrust_tracker_configuration::TrackerPolicy;
@@ -48,13 +49,13 @@ impl Entry for EntrySingle {
4849
}
4950
}
5051

51-
fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
52+
fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
5253
match limit {
5354
Some(limit) => self
5455
.peers
5556
.values()
5657
// Take peers which are not the client peer
57-
.filter(|peer| peer::ReadInfo::get_address(peer.as_ref()) != peer::ReadInfo::get_address(client))
58+
.filter(|peer| peer::ReadInfo::get_address(peer.as_ref()) != *client)
5859
// Limit the number of peers on the result
5960
.take(limit)
6061
.cloned()
@@ -63,7 +64,7 @@ impl Entry for EntrySingle {
6364
.peers
6465
.values()
6566
// Take peers which are not the client peer
66-
.filter(|peer| peer::ReadInfo::get_address(peer.as_ref()) != peer::ReadInfo::get_address(client))
67+
.filter(|peer| peer::ReadInfo::get_address(peer.as_ref()) != *client)
6768
.cloned()
6869
.collect(),
6970
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1+
pub mod repo;
12
pub mod torrent;
23
pub mod torrent_peer_builder;
3-
pub mod torrents;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
use torrust_tracker_configuration::TrackerPolicy;
2+
use torrust_tracker_primitives::info_hash::InfoHash;
3+
use torrust_tracker_primitives::pagination::Pagination;
4+
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
5+
use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
6+
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, PersistentTorrents};
7+
use torrust_tracker_torrent_repository::repository::{Repository as _, RepositoryAsync as _};
8+
use torrust_tracker_torrent_repository::{
9+
EntrySingle, TorrentsRwLockStd, TorrentsRwLockStdMutexStd, TorrentsRwLockStdMutexTokio, TorrentsRwLockTokio,
10+
TorrentsRwLockTokioMutexStd, TorrentsRwLockTokioMutexTokio,
11+
};
12+
13+
#[derive(Debug)]
14+
pub(crate) enum Repo {
15+
Std(TorrentsRwLockStd),
16+
StdMutexStd(TorrentsRwLockStdMutexStd),
17+
StdMutexTokio(TorrentsRwLockStdMutexTokio),
18+
Tokio(TorrentsRwLockTokio),
19+
TokioMutexStd(TorrentsRwLockTokioMutexStd),
20+
TokioMutexTokio(TorrentsRwLockTokioMutexTokio),
21+
}
22+
23+
#[allow(dead_code)]
24+
impl Repo {
25+
pub(crate) async fn get(&self, key: &InfoHash) -> Option<EntrySingle> {
26+
match self {
27+
Repo::Std(repo) => repo.get(key),
28+
Repo::StdMutexStd(repo) => Some(repo.get(key)?.lock().unwrap().clone()),
29+
Repo::StdMutexTokio(repo) => Some(repo.get(key).await?.lock().await.clone()),
30+
Repo::Tokio(repo) => repo.get(key).await,
31+
Repo::TokioMutexStd(repo) => Some(repo.get(key).await?.lock().unwrap().clone()),
32+
Repo::TokioMutexTokio(repo) => Some(repo.get(key).await?.lock().await.clone()),
33+
}
34+
}
35+
pub(crate) async fn get_metrics(&self) -> TorrentsMetrics {
36+
match self {
37+
Repo::Std(repo) => repo.get_metrics(),
38+
Repo::StdMutexStd(repo) => repo.get_metrics(),
39+
Repo::StdMutexTokio(repo) => repo.get_metrics().await,
40+
Repo::Tokio(repo) => repo.get_metrics().await,
41+
Repo::TokioMutexStd(repo) => repo.get_metrics().await,
42+
Repo::TokioMutexTokio(repo) => repo.get_metrics().await,
43+
}
44+
}
45+
pub(crate) async fn get_paginated(&self, pagination: Option<&Pagination>) -> Vec<(InfoHash, EntrySingle)> {
46+
match self {
47+
Repo::Std(repo) => repo.get_paginated(pagination),
48+
Repo::StdMutexStd(repo) => repo
49+
.get_paginated(pagination)
50+
.iter()
51+
.map(|(i, t)| (*i, t.lock().expect("it should get a lock").clone()))
52+
.collect(),
53+
Repo::StdMutexTokio(repo) => {
54+
let mut v: Vec<(InfoHash, EntrySingle)> = vec![];
55+
56+
for (i, t) in repo.get_paginated(pagination).await {
57+
v.push((i, t.lock().await.clone()));
58+
}
59+
v
60+
}
61+
Repo::Tokio(repo) => repo.get_paginated(pagination).await,
62+
Repo::TokioMutexStd(repo) => repo
63+
.get_paginated(pagination)
64+
.await
65+
.iter()
66+
.map(|(i, t)| (*i, t.lock().expect("it should get a lock").clone()))
67+
.collect(),
68+
Repo::TokioMutexTokio(repo) => {
69+
let mut v: Vec<(InfoHash, EntrySingle)> = vec![];
70+
71+
for (i, t) in repo.get_paginated(pagination).await {
72+
v.push((i, t.lock().await.clone()));
73+
}
74+
v
75+
}
76+
}
77+
}
78+
pub(crate) async fn import_persistent(&self, persistent_torrents: &PersistentTorrents) {
79+
match self {
80+
Repo::Std(repo) => repo.import_persistent(persistent_torrents),
81+
Repo::StdMutexStd(repo) => repo.import_persistent(persistent_torrents),
82+
Repo::StdMutexTokio(repo) => repo.import_persistent(persistent_torrents).await,
83+
Repo::Tokio(repo) => repo.import_persistent(persistent_torrents).await,
84+
Repo::TokioMutexStd(repo) => repo.import_persistent(persistent_torrents).await,
85+
Repo::TokioMutexTokio(repo) => repo.import_persistent(persistent_torrents).await,
86+
}
87+
}
88+
pub(crate) async fn remove(&self, key: &InfoHash) -> Option<EntrySingle> {
89+
match self {
90+
Repo::Std(repo) => repo.remove(key),
91+
Repo::StdMutexStd(repo) => Some(repo.remove(key)?.lock().unwrap().clone()),
92+
Repo::StdMutexTokio(repo) => Some(repo.remove(key).await?.lock().await.clone()),
93+
Repo::Tokio(repo) => repo.remove(key).await,
94+
Repo::TokioMutexStd(repo) => Some(repo.remove(key).await?.lock().unwrap().clone()),
95+
Repo::TokioMutexTokio(repo) => Some(repo.remove(key).await?.lock().await.clone()),
96+
}
97+
}
98+
pub(crate) async fn remove_inactive_peers(&self, current_cutoff: DurationSinceUnixEpoch) {
99+
match self {
100+
Repo::Std(repo) => repo.remove_inactive_peers(current_cutoff),
101+
Repo::StdMutexStd(repo) => repo.remove_inactive_peers(current_cutoff),
102+
Repo::StdMutexTokio(repo) => repo.remove_inactive_peers(current_cutoff).await,
103+
Repo::Tokio(repo) => repo.remove_inactive_peers(current_cutoff).await,
104+
Repo::TokioMutexStd(repo) => repo.remove_inactive_peers(current_cutoff).await,
105+
Repo::TokioMutexTokio(repo) => repo.remove_inactive_peers(current_cutoff).await,
106+
}
107+
}
108+
pub(crate) async fn remove_peerless_torrents(&self, policy: &TrackerPolicy) {
109+
match self {
110+
Repo::Std(repo) => repo.remove_peerless_torrents(policy),
111+
Repo::StdMutexStd(repo) => repo.remove_peerless_torrents(policy),
112+
Repo::StdMutexTokio(repo) => repo.remove_peerless_torrents(policy).await,
113+
Repo::Tokio(repo) => repo.remove_peerless_torrents(policy).await,
114+
Repo::TokioMutexStd(repo) => repo.remove_peerless_torrents(policy).await,
115+
Repo::TokioMutexTokio(repo) => repo.remove_peerless_torrents(policy).await,
116+
}
117+
}
118+
pub(crate) async fn update_torrent_with_peer_and_get_stats(
119+
&self,
120+
info_hash: &InfoHash,
121+
peer: &peer::Peer,
122+
) -> (bool, SwarmMetadata) {
123+
match self {
124+
Repo::Std(repo) => repo.update_torrent_with_peer_and_get_stats(info_hash, peer),
125+
Repo::StdMutexStd(repo) => repo.update_torrent_with_peer_and_get_stats(info_hash, peer),
126+
Repo::StdMutexTokio(repo) => repo.update_torrent_with_peer_and_get_stats(info_hash, peer).await,
127+
Repo::Tokio(repo) => repo.update_torrent_with_peer_and_get_stats(info_hash, peer).await,
128+
Repo::TokioMutexStd(repo) => repo.update_torrent_with_peer_and_get_stats(info_hash, peer).await,
129+
Repo::TokioMutexTokio(repo) => repo.update_torrent_with_peer_and_get_stats(info_hash, peer).await,
130+
}
131+
}
132+
pub(crate) async fn insert(&self, info_hash: &InfoHash, torrent: EntrySingle) -> Option<EntrySingle> {
133+
match self {
134+
Repo::Std(repo) => repo.write().insert(*info_hash, torrent),
135+
Repo::StdMutexStd(repo) => Some(repo.write().insert(*info_hash, torrent.into())?.lock().unwrap().clone()),
136+
Repo::StdMutexTokio(repo) => {
137+
let r = repo.write().insert(*info_hash, torrent.into());
138+
match r {
139+
Some(t) => Some(t.lock().await.clone()),
140+
None => None,
141+
}
142+
}
143+
Repo::Tokio(repo) => repo.write().await.insert(*info_hash, torrent),
144+
Repo::TokioMutexStd(repo) => Some(repo.write().await.insert(*info_hash, torrent.into())?.lock().unwrap().clone()),
145+
Repo::TokioMutexTokio(repo) => Some(repo.write().await.insert(*info_hash, torrent.into())?.lock().await.clone()),
146+
}
147+
}
148+
}

packages/torrent-repository/tests/common/torrent.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::net::SocketAddr;
12
use std::sync::Arc;
23

34
use torrust_tracker_configuration::TrackerPolicy;
@@ -54,11 +55,11 @@ impl Torrent {
5455
}
5556
}
5657

57-
pub(crate) async fn get_peers_for_peer(&self, client: &peer::Peer, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
58+
pub(crate) async fn get_peers_for_client(&self, client: &SocketAddr, limit: Option<usize>) -> Vec<Arc<peer::Peer>> {
5859
match self {
59-
Torrent::Single(entry) => entry.get_peers_for_peer(client, limit),
60-
Torrent::MutexStd(entry) => entry.get_peers_for_peer(client, limit),
61-
Torrent::MutexTokio(entry) => entry.clone().get_peers_for_peer(client, limit).await,
60+
Torrent::Single(entry) => entry.get_peers_for_client(client, limit),
61+
Torrent::MutexStd(entry) => entry.get_peers_for_client(client, limit),
62+
Torrent::MutexTokio(entry) => entry.clone().get_peers_for_client(client, limit).await,
6263
}
6364
}
6465

packages/torrent-repository/tests/common/torrent_peer_builder.rs

+14-11
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch, NumberOfBytes};
77
use crate::CurrentClock;
88

99
#[derive(Debug, Default)]
10-
pub struct TorrentPeerBuilder {
10+
struct TorrentPeerBuilder {
1111
peer: peer::Peer,
1212
}
1313

14+
#[allow(dead_code)]
1415
impl TorrentPeerBuilder {
1516
#[must_use]
16-
pub fn new() -> Self {
17+
fn new() -> Self {
1718
Self {
1819
peer: peer::Peer {
1920
updated: CurrentClock::now(),
@@ -23,63 +24,65 @@ impl TorrentPeerBuilder {
2324
}
2425

2526
#[must_use]
26-
pub fn with_event_completed(mut self) -> Self {
27+
fn with_event_completed(mut self) -> Self {
2728
self.peer.event = AnnounceEvent::Completed;
2829
self
2930
}
3031

3132
#[must_use]
32-
pub fn with_event_started(mut self) -> Self {
33+
fn with_event_started(mut self) -> Self {
3334
self.peer.event = AnnounceEvent::Started;
3435
self
3536
}
3637

3738
#[must_use]
38-
pub fn with_peer_address(mut self, peer_addr: SocketAddr) -> Self {
39+
fn with_peer_address(mut self, peer_addr: SocketAddr) -> Self {
3940
self.peer.peer_addr = peer_addr;
4041
self
4142
}
4243

4344
#[must_use]
44-
pub fn with_peer_id(mut self, peer_id: peer::Id) -> Self {
45+
fn with_peer_id(mut self, peer_id: peer::Id) -> Self {
4546
self.peer.peer_id = peer_id;
4647
self
4748
}
4849

4950
#[must_use]
50-
pub fn with_number_of_bytes_left(mut self, left: i64) -> Self {
51+
fn with_number_of_bytes_left(mut self, left: i64) -> Self {
5152
self.peer.left = NumberOfBytes(left);
5253
self
5354
}
5455

5556
#[must_use]
56-
pub fn updated_at(mut self, updated: DurationSinceUnixEpoch) -> Self {
57+
fn updated_at(mut self, updated: DurationSinceUnixEpoch) -> Self {
5758
self.peer.updated = updated;
5859
self
5960
}
6061

6162
#[must_use]
62-
pub fn into(self) -> peer::Peer {
63+
fn into(self) -> peer::Peer {
6364
self.peer
6465
}
6566
}
6667

6768
/// A torrent seeder is a peer with 0 bytes left to download which
6869
/// has not announced it has stopped
6970
#[must_use]
70-
pub fn a_completed_peer() -> peer::Peer {
71+
pub fn a_completed_peer(id: i32) -> peer::Peer {
7172
TorrentPeerBuilder::new()
7273
.with_number_of_bytes_left(0)
7374
.with_event_completed()
75+
.with_peer_id(id.into())
7476
.into()
7577
}
7678

7779
/// A torrent leecher is a peer that is not a seeder.
7880
/// Leecher: left > 0 OR event = Stopped
7981
#[must_use]
80-
pub fn a_started_peer() -> peer::Peer {
82+
pub fn a_started_peer(id: i32) -> peer::Peer {
8183
TorrentPeerBuilder::new()
8284
.with_number_of_bytes_left(1)
8385
.with_event_started()
86+
.with_peer_id(id.into())
8487
.into()
8588
}

0 commit comments

Comments
 (0)