|
| 1 | +/// Integration tests for the tracker API |
| 2 | +/// |
| 3 | +/// cargo test tracker_api -- --nocapture |
| 4 | +extern crate rand; |
| 5 | + |
| 6 | +mod common; |
| 7 | + |
| 8 | +mod tracker_api { |
| 9 | + use core::panic; |
| 10 | + use std::env; |
| 11 | + use std::sync::atomic::{AtomicBool, Ordering}; |
| 12 | + use std::sync::Arc; |
| 13 | + |
| 14 | + use tokio::task::JoinHandle; |
| 15 | + use tokio::time::{sleep, Duration}; |
| 16 | + use torrust_tracker::api::resources::auth_key_resource::AuthKeyResource; |
| 17 | + use torrust_tracker::jobs::tracker_api; |
| 18 | + use torrust_tracker::tracker::key::AuthKey; |
| 19 | + use torrust_tracker::tracker::statistics::StatsTracker; |
| 20 | + use torrust_tracker::tracker::tracker::TorrentTracker; |
| 21 | + use torrust_tracker::{ephemeral_instance_keys, logging, static_time, Configuration}; |
| 22 | + |
| 23 | + use crate::common::ephemeral_random_port; |
| 24 | + |
| 25 | + #[tokio::test] |
| 26 | + async fn should_generate_a_new_auth_key() { |
| 27 | + let configuration = tracker_configuration(); |
| 28 | + let api_server = new_running_api_server(configuration.clone()).await; |
| 29 | + |
| 30 | + let bind_address = api_server.bind_address.unwrap().clone(); |
| 31 | + let seconds_valid = 60; |
| 32 | + let api_token = configuration.http_api.access_tokens.get_key_value("admin").unwrap().1.clone(); |
| 33 | + |
| 34 | + let url = format!("http://{}/api/key/{}?token={}", &bind_address, &seconds_valid, &api_token); |
| 35 | + |
| 36 | + let auth_key: AuthKeyResource = reqwest::Client::new().post(url).send().await.unwrap().json().await.unwrap(); |
| 37 | + |
| 38 | + // Verify the key with the tracker |
| 39 | + assert!(api_server |
| 40 | + .tracker |
| 41 | + .unwrap() |
| 42 | + .verify_auth_key(&AuthKey::from(auth_key)) |
| 43 | + .await |
| 44 | + .is_ok()); |
| 45 | + } |
| 46 | + |
| 47 | + fn tracker_configuration() -> Arc<Configuration> { |
| 48 | + let mut config = Configuration::default(); |
| 49 | + config.log_level = Some("off".to_owned()); |
| 50 | + |
| 51 | + config.http_api.bind_address = format!("127.0.0.1:{}", ephemeral_random_port()); |
| 52 | + |
| 53 | + // Temp database |
| 54 | + let temp_directory = env::temp_dir(); |
| 55 | + let temp_file = temp_directory.join("data.db"); |
| 56 | + config.db_path = temp_file.to_str().unwrap().to_owned(); |
| 57 | + |
| 58 | + Arc::new(config) |
| 59 | + } |
| 60 | + |
| 61 | + async fn new_running_api_server(configuration: Arc<Configuration>) -> ApiServer { |
| 62 | + let mut api_server = ApiServer::new(); |
| 63 | + api_server.start(configuration).await; |
| 64 | + api_server |
| 65 | + } |
| 66 | + |
| 67 | + pub struct ApiServer { |
| 68 | + pub started: AtomicBool, |
| 69 | + pub job: Option<JoinHandle<()>>, |
| 70 | + pub bind_address: Option<String>, |
| 71 | + pub tracker: Option<Arc<TorrentTracker>>, |
| 72 | + } |
| 73 | + |
| 74 | + impl ApiServer { |
| 75 | + pub fn new() -> Self { |
| 76 | + Self { |
| 77 | + started: AtomicBool::new(false), |
| 78 | + job: None, |
| 79 | + bind_address: None, |
| 80 | + tracker: None, |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + pub async fn start(&mut self, configuration: Arc<Configuration>) { |
| 85 | + if !self.started.load(Ordering::Relaxed) { |
| 86 | + self.bind_address = Some(configuration.http_api.bind_address.clone()); |
| 87 | + |
| 88 | + // Set the time of Torrust app starting |
| 89 | + lazy_static::initialize(&static_time::TIME_AT_APP_START); |
| 90 | + |
| 91 | + // Initialize the Ephemeral Instance Random Seed |
| 92 | + lazy_static::initialize(&ephemeral_instance_keys::RANDOM_SEED); |
| 93 | + |
| 94 | + // Initialize stats tracker |
| 95 | + let (stats_event_sender, stats_repository) = StatsTracker::new_active_instance(); |
| 96 | + |
| 97 | + // Initialize Torrust tracker |
| 98 | + let tracker = match TorrentTracker::new(configuration.clone(), Some(stats_event_sender), stats_repository) { |
| 99 | + Ok(tracker) => Arc::new(tracker), |
| 100 | + Err(error) => { |
| 101 | + panic!("{}", error) |
| 102 | + } |
| 103 | + }; |
| 104 | + self.tracker = Some(tracker.clone()); |
| 105 | + |
| 106 | + // Initialize logging |
| 107 | + logging::setup_logging(&configuration); |
| 108 | + |
| 109 | + // Start the HTTP API job |
| 110 | + self.job = Some(tracker_api::start_job(&configuration, tracker.clone())); |
| 111 | + |
| 112 | + self.started.store(true, Ordering::Relaxed); |
| 113 | + |
| 114 | + // Wait to give time to the API server to be ready to accept requests |
| 115 | + sleep(Duration::from_millis(100)).await; |
| 116 | + } |
| 117 | + } |
| 118 | + } |
| 119 | +} |
0 commit comments