diff --git a/src/config.rs b/src/config.rs index 820af77d8..05a446454 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,6 +5,7 @@ use std::str::FromStr; use std::{env, fs}; use config::{Config, ConfigError, File, FileFormat}; +use rand::{thread_rng, Rng}; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, NoneAsEmptyString}; use {std, toml}; @@ -73,6 +74,40 @@ pub enum Error { TrackerModeIncompatible, } +/// This configuration is used for testing. It generates random config values so they do not collide +/// if you run more than one tracker at the same time. +/// +/// # Panics +/// +/// Will panic if it can't convert the temp file path to string +#[must_use] +pub fn ephemeral_configuration() -> Configuration { + let mut config = Configuration { + log_level: Some("off".to_owned()), + ..Default::default() + }; + + // Ephemeral socket addresses + let api_port = random_port(); + config.http_api.bind_address = format!("127.0.0.1:{}", &api_port); + let upd_port = random_port(); + config.udp_trackers[0].bind_address = format!("127.0.0.1:{}", &upd_port); + + // Ephemeral sqlite database + let temp_directory = env::temp_dir(); + let temp_file = temp_directory.join(format!("data_{}_{}.db", &api_port, &upd_port)); + config.db_path = temp_file.to_str().unwrap().to_owned(); + + config +} + +fn random_port() -> u16 { + // todo: this may produce random test failures because two tests can try to bind the same port. + // We could create a pool of available ports (with read/write lock) + let mut rng = thread_rng(); + rng.gen_range(49152..65535) +} + impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self { diff --git a/src/tracker/mod.rs b/src/tracker/mod.rs index e0ea41123..4de168908 100644 --- a/src/tracker/mod.rs +++ b/src/tracker/mod.rs @@ -29,6 +29,7 @@ pub struct Tracker { database: Box, } +#[derive(Debug, PartialEq, Default)] pub struct TorrentsMetrics { pub seeders: u64, pub completed: u64, diff --git a/src/tracker/services/statistics.rs b/src/tracker/services/statistics.rs index 5f8f39856..696ca2ea1 100644 --- a/src/tracker/services/statistics.rs +++ b/src/tracker/services/statistics.rs @@ -3,6 +3,7 @@ use std::sync::Arc; use crate::tracker::statistics::Metrics; use crate::tracker::{TorrentsMetrics, Tracker}; +#[derive(Debug, PartialEq)] pub struct TrackerMetrics { pub torrents_metrics: TorrentsMetrics, pub protocol_metrics: Metrics, diff --git a/src/tracker/statistics.rs b/src/tracker/statistics.rs index b787e1267..f9f6253fd 100644 --- a/src/tracker/statistics.rs +++ b/src/tracker/statistics.rs @@ -23,7 +23,7 @@ pub enum Event { Udp6Scrape, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Default)] pub struct Metrics { pub tcp4_connections_handled: u64, pub tcp4_announces_handled: u64, @@ -39,32 +39,6 @@ pub struct Metrics { pub udp6_scrapes_handled: u64, } -impl Default for Metrics { - fn default() -> Self { - Self::new() - } -} - -impl Metrics { - #[must_use] - pub fn new() -> Self { - Self { - tcp4_connections_handled: 0, - tcp4_announces_handled: 0, - tcp4_scrapes_handled: 0, - tcp6_connections_handled: 0, - tcp6_announces_handled: 0, - tcp6_scrapes_handled: 0, - udp4_connections_handled: 0, - udp4_announces_handled: 0, - udp4_scrapes_handled: 0, - udp6_connections_handled: 0, - udp6_announces_handled: 0, - udp6_scrapes_handled: 0, - } - } -} - pub struct Keeper { pub repository: Repo, } @@ -187,7 +161,7 @@ impl Repo { #[must_use] pub fn new() -> Self { Self { - stats: Arc::new(RwLock::new(Metrics::new())), + stats: Arc::new(RwLock::new(Metrics::default())), } } @@ -280,7 +254,7 @@ mod tests { let stats = stats_tracker.repository.get_stats().await; - assert_eq!(stats.tcp4_announces_handled, Metrics::new().tcp4_announces_handled); + assert_eq!(stats.tcp4_announces_handled, Metrics::default().tcp4_announces_handled); } #[tokio::test] diff --git a/src/udp/handlers.rs b/src/udp/handlers.rs index 001fb2380..076710fb6 100644 --- a/src/udp/handlers.rs +++ b/src/udp/handlers.rs @@ -239,14 +239,13 @@ fn handle_error(e: &Error, transaction_id: TransactionId) -> Response { #[cfg(test)] mod tests { - use std::env; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use std::sync::Arc; use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes}; - use rand::{thread_rng, Rng}; - use crate::config::Configuration; + use crate::config::{ephemeral_configuration, Configuration}; use crate::protocol::clock::{Current, Time}; use crate::tracker::{self, mode, peer, statistics}; @@ -255,28 +254,7 @@ mod tests { } fn default_testing_tracker_configuration() -> Configuration { - let mut config = Configuration { - log_level: Some("off".to_owned()), - ..Default::default() - }; - - // Ephemeral socket address - let port = ephemeral_random_port(); - config.http_api.bind_address = format!("127.0.0.1:{}", &port); - - // Ephemeral database - let temp_directory = env::temp_dir(); - let temp_file = temp_directory.join(format!("data_{}.db", &port)); - config.db_path = temp_file.to_str().unwrap().to_owned(); - - config - } - - fn ephemeral_random_port() -> u16 { - // todo: this may produce random test failures because two tests can try to bind the same port. - // We could create a pool of available ports (with read/write lock) - let mut rng = thread_rng(); - rng.gen_range(49152..65535) + ephemeral_configuration() } fn initialized_public_tracker() -> Arc { diff --git a/tests/api/server.rs b/tests/api/server.rs index 338b068c8..9819a0847 100644 --- a/tests/api/server.rs +++ b/tests/api/server.rs @@ -1,8 +1,7 @@ use core::panic; -use std::env; use std::sync::Arc; -use torrust_tracker::config::Configuration; +use torrust_tracker::config::{ephemeral_configuration, Configuration}; use torrust_tracker::jobs::{tracker_api, tracker_apis}; use torrust_tracker::protocol::info_hash::InfoHash; use torrust_tracker::tracker::peer::Peer; @@ -11,24 +10,9 @@ use torrust_tracker::{ephemeral_instance_keys, logging, static_time, tracker}; use super::connection_info::ConnectionInfo; use super::Version; -use crate::common::ephemeral_random_port; pub fn tracker_configuration() -> Arc { - let mut config = Configuration { - log_level: Some("off".to_owned()), - ..Default::default() - }; - - // Ephemeral socket address - let port = ephemeral_random_port(); - config.http_api.bind_address = format!("127.0.0.1:{}", &port); - - // Ephemeral database - let temp_directory = env::temp_dir(); - let temp_file = temp_directory.join(format!("data_{}.db", &port)); - config.db_path = temp_file.to_str().unwrap().to_owned(); - - Arc::new(config) + Arc::new(ephemeral_configuration()) } pub async fn start_default_api(version: &Version) -> Server { diff --git a/tests/common/mod.rs b/tests/common/mod.rs deleted file mode 100644 index 5fd484cf5..000000000 --- a/tests/common/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -use rand::{thread_rng, Rng}; - -pub fn ephemeral_random_port() -> u16 { - // todo: this may produce random test failures because two tests can try to bind the same port. - // We could create a pool of available ports (with read/write lock) - let mut rng = thread_rng(); - rng.gen_range(49152..65535) -} diff --git a/tests/tracker_api.rs b/tests/tracker_api.rs index bac9d1324..301dd5890 100644 --- a/tests/tracker_api.rs +++ b/tests/tracker_api.rs @@ -14,7 +14,6 @@ extern crate rand; mod api; -mod common; mod tracker_api { diff --git a/tests/udp.rs b/tests/udp.rs index 55384db05..408f4f795 100644 --- a/tests/udp.rs +++ b/tests/udp.rs @@ -3,11 +3,8 @@ /// cargo test `udp_tracker_server` -- --nocapture extern crate rand; -mod common; - mod udp_tracker_server { use core::panic; - use std::env; use std::io::Cursor; use std::net::Ipv4Addr; use std::sync::atomic::{AtomicBool, Ordering}; @@ -17,32 +14,24 @@ mod udp_tracker_server { AnnounceEvent, AnnounceRequest, ConnectRequest, ConnectionId, InfoHash, NumberOfBytes, NumberOfPeers, PeerId, PeerKey, Port, Request, Response, ScrapeRequest, TransactionId, }; + use rand::{thread_rng, Rng}; use tokio::net::UdpSocket; use tokio::task::JoinHandle; - use torrust_tracker::config::Configuration; + use torrust_tracker::config::{ephemeral_configuration, Configuration}; use torrust_tracker::jobs::udp_tracker; use torrust_tracker::tracker::statistics::Keeper; use torrust_tracker::udp::MAX_PACKET_SIZE; use torrust_tracker::{ephemeral_instance_keys, logging, static_time, tracker}; - use crate::common::ephemeral_random_port; - fn tracker_configuration() -> Arc { - let mut config = Configuration { - log_level: Some("off".to_owned()), - ..Default::default() - }; - - // Ephemeral socket address - let port = ephemeral_random_port(); - config.udp_trackers[0].bind_address = format!("127.0.0.1:{}", &port); - - // Ephemeral database - let temp_directory = env::temp_dir(); - let temp_file = temp_directory.join(format!("data_{}.db", &port)); - config.db_path = temp_file.to_str().unwrap().to_owned(); + Arc::new(ephemeral_configuration()) + } - Arc::new(config) + pub fn ephemeral_random_client_port() -> u16 { + // todo: this may produce random test failures because two tests can try to bind the same port. + // We could create a pool of available ports (with read/write lock) + let mut rng = thread_rng(); + rng.gen_range(49152..65535) } pub struct UdpServer { @@ -129,7 +118,7 @@ mod udp_tracker_server { /// Creates a new `UdpClient` connected to a Udp server async fn new_connected_udp_client(remote_address: &str) -> UdpClient { - let client = UdpClient::bind(&source_address(ephemeral_random_port())).await; + let client = UdpClient::bind(&source_address(ephemeral_random_client_port())).await; client.connect(remote_address).await; client }