Skip to content

Commit 2f505a8

Browse files
committed
Merge #1267: Overhaul core Tracker: add integration test
35ca428 test: [#1266] add integartion test for bittorrent_tracker_core lib (Jose Celano) Pull request description: Overhaul core Tracker: add integration test. I have added an integration test as documentation about how to use the lib. That functionality is already covered by unit tests. ACKs for top commit: josecelano: ACK 35ca428 Tree-SHA512: 7195520fa544dc0b3052ce05101255f47f8a767a5122125561a4bfa5b157cf2007dd87d5476be44a6e75e8d3891d7501819d012404a0f3adbdc0630d64cfdf4c
2 parents 1b745a6 + 35ca428 commit 2f505a8

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
2+
use std::str::FromStr;
3+
use std::sync::Arc;
4+
5+
use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes, PeerId};
6+
use bittorrent_primitives::info_hash::InfoHash;
7+
use bittorrent_tracker_core::announce_handler::{AnnounceHandler, PeersWanted};
8+
use bittorrent_tracker_core::databases::setup::initialize_database;
9+
use bittorrent_tracker_core::scrape_handler::ScrapeHandler;
10+
use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository;
11+
use bittorrent_tracker_core::torrent::repository::persisted::DatabasePersistentTorrentRepository;
12+
use bittorrent_tracker_core::whitelist;
13+
use bittorrent_tracker_core::whitelist::repository::in_memory::InMemoryWhitelist;
14+
use torrust_tracker_configuration::Core;
15+
use torrust_tracker_primitives::peer::Peer;
16+
use torrust_tracker_primitives::DurationSinceUnixEpoch;
17+
use torrust_tracker_test_helpers::configuration::ephemeral_sqlite_database;
18+
19+
/// # Panics
20+
///
21+
/// Will panic if the temporary file path is not a valid UTF-8 string.
22+
#[must_use]
23+
pub fn ephemeral_configuration() -> Core {
24+
let mut config = Core::default();
25+
26+
let temp_file = ephemeral_sqlite_database();
27+
temp_file.to_str().unwrap().clone_into(&mut config.database.path);
28+
29+
config
30+
}
31+
32+
/// # Panics
33+
///
34+
/// Will panic if the string representation of the info hash is not a valid infohash.
35+
#[must_use]
36+
pub fn sample_info_hash() -> InfoHash {
37+
"3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0" // DevSkim: ignore DS173237
38+
.parse::<InfoHash>()
39+
.expect("String should be a valid info hash")
40+
}
41+
42+
/// Sample peer whose state is not relevant for the tests.
43+
#[must_use]
44+
pub fn sample_peer() -> Peer {
45+
Peer {
46+
peer_id: PeerId(*b"-qB00000000000000000"),
47+
peer_addr: SocketAddr::new(remote_client_ip(), 8080),
48+
updated: DurationSinceUnixEpoch::new(1_669_397_478_934, 0),
49+
uploaded: NumberOfBytes::new(0),
50+
downloaded: NumberOfBytes::new(0),
51+
left: NumberOfBytes::new(0), // No bytes left to download
52+
event: AnnounceEvent::Completed,
53+
}
54+
}
55+
56+
// The client peer IP.
57+
#[must_use]
58+
fn remote_client_ip() -> IpAddr {
59+
IpAddr::V4(Ipv4Addr::from_str("126.0.0.1").unwrap())
60+
}
61+
62+
struct Container {
63+
pub announce_handler: Arc<AnnounceHandler>,
64+
pub scrape_handler: Arc<ScrapeHandler>,
65+
}
66+
67+
impl Container {
68+
pub fn initialize(config: &Core) -> Self {
69+
let database = initialize_database(config);
70+
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
71+
let db_torrent_repository = Arc::new(DatabasePersistentTorrentRepository::new(&database));
72+
let in_memory_whitelist = Arc::new(InMemoryWhitelist::default());
73+
let whitelist_authorization = Arc::new(whitelist::authorization::WhitelistAuthorization::new(
74+
config,
75+
&in_memory_whitelist.clone(),
76+
));
77+
let announce_handler = Arc::new(AnnounceHandler::new(
78+
config,
79+
&in_memory_torrent_repository,
80+
&db_torrent_repository,
81+
));
82+
let scrape_handler = Arc::new(ScrapeHandler::new(&whitelist_authorization, &in_memory_torrent_repository));
83+
84+
Self {
85+
announce_handler,
86+
scrape_handler,
87+
}
88+
}
89+
}
90+
91+
#[tokio::test]
92+
async fn test_announce_and_scrape_requests() {
93+
let config = ephemeral_configuration();
94+
95+
let container = Container::initialize(&config);
96+
97+
let info_hash = sample_info_hash();
98+
99+
let mut peer = sample_peer();
100+
101+
// Announce
102+
103+
// First announce: download started
104+
peer.event = AnnounceEvent::Started;
105+
let announce_data =
106+
container
107+
.announce_handler
108+
.announce(&info_hash, &mut peer, &remote_client_ip(), &PeersWanted::AsManyAsPossible);
109+
110+
// NOTICE: you don't get back the peer making the request.
111+
assert_eq!(announce_data.peers.len(), 0);
112+
assert_eq!(announce_data.stats.downloaded, 0);
113+
114+
// Second announce: download completed
115+
peer.event = AnnounceEvent::Completed;
116+
let announce_data =
117+
container
118+
.announce_handler
119+
.announce(&info_hash, &mut peer, &remote_client_ip(), &PeersWanted::AsManyAsPossible);
120+
121+
assert_eq!(announce_data.peers.len(), 0);
122+
assert_eq!(announce_data.stats.downloaded, 1);
123+
124+
// Scrape
125+
126+
let scrape_data = container.scrape_handler.scrape(&vec![info_hash]).await;
127+
128+
assert!(scrape_data.files.contains_key(&info_hash));
129+
}
130+
131+
#[test]
132+
fn test_scrape_request() {}

0 commit comments

Comments
 (0)