@@ -127,25 +127,51 @@ mod tests {
127
127
128
128
// The `InMemoryTorrentRepository` has these responsibilities:
129
129
// - 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
132
131
// torrents, including the peer lists.
132
+ // - To return the torrent entries.
133
+ // - To return the peer lists for a given torrent.
133
134
// - To return the torrent metrics.
134
135
// - To return the swarm metadata for a given torrent.
135
136
// - To handle the persistence of the torrent entries.
136
137
137
138
mod maintaining_the_peer_lists {
138
139
// 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
+ }
143
169
}
144
170
145
171
mod returning_peer_lists_for_a_torrent {
146
172
// Methods:
147
- // - get_peers_for
148
- // - get_torrent_peers
173
+ // - [x] get_torrent_peers
174
+ // - [x] get_peers_for
149
175
150
176
use std:: net:: { IpAddr , Ipv4Addr , SocketAddr } ;
151
177
use std:: sync:: Arc ;
@@ -159,6 +185,20 @@ mod tests {
159
185
use crate :: torrent:: repository:: in_memory:: tests:: numeric_peer_id;
160
186
use crate :: torrent:: repository:: in_memory:: InMemoryTorrentRepository ;
161
187
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
+
162
202
#[ tokio:: test]
163
203
async fn it_should_return_74_peers_at_the_most_for_a_given_torrent ( ) {
164
204
let in_memory_torrent_repository = Arc :: new ( InMemoryTorrentRepository :: default ( ) ) ;
@@ -184,20 +224,6 @@ mod tests {
184
224
assert_eq ! ( peers. len( ) , 74 ) ;
185
225
}
186
226
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
-
201
227
#[ tokio:: test]
202
228
async fn it_should_return_the_peers_for_a_given_torrent_excluding_a_given_peer ( ) {
203
229
let in_memory_torrent_repository = Arc :: new ( InMemoryTorrentRepository :: default ( ) ) ;
@@ -243,15 +269,92 @@ mod tests {
243
269
}
244
270
}
245
271
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
+ }
246
349
mod returning_torrent_entries {
247
350
// Methods:
248
- // - get
249
- // - get_paginated
351
+ // - [ ] get
352
+ // - [ ] get_paginated
250
353
}
251
354
252
355
mod returning_torrent_metrics {
253
356
// Methods:
254
- // - get_torrents_metrics
357
+ // - [ ] get_torrents_metrics
255
358
256
359
use std:: sync:: Arc ;
257
360
@@ -326,11 +429,11 @@ mod tests {
326
429
327
430
mod returning_swarm_metadata {
328
431
// Methods:
329
- // - get_swarm_metadata
432
+ // - [ ] get_swarm_metadata
330
433
}
331
434
332
435
mod handling_persistence {
333
436
// Methods:
334
- // - import_persistent
437
+ // - [ ] import_persistent
335
438
}
336
439
}
0 commit comments