Skip to content

Commit

Permalink
Merge #1267: Overhaul core Tracker: add integration test
Browse files Browse the repository at this point in the history
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
  • Loading branch information
josecelano committed Feb 13, 2025
2 parents 1b745a6 + 35ca428 commit 2f505a8
Showing 1 changed file with 132 additions and 0 deletions.
132 changes: 132 additions & 0 deletions packages/tracker-core/tests/integration.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::str::FromStr;
use std::sync::Arc;

use aquatic_udp_protocol::{AnnounceEvent, NumberOfBytes, PeerId};
use bittorrent_primitives::info_hash::InfoHash;
use bittorrent_tracker_core::announce_handler::{AnnounceHandler, PeersWanted};
use bittorrent_tracker_core::databases::setup::initialize_database;
use bittorrent_tracker_core::scrape_handler::ScrapeHandler;
use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository;
use bittorrent_tracker_core::torrent::repository::persisted::DatabasePersistentTorrentRepository;
use bittorrent_tracker_core::whitelist;
use bittorrent_tracker_core::whitelist::repository::in_memory::InMemoryWhitelist;
use torrust_tracker_configuration::Core;
use torrust_tracker_primitives::peer::Peer;
use torrust_tracker_primitives::DurationSinceUnixEpoch;
use torrust_tracker_test_helpers::configuration::ephemeral_sqlite_database;

/// # Panics
///
/// Will panic if the temporary file path is not a valid UTF-8 string.
#[must_use]
pub fn ephemeral_configuration() -> Core {
let mut config = Core::default();

let temp_file = ephemeral_sqlite_database();
temp_file.to_str().unwrap().clone_into(&mut config.database.path);

config
}

/// # Panics
///
/// Will panic if the string representation of the info hash is not a valid infohash.
#[must_use]
pub fn sample_info_hash() -> InfoHash {
"3b245504cf5f11bbdbe1201cea6a6bf45aee1bc0" // DevSkim: ignore DS173237
.parse::<InfoHash>()
.expect("String should be a valid info hash")
}

/// Sample peer whose state is not relevant for the tests.
#[must_use]
pub fn sample_peer() -> Peer {
Peer {
peer_id: PeerId(*b"-qB00000000000000000"),
peer_addr: SocketAddr::new(remote_client_ip(), 8080),
updated: DurationSinceUnixEpoch::new(1_669_397_478_934, 0),
uploaded: NumberOfBytes::new(0),
downloaded: NumberOfBytes::new(0),
left: NumberOfBytes::new(0), // No bytes left to download
event: AnnounceEvent::Completed,
}
}

// The client peer IP.
#[must_use]
fn remote_client_ip() -> IpAddr {
IpAddr::V4(Ipv4Addr::from_str("126.0.0.1").unwrap())
}

struct Container {
pub announce_handler: Arc<AnnounceHandler>,
pub scrape_handler: Arc<ScrapeHandler>,
}

impl Container {
pub fn initialize(config: &Core) -> Self {
let database = initialize_database(config);
let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default());
let db_torrent_repository = Arc::new(DatabasePersistentTorrentRepository::new(&database));
let in_memory_whitelist = Arc::new(InMemoryWhitelist::default());
let whitelist_authorization = Arc::new(whitelist::authorization::WhitelistAuthorization::new(
config,
&in_memory_whitelist.clone(),
));
let announce_handler = Arc::new(AnnounceHandler::new(
config,
&in_memory_torrent_repository,
&db_torrent_repository,
));
let scrape_handler = Arc::new(ScrapeHandler::new(&whitelist_authorization, &in_memory_torrent_repository));

Self {
announce_handler,
scrape_handler,
}
}
}

#[tokio::test]
async fn test_announce_and_scrape_requests() {
let config = ephemeral_configuration();

let container = Container::initialize(&config);

let info_hash = sample_info_hash();

let mut peer = sample_peer();

// Announce

// First announce: download started
peer.event = AnnounceEvent::Started;
let announce_data =
container
.announce_handler
.announce(&info_hash, &mut peer, &remote_client_ip(), &PeersWanted::AsManyAsPossible);

// NOTICE: you don't get back the peer making the request.
assert_eq!(announce_data.peers.len(), 0);
assert_eq!(announce_data.stats.downloaded, 0);

// Second announce: download completed
peer.event = AnnounceEvent::Completed;
let announce_data =
container
.announce_handler
.announce(&info_hash, &mut peer, &remote_client_ip(), &PeersWanted::AsManyAsPossible);

assert_eq!(announce_data.peers.len(), 0);
assert_eq!(announce_data.stats.downloaded, 1);

// Scrape

let scrape_data = container.scrape_handler.scrape(&vec![info_hash]).await;

assert!(scrape_data.files.contains_key(&info_hash));
}

#[test]
fn test_scrape_request() {}

0 comments on commit 2f505a8

Please sign in to comment.