Skip to content

Commit

Permalink
test(http): [#159] add tests for uptadint statistics after announce r…
Browse files Browse the repository at this point in the history
…equest
  • Loading branch information
josecelano committed Jan 25, 2023
1 parent 85a4894 commit 080f3c4
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 12 deletions.
29 changes: 18 additions & 11 deletions tests/http/client.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,38 @@
use reqwest::Response;
use std::net::IpAddr;

use reqwest::{Client as ReqwestClient, Response};

use super::connection_info::ConnectionInfo;
use super::requests::AnnounceQuery;

/// HTTP Tracker Client
pub struct Client {
connection_info: ConnectionInfo,
reqwest_client: ReqwestClient,
}

impl Client {
pub fn new(connection_info: ConnectionInfo) -> Self {
Self { connection_info }
Self {
connection_info,
reqwest_client: reqwest::Client::builder().build().unwrap(),
}
}

/// Creates the new client binding it to an specific local address
pub fn bind(connection_info: ConnectionInfo, local_address: IpAddr) -> Self {
Self {
connection_info,
reqwest_client: reqwest::Client::builder().local_address(local_address).build().unwrap(),
}
}

pub async fn announce(&self, query: &AnnounceQuery) -> Response {
let path_with_query = format!("announce?{query}");
self.get(&path_with_query).await
self.get(&format!("announce?{query}")).await
}

pub async fn get(&self, path: &str) -> Response {
reqwest::Client::builder()
.build()
.unwrap()
.get(self.base_url(path))
.send()
.await
.unwrap()
self.reqwest_client.get(self.base_url(path)).send().await.unwrap()
}

fn base_url(&self, path: &str) -> String {
Expand Down
5 changes: 5 additions & 0 deletions tests/http/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ impl AnnounceQueryBuilder {
self
}

pub fn with_peer_addr(mut self, peer_addr: &IpAddr) -> Self {
self.announce_query.peer_addr = *peer_addr;
self
}

pub fn without_compact(mut self) -> Self {
self.announce_query.compact = None;
self
Expand Down
21 changes: 21 additions & 0 deletions tests/http/server.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use core::panic;
use std::net::SocketAddr;
use std::sync::Arc;

use torrust_tracker::config::{ephemeral_configuration, Configuration};
Expand All @@ -10,10 +11,30 @@ use torrust_tracker::{ephemeral_instance_keys, logging, static_time, tracker};

use super::connection_info::ConnectionInfo;

/// Starts a HTTP tracker with mode "public"
pub async fn start_public_http_tracker() -> Server {
start_default_http_tracker().await
}

/// Starts a HTTP tracker with a wildcard IPV6 address.
/// The configuration in the `config.toml` file would be like this:
///
/// ```text
/// [[http_trackers]]
/// bind_address = "[::]:7070"
/// ```
pub async fn start_ipv6_http_tracker() -> Server {
let mut configuration = ephemeral_configuration();

// Change socket address to "wildcard address" (unspecified address which means any IP address)
// but keeping the random port generated with the ephemeral configuration.
let socket_addr: SocketAddr = configuration.http_trackers[0].bind_address.parse().unwrap();
let new_ipv6_socket_address = format!("[::]:{}", socket_addr.port());
configuration.http_trackers[0].bind_address = new_ipv6_socket_address;

start_custom_http_tracker(Arc::new(configuration)).await
}

pub async fn start_default_http_tracker() -> Server {
let configuration = tracker_configuration();
start_custom_http_tracker(configuration.clone()).await
Expand Down
93 changes: 92 additions & 1 deletion tests/http_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ mod http_tracker_server {
mod configured_as_public {

mod receiving_an_announce_request {
use std::net::{IpAddr, Ipv6Addr};
use std::str::FromStr;

use reqwest::Response;
Expand All @@ -305,7 +306,7 @@ mod http_tracker_server {
use crate::http::responses::{
Announce, CompactAnnounce, CompactPeer, CompactPeerList, DecodedCompactAnnounce, DictionaryPeer,
};
use crate::http::server::start_public_http_tracker;
use crate::http::server::{start_ipv6_http_tracker, start_public_http_tracker};

#[tokio::test]
async fn should_return_no_peers_if_the_announced_peer_is_the_first_one() {
Expand Down Expand Up @@ -471,6 +472,96 @@ mod http_tracker_server {
let compact_announce = serde_bencode::from_bytes::<CompactAnnounce>(&bytes);
compact_announce.is_ok()
}

#[tokio::test]
async fn should_increase_the_number_of_tcp4_connections_handled_in_statistics() {
let http_tracker_server = start_public_http_tracker().await;

Client::new(http_tracker_server.get_connection_info())
.announce(&AnnounceQueryBuilder::default().query())
.await;

let stats = http_tracker_server.tracker.get_stats().await;

assert_eq!(stats.tcp4_connections_handled, 1);
}

#[tokio::test]
async fn should_increase_the_number_of_tcp6_connections_handled_in_statistics() {
let http_tracker_server = start_ipv6_http_tracker().await;

Client::bind(http_tracker_server.get_connection_info(), IpAddr::from_str("::1").unwrap())
.announce(&AnnounceQueryBuilder::default().query())
.await;

let stats = http_tracker_server.tracker.get_stats().await;

assert_eq!(stats.tcp6_connections_handled, 1);
}

#[tokio::test]
async fn should_not_increase_the_number_of_tcp6_connections_handled_if_the_client_is_not_using_an_ipv6_ip() {
// The tracker ignores the peer address in the request param. It uses the client remote ip address.

let http_tracker_server = start_public_http_tracker().await;

Client::new(http_tracker_server.get_connection_info())
.announce(
&AnnounceQueryBuilder::default()
.with_peer_addr(&IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))
.query(),
)
.await;

let stats = http_tracker_server.tracker.get_stats().await;

assert_eq!(stats.tcp6_connections_handled, 0);
}

#[tokio::test]
async fn should_increase_the_number_of_tcp4_announce_requests_handled_in_statistics() {
let http_tracker_server = start_public_http_tracker().await;

Client::new(http_tracker_server.get_connection_info())
.announce(&AnnounceQueryBuilder::default().query())
.await;

let stats = http_tracker_server.tracker.get_stats().await;

assert_eq!(stats.tcp4_announces_handled, 1);
}

#[tokio::test]
async fn should_increase_the_number_of_tcp6_announce_requests_handled_in_statistics() {
let http_tracker_server = start_ipv6_http_tracker().await;

Client::bind(http_tracker_server.get_connection_info(), IpAddr::from_str("::1").unwrap())
.announce(&AnnounceQueryBuilder::default().query())
.await;

let stats = http_tracker_server.tracker.get_stats().await;

assert_eq!(stats.tcp6_announces_handled, 1);
}

#[tokio::test]
async fn should_not_increase_the_number_of_tcp6_announce_requests_handled_if_the_client_is_not_using_an_ipv6_ip() {
// The tracker ignores the peer address in the request param. It uses the client remote ip address.

let http_tracker_server = start_public_http_tracker().await;

Client::new(http_tracker_server.get_connection_info())
.announce(
&AnnounceQueryBuilder::default()
.with_peer_addr(&IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)))
.query(),
)
.await;

let stats = http_tracker_server.tracker.get_stats().await;

assert_eq!(stats.tcp6_announces_handled, 0);
}
}
}
}

0 comments on commit 080f3c4

Please sign in to comment.