Skip to content

Commit 28603fe

Browse files
committed
refactor: [#1524] extract TestEnv for integration tests in tracker-core
1 parent ab2f52d commit 28603fe

File tree

4 files changed

+227
-155
lines changed

4 files changed

+227
-155
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
2+
use std::str::FromStr;
3+
4+
use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes, PeerId};
5+
use bittorrent_primitives::info_hash::InfoHash;
6+
use torrust_tracker_configuration::Core;
7+
use torrust_tracker_primitives::peer::Peer;
8+
use torrust_tracker_primitives::DurationSinceUnixEpoch;
9+
use torrust_tracker_test_helpers::configuration::ephemeral_sqlite_database;
10+
11+
/// # Panics
12+
///
13+
/// Will panic if the temporary file path is not a valid UTF-8 string.
14+
#[must_use]
15+
pub fn ephemeral_configuration() -> Core {
16+
let mut config = Core::default();
17+
18+
let temp_file = ephemeral_sqlite_database();
19+
temp_file.to_str().unwrap().clone_into(&mut config.database.path);
20+
21+
config
22+
}
23+
24+
/// # Panics
25+
///
26+
/// Will panic if the string representation of the info hash is not a valid infohash.
27+
#[must_use]
28+
pub fn sample_info_hash() -> InfoHash {
29+
"3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0" // DevSkim: ignore DS173237
30+
.parse::<InfoHash>()
31+
.expect("String should be a valid info hash")
32+
}
33+
34+
/// Sample peer whose state is not relevant for the tests.
35+
#[must_use]
36+
pub fn sample_peer() -> Peer {
37+
Peer {
38+
peer_id: PeerId(*b"-qB00000000000000000"),
39+
peer_addr: SocketAddr::new(remote_client_ip(), 8080),
40+
updated: DurationSinceUnixEpoch::new(1_669_397_478_934, 0),
41+
uploaded: NumberOfBytes::new(0),
42+
downloaded: NumberOfBytes::new(0),
43+
left: NumberOfBytes::new(0), // No bytes left to download
44+
event: AnnounceEvent::Completed,
45+
}
46+
}
47+
48+
// The client peer IP.
49+
#[must_use]
50+
pub fn remote_client_ip() -> IpAddr {
51+
IpAddr::V4(Ipv4Addr::from_str("126.0.0.1").unwrap())
52+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod fixtures;
2+
pub mod test_env;
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
use std::net::IpAddr;
2+
use std::sync::Arc;
3+
4+
use aquatic_udp_protocol::AnnounceEvent;
5+
use bittorrent_primitives::info_hash::InfoHash;
6+
use bittorrent_tracker_core::announce_handler::PeersWanted;
7+
use bittorrent_tracker_core::container::TrackerCoreContainer;
8+
use tokio::task::yield_now;
9+
use torrust_tracker_configuration::Core;
10+
use torrust_tracker_primitives::core::{AnnounceData, ScrapeData};
11+
use torrust_tracker_primitives::peer::Peer;
12+
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
13+
use torrust_tracker_torrent_repository::container::TorrentRepositoryContainer;
14+
15+
pub struct TestEnv {
16+
pub torrent_repository_container: Arc<TorrentRepositoryContainer>,
17+
pub tracker_core_container: Arc<TrackerCoreContainer>,
18+
}
19+
20+
impl TestEnv {
21+
#[must_use]
22+
pub async fn started(core_config: Core) -> Self {
23+
let test_env = TestEnv::new(core_config);
24+
test_env.start().await;
25+
test_env
26+
}
27+
28+
#[must_use]
29+
pub fn new(core_config: Core) -> Self {
30+
let core_config = Arc::new(core_config);
31+
32+
let torrent_repository_container = Arc::new(TorrentRepositoryContainer::initialize(
33+
core_config.tracker_usage_statistics.into(),
34+
));
35+
36+
let tracker_core_container = Arc::new(TrackerCoreContainer::initialize_from(
37+
&core_config,
38+
&torrent_repository_container,
39+
));
40+
41+
Self {
42+
torrent_repository_container,
43+
tracker_core_container,
44+
}
45+
}
46+
47+
pub async fn start(&self) {
48+
let mut jobs = vec![];
49+
50+
let job = torrust_tracker_torrent_repository::statistics::event::listener::run_event_listener(
51+
self.torrent_repository_container.event_bus.receiver(),
52+
&self.torrent_repository_container.stats_repository,
53+
);
54+
55+
jobs.push(job);
56+
57+
let job = bittorrent_tracker_core::statistics::event::listener::run_event_listener(
58+
self.torrent_repository_container.event_bus.receiver(),
59+
&self.tracker_core_container.db_torrent_repository,
60+
);
61+
62+
jobs.push(job);
63+
64+
// Give the event listeners some time to start
65+
// todo: they should notify when they are ready
66+
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
67+
}
68+
69+
pub async fn announce_peer_started(
70+
&mut self,
71+
mut peer: Peer,
72+
remote_client_ip: &IpAddr,
73+
info_hash: &InfoHash,
74+
) -> AnnounceData {
75+
peer.event = AnnounceEvent::Started;
76+
77+
let announce_data = self
78+
.tracker_core_container
79+
.announce_handler
80+
.announce(info_hash, &mut peer, remote_client_ip, &PeersWanted::AsManyAsPossible)
81+
.await
82+
.unwrap();
83+
84+
// Give time to the event listeners to process the event
85+
yield_now().await;
86+
87+
announce_data
88+
}
89+
90+
pub async fn announce_peer_completed(
91+
&mut self,
92+
mut peer: Peer,
93+
remote_client_ip: &IpAddr,
94+
info_hash: &InfoHash,
95+
) -> AnnounceData {
96+
peer.event = AnnounceEvent::Completed;
97+
98+
let announce_data = self
99+
.tracker_core_container
100+
.announce_handler
101+
.announce(info_hash, &mut peer, remote_client_ip, &PeersWanted::AsManyAsPossible)
102+
.await
103+
.unwrap();
104+
105+
// Give time to the event listeners to process the event
106+
yield_now().await;
107+
108+
announce_data
109+
}
110+
111+
pub async fn scrape(&self, info_hash: &InfoHash) -> ScrapeData {
112+
self.tracker_core_container
113+
.scrape_handler
114+
.scrape(&vec![*info_hash])
115+
.await
116+
.unwrap()
117+
}
118+
119+
pub async fn increase_number_of_downloads(&mut self, peer: Peer, remote_client_ip: &IpAddr, info_hash: &InfoHash) {
120+
let _announce_data = self.announce_peer_started(peer, remote_client_ip, info_hash).await;
121+
let announce_data = self.announce_peer_completed(peer, remote_client_ip, info_hash).await;
122+
123+
assert_eq!(announce_data.stats.downloads(), 1);
124+
}
125+
126+
pub async fn get_swarm_metadata(&self, info_hash: &InfoHash) -> Option<SwarmMetadata> {
127+
self.torrent_repository_container
128+
.swarms
129+
.get_swarm_metadata(info_hash)
130+
.await
131+
.unwrap()
132+
}
133+
134+
pub async fn remove_swarm(&self, info_hash: &InfoHash) {
135+
self.torrent_repository_container.swarms.remove(info_hash).await.unwrap();
136+
}
137+
}

0 commit comments

Comments
 (0)