Skip to content

Commit cdaa1e0

Browse files
committed
test: [#1240] add tests for InMemoryTorrentRepository. WIP
1 parent 806dcc4 commit cdaa1e0

File tree

1 file changed

+130
-27
lines changed

1 file changed

+130
-27
lines changed

packages/tracker-core/src/torrent/repository/in_memory.rs

Lines changed: 130 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -127,25 +127,51 @@ mod tests {
127127

128128
// The `InMemoryTorrentRepository` has these responsibilities:
129129
// - To maintain the peer lists for each torrent.
130-
// - To return the peer lists for a given torrent.
131-
// - To return the torrent entries, which contains all the info about the
130+
// - To maintain the the torrent entries, which contains all the info about the
132131
// torrents, including the peer lists.
132+
// - To return the torrent entries.
133+
// - To return the peer lists for a given torrent.
133134
// - To return the torrent metrics.
134135
// - To return the swarm metadata for a given torrent.
135136
// - To handle the persistence of the torrent entries.
136137

137138
mod maintaining_the_peer_lists {
138139
// Methods:
139-
// - upsert_peer
140-
// - remove
141-
// - remove_inactive_peers
142-
// - remove_peerless_torrents
140+
// - [x] upsert_peer
141+
142+
use std::sync::Arc;
143+
144+
use crate::core_tests::{sample_info_hash, sample_peer};
145+
use crate::torrent::repository::in_memory::InMemoryTorrentRepository;
146+
147+
#[tokio::test]
148+
async fn it_should_add_the_first_peer_to_the_torrent_peer_list() {
149+
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
150+
151+
let info_hash = sample_info_hash();
152+
153+
let () = in_memory_torrent_repository.upsert_peer(&info_hash, &sample_peer());
154+
155+
assert!(in_memory_torrent_repository.get(&info_hash).is_some());
156+
}
157+
158+
#[tokio::test]
159+
async fn it_should_allow_adding_the_same_peer_twice_to_the_torrent_peer_list() {
160+
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
161+
162+
let info_hash = sample_info_hash();
163+
164+
let () = in_memory_torrent_repository.upsert_peer(&info_hash, &sample_peer());
165+
let () = in_memory_torrent_repository.upsert_peer(&info_hash, &sample_peer());
166+
167+
assert!(in_memory_torrent_repository.get(&info_hash).is_some());
168+
}
143169
}
144170

145171
mod returning_peer_lists_for_a_torrent {
146172
// Methods:
147-
// - get_peers_for
148-
// - get_torrent_peers
173+
// - [x] get_torrent_peers
174+
// - [x] get_peers_for
149175

150176
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
151177
use std::sync::Arc;
@@ -159,6 +185,20 @@ mod tests {
159185
use crate::torrent::repository::in_memory::tests::numeric_peer_id;
160186
use crate::torrent::repository::in_memory::InMemoryTorrentRepository;
161187

188+
#[tokio::test]
189+
async fn it_should_return_the_peers_for_a_given_torrent() {
190+
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
191+
192+
let info_hash = sample_info_hash();
193+
let peer = sample_peer();
194+
195+
let () = in_memory_torrent_repository.upsert_peer(&info_hash, &peer);
196+
197+
let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash);
198+
199+
assert_eq!(peers, vec![Arc::new(peer)]);
200+
}
201+
162202
#[tokio::test]
163203
async fn it_should_return_74_peers_at_the_most_for_a_given_torrent() {
164204
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
@@ -184,20 +224,6 @@ mod tests {
184224
assert_eq!(peers.len(), 74);
185225
}
186226

187-
#[tokio::test]
188-
async fn it_should_return_the_peers_for_a_given_torrent() {
189-
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
190-
191-
let info_hash = sample_info_hash();
192-
let peer = sample_peer();
193-
194-
let () = in_memory_torrent_repository.upsert_peer(&info_hash, &peer);
195-
196-
let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash);
197-
198-
assert_eq!(peers, vec![Arc::new(peer)]);
199-
}
200-
201227
#[tokio::test]
202228
async fn it_should_return_the_peers_for_a_given_torrent_excluding_a_given_peer() {
203229
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
@@ -243,15 +269,92 @@ mod tests {
243269
}
244270
}
245271

272+
mod maintaining_the_torrent_entries {
273+
// Methods:
274+
// - [x] remove
275+
// - [x] remove_inactive_peers
276+
// - [x] remove_peerless_torrents
277+
278+
use std::ops::Add;
279+
use std::sync::Arc;
280+
use std::time::Duration;
281+
282+
use bittorrent_primitives::info_hash::InfoHash;
283+
use torrust_tracker_configuration::TrackerPolicy;
284+
use torrust_tracker_primitives::DurationSinceUnixEpoch;
285+
286+
use crate::core_tests::{sample_info_hash, sample_peer};
287+
use crate::torrent::repository::in_memory::InMemoryTorrentRepository;
288+
289+
#[tokio::test]
290+
async fn it_should_remove_a_torrent_entry() {
291+
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
292+
293+
let info_hash = sample_info_hash();
294+
let () = in_memory_torrent_repository.upsert_peer(&info_hash, &sample_peer());
295+
296+
let _unused = in_memory_torrent_repository.remove(&info_hash);
297+
298+
assert!(in_memory_torrent_repository.get(&info_hash).is_none());
299+
}
300+
301+
#[tokio::test]
302+
async fn it_should_remove_peers_that_have_not_been_updated_after_a_cutoff_time() {
303+
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
304+
305+
let info_hash = sample_info_hash();
306+
let mut peer = sample_peer();
307+
peer.updated = DurationSinceUnixEpoch::new(0, 0);
308+
309+
let () = in_memory_torrent_repository.upsert_peer(&info_hash, &peer);
310+
311+
// Cut off time is 1 second after the peer was updated
312+
in_memory_torrent_repository.remove_inactive_peers(peer.updated.add(Duration::from_secs(1)));
313+
314+
assert!(!in_memory_torrent_repository
315+
.get_torrent_peers(&info_hash)
316+
.contains(&Arc::new(peer)));
317+
}
318+
319+
fn initialize_repository_with_one_torrent_without_peers(info_hash: &InfoHash) -> Arc<InMemoryTorrentRepository> {
320+
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
321+
322+
// Insert a sample peer for the torrent to force adding the torrent entry
323+
let mut peer = sample_peer();
324+
peer.updated = DurationSinceUnixEpoch::new(0, 0);
325+
let () = in_memory_torrent_repository.upsert_peer(info_hash, &peer);
326+
327+
// Remove the peer
328+
in_memory_torrent_repository.remove_inactive_peers(peer.updated.add(Duration::from_secs(1)));
329+
330+
in_memory_torrent_repository
331+
}
332+
333+
#[tokio::test]
334+
async fn it_should_remove_torrents_without_peers() {
335+
let info_hash = sample_info_hash();
336+
337+
let in_memory_torrent_repository = initialize_repository_with_one_torrent_without_peers(&info_hash);
338+
339+
let tracker_policy = TrackerPolicy {
340+
remove_peerless_torrents: true,
341+
..Default::default()
342+
};
343+
344+
in_memory_torrent_repository.remove_peerless_torrents(&tracker_policy);
345+
346+
assert!(in_memory_torrent_repository.get(&info_hash).is_none());
347+
}
348+
}
246349
mod returning_torrent_entries {
247350
// Methods:
248-
// - get
249-
// - get_paginated
351+
// - [ ] get
352+
// - [ ] get_paginated
250353
}
251354

252355
mod returning_torrent_metrics {
253356
// Methods:
254-
// - get_torrents_metrics
357+
// - [ ] get_torrents_metrics
255358

256359
use std::sync::Arc;
257360

@@ -326,11 +429,11 @@ mod tests {
326429

327430
mod returning_swarm_metadata {
328431
// Methods:
329-
// - get_swarm_metadata
432+
// - [ ] get_swarm_metadata
330433
}
331434

332435
mod handling_persistence {
333436
// Methods:
334-
// - import_persistent
437+
// - [ ] import_persistent
335438
}
336439
}

0 commit comments

Comments
 (0)