Skip to content

Commit c744e38

Browse files
committed
Merge #1410: Add a test for global metrics with 2 HTTP trackers
b53da07 refactor: [#1407] remove duplicate code (Jose Celano) aff065c fix: [#1407] docker build after adding new integration test (Jose Celano) 4e59dd7 refactor: [#1407] rename (Jose Celano) 398ad9b refactor: remove duplicate code (Jose Celano) eeea77a chore: remove sample integration test (Jose Celano) 8510990 test: [#1407] add test for global metrics with 2 http trackers (Jose Celano) Pull request description: A new integration test that checks that the global metrics are updated when you run 2 HTTP trackers. Only one metric is checked in this test. It uses fixed ports that might conflict with other running instances in the future. We should use a random free port if we run more integration tests like this in the future. The rest of the functionality is already tested at the package level with only one tracker. I've added to make sure nothing is broken while working on the [stats overhaul](#1327). ACKs for top commit: josecelano: ACK b53da07 Tree-SHA512: 2b3a5758532a42c595497b506e8c861f8a3a499f20fa6515a36de76949a6850bc65c767a8c6d8bd2c20eb58a808b6cff7276359faec6268438a30bbbb995a818
2 parents 1f1da7b + b53da07 commit c744e38

File tree

12 files changed

+125
-53
lines changed

12 files changed

+125
-53
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
/tracker.toml
1515
callgrind.out
1616
codecov.json
17+
integration_tests_sqlite3.db
1718
lcov.info
1819
perf.data*
1920
rustc-ice-*.txt

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ tracing = "0"
6060
tracing-subscriber = { version = "0", features = ["json"] }
6161

6262
[dev-dependencies]
63+
bittorrent-primitives = "0.1.0"
64+
bittorrent-tracker-client = { version = "3.0.0-develop", path = "packages/tracker-client" }
6365
local-ip-address = "0"
6466
mockall = "0"
6567
torrust-rest-tracker-api-client = { version = "3.0.0-develop", path = "packages/rest-tracker-api-client" }

src/app.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,28 @@ use torrust_server_lib::registar::Registar;
2828
use torrust_tracker_configuration::Configuration;
2929
use tracing::instrument;
3030

31+
use crate::bootstrap;
3132
use crate::bootstrap::jobs::{health_check_api, http_tracker, torrent_cleanup, tracker_apis, udp_tracker};
3233
use crate::container::AppContainer;
3334

35+
pub async fn run() -> (Arc<AppContainer>, Vec<JoinHandle<()>>, Registar) {
36+
let (config, app_container) = bootstrap::app::setup();
37+
38+
let app_container = Arc::new(app_container);
39+
40+
let (jobs, registar) = start(&config, &app_container).await;
41+
42+
(app_container, jobs, registar)
43+
}
44+
3445
/// # Panics
3546
///
3647
/// Will panic if:
3748
///
3849
/// - Can't retrieve tracker keys from database.
3950
/// - Can't load whitelist from database.
4051
#[instrument(skip(config, app_container))]
41-
pub async fn start(config: &Configuration, app_container: &Arc<AppContainer>) -> Vec<JoinHandle<()>> {
52+
pub async fn start(config: &Configuration, app_container: &Arc<AppContainer>) -> (Vec<JoinHandle<()>>, Registar) {
4253
if config.http_api.is_none()
4354
&& (config.udp_trackers.is_none() || config.udp_trackers.as_ref().map_or(true, std::vec::Vec::is_empty))
4455
&& (config.http_trackers.is_none() || config.http_trackers.as_ref().map_or(true, std::vec::Vec::is_empty))
@@ -138,8 +149,10 @@ pub async fn start(config: &Configuration, app_container: &Arc<AppContainer>) ->
138149
));
139150
}
140151

152+
println!("Registar entries: {:?}", registar.entries());
153+
141154
// Start Health Check API
142155
jobs.push(health_check_api::start_job(&config.health_check_api, registar.entries()).await);
143156

144-
jobs
157+
(jobs, registar)
145158
}

src/console/profiling.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,11 @@
157157
//! kcachegrind callgrind.out
158158
//! ```
159159
use std::env;
160-
use std::sync::Arc;
161160
use std::time::Duration;
162161

163162
use tokio::time::sleep;
164163

165-
use crate::{app, bootstrap};
164+
use crate::app;
166165

167166
pub async fn run() {
168167
// Parse command line arguments
@@ -180,11 +179,7 @@ pub async fn run() {
180179
return;
181180
};
182181

183-
let (config, app_container) = bootstrap::app::setup();
184-
185-
let app_container = Arc::new(app_container);
186-
187-
let jobs = app::start(&config, &app_container).await;
182+
let (_app_container, jobs, _registar) = app::run().await;
188183

189184
// Run the tracker for a fixed duration
190185
let run_duration = sleep(Duration::from_secs(duration_secs));

src/main.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
use std::sync::Arc;
2-
3-
use torrust_tracker_lib::{app, bootstrap};
1+
use torrust_tracker_lib::app;
42

53
#[tokio::main]
64
async fn main() {
7-
let (config, app_container) = bootstrap::app::setup();
8-
9-
let app_container = Arc::new(app_container);
10-
11-
let jobs = app::start(&config, &app_container).await;
5+
let (_app_container, jobs, _registar) = app::run().await;
126

137
// handle the signals
148
tokio::select! {

tests/integration.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
//! Scaffolding for integration tests.
22
//!
3+
//! Integration tests are used to test the interaction between multiple modules,
4+
//! multiple running trackers, etc. Tests for one specific module should be in
5+
//! the corresponding package.
6+
//!
37
//! ```text
48
//! cargo test --test integration
59
//! ```
610
mod servers;
711

8-
// todo: there is only one test example that was copied from other package.
9-
// We have to add tests for the whole app.
10-
1112
use torrust_tracker_clock::clock;
1213

1314
/// This code needs to be copied into each crate.

tests/servers/api/contract/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod stats;
+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
use std::env;
2+
use std::str::FromStr as _;
3+
4+
use bittorrent_primitives::info_hash::InfoHash;
5+
use bittorrent_tracker_client::http::client::requests::announce::QueryBuilder;
6+
use bittorrent_tracker_client::http::client::Client as HttpTrackerClient;
7+
use reqwest::Url;
8+
use serde::Deserialize;
9+
use tokio::time::Duration;
10+
use torrust_rest_tracker_api_client::connection_info::{ConnectionInfo, Origin};
11+
use torrust_rest_tracker_api_client::v1::client::Client as TrackerApiClient;
12+
use torrust_tracker_lib::app;
13+
14+
#[tokio::test]
15+
async fn the_stats_api_endpoint_should_return_the_global_stats() {
16+
// Logging must be OFF otherwise your will get the following error:
17+
// `Unable to install global subscriber: SetGlobalDefaultError("a global default trace dispatcher has already been set")`
18+
// That's because we can't initialize the logger twice.
19+
// You can enable it if you run only this test.
20+
let config_with_two_http_trackers = r#"
21+
[metadata]
22+
app = "torrust-tracker"
23+
purpose = "configuration"
24+
schema_version = "2.0.0"
25+
26+
[logging]
27+
threshold = "off"
28+
29+
[core]
30+
listed = false
31+
private = false
32+
33+
[core.database]
34+
driver = "sqlite3"
35+
path = "./integration_tests_sqlite3.db"
36+
37+
[[http_trackers]]
38+
bind_address = "0.0.0.0:7272"
39+
tracker_usage_statistics = true
40+
41+
[[http_trackers]]
42+
bind_address = "0.0.0.0:7373"
43+
tracker_usage_statistics = true
44+
45+
[http_api]
46+
bind_address = "0.0.0.0:1414"
47+
48+
[http_api.access_tokens]
49+
admin = "MyAccessToken"
50+
"#;
51+
52+
env::set_var("TORRUST_TRACKER_CONFIG_TOML", config_with_two_http_trackers);
53+
54+
let (_app_container, _jobs, _registar) = app::run().await;
55+
56+
announce_to_tracker("http://127.0.0.1:7272").await;
57+
announce_to_tracker("http://127.0.0.1:7373").await;
58+
59+
let global_stats = get_tracker_statistics("http://127.0.0.1:1414", "MyAccessToken").await;
60+
61+
assert_eq!(global_stats.tcp4_announces_handled, 2);
62+
}
63+
64+
/// Make a sample announce request to the tracker.
65+
async fn announce_to_tracker(tracker_url: &str) {
66+
let response = HttpTrackerClient::new(Url::parse(tracker_url).unwrap(), Duration::from_secs(1))
67+
.unwrap()
68+
.announce(
69+
&QueryBuilder::with_default_values()
70+
.with_info_hash(&InfoHash::from_str("9c38422213e30bff212b30c360d26f9a02136422").unwrap()) // DevSkim: ignore DS173237
71+
.query(),
72+
)
73+
.await;
74+
75+
assert!(response.is_ok());
76+
}
77+
78+
/// Global statistics with only metrics relevant to the test.
79+
#[derive(Deserialize)]
80+
struct PartialGlobalStatistics {
81+
tcp4_announces_handled: u64,
82+
}
83+
84+
async fn get_tracker_statistics(aip_url: &str, token: &str) -> PartialGlobalStatistics {
85+
let response = TrackerApiClient::new(ConnectionInfo::authenticated(Origin::new(aip_url).unwrap(), token))
86+
.unwrap()
87+
.get_tracker_statistics(None)
88+
.await;
89+
90+
response
91+
.json::<PartialGlobalStatistics>()
92+
.await
93+
.expect("Failed to parse JSON response")
94+
}

tests/servers/api/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod contract;

tests/servers/health_check_api.rs

-32
This file was deleted.

tests/servers/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
pub mod health_check_api;
1+
pub mod api;

0 commit comments

Comments
 (0)